41.android:id="@+id/pageView1"
42.android:layout_gravity="center"
43.android:layout_marginTop="5px"
44.android:layout_width="fill_parent"
45.android:layout_height="fill_parent"/>
46.
47.由于使用 XML,所以构造方法必须要有,带两个参数的.
48.public PageView(Context context, AttributeSet attrs){
49. super(context, attrs);
50. initView();
51.}
52.InitView:
53.private void initView(){
54. image1 = Bitmap.createBitmap(BitmapFactory.decodeResource
(getResources(), R.drawable.aac));
55. image2 = Bitmap.createBitmap(BitmapFactory.decodeResource
(getResources(), R.drawable.q1));
56. image3 = Bitmap.createBitmap(BitmapFactory.decodeResource
(getResources(), R.drawable.q2));
57.
58. myHandler = new MyHandler();
59. gestureDetector = new GestureDetector(this);
60. mShader = new LinearGradient(10, 250, 250, 250,
61. new int[]{Color.RED, Color.GREEN, Color.BLUE},
62. null, Shader.TileMode.MIRROR);
63. paint1 = new Paint();
64. paint1.setFlags(Paint.ANTI_ALIAS_FLAG); //去除插刺
65. paint2 = new Paint(paint1);
66. paint3 = new Paint(paint2);
67. paint3.setColor(0x45111111);
68. //paint.setShader(mShader);//其间颜色会有变化.
69. paint3.setStrokeWidth(12);
70. paint4 = new Paint(paint2);
71. paint4.setColor(0xff111111);
72. paint4.setShader(mShader);//其间颜色会有变化.
73. paint4.setStrokeWidth(12);
74. }
75.
76.代码就到这里了.关于三角形卷动翻页,代码没有写完整,(第三张图片还
没有弄,也没有阴影),先不写了,而且似乎也不止我这样一种写法的,网上
看到的翻页还有其它的,比如我见到一个,OnDraw 里得到画布的高,然后
一行一行描述,并逐行递减宽度,这样造成一个三角形,速度也不那么地慢.
还可接受.
77.
78.来些图片.
79.page-15.png 到 page-16.png,宽度越来越小了.
80.page-12.png到page-14.png是三角形的,里面具体操作复杂一些,当前差
上面那张遮罩.以后再完善了.
81. android 中颜色对应的值
82.文章分类:移动开发
83. < ?xml version="1.0" encoding="utf-8" ?>
< resources>
< color name="white">#FFFFFF< /color>< !--白色 -->
< color name="ivory">#FFFFF0< /color>< !--象牙色 -->
< color name="lightyellow">#FFFFE0< /color>< !--亮黄色 -->
< color name="yellow">#FFFF00< /color>< !--黄色 -->
< color name="snow">#FFFAFA< /color>< !--雪白色 -->
< color name="floralwhite">#FFFAF0< /color>< !--花白色 -->
< color name="lemonchiffon">#FFFACD< /color>< !--柠檬绸色 -->
< color name="cornsilk">#FFF8DC< /color>< !--米绸色 -->
< color name="seashell">#FFF5EE< /color>< !--海贝色 -->
< color name="lavenderblush">#FFF0F5< /color>< !--淡紫红 -->
< color name="papayawhip">#FFEFD5< /color>< !--番木色 -->
< color name="blanchedalmond">#FFEBCD< /color>< !--白杏色 -->
< color name="mistyrose">#FFE4E1< /color>< !--浅玫瑰色 -->
< color name="bisque">#FFE4C4< /color>< !--桔黄色 -->
< color name="moccasin">#FFE4B5< /color>< !--鹿皮色 -->
< color name="navajowhite">#FFDEAD< /color>< !--纳瓦白 -->
< color name="peachpuff">#FFDAB9< /color>< !--桃色 -->
< color name="gold">#FFD700< /color>< !--金色 -->
< color name="pink">#FFC0CB< /color>< !--粉红色 -->
< color name="lightpink">#FFB6C1< /color>< !--亮粉红色 -->
< color name="orange">#FFA500< /color>< !--橙色 -->
< color name="lightsalmon">#FFA07A< /color>< !--亮肉色 -->
< color name="darkorange">#FF8C00< /color>< !--暗桔黄色 -->
< color name="coral">#FF7F50< /color>< !--珊瑚色 -->
< color name="hotpink">#FF69B4< /color>< !--热粉红色 -->
< color name="tomato">#FF6347< /color>< !--西红柿色 -->
< color name="orangered">#FF4500< /color>< !--红橙色 -->
< color name="deeppink">#FF1493< /color>< !--深粉红色 -->
< color name="fuchsia">#FF00FF< /color>< !--紫红色 -->
< color name="magenta">#FF00FF< /color>< !--红紫色 -->
< color name="red">#FF0000< /color>< !--红色 -->
< color name="oldlace">#FDF5E6< /color>< !--老花色 -->
< color name="lightgoldenrodyellow">#FAFAD2< /color>< !--亮
金黄色 -->
< color name="linen">#FAF0E6< /color>< !--亚麻色 -->
< color name="antiquewhite">#FAEBD7< /color>< !--古董白 -->
< color name="salmon">#FA8072< /color>< !--鲜肉色 -->
< color name="ghostwhite">#F8F8FF< /color>< !--幽灵白 -->
< color name="mintcream">#F5FFFA< /color>< !--薄荷色 -->
< color name="whitesmoke">#F5F5F5< /color>< !--烟白色 -->
< color name="beige">#F5F5DC< /color>< !--米色 -->
< color name="wheat">#F5DEB3< /color>< !--浅黄色 -->
< color name="sandybrown">#F4A460< /color>< !--沙褐色 -->
< color name="azure">#F0FFFF< /color>< !--天蓝色 -->
< color name="honeydew">#F0FFF0< /color>< !--蜜色 -->
< color name="aliceblue">#F0F8FF< /color>< !--艾利斯兰 -->
< color name="khaki">#F0E68C< /color>< !--黄褐色 -->
< color name="lightcoral">#F08080< /color>< !--亮珊瑚色 -->
< color name="palegoldenrod">#EEE8AA< /color>< !--苍麒麟色 -->
< color name="violet">#EE82EE< /color>< !--紫罗兰色 -->
< color name="darksalmon">#E9967A< /color>< !--暗肉色 -->
< color name="lavender">#E6E6FA< /color>< !--淡紫色 -->
< color name="lightcyan">#E0FFFF< /color>< !--亮青色 -->
< color name="burlywood">#DEB887< /color>< !--实木色 -->
< color name="plum">#DDA0DD< /color>< !--洋李色 -->
< color name="gainsboro">#DCDCDC< /color>< !--淡灰色 -->
< color name="crimson">#DC143C< /color>< !--暗深红色 -->
< color name="palevioletred">#DB7093< /color>< !--苍紫罗兰色
-->
< color name="goldenrod">#DAA520< /color>< !--金麒麟色 -->
< color name="orchid">#DA70D6< /color>< !--淡紫色 -->
< color name="thistle">#D8BFD8< /color>< !--蓟色 -->
< color name="lightgray">#D3D3D3< /color>< !--亮灰色 -->
< color name="lightgrey">#D3D3D3< /color>< !--亮灰色 -->
< color name="tan">#D2B48C< /color>< !--茶色 -->
< color name="chocolate">#D2691E< /color>< !--巧可力色 -->
< color name="peru">#CD853F< /color>< !--秘鲁色 -->
< color name="indianred">#CD5C5C< /color>< !--印第安红 -->
< color name="mediumvioletred">#C71585< /color>< !--中紫罗兰色 -->
< color name="silver">#C0C0C0< /color>< !--银色 -->
< color name="darkkhaki">#BDB76B< /color>< !--暗黄褐色
< color name="rosybrown">#BC8F8F< /color>< !--褐玫瑰红 -->
< color name="mediumorchid">#BA55D3< /color>< !--中粉紫色 -->
< color name="darkgoldenrod">#B8860B< /color>< !--暗金黄色 -->
< color name="firebrick">#B22222< /color>< !--火砖色 -->
< color name="powderblue">#B0E0E6< /color>< !--粉蓝色 -->
< color name="lightsteelblue">#B0C4DE< /color>< !--亮钢兰色 -->
< color name="paleturquoise">#AFEEEE< /color>< !--苍宝石绿 -->
< color name="greenyellow">#ADFF2F< /color>< !--黄绿色 -->
< color name="lightblue">#ADD8E6< /color>< !--亮蓝色 -->
< color name="darkgray">#A9A9A9< /color>< !--暗灰色 -->
< color name="darkgrey">#A9A9A9< /color>< !--暗灰色 -->
< color name="brown">#A52A2A< /color>< !--褐色 -->
< color name="sienna">#A0522D< /color>< !--赭色 -->
< color name="darkorchid">#9932CC< /color>< !--暗紫色 -->
< color name="palegreen">#98FB98< /color>< !--苍绿色 -->
< color name="darkviolet">#9400D3< /color>< !--暗紫罗兰色 -->
< color name="mediumpurple">#9370DB< /color>< !--中紫色 -->
< color name="lightgreen">#90EE90< /color>< !--亮绿色 -->
< color name="darkseagreen">#8FBC8F< /color>< !--暗海兰色 -->
< color name="saddlebrown">#8B4513< /color>< !--重褐色 -->
< color name="darkmagenta">#8B008B< /color>< !--暗洋红 -->
< color name="darkred">#8B0000< /color>< !--暗红色 -->
< color name="blueviolet">#8A2BE2< /color>< !--紫罗兰蓝色
< color name="lightskyblue">#87CEFA< /color>< !--亮天蓝色 -->
< color name="skyblue">#87CEEB< /color>< !--天蓝色 -->
< color name="gray">#808080< /color>< !--灰色 -->
< color name="grey">#808080< /color>< !--灰色 -->
< color name="olive">#808000< /color>< !--橄榄色 -->
< color name="purple">#800080< /color>< !--紫色 -->
< color name="maroon">#800000< /color>< !--粟色 -->
< color name="aquamarine">#7FFFD4< /color>< !--碧绿色 -->
< color name="chartreuse">#7FFF00< /color>< !--黄绿色 -->
< color name="lawngreen">#7CFC00< /color>< !--草绿色 -->
< color name="mediumslateblue">#7B68EE< /color>< !--中暗蓝色-->
< color name="lightslategray">#778899< /color>< !--亮蓝灰 -->
< color name="lightslategrey">#778899< /color>< !--亮蓝灰 -->
< color name="slategray">#708090< /color>< !--灰石色 -->
< color name="slategrey">#708090< /color>< !--灰石色 -->
< color name="olivedrab">#6B8E23< /color>< !--深绿褐色 -->
< color name="slateblue">#6A5ACD< /color>< !--石蓝色 -->
< color name="dimgray">#696969< /color>< !--暗灰色 -->
< color name="dimgrey">#696969< /color>< !--暗灰色 -->
< color name="mediumaquamarine">#66CDAA< /color>< !--中绿色-->
< color name="cornflowerblue">#6495ED< /color>< !--菊兰色 -->
< color name="cadetblue">#5F9EA0< /color>< !--军兰色 -->
< color name="darkolivegreen">#556B2F< /color>< !--暗橄榄绿
< color name="indigo">#4B0082< /color>< !--靛青色 -->
< color name="mediumturquoise">#48D1CC< /color>< !--中绿宝石 -->
< color name="darkslateblue">#483D8B< /color>< !--暗灰蓝色 -->
< color name="steelblue">#4682B4< /color>< !--钢兰色 -->
< color name="royalblue">#4169E1< /color>< !--皇家蓝 -->
< color name="turquoise">#40E0D0< /color>< !--青绿色 -->
< color name="mediumseagreen">#3CB371< /color>< !--中海蓝 -->
< color name="limegreen">#32CD32< /color>< !--橙绿色 -->
< color name="darkslategray">#2F4F4F< /color>< !--暗瓦灰色 -->
< color name="darkslategrey">#2F4F4F< /color>< !--暗瓦灰色 -->
< color name="seagreen">#2E8B57< /color>< !--海绿色 -->
< color name="forestgreen">#228B22< /color>< !--森林绿 -->
< color name="lightseagreen">#20B2AA< /color>< !--亮海蓝色 -->
< color name="dodgerblue">#1E90FF< /color>< !--闪兰色 -->
< color name="midnightblue">#191970< /color>< !--中灰兰色 -->
< color name="aqua">#00FFFF< /color>< !--浅绿色 -->
< color name="cyan">#00FFFF< /color>< !--青色 -->
< color name="springgreen">#00FF7F< /color>< !--春绿色 -->
< color name="lime">#00FF00< /color>< !--酸橙色 -->
< color name="mediumspringgreen">#00FA9A< /color>< !--中春绿色 -->
< color name="darkturquoise">#00CED1< /color>< !--暗宝石绿 -->
< color name="deepskyblue">#00BFFF< /color>< !--深天蓝色 -->
< color name="darkcyan">#008B8B< /color>< !--暗青色 -->
< color name="teal">#008080< /color>< !--水鸭色 -->
< color name="green">#008000< /color>< !--绿色 -->
< color name="darkgreen">#006400< /color>< !--暗绿色 -->
< color name="blue">#0000FF< /color>< !--蓝色 -->
< color name="mediumblue">#0000CD< /color>< !--中兰色 -->
< color name="darkblue">#00008B< /color>< !--暗蓝色 -->
< color name="navy">#000080< /color>< !--海军色 -->
< color name="black">#000000< /color>< !--黑色 -->
< /resources>
android ListView 详解
在 android 开发中 ListView 是比较常用的组件,它以列表的形式展示具体内容,并且
能够根据数据的长度自适应显示。抽空把对 ListView 的使用做了整理,并写了个小例子,
如下图。
列表的显示需要三个元素:
1.ListVeiw 用来展示列表的 View。
2.适配器 用来把数据映射到 ListView 上的中介。
3.数据 具体的将被映射的字符串,图片,或者基本组件。
根据列表的适配器类型,列表分为三种,ArrayAdapter,SimpleAdapter 和 SimpleCur
sorAdapter
其中以 ArrayAdapter 最为简单,只能展示一行字。SimpleAdapter 有最好的扩充性,可
以自定义出各种效果。SimpleCursorAdapter 可以认为是 SimpleAdapter 对数据库的简
单结合,可以方面的把数据库的内容以列表的形式展示出来。
我们从最简单的 ListView 开始:
print?
01 /**
02 * @author allin
03 *
04 */
05 public class MyListView extends Activity {
06
07 private ListView listView;
08 //private List data = new ArrayList();
09 @Override
10 public void onCreate(Bundle savedInstanceState){
11 super.onCreate(savedInstanceState);
12
13 listView = new ListView(this);
14
listView.setAdapter(new ArrayAdapter(this,
android.R.layout.simple_expandable_list_item_1,getData()));
15 setContentView(listView);
16 }
17
18
19
20 private List getData(){
21
22 List data = new ArrayList();
23 data.add("测试数据 1");
24 data.add("测试数据 2");
25 data.add("测试数据 3");
26 data.add("测试数据 4");
28 return data;
29 }
30 }
上面代码使用了 ArrayAdapter(Context context, int textViewResourceId, List
objects)来装配数据,要装配这些数据就需要一个连接 ListView 视图对象和数组数据的
适配器来两者的适配工作,ArrayAdapter 的构造需要三个参数,依次为 this,布局文件(注
意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_
1 是系统定义好的布局文件只显示一行文字,数据源(一个 List 集合)。同时用 setAdapter
()完成适配的最后工作。运行后的现实结构如下图:
SimpleCursorAdapter
sdk 的解释是这样的:An easy adapter to map columns from a cursor to T
extViews or ImageViews defined in an XML file. You can specify which colu
mns you want, which views you want to display the columns, and the XML
file that defines the appearance of these views。简单的说就是方便把从游标得到
的数据进行列表显示,并可以把指定的列映射到对应的 TextView 中。
下面的程序是从电话簿中把联系人显示到类表中。先在通讯录中添加一个联系人作为数
据库的数据。然后获得一个指向数据库的 Cursor 并且定义一个布局文件(当然也可以使用
系统自带的)。
view source
print?
01 /**
02 * @author allin
03 *
04 */
05 public class MyListView2 extends Activity {
07 private ListView listView;
08 //private List data = new ArrayList();
09 @Override
10 public void onCreate(Bundle savedInstanceState){
11 super.onCreate(savedInstanceState);
13 listView = new ListView(this);
15
Cursor cursor = getContentResolver().query(People.CONTENT_URI,
null, null, null, null);
16 startManagingCursor(cursor);
18
ListAdapter listAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_expandable_list_item_1,
19 cursor,
20 new String[]{People.NAME},
21 new int[]{android.R.id.text1});
23 listView.setAdapter(listAdapter);
24 setContentView(listView);
25 }
Cursor cursor = getContentResolver().query(People.CONTENT_URI, null,
null, null, null);先获得一个指向系统通讯录数据库的 Cursor 对象获得数据来源。
startManagingCursor(cursor);我们将获得的 Cursor 对象交由 Activity 管理,这样 C
ursor 的生命周期和 Activity 便能够自动同步,省去自己手动管理 Cursor。
SimpleCursorAdapter 构造函数前面 3 个参数和 ArrayAdapter 是一样的,最后两个
参数:一个包含数据库的列的 String 型数组,一个包含布局文件中对应组件 id 的 int 型数
组。其作用是自动的将String 型数组所表示的每一列数据映射到布局文件对应id 的组件上。
上面的代码,将 NAME 列的数据一次映射到布局文件的 id 为 text1 的组件上。
注意:需要在 AndroidManifest.xml 中如权限: android.permission.READ_CONTACTS">
运行后效果如下图:
SimpleAdapter
simpleAdapter 的扩展性最好,可以定义各种各样的布局出来,可以放上 ImageView(图
片),还可以放上 Button(按钮),CheckBox(复选框)等等。下面的代码都直接继承了
ListActivity,ListActivity 和普通的 Activity 没有太大的差别,不同就是对显示 ListView
做了许多优化,方面显示而已。
下面的程序是实现一个带有图片的类表。
首先需要定义好一个用来显示每一个列内容的 xml
vlist.xml
view source
print?
01
02
xmlns:android="http://schemas.android.com/apk/res/android"
03
android:orientation="horizontal"
android:layout_width="fill_parent"
04 android:layout_height="fill_parent">
07
08 android:layout_width="wrap_content"
09 android:layout_height="wrap_content"
10 android:layout_margin="5px"/>
11
12
13 android:layout_width="wrap_content"
14 android:layout_height="wrap_content">
15
16
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:textColor="#FFFFFFFF"
20 android:textSize="22px" />
21
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:textColor="#FFFFFFFF"
25 android:textSize="13px" />
26
27
30
下面是实现代码:
view source
print?
01 /**
02 * @author allin
03 *
04 */
05 public class MyListView3 extends ListActivity {
08 // private List data = new ArrayList();
09 @Override
10 public void onCreate(Bundle savedInstanceState) {
11 super.onCreate(savedInstanceState);
13
SimpleAdapter adapter =
new SimpleAdapter(this,getData(),R.layout.vlist,
14 new String[]{"title","info","img"},
15 new int[]{R.id.title,R.id.info,R.id.img});
16 setListAdapter(adapter);
17 }
18
19 private List> getData() {
20
List> list =
new ArrayList>();
22 Map map = new HashMap();
23 map.put("title", "G1");
24 map.put("info", "google 1");
25 map.put("img", R.drawable.i1);
26 list.add(map);
27
28 map = new HashMap();
29 map.put("title", "G2");
30 map.put("info", "google 2");
31 map.put("img", R.drawable.i2);
32 list.add(map);
33
34 map = new HashMap();
35 map.put("title", "G3");
36 map.put("info", "google 3");
37 map.put("img", R.drawable.i3);
38 list.add(map);
39
40 return list;
41 }
42 }
使用 simpleAdapter 的数据用一般都是 HashMap 构成的 List,list 的每一节对应 ListVi
ew 的每一行。HashMap 的每个键值数据映射到布局文件中对应 id 的组件上。因为系统没
有对应的布局文件可用,我们可以自己定义一个布局 vlist.xml。下面做适配,new 一个 S
impleAdapter 参数一次是:this,布局文件(vlist.xml),HashMap 的 title 和 info,
img。布局文件的组件 id,title,info,img。布局文件的各组件分别映射到 HashMap 的
各元素上,完成适配。
运行效果如下图:
有按钮的 ListView
但是有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要
写一个有按钮的 xml 文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映
射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显
示出了按钮也无法添加按钮的响应,这时就要研究一下 ListView 是如何现实的了,而且必
须要重写一个类继承 BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果
单击按钮将删除此按钮的所在行。并告诉你 ListView 究竟是如何工作的。效果如下:
vlist2.xml
view source
print?
01
02
xmlns:android="http://schemas.android.com/apk/res/android"
03 android:orientation="horizontal"
04
android:layout_width="fill_parent
"
05 android:layout_height="fill_parent">
06
07
08
09 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:layout_margin="5px"/>
12
13
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content">
16
17
18 android:layout_width="wrap_content"
19 android:layout_height="wrap_content"
20 android:textColor="#FFFFFFFF"
21 android:textSize="22px" />
22
23 android:layout_width="wrap_content"
24 android:layout_height="wrap_content"
25 android:textColor="#FFFFFFFF"
26 android:textSize="13px" />
27
28
29
30
31
32 android:layout_width="wrap_content"
33 android:layout_height="wrap_content"
34 android:text="@string/s_view_btn"
35 android:layout_gravity="bottom|right" />
36
程序代码:
view source
print?
001 /**
002 * @author allin
003 *
004 */
005 public class MyListView4 extends ListActivity {
008 private List> mData;
010 @Override
011 public void onCreate(Bundle savedInstanceState) {
012 super.onCreate(savedInstanceState);
013 mData = getData();
014 MyAdapter adapter = new MyAdapter(this);
015 setListAdapter(adapter);
016 }
017
018 private List> getData() {
019
List> list = new ArrayList
Object>>();
020
021 Map map = new HashMap();
022 map.put("title", "G1");
023 map.put("info", "google 1");
024 map.put("img", R.drawable.i1);
025 list.add(map);
026
027 map = new HashMap();
028 map.put("title", "G2");
029 map.put("info", "google 2");
030 map.put("img", R.drawable.i2);
031 list.add(map);
032
033 map = new HashMap();
034 map.put("title", "G3");
035 map.put("info", "google 3");
036 map.put("img", R.drawable.i3);
037 list.add(map);
038
039 return list;
040 }
041
042 // ListView 中某项被选中后的逻辑
043 @Override
044
protected void onListItemClick(ListView l, View v, int position,
long id) {
045
046
Log.v("MyListView4-click",
(String)mData.get(position).get("title"));
047 }
048
049 /**
050 * listview 中点击按键弹出对话框
051 */
052 public void showInfo(){
053 new AlertDialog.Builder(this)
054 .setTitle("我的 listview")
055 .setMessage("介绍...")
056
.setPositiveButton("确定",
new DialogInterface.OnClickListener()
{
057 @Override
058 public void onClick(DialogInterface dialog, int which) {
059 }
060 })
061 .show();
062
067 public final class ViewHolder{
068 public ImageView img;
069 public TextView title;
070 public TextView info;
071 public Button viewBtn;
072
}
075
public class MyAdapter extends BaseAdapter{
076
077 private LayoutInflater mInflater;
080 public MyAdapter(Context context){
081 this.mInflater = LayoutInflater.from(context);
082 }
083 @Override
084 public int getCount() {
085 // TODO Auto-generated method stub
086 return mData.size();
087 }
088
089 @Override
090 public Object getItem(int arg0) {
091 // TODO Auto-generated method stub
092 return null;
093 }
094
095 @Override
096 public long getItemId(int arg0) {
097 // TODO Auto-generated method stub
098 return 0;
099 }
100
101 @Override
102
public View getView(int position, View convertView, ViewGroup
parent) {
103
104 ViewHolder holder = null;
105 if (convertView == null) {
107 holder=new ViewHolder();
109 convertView = mInflater.inflate(R.layout.vlist2, null);
110 holder.img = (ImageView)convertView.findViewById(R.id.img);
111 holder.title = (TextView)convertView.findViewById(R.id.title);
112 holder.info = (TextView)convertView.findViewById(R.id.info);
113 holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
114 convertView.setTag(holder);
115
116 }else {
117
118 holder = (ViewHolder)convertView.getTag();
119 }
120
12
2
holder.img.setBackgroundResource((Integer)mData.get(position).ge
t("img"));
123 holder.title.setText((String)mData.get(position).get("title"));
124 holder.info.setText((String)mData.get(position).get("info"));
125
126 holder.viewBtn.setOnClickListener(new View.OnClickListener() {
127
128 @Override
129 public void onClick(View v) {
130 showInfo();
131 }
132 });
133
134
135 return convertView;
136 }
137
下面将对上述代码,做详细的解释,listView 在开始绘制的时候,系统首先调用 getC
ount()函数,根据他的返回值得到 listView 的长度(这也是为什么在开始的第一张图特
别的标出列表长度),然后根据这个长度,调用 getView()逐一绘制每一行。如果你的 g
etCount()返回值是 0 的话,列表将不显示同样 return 1,就只显示一行。
系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完
成适配时,必须手动映射数据,这需要重写 getView()方法。系统在绘制列表的每一行
的时候将调用此方法。getView()有三个参数,position 表示将显示的是第几行,covert
View 是从布局文件中 inflate 来的布局。我们用 LayoutInflater 的方法将定义好的 vlist
2.xml 文件提取成 View 实例用来显示。然后将 xml 文件中的各个组件实例化(简单的 fi
ndViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事
件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的 listView 就完
成了,现在让我们回过头从新审视这个过程。系统要绘制 ListView 了,他首先获得要绘制
的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用 getView()函数。在这个函
数里面首先获得一个 View(实际上是一个 ViewGroup),然后再实例并设置各个组件,显
示之。好了,绘制完这一行了。那再绘制下一行,直到绘完为止。在实际的运行过程中会
发现 listView 的每一行没有焦点了,这是因为 Button 抢夺了 listView 的焦点,只要布局
文件中将 Button 设置为没有焦点就 OK 了。
Android API Demo 研究(2)
文章分类:移动开发
1. Forwarding
这个实现很简单,就是启动新的 Activity 或者 Service 后,增加一个 finish()
语句就可以了,这个语句会主动将当前 activity从历史stack中清除,这样back
操作就不会打开当前 activity。
做这个实验的时候,发现开发 Android 程序需要注意的一点小问题:增加新的
activity 时,不能只增加一个 class,一定要记得要在 manifest 文件中增加该
activity 的描述。(这个简单的功能,未来 google 应该给增加吧)
“android:name 中的点”意义:首先 manifest 会有一个默认指定的 package
属性,比如指定为"com.android.sample",如果我们增加的 activity 的实现
也在这个 package 下,则 android:name 为实现的类名,这个类名前加不加
点都没有关系,都会自动找到该实现,比如实现为 forwardtarget,则
android:name 写成 forwardtarget 或者.forwardtarget 都可以。唯一有区
别的是,如果 activity 的实现是在默认包的子包里面,则前面这个点就尤为重
要,比如 activity 的实现是 com.android.sample.app.forwardtarget,则
android:name 必须写成.app.forwardtarget 或者
com.android.sample.app.forwardtarget。如果只写 app.forwardtarget,
通常编辑器就会提示该类找不到,但不巧的是,你恰好有一个类是
app.forwardtarget,那你只有等着运行时报错吧。
所以建议养成习惯只要是默认 package 下面的类,无论是否是在子包里面,前
面都要加上一个点,现在当前实现是在默认 package 下。
2.Persistent
这里的持久化其实就是本地配置文件的读写,实现方法是通过
Activity.getPreferences(int)获取 SharedPreferences 对象,然后操作配置
文件的读写,值得注意的是以下几点:
1)Activity.getPreferences(int mode)等价于
Content.getSharedPreferences(String filename,int mode),这里面的
filename 就是当前 class 的名称,例如在 PersistentTest 类中调用
getPreferences(0),等价于调用 getPreferences("PersistentTest", 0)。如
不想用 class name 做文件名,可以直接调用 getSharedPreferences 方法,
自己指定配置文件的名称。
2)mode 值的定义:
MODE_PRIVATE = 0,表示当前配置文件为私有文件,只有当前的应用可以
访问。
MODE_WORLD_READABLE = 1,表示当前配置文件可以被其他应用读取。
MODE_WORLD_WRITEABLE = 2,表示当前配置文件可以被其他应用写入。
如果配置文件又想被人读又想被写人,怎么办呢,呵呵,当然是
MODE_WORLD_READABLE&MODE_WORLD_WRITEABLE,真的怀疑设
计 android 的人以前是做 C/C++的。
3)SharedPreferences 是个很有意思的实现,读取数据的时候,直接用 get
方法就可以了,可是写数据的时候,没用给 set 方法,呵呵,第一次用这个类一
定会以为只能读不能写。如果要写数据的话,需要用 editor()方法(为什么不是
getEditor()呢?看来设计的人一定是做 C/C++的)获取
SharedPreferences.Editor 类,然后用这个类的 put 方法写文件。为什么要
这样做呢?好久没有看设计模式了,不知道他采用是哪种高级模式,等以后有时
间,看看它的实现再做研究吧。
4)在这个实现中,读文件是放在 onResume()中,写文件是在 onPause()中,
为什么要这么做呢,看字面意思,好像只有恢复和暂停的时候才会被执行,那程
序第一次创建的时候会读文件吗?来让我们看看 Activity 的生命周期,就会发
现这么做的巧妙之处:
文章分类:移动开发
1. Custom Dialog
Android 支持自定义窗口的风格:
1)首先在资源里面建立 style 的 value;
example:
drawable/filled_box.xml
xmlns:android="http://schemas.android.com/apk/res/android"
>
android:right="10dp" android:bottom="10dp" />
PS:关于 Styles的学习,可以参见:
http://code.google.com/android/reference/available-resour
ces.html#stylesandthemes
2)设置当前activity 的属性,两种方式:1.在manifest 文件中给指定的activity
增加属性
android:theme="@android:style/Theme.CustomDialog"。2.在程序中增
加语句 setTheme(R.style.Theme_CustomDialog);
PS1:如果只是将 Acticity 显示为默认的 Dialog, 跳过第一步,只需要在
manifest 文中增加属性:
android:theme="@android:style/Theme.Dialog"或者在程序中增加
setTheme(android.R.style.Theme_Dialog).
PS2:其他创建 Dialog 的方法:创建 app.Dialog 类或者创建 app.AlertDialog
类。
Next Study:能不能在 Activity 已经打开以后动态修改当前 Activity 的风格?
在测试中发现,在 onCreate()事件中增加 setTheme(),必须在 setContentView()之前,否则指定的
Style 不能生效
2.Custom Title
Android 除了可以为指定的 Activity 设置显示风格,此外也可以为指定的
Activity 设置一些特效,比如自定义 Title,没有 Title 的 Activity 或者增加一
个 ICON 等。
有意思的一点是,这些特效并不是你想设置的时候就行设置,你需要在 Activity
显示之前向系统申请要显示的特效,这样才能在下面的程序中为这些特效进行设
置。(这样是不是多此一举有待研究)
为一个 Activity 设置自定义 Title 的流程:
1)为自定义的 Title 建立一个 layout(custom_title_1.xml)
/apk/res/android" android:id="@+id/screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Left" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Right" />
关于为什么采用 RelativeLayout,可以参见:
http://code.google.com/android/devel/ui/layout.html
2)为 activity设定自定义 Title特效并指定 Title的 layout:
在 onCreate()事件中增加:
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.custom_title);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
R.layout.custom_title_1);
这三条语句的次序不能颠倒,依次为申请特效,创建 view,设置特效属性。其
中 requestWindowFeature等价于 getWindow().requestFeature()
3)在需要修改 Title的地方,获取 left_text或者 right_text进行设置
即可。
Next Study:Activity 的其他显示特效
Window 还有其他一些 feature,比如 FEATURE_CONTEXT_MENU,FEATURE_NO_TITLE,
FEATURE_LEFT_ICON 等,有待继续学习研究。
Animations(转)
文章分类:移动开发
仅用于方便查找
Animations 链接
Android 支持 2 种类型的动画。内插动画可以应用于旋转、平移、放缩和渐变;
frame-by-frame 动画用来显示一系列的图片。关于创建、使用和应用动画的广
泛概述可以在 11 章找到。
把动画定义成外部资源,有利于在多个地方使用,并且能基于设备硬件或方向选
择适应的动画。
Tweened Animations
每个内插动画以独立的 XML 文件存储在/res/anim 文件夹下。和 layouts 和
drawable 资源一样,动画 XML 的文件名用作资源的标识。
每个动画可以用来定义以下的变化:alpha(渐变)、scale(放缩)、translate
(平移)和 rotate(旋转)。
每个类型的动画都有特性来定义内插序列如何作用:
Alpha fromAlpha/toAlpha 0-1
Scale fromXScale/toXScale 0-1
fromYScale/toYScale 0-1
pivotX/pivotY
图像的宽度/高度的百分比字符串 0%-100%
Translate fromX/toX 0-1
fromY/toY 0-1
Rotate fromDegrees/toDegrees 0-360
pivotX/pivotY
图像的宽度/高度的百分比字符串 0%-100%
你可以使用 标签来创建多个动画。一个动画集包含一个到多个动画变化,
并且支持一些额外的标签和特性来定制动画集中的动画何时以及怎样运行。
接下来的列表给了一些 set 标签一些特性:
❑ duration 动画的持续时间(毫秒)
❑ startOffset 启动动画的延时(毫秒)
❑ fillBefore True 表示在动画开始前应用动画变换
❑ fillAfter True 表示动画开始后应用动画变换
❑ interpolator 设置整个时间范围如何影响动画的速度。在 11 章中会探讨
这个变量。指定 interpolator 时需要引用系统的动画资源
(android:anim/interpolatorName)。
如果你不使用 startOffset 标签,动画集中的动画将同步执行。
接下来的例子显示了动画集控制目标在缩小淡出的同时旋转 360 度:
Xml 代码
Java 代码
1.
2.
3.
d”
4.
5. android:interpolator=”@android:anim/accelerate_interpolator”>
6.
7.
8.
9. android:fromDegrees=”0”
10.
11.android:toDegrees=”360”
12.
13.android:pivotX=”50%”
14.
15.android:pivotY=”50%”
16.
17.android:startOffset=”500”
18.
19.android:duration=”1000” />
20.
21.
22.
23.android:fromXScale=”1.0”
24.
25.android:toXScale=”0.0”
26.
27.android:fromYScale=”1.0”
28.
29.android:toYScale=”0.0”
30.
31.android:pivotX=”50%”
32.
33.android:pivotY=”50%”
34.
35.android:startOffset=”500”
36.
37.android:duration=”500” />
38.
39.
40.
41.android:fromAlpha=”1.0”
42.
43.android:toAlpha=”0.0”
44.
45.android:startOffset=”500”
46.
47.android:duration=”500” />
48.
49.
Frame-by-Frame Animations
Frame-by-Frame 动画用于 View 的背景上,显示一系列的图片,每张图片显示指
定的时间。
因为 Frame-by-Frame 动画显示 drawables,所以,它们也被放在/res/drawble
文件夹下(和 Tweened 动画不同),并且使用它们的文件名作为它们的资源标识。
接下来的 XML 片段显示了一个简单的动画,它循环显示一些位图资源,每张位图
显示 0.5 秒。为了能使用这个 XML 片段,你需要创建 rocket1-rocket3 三个新
的图片资源。
Java 代码
1. Xml 代码
2.
3.
4. xmlns:android=”http://schemas.android.com/apk/res/android”
5.
6. android:oneshot=”false”>
7.
8. -
500” />
9.
10.-
500” />
11.
12.-
500” />
13.
14.
看到了吧,在 Activity 运行的前后,无论状态怎么转移,onResume()和
onPause()一定会被执行,与其说实现的巧妙,还不如赞一下这个生命周期的设
计的巧妙,这个巧妙不是说说而已,有时间的话,看看 MFC 中一个 windows
或者 dialog 的生命周期,你就知道这个巧妙的含义了,我们可以省多少的事情
啊!所以值得记住的是,在 android 中想在运行前后必须要执行的语句,就应
该放在 onResume()和 onPause()中。
4)最后说一个对 android 小不爽的地方:drawable,什么鬼东西啊!在
res/drawable 放一个文件,访问的时候是 drawable/name,如果在 values
里面建立一个 drawable 的变量,访问的时候也是 drawable/name,例如在
drawable 目录下放入一个 red.xml 文件,访问的时候是@drawable/red,如
果建立一个 drawable 的变量 red,访问也是@drawable/red,这完全就是两
个东西啊,虽然最新的编辑器会提示重名,但查找的时候真的很不方便啊,尤其
是 drawable 变量,可以放在一个 abc.xml 中,以后资源文件多了,管理起来
想想都头麻,就不能把其中一个改改名字吗?把 drawable 变量叫成
drawable_value 不行吗?
用 GridView 实现 Gallery 的效果(转)
在实现横向的类似 Gallery 的效果中做了实现 Gallery 的尝试,但是效果不好。
使用的是 TableLayout,出现了横向拖动图片的时候,因为有倾斜(轻微的竖向
拖动),会整个列表竖向滚动。其实这个问题可以将 TableRow 中条目设置为
clickable 来解决。但是效果依然不好。
这次尝试通过 GridView 来解决问题,效果很好,见截图:
基本思路是:
· 每个可选的图,包括文字部分,是 GridView 中的一个条目;
· 一个 GridView 条目是相对布局(RelativeLayout),里面包含一个图片(ImageView)
和一个文字(TextView);
· 关键点是 GridView 如何保持横向,默认的情况下会折行的,首先要用一个
HorizontalScrollView 提供横向滚动容器,然后内部放置一个 FrameLayout,如果不放
置 FrameLayout 布局,直接放入下面的布局或者视图,GridView 将会变成单列纵向
滚动,在FrameLayout 布局中加入横向的LinearLayout 布局,要设置它的layout_width,
要足够大,这样在其中加入 GridView 就能横向排列了。
首先看一下 GridView 中条目的布局:
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingBottom="10.0dip"
android:layout_width="90.0dip"
android:layout_height="140.0dip">
android:layout_width="80.0dip"
android:layout_height="108.0dip"
android:layout_marginLeft="10.0dip"
android:layout_centerHorizontal="true">
android:layout_below="@+id/ItemImage"
android:id="@+id/ItemText"
android:ellipsize="end"
android:layout_width="80.0dip"
android:layout_height="26.0dip"
android:layout_marginTop="5.0dip"
android:singleLine="true"
android:layout_centerHorizontal="true">
这里使用了相对布局的特性,android:layout_below,表示 TextView 在
ImageView 下面。这里的图都是用的 res/drawable 目录下的静态图形文件,正
式情况下,应该是从网络获取,可参见用 Java concurrent 编写异步加载图片功
能的原型实现,二者结合可用于正式生产环境。
ListView 的 Header 使用了自定义视图,更简单的示例可参见为 ListView 增加
Header。表头(ListView Header)的布局文件:
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="200dp">
android:layout_height="wrap_content" android:text="最近访问人物" />
android:layout_height="160dp">
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="horizontal">
android:layout_width="fill_parent"
android:gravity="center"
android:layout_height="fill_parent"
android:horizontalSpacing="1.0dip"
android:verticalSpacing="1.0dip"
android:stretchMode="spacingWidthUniform"
android:numColumns="auto_fit"
android:columnWidth="80dip">
这是比较关键的布局文件,GridView 能实现横向滚动主要靠它了。其中:
我是写死了 1100dp,正式使用的时候,因为图片都可能是动态从服务器上获取
的,可以根据数量以及图片的宽度,空白边动态计算这个长度。
GridView 和 ListView 类似,都需要 ViewAdapter 来适配数据和视图。
见 Activity 的源代码:
package com.easymorse.grid.demo;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class GridDemoActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService("layout_inflater");
View
headerView=layoutInflater.inflate(R.layout.list_header, null);
setGridView(headerView);
ListView listView=(ListView)
this.findViewById(android.R.id.list);
listView.addHeaderView(headerView);
listView.setAdapter(new ArrayAdapter(this,
android.R.layout.simple_list_item_1,new String[]{"隋","唐","宋","元
","明","清"}));
}
private void setGridView(View view) {
GridView gridView = (GridView)
view.findViewById(R.id.grid);
gridView.setNumColumns(10);
ArrayList> items = new
ArrayList>();
for (int i = 0; i < 10; i++) {
HashMap map = new HashMap
Object>();
map.put("ItemImage", R.drawable.k);
map.put("ItemText", "清.康熙" + "(" + i + ")");
items.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(this, items,
R.layout.item,
new String[] { "ItemImage", "ItemText" },
new int[] {
R.id.ItemImage,
R.id.ItemText });
gridView.setAdapter(adapter);
}
}
Android 画图之 Matrix(一)
Matrix ,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平
面的缩放、平移、旋转等操作。
首先介绍一下矩阵运算。加法和减法就不用说了,太简单了,
对应位相加就好。图像处理,主要用到的是乘法 。下面是一个乘法的公式:
在 Android 里面, Matrix 由 9 个 float 值构成,
是一个 3*3 的矩阵。如下图。
没专业工具,画的挺难看。解释一下,上面的 sinX 和 cosX ,表示旋
转角度的 cos 值和 sin 值,注意,旋转角度是按顺时针方向计算
的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是
缩放的比例, 1 是不变, 2 是表示缩放 1/2 ,这样子。
下面在 Android 上试试 Matrix 的效果。
Java 代码
1. public class MyView extends View {
2.
3. private Bitmap mBitmap;
4.
5. private Matrix mMatrix = new Matrix();
6.
7. public MyView(Context context) {
8.
9. super(context);
10.
11. initialize();
12.
13. }
14.
15. private void initialize() {
16.
17. mBitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.sho
w)).getBitmap();
18.
19. float cosValue = (float) Math.cos(-Math.PI/6);
20.
21. float sinValue = (float) Math.sin(-Math.PI/6);
22.
23. mMatrix.setValues(
24.
25. new float[]{
26.
27. cosValue, -sinValue, 100,
28.
29. sinValue, cosValue, 100,
30.
31. 0, 0, 2});
32.
33. }
34.
35. @Override protected void onDraw(Canvas canvas) {
36.
37. // super.onDraw(canvas); //当然,如果界面上还有其他元素需要绘制,只需要将这
句话写上就行了。
38.
39. canvas.drawBitmap(mBitmap, mMatrix, null);
40.
41. }
42.
43. }
运行结果如下:
以左上角为顶点,缩放一半,逆时针旋转 30 度,然后沿 x 轴和 y 轴分别平
移 50 个像素,代码 里面写的是 100,为什么是平移 50 呢,因为缩放了一半。
大家可以自己设置一下 Matrix 的值,或者尝试一下两个 Matrix 相乘,得
到的值设置进去,这样才能对 Matrix 更加熟练。
这里讲的直接赋值的方式也许有点不好理解,不过还好, andrid 提供了
对矩阵的更方便的方法,下一篇介绍 。
Android 画图之 Matrix(二)
文章分类:移动开发
上一篇 Android 画图之 Matrix(一) 讲了一下 Matrix 的原理和运算方法,涉及
到高等数学,有点难以理解。还好 Android 里面提供了对 Matrix 操作的一系
列方便的接口。
Matrix 的操作,总共分为 translate(平移),rotate(旋转),scale
(缩放)和 skew(倾斜)四种,每一种变换在
Android 的 API 里都提供了 set, post 和 pre 三种操作方式,除了 translate,其
他三种操作都可以指定中心点。
set 是直接设置 Matrix 的值,每次 set 一次,整个 Matrix 的数组都会
变掉。
post 是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用 post,
来完成所需的整个变换。例如,要将一个图片旋
转 30 度,然后平移到(100,100)的地方,那么可以这样做:
Java 代码
1. Matrix m = new Matrix();
2.
3. m.postRotate(30 );
4.
5. m.postTranslate(100 , 100 );
这样就达到了想要的效果。
pre 是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵
的最前面发生的。例如上面的例子,如果用 pre 的话
,就要这样:
Java 代码
1. Matrix m = new Matrix();
2.
3. m.setTranslate(100 , 100 );
4.
5. m.preRotate(30 );
旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情
况下,是围绕(0,0)点来进行。
下面给出一个例子。
Java 代码
1. package chroya.demo.graphics;
2.
3. import android.content.Context;
4. import android.graphics.Bitmap;
5. import android.graphics.Canvas;
6. import android.graphics.Matrix;
7. import android.graphics.Rect;
8. import android.graphics.drawable.BitmapDrawable;
9. import android.util.DisplayMetrics;
10.import android.view.MotionEvent;
11.import android.view.View;
12.
13.public class MyView extends View {
14.
15. private Bitmap mBitmap;
16. private Matrix mMatrix = new Matrix();
17.
18. public MyView(Context context) {
19. super (context);
20. initialize();
21. }
22.
23. private void initialize() {
24.
25. Bitmap bmp = ((BitmapDrawable)getResources().ge
tDrawable(R.drawable.show)).getBitmap();
26. mBitmap = bmp;
27. /*首先,将缩放为 100*100。这里 scale 的参数是比例。
有一点要注意,如果直接用 100/
28.bmp.getWidth()的话,会得到 0,因为是整型相除,所以必须其中有一个是
float 型的,直接用 100f 就好。*/
29. mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.ge
tHeight());
30. //平移到(100,100)处
31. mMatrix.postTranslate(100 , 100 );
32. //倾斜 x 和 y 轴,以(100,100)为中
心。
33. mMatrix.postSkew(0 .2f, 0 .2f, 100 , 100 );
34. }
35.
36. @Override protected void onDraw(Canvas canvas) {
37.// super.onDraw(canvas); //如果界面上还有其他元素需
要绘制,只需要将这句话写上就行了。
38.
39. canvas.drawBitmap(mBitmap, mMatrix, null );
40. }
41.}
运行效果如下:
红色的 x 和 y 表示倾斜的角度,下面是 x,上面是 y。看到了没,Matrix
就这么简单 。
XML 属性
文章分类:移动开发
一、属性分类
1. View 的属性
2. TextView 的属性
二、View 的属性
1. 基础属性
· android:id : 设定 view 的 id。之后在代码里面可以通过
View.findViewById()来获取相应的 View
· android:tag : 设定 view 的 tag。之后可以再代码里面通过
View.findViewByTag 来获取相应的 View
2. 事件相关
2.1 Click 事件相关
· android:clickable : view 是否能对 click 事件作出反应。值域【true,
false】
· android:onClick : 当 view 被 click 之后,view 的 context 的哪个方
法被呼叫。通常这个 context 是指 vieW 所在的 Acitvity。例如:
android:onClick = 'sayHello'.则相应的 Activity 里面有一个方法
public void sayHello(View view)方法。当这个 view 被 click 之后,
sayHello 方法就会被调用。
· android:longClickable : view 是否可以对长时间的 click 事件作出反
应。值域【true,false】
2.1 Focus 事件相关
· android:focusable : view 是否能响应焦点事件
· android:
三、TextView 的属性
其他的属性请参考:View 的属性
1 文本相关的属性
1.1 文本属性
· android:text 文字
· android:typeface : 设定字体
· android:textStyle : 风格。值域【bold,italic,normal】。可以组合
设定。例如:bold | italic
· android:textSize : 文字大小
· android:textColor : 文字的颜色
· android:textColorHight : 文字被选择的时候,高亮的颜色
1.2 提示文本相关的属性
· android:hint 当文本内容为空时,提示信息
· android:textColorHint 提示文本的颜色
2. 输入内容的控制
· android:number 只能输入数字。值域【integer , decimal , signed】,
可以组合设定。例如:integer | signed
· 2010-10-22
Android 中的长度单位详解(dp、sp、px、in、pt、mm)
· 文章分类:移动开发
· 看到有很多网友不太理解 dp、sp 和 px 的区别:现在这里介绍一下 dp 和
sp。dp 也就是 dip。这个和 sp 基本类似。如果设置表示长度、高度等属
性时可以使用 dp 或 sp。但如果设置字体,需要使用 sp。dp 是与密度无
关,sp 除了与密度无关外,还与 scale 无关。如果屏幕密度为 160,这时
dp 和 sp 和 px 是一样的。1dp=1sp=1px,但如果使用 px 作单位,如果屏
幕大小不变(假设还是3.2寸),而屏幕密度变成了320。那么原来TextView
的宽度设成 160px,在密度为 320 的 3.2 寸屏幕里看要比在密度为 160 的
3.2 寸屏幕上看短了一半。但如果设置成 160dp 或 160sp 的话。系统会自
动将 width 属性值设置成 320px 的。也就是 160 * 320 / 160。其中 320 /
160 可称为密度比例因子。也就是说,如果使用 dp 和 sp,系统会根据屏
幕密度的变化自动进行转换。
下面看一下其他单位的含义
px:表示屏幕实际的象素。例如,320*480 的屏幕在横向有 320 个象素,
在纵向有 480 个象素。
in:表示英寸,是屏幕的物理尺寸。每英寸等于 2.54 厘米。例如,形容
手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指
这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是 3.2 英寸,
表示手机的屏幕(可视区域)对角线长度是 3.2*2.54 = 8.128 厘米。读
者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。
mm:表示毫米,是屏幕的物理尺寸。
pt:表示一个点,是屏幕的物理尺寸。大小为 1 英寸的 1/72。
原创--解剖 android Style 原理从 Button 入手
文章分类:移动开发
转载 声明原处 :博客 http://pk272205020.blog.163.com/
参考论坛外国 android 论坛 http://www.androidpeople.com/
参考资料:android Button 原理
这几日都是看 android SDK 原码,想封装一个 HERO 效果的 UI 界面。刚
想以为很容易,但越做越难,为有百度,Google 求救,但这方面的资料还是不多,
这个我也不怪了,可能 android 在中国的市场还是刚刚起步。外面的一些网站
android 技术论坛打不开,闷 ...
但我发现http://www.android.com/ 可以打开了,以前要用XX软件先打得开,但
里面的 developer 标签还是俾中国网关封,这个更郁闷... 不讲了,直入正题
android Styel 原理
刚刚开始得写时从最简单的 Button 入手,下载 SDK 原码候 Button 继续
TextView 原码里就三个构造方法....
Java 代码
1. @RemoteView
2. public class Button extends TextView {
3. public Button(Context context) {
4. this(context, null);
5. }
6.
7. public Button(Context context, AttributeSet attrs)
{
8. this(context, attrs, com.android.internal.R.a
ttr.buttonStyle);
9. }
10.
11. public Button(Context context, AttributeSet attrs,
int defStyle) {
12. super(context, attrs, defStyle);
13. }
14.}[
默认样式:com.android.internal.R.attr.buttonStyle ,android 的 style
太强大, 网上有人说过是 GWT模式, 在校的时候我也用过GWT写过小网页,HTML
文件里标签里嵌入 GWT 标签,通过服务端 Java 代码生成页面,GWT 就讲到这里,
有开展过 GWT 的同志就知道这个也很像 android 的 Layout 布局文件,哈哈 我也
是认同网上的人说。
知道 android 的 Style 模式后,我们要进一步了解内部的实现,我们
要打开 com.android.internal.R.attr.buttonStyle 这个对应的 XML
Xml 代码
1. < style name="Widget.Button" >
2.
3. < item name="android:background">@android:drawable/btn_defaul
t< /item>
4.
5. < item name="android:focusable" >true< /item >
6.
7. < item name="android:clickable" >true< /item >
8.
9. < item name="android:textSize" >20sp< /item >
10.
11.< item name="android:textStyle" >normal< /item >
12.
13.< item name="android:textColor" >@android:color/button_text
14.
15.- center_vertical|center_horizontal>
16.< /item>
17.
18.< /style >
这个文件定义了好多 style 相关的属性,每个属性都好理解,这个
backgroud 属性难道仅仅是一个 drawable 图片?如果仅仅是一个图片的化,怎么
能够实现 button 各种状态下表现出不同背景的功能呢?还是来看看这个
drawable 到底是什么东西。
还是埋头苦干地找出答案
在 drwable 目录中发现这个 btn_default 这个文件,还有许多这样的 xml 文件,
看名字可以估到是什么来的
btn_default.xml 内容
Xml 代码
1. < selector xmlns:android="http://schemas.android.com/apk/res/
android">
2.
3. < item android:state_window_focused="false" android:state_en
abled="true"
4. android:drawable="@drawable/btn_default_normal" / >
5.
6. < item android:state_window_focused="false" android:state_
enabled="false"
7. android:drawable="@drawable/btn_default_normal_disable" / >
8.
9. < item android:state_pressed="true"
10.android:drawable="@drawable/btn_default_pressed" / >
11.
12.< item android:state_focused="true" android:state_enabled="t
rue"
13.android:drawable="@drawable/btn_default_selected" / >
14.
15.< item android:state_enabled="true"
16.android:drawable="@drawable/btn_default_normal" / >
17.
18.< item android:state_focused="true"
19.android:drawable="@drawable/btn_default_normal_disable_focused"
/ >
20.
21.< item android:drawable="@drawable/btn_default_normal_disable
" / >
22.
23.< /selector >
在 android 中 drawable 文件是看图片存放的,最普通的就是一个图片。而这里
用到的是 StateListDrawable。当 Android 的解析器解析到上面的 xml 时,会自
动转化成一个 StateListDrawable 类的实例,看看 SDK 是这样说的
Lets you assign a number of graphic images to a single Drawable
and swap out the visible item by a string ID value.
It can be defined in an XML file with the element. Each state
Drawable is defined in a nested - element. For more information, see
the guide to Drawable Resources.
意思就是通过字符串标识符值 ID 分配单个可绘制可切换 的可视图形项
看看核心代码吧:大部多代码删除了
Java 代码
1. public class StateListDrawable extends DrawableContainer {
2. /**
3. * To be proper, we should have a getter for dither (and
alpha, etc.)
4. * so that proxy classes like this can save/restore their
delegates'
5. * values, but we don't have getters. Since we do have s
etters
6. * (e.g. setDither), which this proxy forwards on, we have
to have some
7. * default/initial setting.
8. *
9. * The initial setting for dither is now true, since it
almost always seems
10.* to improve the quality at negligible cost.
11.*/
12.private static final boolean DEFAULT_DITHER = true;
13.private final StateListState mStateListState;
14.private boolean mMutated;
15.
16.public StateListDrawable() {
17.this(null, null);
18.}
19.
20./**
21.* Add a new image/string ID to the set of images.
22.*
23.* @param stateSet - An array of resource Ids to associat
e with the image.
24.* Switch to this image by calling setState().
25.* @param drawable -The image to show.
26.*/
27.public void addState(int[] stateSet, Drawable drawable) {
28.if (drawable != null) {
29.mStateListState.addStateSet(stateSet, drawable);
30.// in case the new state matches our current state...
31.onStateChange(getState());
32.}
33.}
34.
35.@Override
36.public boolean isStateful() {
37.return true;
38.}
39.
40.@Override
41.protected boolean onStateChange(int[] stateSet) {
42.int idx = mStateListState.indexOfStateSet(stateSet);
43.if (idx < 0) {
44.idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);
45.}
46.if (selectDrawable(idx)) {
47.return true;
48.}
49.return super.onStateChange(stateSet);
50.}
51.
52.
53./**
54.* Gets the state set at an index.
55.*
56.* @param index The index of the state set.
57.* @return The state set at the index.
58.* @hide pending API council
59.* @see #getStateCount()
60.* @see #getStateDrawable(int)
61.*/
62.public int[] getStateSet(int index) {
63.return mStateListState.mStateSets[index];
64.}
65.
66.
67.static final class StateListState extends DrawableContainerSt
ate {
68.private int[][] mStateSets;
69.
70.StateListState(StateListState orig, StateListDrawable owner, R
esources res) {
71.super(orig, owner, res);
72.
73.if (orig != null) {
74.mStateSets = orig.mStateSets;
75.} else {
76.mStateSets = new int[getChildren().length][];
77.}
78.}
79.
80.
81.
82.
83. int addStateSet(int[] stateSet, Drawable drawable) {
84. final int pos = addChild(drawable);
85. mStateSets[pos] = stateSet;
86. return pos;
87. }
88.
89.
90.}
91.
92.private StateListDrawable(StateListState state, Resources res)
{
93.StateListState as = new StateListState(state, this, res);
94.mStateListState = as;
95.setConstantState(as);
96.onStateChange(getState());
97.}
98.}
xml 中每一个 Item 就对应一种状态,而每一个有 state_的属性就是描述状态,
drawable 则是真正的 drawable 图片。当把这个实例付给 View 作为 Background
的时候,View 会根据不同的 state 来切换不同状态的图片,从而实现了 Press
等诸多效果。简单看一下 View 中有关状态切换的代码吧:
Java 代码
1. /**
2. * The order here is very important to {@link #getDrawa
bleState()}
3. */
4. private static final int[][] VIEW_STATE_SETS = {
5. EMPTY_STATE_SET, // 0 0 0 0 0
6. WINDOW_FOCUSED_STATE_SET, // 0 0 0 0 1
7. SELECTED_STATE_SET, // 0 0 0 1 0
8. SELECTED_WINDOW_FOCUSED_STATE_SET, // 0 0 0 1 1
9. FOCUSED_STATE_SET, // 0 0 1 0 0
10.FOCUSED_WINDOW_FOCUSED_STATE_SET, // 0 0 1 0 1
11.FOCUSED_SELECTED_STATE_SET, // 0 0 1 1 0
12.FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, // 0 0 1 1 1
13.ENABLED_STATE_SET, // 0 1 0 0 0
14.ENABLED_WINDOW_FOCUSED_STATE_SET, // 0 1 0 0 1
15.ENABLED_SELECTED_STATE_SET, // 0 1 0 1 0
16.ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, // 0 1 0 1 1
17.ENABLED_FOCUSED_STATE_SET, // 0 1 1 0 0
18.ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, // 0 1 1 0 1
19.ENABLED_FOCUSED_SELECTED_STATE_SET, // 0 1 1 1 0
20.ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, // 0 1 1
1 1
21.PRESSED_STATE_SET, // 1 0 0 0 0
22.PRESSED_WINDOW_FOCUSED_STATE_SET, // 1 0 0 0 1
23.PRESSED_SELECTED_STATE_SET, // 1 0 0 1 0
24.PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET, // 1 0 0 1 1
25.PRESSED_FOCUSED_STATE_SET, // 1 0 1 0 0
26.PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET, // 1 0 1 0 1
27.PRESSED_FOCUSED_SELECTED_STATE_SET, // 1 0 1 1 0
28.PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, // 1 0 1
1 1
29.PRESSED_ENABLED_STATE_SET, // 1 1 0 0 0
30.PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET, // 1 1 0 0 1
31.PRESSED_ENABLED_SELECTED_STATE_SET, // 1 1 0 1 0
32.PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, // 1 1 0
1 1
33.PRESSED_ENABLED_FOCUSED_STATE_SET, // 1 1 1 0 0
34.PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, // 1 1 1
0 1
35.PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, // 1 1 1 1 0
36.PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, //
1 1 1 1 1
37.};
详细打开 View.java 自己看
下面是 setBackground 方法,红字就是是 state 切换 ,View 这个类太长了,
android2.2 版一共 9321 行
Java 代码
1. /**
2. * Set the background to a given Drawable, or
remove the background. If the
3. * background has padding, this View's padding
is set to the background's
4. * padding. However, when a background is remov
ed, this View's padding isn't
5. * touched. If setting the padding is desired,
please use
6. * {@link #setPadding(int, int, int, int)}.
7. *
8. * @param d The Drawable to use as the backgr
ound, or null to remove the
9. * background
10. */
11. public void setBackgroundDrawable(Drawable d) {
12. boolean requestLayout = false;
13.
14. mBackgroundResource = 0;
15.
16. ...............
17.
18. if (d.isStateful()) {
19. d.setState(getDrawableState());
20. }
21. d.setVisible(getVisibility() == VISIB
LE, false);
22. mBGDrawable = d;
23.
24. ...............
25.
26. mBackgroundSizeChanged = true;
27. invalidate();
28.}
setBackgound 方法先判断 Drawable 对象是否支持 state 切换 如果支持,设置
状态就可达到图片切换的效果。
就写到这里
Android-----使用 Button 特效 selector+shape
文章分类:移动开发
当然除了使用 drawable 这样的图片外今天谈下自定义图形 shape 的方法,对于 Button 控件
Android 上支持以下几种属性 shape、gradient、stroke、corners 等。
我们就以目前系统的 Button 的 selector 为例说下:
Java 代码
1.
2.
3. android:startColor="#ff8c00"
4. android:endColor="#FFFFFF"
5. android:angle="270" />
6.
7. android:width="2dp"
8. android:color="#dcdcdc" />
9.
10. android:radius="2dp" />
11.
12. android:left="10dp"
13. android:top="10dp"
14. android:right="10dp"
15. android:bottom="10dp" />
16.
对于上面,这条 shape 的定义,分别为渐变,在 gradient 中 startColor 属性为开始的颜色,
endColor 为渐变结束的颜色,下面的 angle 是角度。接下来是 stroke 可以理解为边缘,corners
为拐角这里 radius 属性为半径,最后是相对位置属性 padding。
对于一个 Button 完整的定义可以为:
Java 代码
1.
2.
3. xmlns:android="http://www.norkoo.com">
4. -
5.
6.
7. android:startColor="#ff8c00"
8. android:endColor="#FFFFFF"
9. android:angle="270" />
10.
11. android:width="2dp"
12. android:color="#dcdcdc" />
13.
14. android:radius="2dp" />
15.
16. android:left="10dp"
17. android:top="10dp"
18. android:right="10dp"
19. android:bottom="10dp" />
20.
21.
22.
23. -
24.
25.
26. android:startColor="#ffc2b7"
27. android:endColor="#ffc2b7"
28. android:angle="270" />
29.
30. android:width="2dp"
31. android:color="#dcdcdc" />
32.
33. android:radius="2dp" />
34.
35. android:left="10dp"
36. android:top="10dp"
37. android:right="10dp"
38. android:bottom="10dp" />
39.
40.
41.
42. -
43.
44.
45. android:startColor="#ff9d77"
46. android:endColor="#ff9d77"
47. android:angle="270" />
48.
49. android:width="2dp"
50. android:color="#fad3cf" />
51.
52. android:radius="2dp" />
53.
54. android:left="10dp"
55. android:top="10dp"
56. android:right="10dp"
57. android:bottom="10dp" />
58.
59.
60.
注意!提示大家,以上几个 item 的区别主要是体现在 state_pressed 按下或 state_focused 获
得焦点时,当当来判断显示什么类型,而没有 state_xxx 属性的 item 可以看作是常规状态下。
xmlns:android="http://schemas.android.com/apk/res/android" >
-
android:color="hex_color"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_active=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_window_focused=["true" | "false"] />
Elements:
必须。必须是根元素。包含一个或多个- 元素。
Attributes:
xmlns:android
String,必须。定义 XML 的命名空间,必须是
“http://schemas.android.com/apk/res/android”.
定义特定状态的 color,通过它的特性指定。必须是的子元
素。
Attributes:
android:color
16 进制颜色。必须。这个颜色由 RGB 值指定,可带 Alpha。
这个值必须以“#”开头,后面跟随 Alpha-Red-Green-Blue
信息:
l #RGB
l #ARGB
l #RRGGBB
l #AARRGGBB
android:state_pressed
Boolean。“true”表示按下状态使用(例如按钮按下);“false”
表示非按下状态使用。
android:state_focused
Boolean。“true”表示聚焦状态使用(例如使用滚动球/D-pad
聚焦 Button);“false”表示非聚焦状态使用。
android:state_selected
Boolean。“true”表示选中状态使用(例如 Tab 打开);“false”
表示非选中状态使用。
android:state_checkable
Boolean。“true”表示可勾选状态时使用;“false”表示非可
勾选状态使用。(只对能切换可勾选—非可勾选的构件有用。)
android:state_checked
Boolean。“true”表示勾选状态使用;“false”表示非勾选
状态使用。
android:state_enabled
Boolean。“true”表示可用状态使用(能接收触摸/点击事件);
“false”表示不可用状态使用。
android:window_focused
Boolean。“true”表示应用程序窗口有焦点时使用(应用程序
在前台);“false”表示无焦点时使用(例如 Notification 栏拉
下或对话框显示)。
注意:记住一点,StateList 中第一个匹配当前状态的 item 会被使用。因此,如果第一个 item 没
有任何状态特性的话,那么它将每次都被使用,这也是为什么默认的值必须总是在最后(如下面的
例子所示)。
Examples:
XML 文件保存在 res/color/button_text.xml
-
android:color="#ffff0000"/>
-
android:color="#ff0000ff"/>
这个 Layout XML 会应用 ColorStateList 到一个 View 上:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/button_text"
android:textColor="@color/button_text" />
Android——字符高亮显示(转载)
文章分类:移动开发
Java 代码
1. String str="adsjoiasdjpaisdjpaidj";
2. /** Called when the activity is first created. */
3. @Override
4. public void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.main);
7. TextView textview=(TextView)findViewById(R.id.textView);
8. SpannableStringBuilder style=new SpannableStringBuilder(s
tr);
9. style.setSpan(new ForegroundColorSpan(Color.RED),3,8,Spann
able.SPAN_EXCLUSIVE_EXCLUSIVE);
10. textview.setText(style);
11.}
Android SDCard 操作(文件读写,容量计算)
文章分类:移动开发
android.os.Environment
提供访问环境变量
java.lang.Object
android.os.Environment
Environment 静态方法:
方法 : getDataDirectory ()
返回 : File
解释 : 返回 Data 的目录
方法 : getDownloadCacheDirectory ()
返回 : File
解释 : 返回下载缓冲区目录
方法 : getExternalStorageDirectory ()
返回 : File
解释 : 返回扩展存储区目录(SDCard)
方法 : getExternalStoragePublicDirectory (String type)
返回 : File
解释 : 返回一个高端的公用的外部存储器目录来摆放某些类型的文件(来自网
上)
方法 : getRootDirectory ()
返回 : File
解释 : 返回 Android 的根目录
方法 : getExternalStorageState ()
返回 : String
解释 : 返回外部存储设备的当前状态
getExternalStorageState () 返回的状态 String 类型常量 :
常量 : MEDIA_BAD_REMOVAL
值 : "bad_removal"
解释 : 在没有正确卸载 SDCard 之前移除了
常量 :MEDIA_CHECKING
值 : "checking"
解释 : 正在磁盘检查
常量 : MEDIA_MOUNTED
值 : "mounted"
解释 : 已经挂载并且拥有可读可写权限
常量 : MEDIA_MOUNTED_READ_ONLY
值 : "mounted_ro"
解释 : 已经挂载,但只拥有可读权限
常量 :MEDIA_NOFS
值 : "nofs"
解释 : 对象空白,或者文件系统不支持
常量 : MEDIA_REMOVED
值 : "removed"
解释 : 已经移除扩展设备
常量 : MEDIA_SHARED
值 : "shared"
解释 : 如果 SDCard 未挂载,并通过 USB 大容量存储共享
常量 : MEDIA_UNMOUNTABLE
值 : "unmountable"
解释 : 不可以挂载任何扩展设备
常量 : MEDIA_UNMOUNTED
值 : "unmounted"
解释 : 已经卸载
使用时只需先判断 SDCard 当前的状态然后取得 SdCard 的目录即可(见源代码)
Java 代码
1. 1 //SDcard 操作
2. public void SDCardTest() {
3. // 获取扩展 SD 卡设备状态
4.
String sDStateString = android.os.Environment.getExternalSto
rageState();
5.
6. // 拥有可读可写权限
if (sDStateString.equals(android.os.Environment.MEDIA_MOUNTED))
{
try {
// 获取扩展存储设备的文件目录
7. File SDFile = android.os.Environment
8. .getExternalStorageDirectory();
// 打开文件
9. File myFile = new File(SDFile.getAbsolutePath()
10. + File.separator + "MyFile.txt");
11. // 判断是否存在,不存在则创建
12. if (!myFile.exists()) {
13. myFile.createNewFile();
14. }
15. // 写数据
16. String szOutText = "Hello, World!";
17. FileOutputStream outputStream = new FileOutputStream
(myFile);
18. outputStream.write(szOutText.getBytes());
19. outputStream.close();
20. } catch (Exception e) {
21. // TODO: handle exception
}// end of try
22.}// end of if(MEDIA_MOUNTED)
23.// 拥有只读权限
24.else if (sDStateString
25. .endsWith(android.os.Environment.MEDIA_MOUNTED_READ_ONLY))
{
26. // 获取扩展存储设备的文件目录
27. File SDFile = android.os.Environment
28. .getExternalStorageDirectory();
29.// 创建一个文件
30.File myFile = new File(SDFile.getAbsolutePath()
31. + File.separator
32. + "MyFile.txt");
33.// 判断文件是否存在
34.if (myFile.exists()) {
35. try {
36. // 读数据
37.
FileInputStream inputStream = new FileInputStream(myFile);
38. byte[] buffer = new byte[1024];
39. inputStream.read(buffer);
40. inputStream.close();
41. } catch (Exception e) {
42. // TODO: handle exception
43.}// end of try
}// end of if(myFile)
44.}// end of if(MEDIA_MOUNTED_READ_ONLY)
45.}// end of func
计算 SDCard 的容量大小
android.os.StatFs
一个模拟 linux 的 df 命令的一个类,获得 SD 卡和手机内存的使用情况
java.lang.Object
android.os.StatFs
构造方法:
StatFs (String path)
公用方法:
方法 : getAvailableBlocks ()
返回 : int
解释 :返回文件系统上剩下的可供程序使用的块
方法 : getBlockCount ()
返回 : int
解释 : 返回文件系统上总共的块
方法 : getBlockSize ()
返回 : int
解释 : 返回文件系统 一个块的大小单位 byte
方法 : getFreeBlocks ()
返回 : int
解释 : 返回文件系统上剩余的所有块包括预留的一般程序无法访问的
方法 : restat (String path)
返回 : void
解释 : 执行一个由该对象所引用的文件系统雷斯塔特.(Google 翻译)
想计算SDCard大小和使用情况时, 只需要得到SD卡总共拥有的Block数或是剩
余没用的 Block 数,再乘以每个 Block 的大小就是相应的容量大小了单位
byte.(见代码)
Java 代码
1. 1
2. public void SDCardSizeTest() {
3. 2
4. 3 // 取得 SDCard 当前的状态
5. 4 String sDcString = android.os.Environme
nt.getExternalStorageState();
6. 5
7. 6 if (sDcString.equals(android.os.Environme
nt.MEDIA_MOUNTED)) {
8. 7
9. 8 // 取得 sdcard 文件路径
10. 9 File pathFile = android.os.Envi
ronment
11.10 .getExternalStorage
Directory();
12.11
13.12 android.os.StatFs statfs = new
android.os.StatFs(pathFile.getPath());
14.13
15.14 // 获取 SDCard 上 BLOCK 总数
16.15 long nTotalBlocks = statfs.getBl
ockCount();
17.16
18.17 // 获取 SDCard 上每个 block 的
SIZE
19.18 long nBlocSize = statfs.getBlock
Size();
20.19
21.20 // 获取可供程序使用的 Block 的数
量
22.21 long nAvailaBlock = statfs.getAv
ailableBlocks();
23.22
24.23 // 获取剩下的所有 Block 的数量(包括
预留的一般程序无法使用的块)
25.24 long nFreeBlock = statfs.getFree
Blocks();
26.25
27.26 // 计算 SDCard 总容量大小 MB
28.27 long nSDTotalSize = nTotalBlocks
* nBlocSize / 1024 / 1024;
29.28
30.29 // 计算 SDCard 剩余大小 MB
31.30 long nSDFreeSize = nAvailaBlock
* nBlocSize / 1024 / 1024;
32.31 }// end of if
33.32 }// end of func
Android 将 ButtonBar 放在屏幕底部 ? 转烛空间(转载)
文章分类:移动开发
接上篇《Android 将 TAB 选项卡放在屏幕底部》写。上篇提到 ButtonBar
的方式写底部 button,试了试,看起来外观貌似比 Tab 好看,不过恐怕
没有 Tab 管理 Activity 方便吧,毕竟一个 Tab 就是一个 Activity,但
是这样用 Button 的话,却并不如此,所以这样的涉及可能虽然好看点,
但是管理起来却是相当麻烦。那么暂且把对 activity 的管理放在一边,
只看界面的设计吧。
要涉及这样的一个 buttonbar,主要就是要用到
style="@android:style/ButtonBar"这个风格。首先还是来看 xml 的设
计,保存 layout/bottombtn.xml
Java 代码
1.
2. ndroid"
3. android:orientation="vertical"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent">
6.
7.
8. android:layout_width="fill_parent"
9. android:layout_height="fill_parent">
10.
11. android:layout_width="fill_parent"
12. android:layout_height="fill_parent"
13. android:padding="5dp">
14.
15. android:layout_width="fill_parent"
16. android:layout_height="wrap_content"
17. android:padding="5dp"
18. android:layout_weight="1" />
19.
20. android:layout_width="fill_parent"
21. android:layout_height="wrap_content"
22. android:layout_weight="0" />
23.
24.
25.
然后以下就是完整的代码了:
Java 代码
1. package net.wangliping.test;
2.
3. import android.app.ActivityGroup;
4. import android.content.Intent;
5. import android.os.Bundle;
6. import android.widget.TabHost;
7. import android.widget.TabHost.TabSpec;
8.
9. public class TestTab extends ActivityGroup {
10. public static TabHost tab_host;
11. @Override
12. protected void onCreate(Bundle savedInstanceState)
{
13. super.onCreate(savedInstanceState);
14. setContentView(R.layout.bottomtab);
15.
16. tab_host = (TabHost) findViewById(R.id.edit_
item_tab_host);
17. tab_host.setup(this.getLocalActivityManager());
18.
19. TabSpec ts1 = tab_host.newTabSpec("TAB_WEATH
ER");
20. ts1.setIndicator("Weather");
21. ts1.setContent(new Intent(this, Weather.class
));
22. tab_host.addTab(ts1);
23.
24. TabSpec ts2 = tab_host.newTabSpec("TAB_MAIL"
);
25. ts2.setIndicator("Mail");
26. ts2.setContent(new Intent(this, MailSend.clas
s));
27. tab_host.addTab(ts2);
28.
29. TabSpec ts3 = tab_host.newTabSpec("TAB_JUMP"
);
30. ts3.setIndicator("Jump");
31. ts3.setContent(new Intent(this, TabJump.class
));
32. tab_host.addTab(ts3);
33.
34. tab_host.setCurrentTab(0);
35. }
36.}
而关于页面的跳转,就是:
Java 代码
1. TestTab.tabHost.setCurrentTab(0);
如此这般,就形成了下面的这个东西,其实还没有放在上面好看。。。所以也证
实了上面那个应用不是简单地放置 TAB 在底端了。有机会还是再看看 ButtonBar
了。
Android2.2 API 中文文档系列(1) —— TextView
文章分类:移动开发
正文
一、TextView 的 API 中文文档
1.1 结构
java .lang.Object
↳ android.view.View
↳ android.widget.TextView
直接子类:
Button, CheckedTextView, Chronometer, DigitalClock, EditText
间接子类:
AutoCompleteTextView, CheckBox, CompoundButton,
ExtractEditText,MultiAutoCompleteTextView, RadioButton, ToggleButton
1.2 API
属性名称 描述
android:autoL
ink
设置是否当文本为 URL 链接/email/电话号码/map 时,文本
显示为可点击的链接。可选值(none/web/email/phone/map/all)
android:autoT
ext
如果设置,将自动执行输入值的拼写纠正。此处无效果,在
显示输入法并输入的时候起作用。
android:buffe
rType
指定 getText()方式取得的文本类别。选项 editable 类似
于 StringBuilder 可追加字符,
也就是说 getText 后可调用 append 方法设置文本内容。
spannable 则可在给定的字符区域使用样式,参见这里 1 、这里
2 。
android:capit
alize
设置英文字母大写类型。此处无效果,需要弹出输入法才能
看得到,参见 EditText 此属性说明。
android:curso
rVisible
设定光标为显示/隐藏,默认显示。
android:digit
s
设置允许输入哪些字符。如“1234567890.+-*/%\n()”
android:drawa
bleBottom
在 text 的下方输出一个 drawable,如图片。如果指定一个
颜色的话会把 text 的背景设为该颜色,并且同时和 background
使用时覆盖后者。
android:drawa
bleLeft
在 text 的左边输出一个 drawable,如图片。
android:drawa
blePadding
设置 text 与 drawable(图片)的间隔,与 drawableLeft、
drawableRight、drawableTop、drawableBottom 一起使用,可设
置为负数,单独使用没有效果。
android:drawa
bleRight
在 text 的右边输出一个 drawable,如图片。
android:drawa
在 text 的正上方输出一个 drawable,如图片。
bleTop
android:edita
ble
设置是否可编辑。这里无效果,参见 EditView。
android:edito
rExtras
设置文本的额外的输入数据。在 EditView 再讨论。
android:ellip
size
设置当文字过长时,该控件该如何显示。有如下值设
置:”start”—–省略号显示在开头;”end”——省略号显示
在结尾;”middle”—-省略号显示在中间;”marquee” ——
以跑马灯 的方式显示(动画横向移动 )
android:freez
esText
设置保存文本的内容以及光标的位置。参见:这里 。
android:gravi
ty
设置文本位置,如设置成“center”,文本将居中显示。
android:hint
Text 为空时显示的文字提示信息,可通过 textColorHint
设置提示信息的颜色。此属性在 EditView 中使用,但是这里也
可以用。
android:imeOp
tions
附加功能,设置右下角 IME 动作与编辑框相关的动作,如
actionDone 右下角将显示一个“完成”,而不设置默认是一个回
车符号。这个在 EditText 中再详细说明,此处无用。
android:imeAc
tionId
设置 IME 动作 ID。在 EditText 再做说明,可以先看这篇帖
子:这里 。
android:imeAc
tionLabel
设置 IME 动作标签。在 EditText 再做说明。
android:inclu
deFontPadding
设置文本是否包含顶部和底部额外空白,默认为 true。
android:input
Method
为文本指定输入法,需要完全限定名(完整的包名)。例如:
com.google.android.inputmethod.pinyin,但是这里报错找不
到。
android:input
Type
设置文本的类型,用于帮助输入法显示合适的键盘类型。在
EditText 中再详细说明,这里无效果。
android:links
Clickable
设置链接是否点击连接,即使设置了 autoLink。
android:marqu
eeRepeatLimit
在ellipsize指定marquee的情况下,设置重复滚动的次数,
当设置为 marquee_forever 时表示无限次。
android:ems
设置 TextView 的宽度为 N 个字符的宽度。这里测试为一个
汉字字符宽度,如图:
android:maxEm
s
设置 TextView 的宽度为最长为 N 个字符的宽度。与 ems 同
时使用时覆盖 ems 选项。
android:minEm
s
设置 TextView 的宽度为最短为 N 个字符的宽度。与 ems 同
时使用时覆盖 ems 选项。
android:maxLe
ngth
限制显示的文本长度,超出部分不显示。
android:lines
设置文本的行数,设置两行就显示两行,即使第二行没有数
据。
android:maxLi
nes
设置文本的最大显示行数,与 width 或者 layout_width 结
合使用,超出部分自动换行,超出行数将不显示。
android:minLi
nes
设置文本的最小行数,与 lines 类似。
android:lineS
pacingExtra
设置行间距。
android:lineS
pacingMultipl
ier
设置行间距的倍数。如”1.2”
android:numer
ic
如果被设置,该 TextView 有一个数字输入法。此处无用,
设置后唯一效果是 TextView 有点击效果,此属性在 EditText 将
详细说明。
android:passw
ord
以小点”.”显示文本
android:phone
Number
设置为电话号码的输入方式。
android:priva
设置输入法选项,此处无用,在 EditText 将进一步讨论。
teImeOptions
android:scrol
lHorizontally
设置文本超出 TextView 的宽度的情况下,是否出现横拉条。
android:selec
tAllOnFocus
如果文本是可选择的,让他获取焦点而不是将光标移动为文
本的开始位置或者末尾位置。EditText 中设置后无效果。
android:shado
wColor
指定文本阴影的颜色,需要与 shadowRadius 一起使用。效
果:
android:shado
wDx
设置阴影横向坐标开始位置。
android:shado
wDy
设置阴影纵向坐标开始位置。
android:shado
wRadius
设置阴影的半径。设置为 0.1 就变成字体的颜色了,一般设
置为 3.0 的效果比较好。
android:singl
eLine
设置单行显示。如果和 layout_width 一起使用,当文本不
能全部显示时,后面用“„”来表示。如 android:text="test_
singleLine " android:singleLine="true"
android:layout_width="20dp"将只显示“t„”。如果不设置
singleLine 或者设置为 false,文本将自动换行
android:text
设置显示文本.
android:textA
ppearance
设置文字外观。如
“?android:attr/textAppearanceLargeInverse
”这里引用的是系统自带的一个外观,?表示系统是否有这
种外观,否则使用默认的外观。可设置的值如下:
textAppearanceButton/textAppearanceInverse/textAppearan
ceLarge
/textAppearanceLargeInverse/textAppearanceMedium/textAp
pearanceMediumInverse/textAppearanceSmall/textAppearanc
eSmallInverse
android:textC
olor
设置文本颜色
android:textC
olorHighlight
被选中文字的底色,默认为蓝色
android:textC
olorHint
设置提示信息文字的颜色,默认为灰色。与 hint 一起使用。
android:textC
olorLink
文字链接的颜色.
android:textS
caleX
设置文字之间间隔,默认为 1.0f。分别设置
0.5f/1.0f/1.5f/2.0f 效果如下:
android:textS
ize
设置文字大小,推荐度量单位”sp”,如”15sp”
android:textS
tyle
设置字形[bold(粗体) 0, italic(斜体) 1, bolditalic(又
粗又斜) 2] 可以设置一个或多个,用“|”隔开
android:typef
ace
设置文本字体,必须是以下常量值之一:normal 0, sans 1,
serif 2, monospace(等宽字体) 3]
android:heigh
t
设置文本区域的高度,支持度量单位:px(像
素)/dp/sp/in/mm(毫米)
android:maxHe
ight
设置文本区域的最大高度
android:minHe
ight
设置文本区域的最小高度
android:width
设置文本区域的宽度,支持度量单位:px(像
素)/dp/sp/in/mm(毫米),与 layout_width 的区别看这里 。
android:maxWi
dth
设置文本区域的最大宽度
android:minWi
dth
设置文本区域的最小宽度
1.3 补充说明
1.3.1 以下几个属性以及输入法相关的在这里都没有效果,在 EditText
将补充说明。
android:numeric/android:digits/android:phoneNumber/android:inputMetho
d/android:capitalize/android:autoText
1.4 Word 格式的 API 文档下载
http://download.csdn.net/source/2649980
二、例子
2.1 跑马灯的效果
http://www.cnblogs.com/over140/archive/2010/08/20/1804770.html
结束
鉴于至此仍未有完整的 Android API 中文文档公布出来,我会一直坚持翻译
到有其他组织或官方出完整的 API 中文文档为止。在这里感谢女朋友的支持和帮
助,为我提供日中翻译(将 Android API 日文版翻译成中文)和英中翻译;感谢
翻译工具和搜索引擎以及其他提供部分属性翻译参考的分享者;感谢大家的支持!
Android 震动示例--心跳效果
正在开发第二个游戏,计时就要结束的时候,为了营造紧张的气氛,会利用手机自身的震动
模拟心跳效果,其实这个心跳效果做起来真的非常的简单。所以直接上代码了(注意模拟器
是模拟不了震动的,得真机测试哦):
程序效果:
Java 代码
1. package com.ray.test;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.os.Vibrator;
6. import android.view.MotionEvent;
7.
8. public class TestViberation extends Activity {
9. Vibrator vibrator;
10. /** Called when the activity is first created. */
11. @Override
12. public void onCreate(Bundle savedInstanceState) {
13. super.onCreate(savedInstanceState);
14. setContentView(R.layout.main);
15. }
16.
17. @Override
18. protected void onStop() {
19. if(null!=vibrator){
20. vibrator.cancel();
21. }
22. super.onStop();
23. }
24.
25. @Override
26. public boolean onTouchEvent(MotionEvent event) {
27.
28. if(event.getAction() == MotionEvent.ACTION_DOWN){
29. vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
30. long[] pattern = {800, 50, 400, 30}; // OFF/ON/OFF/ON...
31. vibrator.vibrate(pattern, 2);//-1 不重复,非-1 为从 pattern 的指定下标开始重
复
32. }
33. return super.onTouchEvent(event);
34. }
35.
36.
37. }
android animation
动画效果编程基础--AnimationAndroid
在 Android 中,分别可以在 xml 中定义 Animation,也可以在程序代码中定义动画类型
Android 的 animation 由四种类型组成
XML 中
alpha
渐变透明度动画效果
scale
渐变尺寸伸缩动画效果
translate
画面转换位置移动动画效果
rotate
画面转移旋转动画效果
代码中
AlphaAnimation
渐变透明度动画效果
ScaleAnimation
渐变尺寸伸缩动画效果
TranslateAnimation
画面转换位置移动动画效果
RotateAnimation
画面转移旋转动画效果
Android 动画模式
Animation 主要有两种动画模式:
一种是 tweened animation(渐变动画)
alpha
AlphaAnimation
scale
ScaleAnimation
一种是 frame by frame(画面转换动画)
translate
TranslateAnimation
rotate
RotateAnimation
如何在 XML 文件中定义动画
① 打开 Eclipse,新建 Android 工程
② 在 res 目录中新建 anim 文件夹
③ 在 anim 目录中新建一个 myanim.xml(注意文件名小写)
④ 加入 XML 的动画代码
每个元素表示不同的动画效果
Android 动画解析--XML
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="3000"
/>
android:interpolator=
"@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="0.0"
android:toXScale="1.4"
android:fromYScale="0.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:startOffset=“700”
android:duration="700" />
android:fromXDelta="30"
android:toXDelta="-80"
android:fromYDelta="30"
android:toYDelta="300"
android:duration="2000"
/>
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="+350"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000" />
在编码中如何使用如何使用 XML 中的动画效果
在代码中使用这个方法得到 Animation 实例
public static Animation loadAnimation (Context context, int id)
//第一个参数 Context 为程序的上下文
//第二个参数 id 为动画 XML 文件的引用
//例子:
myAnimation= AnimationUtils.loadAnimation(this,R.anim.my_action);
//使用 AnimationUtils 类的静态方法 loadAnimation()来加载 XML 中的动画 XML 文件
如何在 Java 代码中定义动画
//在代码中定义 动画实例对象
private Animation myAnimation_Alpha;
private Animation myAnimation_Scale;
private Animation myAnimation_Translate;
private Animation myAnimation_Rotate;
//根据各自的构造方法来初始化一个实例对象
myAnimation_Alpha=new AlphaAnimation(0.1f, 1.0f);
myAnimation_Scale =new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
myAnimation_Translate=new TranslateAnimation(30.0f, -80.0f, 30.0f, 300.0f);
myAnimation_Rotate=new RotateAnimation(0.0f,
+350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
--------------------------------------------------------------------
Android 动画解析
AlphaAnimation
① AlphaAnimation 类对象定义
private AlphaAnimation myAnimation_Alpha;
② AlphaAnimation 类对象构造
AlphaAnimation(float fromAlpha, float toAlpha)
//第一个参数 fromAlpha 为 动画开始时候透明度
//第二个参数 toAlpha 为 动画结束时候透明度
myAnimation_Alpha=new AlphaAnimation(0.1f, 1.0f);
//说明:
// 0.0 表示完全透明
// 1.0 表示完全不透明
③ 设置动画持续时间
myAnimation_Alpha.setDuration(5000);
//设置时间持续时间为 5000 毫秒
ScaleAnimation
①ScaleAnimation 类对象定义
private AlphaAnimation myAnimation_Scale;
② ScaleAnimation 类对象构造
ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一个参数 fromX 为动画起始时 X 坐标上的伸缩尺寸
//第二个参数 toX 为动画结束时 X 坐标上的伸缩尺寸
//第三个参数 fromY 为动画起始时 Y 坐标上的伸缩尺寸
//第四个参数 toY 为动画结束时 Y 坐标上的伸缩尺寸
/*说明:
以上四种属性值
0.0 表示收缩到没有
1.0 表示正常无伸缩
值小于 1.0 表示收缩
值大于 1.0 表示放大
*/
//第五个参数 pivotXType 为动画在 X 轴相对于物件位置类型
//第六个参数 pivotXValue 为动画相对于物件的 X 坐标的开始位置
//第七个参数 pivotXType 为动画在 Y 轴相对于物件位置类型
//第八个参数 pivotYValue 为动画相对于物件的 Y 坐标的开始位置
myAnimation_Scale =new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
③ 设置动画持续时间
myAnimation_Scale.setDuration(700);
//设置时间持续时间为 700 毫秒
TranslateAnimation
① TranslateAnimation 类对象定义
private AlphaAnimation myAnimation_Translate;
② TranslateAnimation 类对象构造
TranslateAnimation(float fromXDelta, float toXDelta,
float fromYDelta, float toYDelta)
//第一个参数 fromXDelta 为动画起始时 X 坐标上的移动位置
//第二个参数 toXDelta 为动画结束时 X 坐标上的移动位置
//第三个参数 fromYDelta 为动画起始时 Y 坐标上的移动位置
//第四个参数 toYDelta 为动画结束时 Y 坐标上的移动位置
③ 设置动画持续时间
myAnimation_Translate.setDuration(2000);
//设置时间持续时间为 2000 毫秒
RotateAnimation
① RotateAnimation 类对象定义
private AlphaAnimation myAnimation_Rotate;
② RotateAnimation 类对象构造
RotateAnimation(float fromDegrees, float toDegrees,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一个参数 fromDegrees 为动画起始时的旋转角度
//第二个参数 toDegrees 为动画旋转到的角度
//第三个参数 pivotXType 为动画在 X 轴相对于物件位置类型
//第四个参数 pivotXValue 为动画相对于物件的 X 坐标的开始位置
//第五个参数 pivotXType 为动画在 Y 轴相对于物件位置类型
//第六个参数 pivotYValue 为动画相对于物件的 Y 坐标的开始位置
myAnimation_Rotate=new RotateAnimation(0.0f,
+350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f)
③ 设置动画持续时间
myAnimation_Rotate.setDuration(3000);
//设置时间持续时间为 3000 毫秒
---------------------------------------------------------------------
下面的小例子是利用 RotateAnimation 简单展示一下两种方法的用法,对于其他动画,如
ScaleAnimation,AlphaAnimation,原理是一样的。
方法一:在 xml 中定义动画:
Xml 代码
1.
2.
3.
4.
5. android:interpolator="@android:anim/accelerate_decelerate_interpolator"
6. android:fromDegrees="0"
7. android:toDegrees="+360"
8. android:duration="3000" />
9.
10.
16. lt;/set>
使用动画的 Java 代码,程序的效果是点击按钮,TextView 旋转一周:
Java 代码
1. package com.ray.animation;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.view.View;
6. import android.view.View.OnClickListener;
7. import android.view.animation.Animation;
8. import android.view.animation.AnimationUtils;
9. import android.widget.Button;
10. import android.widget.TextView;
11.
12. public class TestAnimation extends Activity implements OnClickListener{
13. public void onCreate(Bundle savedInstanceState) {
14. super.onCreate(savedInstanceState);
15. setContentView(R.layout.main);
16. Button btn = (Button)findViewById(R.id.Button01);
17. btn.setOnClickListener(this);
18. }
19.
20. @Override
21. public void onClick(View v) {
22. Animation anim = AnimationUtils.loadAnimation(this, R.anim.my_rotate_action);
23. findViewById(R.id.TextView01).startAnimation(anim);
24. }
25. }
方法二:直接在代码中定义动画(效果跟方法一类似):
Java 代码
1. package com.ray.animation;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.view.View;
6. import android.view.View.OnClickListener;
7. import android.view.animation.AccelerateDecelerateInterpolator;
8. import android.view.animation.Animation;
9. import android.view.animation.RotateAnimation;
10. import android.widget.Button;
11.
12. public class TestAnimation extends Activity implements OnClickListener{
13.
14. public void onCreate(Bundle savedInstanceState) {
15. super.onCreate(savedInstanceState);
16. setContentView(R.layout.main);
17. Button btn = (Button)findViewById(R.id.Button);
18. btn.setOnClickListener(this);
19. }
20.
21. public void onClick(View v) {
22. Animation anim = null;
23. anim = new RotateAnimation(0.0f,+360.0f);
24. anim.setInterpolator(new AccelerateDecelerateInterpolator());
25. anim.setDuration(3000);
26. findViewById(R.id.TextView01).startAnimation(anim);
27. }
28. }
29.一、Android 中的通知
30. 一般手机上边都有一个状态条,显示电池电量、信号强度、未接来电、短信...。Android 的屏
幕上方也具有状态条。这里所说的通知,就是在这个状态条上显示通知。
31.
32. 发送通知的步骤如下:
33. 1).获取通知管理器
34. NotificationManager mNotificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
35. 2).新建一个通知,指定其图标和标题
36. int icon = android.R.drawable.stat_notify_chat;
37. long when = System.currentTimeMillis();
38. //第一个参数为图标,第二个参数为标题,第三个为通知时间
39. Notification notification = new Notification(icon, null, when);
40. Intent openintent = new Intent(this, OtherActivity.class);
41. //当点击消息时就会向系统发送 openintent 意图
42. PendingIntent contentIntent = PendingIntent.getActivity(this, 0, openintent, 0);
43. notification.setLatestEventInfo(this, “标题”, “内容", contentIntent);
44. mNotificationManager.notify(0, notification);
45.
Android 中的样式和主题
46. android 中的样式和 CSS 样式作用相似,都是用于为界面元素定义显示风格,它是一个包含一
个戒者多个 view 控件属性的集合。如:需要定义字体的颜色和大小。
47.
48. 1).在 values 目录下添加 styles.xml:
49.
50. 2).在 layout 文件中可以通过 style 戒 theme 属性设置样式戒主题。
三、使用 HTML 做为 UI
51. 使用 LayoutUI 比较麻烦,丌能让美工参不进来,这样就为开发人员带来了麻烦。但我们可以
通过 HTML+JS 来进行 UI 的设计不操作。
52.
53. 1).在 assets 添加 Html 页面
联系人列表
function show(jsondata){
var jsonobjs = eval(jsondata);
var table = document.getElementById("personTable");
for(var y=0; y
var tr = table.insertRow(table.rows.length); //添加一行
//添加三列
var td1 = tr.insertCell(0);
var td2 = tr.insertCell(1);
td2.align = "center";
var td3 = tr.insertCell(2);
//设置列内容和属性
td1.innerHTML = jsonobjs[y].id;
td2.innerHTML = jsonobjs[y].name;
td3.innerHTML = ""+ jsonobjs[y].phone+
"";
}
}
54.
55. 2).在 main.xlm 中添加一个 WebView 控件
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/webView"
/>
56.
57. 3).Activity 类
package cn.itcast.html;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import cn.itcast.domain.Contact;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.webkit.WebView;
public class ContactActivity extends Activity {
private static final String TAG = "ContactActivity";
private WebView webView;
private Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)this.findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);//设置支持javaScript
webView.getSettings().setSaveFormData(false);//丌保存表单数据
webView.getSettings().setSavePassword(false);//丌保存密码
webView.getSettings().setSupportZoom(false);//丌支持页面放大功能
//addJavascriptInterface方法中要绑定的Java对象及方法要运行在另外的线程中,丌能运行在构造他的线程中
webView.addJavascriptInterface(new MyJavaScript(), "itcast");
webView.loadUrl("file:///android_asset/index.html");
}
private final class MyJavaScript{
public void call(final String phone){
handler.post(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+ phone));
startActivity(intent);
}
});
}
/**
* 获取所有联系人
*/
public void getContacts(){
handler.post(new Runnable() {
@Override
public void run() {
//可以通过访问SQLLite数据库得到联系人
List contacts = new ArrayList();
contacts.add(new Contact(27, "路飞", "12345"));
contacts.add(new Contact(28, "索隆", "67890"));
String json = buildJson(contacts);
webView.loadUrl("javascript:show('"+ json +"')");
}
});
}
//生成Json格式的数据
private String buildJson(List contacts){
try {
JSONArray array = new JSONArray();
for(Contact contact : contacts){
JSONObject item = new JSONObject();
item.put("id", contact.getId());
item.put("name", contact.getName());
item.put("phone", contact.getPhone());
array.put(item);
}
return array.toString();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return "";
}
}
}
58.
59. MyJavaScript 接口实现的方法正是提供给页面中的 JS 代码调用的!
60. 2.将 APK 包放入到 SDCard 目录中
61. 在 FileExplorer 面板的右上角有一个导入手机图标,将上面生成的 APK 包导入到 SDCard 目
录中。
Android 选项卡效果
首先创建 Android 工程命名自己的 Activity 为 HelloTabWidget
在 main.xml 或者自己定义的*.xml 文件中创建一个 TabHost,需要两个元素
TabWidget 和 FrameLayout 通常会把这两个元素放到 LinearLayout 中。
FrameLayout 作为改变内容 content 用的。
注意:TabWidget 和 FrameLayout 有不同的 ID 命名空间
android:id="@android:id/idnames",这个是必须的因此 TabHost 才能自动找到
它,Activity 需要继承 TabActivity。
Xml 代码
1.
2.
3. android:id="@android:id/tabhost"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent">
6.
7. android:orientation="vertical"
8. android:layout_width="fill_parent"
9. android:layout_height="fill_parent">
10.
11. android:id="@android:id/tabs"
12. android:layout_width="fill_parent"
13. android:layout_height="wrap_content" />
14.
15. android:id="@android:id/tabcontent"
16. android:layout_width="fill_parent"
17. android:layout_height="fill_parent">
18.
19. android:id="@+id/textview1"
20. android:layout_width="fill_parent"
21. android:layout_height="fill_parent"
22. android:text="this is a tab" />
23.
24. android:id="@+id/textview2"
25. android:layout_width="fill_parent"
26. android:layout_height="fill_parent"
27. android:text="this is another tab" />
28.
29. android:id="@+id/textview3"
30. android:layout_width="fill_parent"
31. android:layout_height="fill_parent"
32. android:text="this is a third tab" />
33.
34.
35.
Activity 需要继承 TabActivity
Java 代码
1. public class HelloTabWidget extends TabActivity
Java 代码
1. public void onCreate(Bundle savedInstanceState) {
2. super.onCreate(savedInstanceState);
3. setContentView(R.layout.main);
4. mTabHost = getTabHost();
5. mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 1")
6. . setContent(R.id.textview1));
7. mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB 2").setConte
nt(R.id.textview2));
8. mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("TAB 3").setConte
nt(R.id.textview3));
9.
10. mTabHost.setCurrentTab(0);
11. }
Android BaseExpandableListAdapter 教程
文章分类:移动开发
先上图再说,实现效果如下图,选项可多少可变化。
BaseExpandableListAdapter 实现
Java 代码
1. import java.util.List;
2.
3. import android.content.Context;
4. import android.graphics.drawable.Drawable;
5. import android.view.LayoutInflater;
6. import android.view.View;
7. import android.view.ViewGroup;
8. import android.widget.BaseExpandableListAdapter;
9. import android.widget.CheckBox;
10. import android.widget.ImageView;
11. import android.widget.TextView;
12. import com.iwidsets.clear.manager.R;
13. import com.iwidsets.clear.manager.adapter.BrowserInfo;
14.
15. public class ClearExpandableListAdapter extends BaseExpandableListAdapter {
16.
17. class ExpandableListHolder {
18. ImageView appIcon;
19. TextView appInfo;
20. CheckBox appCheckBox;
21. }
22.
23. private Context context;
24. private LayoutInflater mChildInflater;
25. private LayoutInflater mGroupInflater;
26. private List group;
27.
28. public ClearExpandableListAdapter(Context c, List group) {
29. this.context = c;
30. mChildInflater = (LayoutInflater) context
31. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
32. mGroupInflater = (LayoutInflater) context
33. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
34. this.group = group;
35. }
36.
37. public Object getChild(int childPosition, int itemPosition) {
38. return group.get(childPosition).getChild(itemPosition);
39. }
40.
41. public long getChildId(int childPosition, int itemPosition) {
42.
43. return itemPosition;
44. }
45.
46. @Override
47. public int getChildrenCount(int index) {
48. return group.get(index).getChildSize();
49. }
50.
51. public Object getGroup(int index) {
52. return group.get(index);
53. }
54.
55. public int getGroupCount() {
56. return group.size();
57. }
58.
59. public long getGroupId(int index) {
60. return index;
61. }
62.
63. public View getGroupView(int position, boolean flag, View view,
64. ViewGroup parent) {
65. ExpandableListHolder holder = null;
66. if (view == null) {
67. view = mGroupInflater.inflate(
68. R.layout.browser_expandable_list_item, null);
69. holder = new ExpandableListHolder();
70. holder.appIcon = (ImageView) view.findViewById(R.id.app_icon);
71. view.setTag(holder);
72. holder.appInfo = (TextView) view.findViewById(R.id.app_info);
73. holder.appCheckBox = (CheckBox) view
74. .findViewById(R.id.app_checkbox);
75. } else {
76. holder = (ExpandableListHolder) view.getTag();
77. }
78. GroupInfo info = this.group.get(position);
79. if (info != null) {
80. holder.appInfo.setText(info.getBrowserInfo().getAppInfoId());
81. Drawable draw = this.context.getResources().getDrawable(
82. info.getBrowserInfo().getImageId());
83. holder.appIcon.setImageDrawable(draw);
84. holder.appCheckBox.setChecked(info.getBrowserInfo().isChecked());
85. }
86. return view;
87. }
88.
89. public boolean hasStableIds() {
90. return false;
91. }
92.
93. public boolean isChildSelectable(int arg0, int arg1) {
94. return false;
95. }
96.
97. @Override
98. public View getChildView(int groupPosition, int childPosition,
99. boolean isLastChild, View convertView, ViewGroup parent) {
100. ExpandableListHolder holder = null;
101. if (convertView == null) {
102. convertView = mChildInflater.inflate(
103. R.layout.browser_expandable_list_item, null);
104. holder = new ExpandableListHolder();
105. holder.appIcon = (ImageView) convertView
106. .findViewById(R.id.app_icon);
107. convertView.setTag(holder);
108. holder.appInfo = (TextView) convertView.findViewById(R.id.app_info);
109. holder.appCheckBox = (CheckBox) convertView
110. .findViewById(R.id.app_checkbox);
111. } else {
112. holder = (ExpandableListHolder) convertView.getTag();
113. }
114. BrowserInfo info = this.group.get(groupPosition)
115. .getChild(childPosition);
116. if (info != null) {
117. holder.appInfo.setText(info.getAppInfoId());
118. Drawable draw = this.context.getResources().getDrawable(
119. info.getImageId());
120. holder.appIcon.setImageDrawable(draw);
121. holder.appCheckBox.setChecked(info.isChecked());
122. }
123. return convertView;
124. }
125.
126. }
要想让 child 获得焦点,只在改
Java 代码
1. public boolean isChildSelectable(int arg0, int arg1) {
2. return true;
3. }
browser_expandable_list_item.xml 用于显示每一个 ITEM 的 XML
Xml 代码
1.
2.
3. android:layout_width="fill_parent" android:layout_height="wrap_content"
4. android:orientation="horizontal" android:minHeight="40px"
5. android:layout_gravity="center_vertical">
6.
7. android:layout_width="wrap_content" android:layout_height="wrap_content"
8. android:layout_marginLeft="35px" android:checked="true"/>
9.
10. android:layout_height="wrap_content" android:layout_gravity="center_vertical" />
11.
12.
13. android:layout_height="wrap_content" android:textColor="?android:attr/textColorPrim
ary"
14. android:paddingLeft="3px" android:layout_gravity="center_vertical" />
15.
browserlayout.xml 用于显示整个界面
Xml 代码
1.
2.
3. android:layout_width="fill_parent" android:layout_height="fill_parent"
4. android:orientation="vertical">
5.
6. android:layout_width="fill_parent" android:layout_height="0dip"
7. android:layout_weight="1" />
8.
9. android:layout_width="fill_parent" android:paddingLeft="4dip"
10. android:paddingRight="4dip" android:paddingBottom="1dip"
11. android:paddingTop="5dip" android:background="@android:drawable/bottom_bar"
12. android:id="@+id/app_footer">
13.
14. android:layout_width="0dip" android:layout_height="fill_parent"
15. android:text="@string/clear">
16.
17. android:layout_width="0dip" android:layout_height="fill_parent"
18. android:text="select_all">
19.
20. android:layout_width="0dip" android:layout_height="fill_parent"
21. android:text="deselect_all">
22.
23.
24.
BrowserInfo 用于提供一个项的信息
Java 代码
1. public class BrowserInfo {
2.
3. private int appInfoId;
4. private int imageId;
5. private boolean checked;
6.
7. public BrowserInfo(int appInfoId, int imageId, boolean checked) {
8. this.appInfoId = appInfoId;
9. this.imageId = imageId;
10. this.checked = checked;
11. }
12.
13. public boolean isChecked() {
14. return checked;
15. }
16.
17. public void setChecked(boolean checked) {
18. this.checked = checked;
19. }
20.
21. public int getAppInfoId() {
22. return appInfoId;
23. }
24.
25. public void setAppInfoId(int appInfoId) {
26. this.appInfoId = appInfoId;
27. }
28.
29. public int getImageId() {
30. return imageId;
31. }
32.
33. public void setImageId(int imageId) {
34. this.imageId = imageId;
35. }
36.
37. }
GroupInfo 用于显示一个组的信息
Java 代码
1. import java.util.List;
2.
3. public class GroupInfo {
4.
5. private BrowserInfo group;
6. private List child;
7.
8. public GroupInfo(BrowserInfo group, List child) {
9.
10. this.group = group;
11. this.child = child;
12. }
13.
14. public void add(BrowserInfo info){
15. child.add(info);
16. }
17.
18. public void remove(BrowserInfo info){
19. child.remove(info);
20. }
21.
22. public void remove(int index){
23. child.remove(index);
24. }
25.
26. public int getChildSize(){
27. return child.size();
28. }
29.
30. public BrowserInfo getChild(int index){
31. return child.get(index);
32. }
33.
34. public BrowserInfo getBrowserInfo() {
35. return group;
36. }
37.
38. public void setBrowserInfo(BrowserInfo group) {
39. this.group = group;
40. }
41.
42. public List getChild() {
43. return child;
44. }
45.
46. public void setChild(List child) {
47. this.child = child;
48. }
49.
50. }
ClearBrowserActivity 最后就是把要显示的内容显示出来的。
Java 代码
1. public class ClearBrowserActivity extends Activity implements ExpandableListView.OnGr
oupClickListener,ExpandableListView.OnChildClickListener{
2.
3. private List group;
4.
5. private ClearExpandableListAdapter listAdapter = null;
6. private ExpandableListView appList;
7.
8. public void onCreate(Bundle savedInstanceState) {
9. super.onCreate(savedInstanceState);
10. setContentView(R.layout.browserlayout);
11. appList = (ExpandableListView) findViewById(R.id.appList);
12. init();
13. BrowserInfo browsingHistoryParents = newBrowserInfo(
14. R.string.browsinghistory, R.drawable.browser_image,true);
15. List browsingHistoryChild = new ArrayList();
16. BrowserInfo browser = newBrowserInfo(R.string.browser,
17. R.drawable.browser_image, true);
18. browsingHistoryChild.add(browser);
19.
20. BrowserInfo operaClear = newBrowserInfo(R.string.opera_clear,
21. R.drawable.browser_image,true);
22. browsingHistoryChild.add(operaClear);
23.
24. BrowserInfo firefoxClear = newBrowserInfo(R.string.firefox_clear,
25. R.drawable.browser_image,true);
26. browsingHistoryChild.add(firefoxClear);
27.
28. BrowserInfo ucwebClear = newBrowserInfo(R.string.ucweb_clear,
29. R.drawable.browser_image,false);
30. browsingHistoryChild.add(ucwebClear);
31.
32. GroupInfo browserGroup = new GroupInfo(browsingHistoryParents,
33. browsingHistoryChild);
34. addGroup(browserGroup);
35.
36. listAdapter = new ClearExpandableListAdapter(this, group);
37. appList.setOnChildClickListener(this);
38. appList.setOnGroupClickListener(this);
39. appList.setAdapter(listAdapter);
40. }
41.
42. private void init() {
43. group = new ArrayList();
44. }
45.
46. private void addGroup(GroupInfo info) {
47. group.add(info);
48. }
49.
50. private static BrowserInfo newBrowserInfo(int infoId, int imageId,boolean checked) {
51. return new BrowserInfo(infoId, imageId,checked);
52. }
53.
54. @Override
55. public boolean onGroupClick(ExpandableListView parent, View v,
56. int groupPosition, long id) {
57. return false;
58. }
59.
60. @Override
61. public boolean onChildClick(ExpandableListView parent, View v,
62. int groupPosition, int childPosition, long id) {
63. return false;
64. }
65. }
android 3d 旋转
文章分类:Java 编程
在javaeye里看到了关于3d旋转的文章,可是博主没有透入什么技术细节。
由于一直想做出那种旋转效果,所以就想啊想,终于想出来了( 我是个小菜
鸟)。呵呵,不管怎样,希望对想做还没做出来的朋友一些帮助。
先上一个效果图:
这是你想要的吗?如果是就继续往下看吧。
其实,这个效果是用 animation 配合 camera 做出来的,相信大家在 apidemo
里面看过类似的。
那么先写一个继承 animation 的类:Rotate3d
Rotate3d 代码
1. public class Rotate3d extends Animation {
2. private float mFromDegree;
3. private float mToDegree;
4. private float mCenterX;
5. private float mCenterY;
6. private float mLeft;
7. private float mTop;
8. private Camera mCamera;
9. private static final String TAG = "Rotate3d";
10.
11. public Rotate3d(float fromDegree, float toDegree, float left, float top,
12. float centerX, float centerY) {
13. this.mFromDegree = fromDegree;
14. this.mToDegree = toDegree;
15. this.mLeft = left;
16. this.mTop = top;
17. this.mCenterX = centerX;
18. this.mCenterY = centerY;
19.
20. }
21.
22. @Override
23. public void initialize(int width, int height, int parentWidth,
24. int parentHeight) {
25. super.initialize(width, height, parentWidth, parentHeight);
26. mCamera = new Camera();
27. }
28.
29. @Override
30. protected void applyTransformation(float interpolatedTime, Transformation t) {
31. final float FromDegree = mFromDegree;
32. float degrees = FromDegree + (mToDegree - mFromDegree)
33. * interpolatedTime;
34. final float centerX = mCenterX;
35. final float centerY = mCenterY;
36. final Matrix matrix = t.getMatrix();
37.
38. if (degrees <= -76.0f) {
39. degrees = -90.0f;
40. mCamera.save();
41. mCamera.rotateY(degrees);
42. mCamera.getMatrix(matrix);
43. mCamera.restore();
44. } else if(degrees >=76.0f){
45. degrees = 90.0f;
46. mCamera.save();
47. mCamera.rotateY(degrees);
48. mCamera.getMatrix(matrix);
49. mCamera.restore();
50. }else{
51. mCamera.save();
52. //这里很重要哦。
53. mCamera.translate(0, 0, centerX);
54. mCamera.rotateY(degrees);
55. mCamera.translate(0, 0, -centerX);
56. mCamera.getMatrix(matrix);
57. mCamera.restore();
58. }
59.
60. matrix.preTranslate(-centerX, -centerY);
61. matrix.postTranslate(centerX, centerY);
62. }
63. }
有了这个类一切都会变得简单的,接着只要在 activity 中写两个 Rotate3d
的对象,让两个 view,分别做这两个对象的 animation 就好了。( 原来就这么
简单啊!无语)
Activity 代码
1. //下面两句很关键哦,呵呵,心照不宣。
2. Rotate3d leftAnimation = new Rotate3d(-0, -90, 0, 0, mCenterX, mCenterY);
3. Rotate3d rightAnimation = new Rotate3d(-0+90, -90+90, 0.0f, 0.0f, mCenterX, mCent
erY);
4.
5. leftAnimation.setFillAfter(true);
6. leftAnimation.setDuration(1000);
7. rightAnimation.setFillAfter(true);
8. rightAnimation.setDuration(1000);
9.
10. mImageView1.startAnimation(leftAnimation);
11. mImageView2.startAnimation(rightAnimation);
还要写一下 mImageView1,mImageView2 的 xml,
Xml 代码
1.
2.
3. android:orientation="vertical"
4. android:layout_width="fill_parent"
5. android:layout_height="wrap_content"
6. >
7.
8.
9. android:layout_width="fill_parent"
10. android:layout_height="fill_parent">
11.
12.
13. android:id="@+id/image1"
14. android:layout_gravity="center_horizontal"
15. android:layout_width="fill_parent"
16. android:layout_height="wrap_content"
17. android:src="@drawable/image1"
18. />
19.
20. android:id="@+id/image2"
21. android:background="#ffff0000"
22. android:layout_gravity="center_horizontal"
23. android:layout_width="fill_parent"
24. android:layout_height="wrap_content"
25. android:src="@drawable/image2"
26. />
27.
28.
29.
写完收工。如果有不足之处,还请朋友们不吝指教。
Android File Explorer 展示图片
文章分类:移动开发
res/layout/row.xml
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rowtext"
android:layout_width="fill_parent"
android:layout_height="25px"
android:textSize="23sp" />
/res/layout/main.xml
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:id="@+id/path"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="No Data"
/>
/res/layout/jpgdialog.xml
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="10dip"
android:paddingRight="10dip"
>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="11sp" />
/>
android:layout_width="150px"
android:layout_height="150px"
/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="OK"
/>
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class AndroidExplorer extends ListActivity {
static final int ID_JPGDIALOG = 0;
String filename;
String exifAttribute;
TextView exifText;
ImageView bmImage;
BitmapFactory.Options bmOptions;
File jpgFile;
Dialog jpgDialog;
private List item = null;
private List path = null;
private String root="/";
private TextView myPath;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myPath = (TextView)findViewById(R.id.path);
getDir(root);
}
private void getDir(String dirPath)
{
myPath.setText("Location: " + dirPath);
item = new ArrayList();
path = new ArrayList();
File f = new File(dirPath);
File[] files = f.listFiles();
if(!dirPath.equals(root))
{
item.add(root);
path.add(root);
item.add("../");
path.add(f.getParent());
}
for(int i=0; i < files.length; i++)
{
File file = files[i];
path.add(file.getPath());
if(file.isDirectory())
item.add(file.getName() + "/");
else
item.add(file.getName());
}
ArrayAdapter fileList =
new ArrayAdapter(this, R.layout.row, item);
setListAdapter(fileList);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
File file = new File(path.get(position));
if (file.isDirectory())
{
if(file.canRead())
getDir(path.get(position));
else
{
new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle("[" + file.getName() + "] folder can't be read!")
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).show();
}
}
else
{
exifAttribute = null;
filename = file.getName();
String ext = filename.substring(filename.lastIndexOf('.')+1,
filename.length());
if(ext.equals("JPG")||ext.equals("jpg"))
{
try {
ExifInterface exif = new ExifInterface(file.toString());
exifAttribute = getExif(exif);
} catch (IOException e) {
// TODO Auto-generated catch block
;
}
jpgFile = file;
showDialog(ID_JPGDIALOG);
}
else{
new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle("[" + filename + "]")
.setMessage(exifAttribute)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which) {
// TODO Auto-generated method stub
}
}).show();
}
}
}
private String getExif(ExifInterface exif)
{
String myAttribute=null;
myAttribute += getTagString(ExifInterface.TAG_DATETIME, exif);
myAttribute += getTagString(ExifInterface.TAG_FLASH, exif);
myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE,
exif);
myAttribute +=
getTagString(ExifInterface.TAG_GPS_LATITUDE_REF, exif);
myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE,
exif);
myAttribute +=
getTagString(ExifInterface.TAG_GPS_LONGITUDE_REF, exif);
myAttribute += getTagString(ExifInterface.TAG_IMAGE_LENGTH,
exif);
myAttribute += getTagString(ExifInterface.TAG_IMAGE_WIDTH,
exif);
myAttribute += getTagString(ExifInterface.TAG_MAKE, exif);
myAttribute += getTagString(ExifInterface.TAG_MODEL, exif);
myAttribute += getTagString(ExifInterface.TAG_ORIENTATION,
exif);
myAttribute += getTagString(ExifInterface.TAG_WHITE_BALANCE,
exif);
return myAttribute;
}
private String getTagString(String tag, ExifInterface exif)
{
return(tag + " : " + exif.getAttribute(tag) + "\n");
}
@Override
protected Dialog onCreateDialog(int id) {
jpgDialog = null;;
switch(id){
case ID_JPGDIALOG:
Context mContext = this;
jpgDialog = new Dialog(mContext);
jpgDialog.setContentView(R.layout.jpgdialog);
exifText = (TextView) jpgDialog.findViewById(R.id.text);
bmImage = (ImageView)jpgDialog.findViewById(R.id.image);
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 2;
Button okDialogButton =
(Button)jpgDialog.findViewById(R.id.okdialogbutton);
okDialogButton.setOnClickListener(okDialogButtonOnClickListener);
break;
default:
break;
}
return jpgDialog;
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
// TODO Auto-generated method stub
switch(id){
case ID_JPGDIALOG:
dialog.setTitle("[" + filename + "]");
exifText.setText(exifAttribute);
Bitmap bm = BitmapFactory.decodeFile(jpgFile.getPath(), bmOptions);
bmImage.setImageBitmap(bm);
break;
default:
break;
}
}
private Button.OnClickListener okDialogButtonOnClickListener
= new Button.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
jpgDialog.dismiss();
}
};
}
android ShapeDrawable 实例
文章分类:移动开发
今天看了一下 api 中的画图,遇到了一个新的类,Shader 类介绍,android
中提供了 Shader 类专门来渲染图像已经一些几何图形,shader 下面包括几个直
接子类,分别是 BitmapShaper,ComposeShader,
LinerGradient,RadialGradient,SweepGradient.BitmapShader 主要用来渲染
图像,Shader 类的使用,先构造 Shdaer 对象,然后通过 Paint 的 setShader 方
法来设置渲染对象,然后再绘制使用这个 Paint 对象既可。
Java 代码
1. import android.app.Activity;
2. import android.content.Context;
3. import android.graphics.Bitmap;
4. import android.graphics.BitmapShader;
5. import android.graphics.Canvas;
6. import android.graphics.ComposePathEffect;
7. import android.graphics.CornerPathEffect;
8. import android.graphics.DiscretePathEffect;
9. import android.graphics.LinearGradient;
10. import android.graphics.Paint;
11. import android.graphics.Path;
12. import android.graphics.PathEffect;
13. import android.graphics.RectF;
14. import android.graphics.Shader;
15. import android.graphics.SweepGradient;
16. import android.graphics.drawable.Drawable;
17. import android.graphics.drawable.ShapeDrawable;
18. import android.graphics.drawable.shapes.ArcShape;
19. import android.graphics.drawable.shapes.OvalShape;
20. import android.graphics.drawable.shapes.PathShape;
21. import android.graphics.drawable.shapes.RectShape;
22. import android.graphics.drawable.shapes.RoundRectShape;
23. import android.graphics.drawable.shapes.Shape;
24. import android.os.Bundle;
25. import android.view.View;
26.
27. public class ShapeDrawble1 extends Activity {
28. /** Called when the activity is first created. */
29.
30.
31. @Override
32. protected void onCreate(Bundle savedInstanceState) {
33. super.onCreate(savedInstanceState);
34. setContentView(new SampleView(this));
35. }
36.
37. private static class SampleView extends View {
38. private ShapeDrawable[] mDrawables;
39.
40. private static Shader makeSweep() {
41. /* SweepGradient 是继承于 Shader 的,它是以中心点(150,25)
42. * 按照下列四种颜色进行变化的*/
43. return new SweepGradient(0, 0,
44. new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 },
45. null);// null 表示均衡变化
46. }
47.
48. private static Shader makeLinear() {
49. //颜色按照直线线性变化的着色器
50. return new LinearGradient(100, 100, 0, 0,
51. new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF },
52. null, Shader.TileMode.MIRROR);
53. }
54.
55. private static Shader makeTiling() {
56. int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0};
57. Bitmap bm = Bitmap.createBitmap(pixels, 1, 1,
58. Bitmap.Config.ARGB_8888);
59. /**
60. * BitmapShader 是一个位图着色器,这个着色器是通过
61. * 在 x,y 方向重复位图 bm 的像素来着色的
62. *
63. */
64. return new BitmapShader(bm, Shader.TileMode.REPEAT,
65. Shader.TileMode.REPEAT);
66. }
67. /**
68. * ShapeDrawable 是绘制各种几何体的类。它注入想要绘制的形状 shap
69. * 类,就可以绘制出我们想要的集合体,这个类最寒心的就是 draw(canvas)
70. * 和 onDraw(Shape,Canvas,Paint)这个方法调用
71. *
72. */
73. private static class MyShapeDrawable extends ShapeDrawable {
74. //Paint.ANTI_ALIAS_FLAG 代表这个画笔的图形是光滑的
75. private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
76.
77. public MyShapeDrawable(Shape s) {
78. super(s);
79. mStrokePaint.setStyle(Paint.Style.STROKE);
80. }
81.
82. public Paint getStrokePaint() {
83. return mStrokePaint;
84. }
85.
86. @Override protected void onDraw(Shape s, Canvas c, Paint p) {
87. //绘制填充效果的图形
88. s.draw(c, p);
89. //绘制黑边
90. s.draw(c, mStrokePaint);
91. }
92. }
93.
94. public SampleView(Context context) {
95. super(context);
96. setFocusable(true);
97. //外部圆角矩形的圆角圆半径,上面俩个角是圆
98. float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
99. //内部矩形
100. RectF inset = new RectF(6, 6, 6, 6);
101. //内部圆角矩形的圆角是圆半径,左上角和右下角是圆角矩形
102. float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
103. //绘制一个顶点为下列四个点的棱形
104. Path path = new Path();
105. path.moveTo(50, 0);
106. path.lineTo(0, 50);
107. path.lineTo(50, 100);
108. path.lineTo(100, 50);
109. //封闭前面点所绘制的路径
110. path.close();
111.
112. mDrawables = new ShapeDrawable[7];
113. //绘制矩形
114. mDrawables[0] = new ShapeDrawable(new RectShape());
115. //绘制椭圆
116. mDrawables[1] = new ShapeDrawable(new OvalShape());
117. //绘制上面俩个角是圆角的矩形
118. mDrawables[2] = new ShapeDrawable(new RoundRectShape(outerR, null,
119. null));
120. //绘制上面俩角是圆角,并且有一个内嵌的矩形
121. mDrawables[3] = new ShapeDrawable(new RoundRectShape(outerR, inset,
122. null));
123. 绘制上面俩角是圆角,并且有一个内嵌的矩形且左上角和右下角是圆形
矩形环
124. mDrawables[4] = new ShapeDrawable(new RoundRectShape(outerR, inset,
125. innerR));
126. //绘制指定路径的集合体
127. mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
128. // 用自定的 ShapDrawble 绘制开始弧度 45 扫过弧度-270 的椭圆
129. mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
130.
131. mDrawables[0].getPaint().setColor(0xFFFF0000);
132. mDrawables[1].getPaint().setColor(0xFF00FF00);
133. mDrawables[2].getPaint().setColor(0xFF0000FF);
134. mDrawables[3].getPaint().setShader(makeSweep());
135. mDrawables[4].getPaint().setShader(makeLinear());
136. mDrawables[5].getPaint().setShader(makeTiling());
137. mDrawables[6].getPaint().setColor(0x88FF8844);
138. //DiscretePathEffect 是一个折线路径效果,分割长度是 10,偏差时 4
139. PathEffect pe = new DiscretePathEffect(10, 4);
140. //CornerPathEffect 是将 2 个路径效果合并后的路径效果
141. PathEffect pe2 = new CornerPathEffect(4);
142. mDrawables[3].getPaint().setPathEffect(
143. new ComposePathEffect(pe2, pe));
144.
145. MyShapeDrawable msd = (MyShapeDrawable)mDrawables[6];
146. //设置笔画宽度等于 4
147. msd.getStrokePaint().setStrokeWidth(4);
148. }
149.
150. @Override protected void onDraw(Canvas canvas) {
151.
152. int x = 10;
153. int y = 10;
154. int width = 300;
155. int height = 50;
156. //循环绘制
157. for (Drawable dr : mDrawables) {
158. dr.setBounds(x, y, x + width, y + height);
159. dr.draw(canvas);
160. y += height + 5;
161. }
162. }
163. }
164. }
Eclipse 开发 Android, TableLayout(学习 4)
Hello, TableLayout
A TableLayout is a ViewGroup that will lay child View elements into rows
and columns.
1. Start a new project/Activity called HelloTableLayout.
2. Open the layout file. Make it like so:
3.
4.
xmlns:android="http://schemas.android.com/apk/res/android"
5. android:layout_width="fill_parent"
6. android:layout_height="fill_parent"
7. android:stretchColumns="1">
8.
9.
10.
11. android:layout_column="1"
12. android:text="Open..."
13. android:padding="3dip" />
14.
15. android:text="Ctrl-O"
16. android:gravity="right"
17. android:padding="3dip" />
18.
19.
20.
21.
22. android:layout_column="1"
23. android:text="Save..."
24. android:padding="3dip" />
25.
26. android:text="Ctrl-S"
27. android:gravity="right"
28. android:padding="3dip" />
29.
30.
31.
32.
33. android:layout_column="1"
34. android:text="Save As..."
35. android:padding="3dip" />
36.
37. android:text="Ctrl-Shift-S"
38. android:gravity="right"
39. android:padding="3dip" />
40.
41.
42.
43. android:layout_height="2dip"
44. android:background="#FF909090" />
45.
46.
47.
48. android:text="X"
49. android:padding="3dip" />
50.
51. android:text="Import..."
52. android:padding="3dip" />
53.
54.
55.
56.
57. android:text="X"
58. android:padding="3dip" />
59.
60. android:text="Export..."
61. android:padding="3dip" />
62.
63. android:text="Ctrl-E"
64. android:gravity="right"
65. android:padding="3dip" />
66.
67.
68.
69. android:layout_height="2dip"
70. android:background="#FF909090" />
71.
72.
73.
74. android:layout_column="1"
75. android:text="Quit"
76. android:padding="3dip" />
77.
78.
Notice how this resembles the structure of an HTML table.
TableLayout is like the table element; TableRow is like a tr element;
but for our cells like the html td element, we can use any kind of
View. Here, we use TextView for the cells.
79. Make sure your Activity loads this layout in the onCreate() method:
80.public void onCreate(Bundle savedInstanceState) {
81. super.onCreate(savedInstanceState);
82. setContentView(R.layout.main);
83.}
R.layout.main refers to the main.xml layout file.
84. Run it.
You should see the following:
备注:TableLayout 与 html 中表格类似。
系出名门 Android(8)
文章分类:移动开发
系出名门Android(8) - 控件(View)之TextSwitcher, Gallery, ImageSwitcher,
GridView, ListView, ExpandableList
介绍
在 Android 中使用各种控件(View)
TextSwitcher - 文字转换器控件(改变文字时增加一些动画效果)
Gallery - 缩略图浏览器控件
ImageSwitcher - 图片转换器控件(改变图片时增加一些动画效果)
GridView - 网格控件
ListView - 列表控件
ExpandableList - 支持展开/收缩功能的列表控件
Java 代码
1. 1、TextSwitcher 的 Demo
2. textswitcher.xml
3.
4. 代码
5.
6.
7. android:orientation="vertical" android:layout_width="fill_parent"
8. android:layout_height="fill_parent">
9.
10.
11. android:layout_height="wrap_content" android:text="改变文字" />
12.
13.
16.
17. android:layout_width="fill_parent" android:layout_height="wrap_content" />
18.
19.
20.
21.
22. _TextSwitcher.java
23.
24. 代码
25. package com.webabcd.view;
26.
27. import java.util.Random;
28.
29. import android.app.Activity;
30. import android.os.Bundle;
31. import android.view.View;
32. import android.view.animation.Animation;
33. import android.view.animation.AnimationUtils;
34. import android.widget.Button;
35. import android.widget.TextSwitcher;
36. import android.widget.TextView;
37. import android.widget.ViewSwitcher;
38.
39. public class _TextSwitcher extends Activity implements ViewSwitcher.ViewFactory {
40.
41. @Override
42. protected void onCreate(Bundle savedInstanceState) {
43. // TODO Auto-generated method stub
44. super.onCreate(savedInstanceState);
45. this.setContentView(R.layout.textswithcer);
46.
47. setTitle("TextSwithcer");
48.
49. final TextSwitcher switcher = (TextSwitcher) findViewById(R.id.textSwitcher);
50. // 指定转换器的 ViewSwitcher.ViewFactory
51. switcher.setFactory(this);
52.
53. // 设置淡入和淡出的动画效果
54. Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
55. Animation out = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
56. switcher.setInAnimation(in);
57. switcher.setOutAnimation(out);
58.
59. // 单击一次按钮改变一次文字
60. Button btnChange = (Button) this.findViewById(R.id.btnChange);
61. btnChange.setOnClickListener(new View.OnClickListener() {
62. @Override
63. public void onClick(View v) {
64. switcher.setText(String.valueOf(new Random().nextInt()));
65. }
66. });
67. }
68.
69. // 重写 ViewSwitcher.ViewFactory 的 makeView(),返回一个 View
70. @Override
71. public View makeView() {
72. TextView textView = new TextView(this);
73. textView.setTextSize(36);
74. return textView;
75. }
76. }
77.
78.
79.
80. 2、Gallery 的 Demo
81. gallery.xml
82.
83. 代码
84.
85.
86. android:orientation="vertical" android:layout_width="fill_parent"
87. android:layout_height="fill_parent">
88.
89.
93.
94. android:layout_height="wrap_content" android:spacing="20px" />
95.
96.
97.
98.
99. _Gallery.java
100.
101. 代码
102. package com.webabcd.view;
103.
104. import android.app.Activity;
105. import android.content.Context;
106. import android.os.Bundle;
107. import android.view.View;
108. import android.view.ViewGroup;
109. import android.widget.AdapterView;
110. import android.widget.BaseAdapter;
111. import android.widget.Gallery;
112. import android.widget.ImageView;
113. import android.widget.Toast;
114. import android.widget.Gallery.LayoutParams;
115.
116. public class _Gallery extends Activity {
117.
118. @Override
119. protected void onCreate(Bundle savedInstanceState) {
120. // TODO Auto-generated method stub
121. super.onCreate(savedInstanceState);
122. this.setContentView(R.layout.gallery);
123.
124. setTitle("Gallery");
125.
126. Gallery gallery = (Gallery) findViewById(R.id.gallery);
127. // 为缩略图浏览器指定一个适配器
128. gallery.setAdapter(new ImageAdapter(this));
129. // 响应 在缩略图列表上选中某个缩略图后的 事件
130. gallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
131. @Override
132. public void onItemSelected(AdapterView> parent, View v,
133. int position, long id) {
134. Toast.makeText(_Gallery.this, String.valueOf(position), Toast.LENGTH_SHORT).show
();
135. }
136.
137. @Override
138. public void onNothingSelected(AdapterView> arg0) {
139.
140. }
141. });
142. }
143.
144. // 继承 BaseAdapter 用以实现自定义的图片适配器
145. public class ImageAdapter extends BaseAdapter {
146.
147. private Context mContext;
148.
149. public ImageAdapter(Context context) {
150. mContext = context;
151. }
152.
153. public int getCount() {
154. return mThumbIds.length;
155. }
156.
157. public Object getItem(int position) {
158. return position;
159. }
160.
161. public long getItemId(int position) {
162. return position;
163. }
164.
165. public View getView(int position, View convertView, ViewGroup parent) {
166. ImageView image = new ImageView(mContext);
167.
168. image.setImageResource(mThumbIds[position]);
169. image.setAdjustViewBounds(true);
170. image.setLayoutParams(new Gallery.LayoutParams(
171. LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
172.
173. return image;
174. }
175. }
176.
177. // 需要显示的图片集合
178. private Integer[] mThumbIds = { R.drawable.icon01, R.drawable.icon02,
179. R.drawable.icon03, R.drawable.icon04, R.drawable.icon05 };
180. }
181.
182.
183.
184. 3、ImageSwitcher 的 Demo
185. imageswitcher.xml
186.
187. 代码
188.
189.
190. android:orientation="vertical" android:layout_width="fill_parent"
191. android:layout_height="fill_parent">
192.
193.
194. android:layout_height="wrap_content" android:spacing="20px" />
195.
196.
199.
200. android:layout_width="fill_parent" android:layout_height="wrap_content" />
201.
202.
203.
204.
205. _ImageSwitcher.java
206.
207. 代码
208. package com.webabcd.view;
209.
210. import android.app.Activity;
211. import android.content.Context;
212. import android.os.Bundle;
213. import android.view.View;
214. import android.view.ViewGroup;
215. import android.view.animation.AnimationUtils;
216. import android.widget.AdapterView;
217. import android.widget.BaseAdapter;
218. import android.widget.Gallery;
219. import android.widget.ImageSwitcher;
220. import android.widget.ImageView;
221. import android.widget.ViewSwitcher;
222. import android.widget.Gallery.LayoutParams;
223.
224. // 图片转换器的使用基本同文字转换器
225. // 以下是一个用 ImageSwitcher + Gallery 实现的经典的图片浏览器的 Demo
226. public class _ImageSwitcher extends Activity implements
227. ViewSwitcher.ViewFactory {
228.
229. private ImageSwitcher mSwitcher;
230.
231. @Override
232. protected void onCreate(Bundle savedInstanceState) {
233. // TODO Auto-generated method stub
234. super.onCreate(savedInstanceState);
235. this.setContentView(R.layout.imageswithcer);
236.
237. setTitle("ImageSwithcer");
238.
239. mSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
240. mSwitcher.setFactory(this);
241. mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
242. android.R.anim.fade_in));
243. mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
244. android.R.anim.fade_out));
245.
246. Gallery gallery = (Gallery) findViewById(R.id.gallery);
247. gallery.setAdapter(new ImageAdapter(this));
248. gallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
249. @Override
250. public void onItemSelected(AdapterView> parent, View v,
251. int position, long id) {
252. mSwitcher.setImageResource(mImageIds[position]);
253. }
254.
255. @Override
256. public void onNothingSelected(AdapterView> arg0) {
257.
258. }
259. });
260. }
261.
262. public class ImageAdapter extends BaseAdapter {
263.
264. private Context mContext;
265.
266. public ImageAdapter(Context context) {
267. mContext = context;
268. }
269.
270. public int getCount() {
271. return mThumbIds.length;
272. }
273.
274. public Object getItem(int position) {
275. return position;
276. }
277.
278.