Android系统UI设计之:Widget控件
2015-07-20 19:36
585 查看
Widget控件
[1]显示控件
TextView文本控件 autoLink、visibility、textSize、textColor、background
EditText可编辑的文本控件 hint、inputType
ProgressBar进度条 max、progress
ImageView显示图片的控件 src、scaleType
WebView显示网页的控件
[2]交互控件
Button按钮 enable
checkBox多选按钮 checked
radioButton单选按钮 checked
seekBar可拖动的进度条 max、progress 监听接口 OnSeekBarChangeListener
[3]容器控件
1. LinearLayout线性布局
oritation: 布局的方向 vitical,horizental
gravity/padding 重心/内间距
layout_gravity/layout_margin 相对重心/外间距
layout_weight 权重 对剩余空间的分配
2. RelativeLayout相对布局
当前控件相对于父控件的位置 layout_alignParent
当前控件相对于其它控件的位置 layout_above / layout_alignLeft
位置的微调 layout_margin
3. FrameLayout帧布局
layout_gravity
(绝对布局,表格布局,已被淘汰)
4.ListView列表视图
[1]ListView 由一行一行的控件组成,每一行称为ListView的item项。
[2]Adapter
适配器Adapter概念:控制ListView中显示的内容和布局
适配器Adapter分类:1.系统提供的适配器
ArrayAdapter数组适配器 ---- 用来显示简单布局
SimpleAapter简单的适配器 ---- 用来显示复杂布局
SimpleCursorAdapter ---- 用来显示数据库中的记录
[3]ListView的item项的监听接口 OnItemClickListenner
运行效果如下:
实战项目:制作出如下图所示布局:
[4]自定适配器的步骤
(1)定义类继承BaseAdapter
(2)在BaseAdapter的子类中,需要声明三个属性:1.item布局文件的索引
2.数据(链表或者数组)
3.布局加载器(LayoutInflater inflater = LayoutInflate.from(context))
功能:解析item项的布局,生成item项的视图对象
View view = inflater.inflate(id, null);
(3)重写四个方法:1.getCount() 系统调用该方法,得到item项的数量,item项数量取决于链表(数组)的长度
2.getItem(int position) 系统调用该方法,得到第position项的数据对象
3.getItemId(int position) 系统调用该方法,得到item的id号
4.getView(int position, ..., ...) 系统调用该方法,得到第position项的视图对象
在控件上绑定数据
(4)如果用户修改ListView上显示的数据,那么需要使用adapter.notifyDataSetChanged方法刷新适配器,更新视图对象。
用户在调用notifyDataSetChanged方法时,系统会自动调用getView方法。
案例一:
5.GridView 网格视图
一格为一个item项。使用适配器填充内容。
使用方式和ListView完全相同。例如适配器,监听接口等等。
属性:numColumns 列数
6.对话框和Menu,详见代码
对话框:
7.特殊控件
Toast温馨提示 AlertDialog对话框 Menu菜单
8.自定义控件
继承View类,重写onDraw方法
容器控件:
1.布局控件
[1]线性布局LinearLayout:orientation
graviy, padding (gravity重心: 指控件内容相对于控件的位置,一共9个方位 -->
<!-- 默认 left|top , 其它分别是 right|top, right|bottom, center_vertical|right ... -->
<!-- padding内间距:配合重心使用,对位置进行微调。例如重心为right|top,那么只收到paddingRight 和 paddingTop的影响 -->)
layout_gravity, layout_margin (<!-- layout_gravity相对重心 : 指当前控件相对于父控件的位置-->
<!-- 相对重心受到父控件orientation的影响 -->
<!-- 如果父控件的orientation为vertical,那么相对重心只有left center_horizental right -->例如
<!-- 如果父控件的orientation为horizontal,那么相对重心只有top center_vertical bottom -->
<!-- layout_margin外间距配合相对重心使用,对位置进行微调。 -->
<!-- 例如相对重心为right,那么外间距一定是marginRight -->)
layout_weight 权重,对剩下的空间进行分配
[2]相对布局RelativeLayout:相对于父控件位置:layout_alignPrent... 有9个位置(layout_centerVertical="true"、layout_alignParentRight、layout_centerHorizontal、layout_centerInParent、layout_alignParentBottom、layout_alignParentLeft、layout_alignParentTop),配合layout_margin进行微调
相对于其它控件位置:方 layout_above, 下方layout_below, 左方layout_toLeftOf, 右方layout_toRightOf
边缘对齐:layout_alignTop, layout_alignBottom, layout_alignRight, layout_alignLeft, layout_alignBaseLine基线对齐,例如:layout_alignLeft="@id/button1"
[3]帧布局FrameLayout:layout_gravity(不受任何限制), layout_margin 分层的布局
[4]布局使用的方式:三种布局灵活组合嵌套使用。
容器控件 -------(重点)
[1]ListView 列表视图
[2]适配器Adapter概念:控制ListView中显示的内容和布局
[3]适配器Adapter分类:1.系统适配器
ArrayAdapter 用来显示简单布局
SimpleAdapter 用来显示复杂布局
SimpleCursorAdapter 用来显示数据库中的记录
2.自定义适配器
继承BaseAdapte类,重写基本适配器
[1]显示控件
TextView文本控件 autoLink、visibility、textSize、textColor、background
EditText可编辑的文本控件 hint、inputType
ProgressBar进度条 max、progress
ImageView显示图片的控件 src、scaleType
WebView显示网页的控件
[2]交互控件
Button按钮 enable
checkBox多选按钮 checked
radioButton单选按钮 checked
seekBar可拖动的进度条 max、progress 监听接口 OnSeekBarChangeListener
package com.farsight.widget02; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.CheckBox; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; public class Android_10_Widget02Activity extends Activity implements OnClickListener, OnSeekBarChangeListener { CheckBox cb01; CheckBox cb02; CheckBox cb03; TextView tv; String s01 = ""; String s02 = ""; String s03 = ""; TextView tvProgress; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); cb01 = (CheckBox) findViewById(R.id.checkBox1); cb02 = (CheckBox) findViewById(R.id.checkBox2); cb03 = (CheckBox) findViewById(R.id.checkBox3); tv = (TextView) findViewById(R.id.tv1); check(); cb01.setOnClickListener(this); cb02.setOnClickListener(this); cb03.setOnClickListener(this); SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar1); seekBar.setOnSeekBarChangeListener(this); tvProgress = (TextView) findViewById(R.id.tv2); tvProgress.setText(String.valueOf(seekBar.getProgress())); } @Override public void onClick(View v) { // TODO Auto-generated method stub check(); } private void check() { if (cb01.isChecked()) { s01 = cb01.getText().toString(); } else { s01 = ""; } if (cb02.isChecked()) { s02 = cb02.getText().toString(); } else { s02 = ""; } if (cb03.isChecked()) { s03 = cb03.getText().toString(); } else { s03 = ""; } tv.setText(s01 + " " + s02 + " " + s03); } //当用户在拖动进度条时,调用该方法 @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub Log.e("Test", "move"); tvProgress.setText(String.valueOf(progress)); } //当用户点击进度条时,调用该方法 @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub Log.e("Test", "start"); } //当用户松开进度条时,调用该方法 @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub Log.e("Test", "stop"); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <CheckBox android:id="@+id/checkBox1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="music" /> <CheckBox android:id="@+id/checkBox2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="coding" /> <CheckBox android:id="@+id/checkBox3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="read" android:checked="true" /> <TextView android:id="@+id/tv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="coding" android:textAppearance="?android:attr/textAppearanceLarge" /> <RadioGroup android:id="@+id/radioGroup1" android:layout_width="wrap_content" android:layout_height="wrap_content" > <RadioButton android:id="@+id/radio0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="woman" /> <RadioButton android:id="@+id/radio1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="man" /> </RadioGroup> <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50"/> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="当前进度:" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/btn_selector"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large TextLarge TextLarge Text" android:textAppearance="?android:attr/textAppearanceLarge" android:background="@drawable/chat_bubble_red"/> </LinearLayout>运行效果如下:
[3]容器控件
1. LinearLayout线性布局
oritation: 布局的方向 vitical,horizental
gravity/padding 重心/内间距
layout_gravity/layout_margin 相对重心/外间距
layout_weight 权重 对剩余空间的分配
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- 嵌套布局 --> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFF"> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" > <requestFocus /> </EditText> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="right" android:paddingRight="50dp" android:paddingTop="20dp"> <!-- gravity重心: 指控件内容相对于控件的位置,一共9个方位 --> <!-- 默认 left|top , 其它分别是 right|top, right|bottom, center_vertical|right ... --> <!-- padding内间距:配合重心使用,对位置进行微调。例如重心为right|top,那么只收到paddingRight 和 paddingTop的影响 --> <Button android:id="@+id/button1" android:layout_width="100dp" android:layout_height="100dp" android:gravity="right" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- layout_gravity相对重心 : 指当前控件相对于父控件的位置--> <!-- 相对重心受到父控件orientation的影响 --> <!-- 如果父控件的orientation为vertical,那么相对重心只有left center_horizental right --> <!-- 如果父控件的orientation为horizontal,那么相对重心只有top center_vertical bottom --> <!-- layout_margin外间距配合相对重心使用,对位置进行微调。 --> <!-- 例如相对重心为right,那么外间距一定是marginRight --> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" android:layout_gravity="right" android:layout_marginRight="20dp"/> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <!-- layout_weight权重:可以对剩余空间进行分配 --> <Button android:id="@+id/button1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Btn" android:layout_weight="1" /> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button02" android:layout_weight="1"/> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <!-- 布局方向 orientation : 1.vertical垂直 2.horizontal水平 --> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
2. RelativeLayout相对布局
当前控件相对于父控件的位置 layout_alignParent
当前控件相对于其它控件的位置 layout_above / layout_alignLeft
位置的微调 layout_margin
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- 当前控件相对于父控件的位置 9个位置 配合layout_margin进行微调--> <!-- 默认在左上 --> <!-- 没有该属性 layout_gravity --> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="Button" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="Button" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="Button" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Button" /> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:text="Button" /> <Button android:id="@+id/button7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:text="Button" /> <Button android:id="@+id/button8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="Button" /> <Button android:id="@+id/button9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginTop="10dp" android:text="Button" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- 当前控件相对于其它控件的位置 --> <!-- 当前控件在其它控件的上方 layout_above, 下方layout_below, 左方layout_toLeftOf, 右方layout_toRightOf--> <!-- 当前控件和其它控件边缘对齐layout_alignTop, layout_alignBottom, layout_alignRight, layout_alignLeft, layout_alignBaseLine基线对齐 --> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="57dp" android:layout_marginTop="54dp" android:text="Button01" /> <!-- maginTop 指 按钮2上方距离按钮1有20dp --> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/button1" android:layout_alignLeft="@id/button1" android:layout_marginTop="20dp" android:text="Button02" /> </RelativeLayout>效果如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/button1" android:layout_toLeftOf="@+id/button1" android:text="Button" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@id/button1" android:layout_toRightOf="@id/button1" android:text="Button" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button1" android:layout_toLeftOf="@+id/button1" android:text="Button" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/button1" android:layout_toRightOf="@id/button1" android:text="Button" /> </RelativeLayout>实战项目(我们约会吧登陆界面)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/back" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="22dp" android:layout_marginTop="156dp" android:text="账号:" android:textColor="#000000" android:textSize="25dp" /> <EditText android:id="@+id/editText1" android:layout_width="216dp" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView1" android:layout_alignBottom="@+id/textView1" android:layout_toRightOf="@+id/textView1" > <requestFocus /> </EditText> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@+id/editText1" android:text="密码:" android:textColor="#000000" android:textSize="25dp" /> <EditText android:id="@+id/editText2" android:layout_width="216dp" android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1" android:layout_centerVertical="true" android:inputType="textPassword" /> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_alignParentTop="true" android:layout_alignRight="@+id/editText1" android:src="@drawable/log" /> <CheckBox android:id="@+id/checkBox2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/editText2" android:layout_below="@+id/editText2" android:text="自动登陆" android:textColor="#000000" /> <CheckBox android:id="@+id/checkBox1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_below="@+id/editText2" android:text="记住密码" android:textColor="#000000" /> <Button android:id="@+id/button1" android:layout_width="275dp" android:layout_height="wrap_content" android:layout_alignLeft="@+id/checkBox1" android:layout_below="@+id/checkBox1" android:layout_centerHorizontal="true" android:text="登陆" /> <CheckedTextView android:id="@+id/checkedTextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:textColor="#000000" android:text="用户注册" /> <CheckedTextView android:id="@+id/checkedTextView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/checkedTextView1" android:layout_alignBottom="@+id/checkedTextView1" android:layout_centerHorizontal="true" android:textColor="#000000" android:text="匿名登陆" /> <CheckedTextView android:id="@+id/checkedTextView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/checkBox2" android:layout_below="@+id/button1" android:textColor="#000000" android:text="退出系统" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/checkedTextView1" android:layout_alignParentBottom="true" android:layout_marginBottom="16dp" android:text="Copyright © 2004-2015,farsight.com,All Rights Reserved" android:textColor="#000000" /> </RelativeLayout>效果如下:
3. FrameLayout帧布局
layout_gravity
(绝对布局,表格布局,已被淘汰)
4.ListView列表视图
[1]ListView 由一行一行的控件组成,每一行称为ListView的item项。
[2]Adapter
适配器Adapter概念:控制ListView中显示的内容和布局
适配器Adapter分类:1.系统提供的适配器
ArrayAdapter数组适配器 ---- 用来显示简单布局
SimpleAapter简单的适配器 ---- 用来显示复杂布局
SimpleCursorAdapter ---- 用来显示数据库中的记录
[3]ListView的item项的监听接口 OnItemClickListenner
package com.farsight.listview01; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleAdapter; public class Android_12_ListView01Activity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); // String texts[] = { "01", "02", "03", "04", "05", "06", "07", "08", // "09", "10" }; // // 数组适配器 // // 适配器中需要指定两个内容:1.显示的数据 2.布局文件 // ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, // android.R.layout.simple_list_item_1, texts); // 文字内容 String texts[] = { "01", "02", "03", "04" }; // 图片内容 int imageIds[] = { R.drawable.ic_launcher, R.drawable.emoticon_02, R.drawable.emoticon_03, R.drawable.emoticon_04 }; // 将文字内容和图片内容放入链表中 ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>(); for (int i = 0; i < imageIds.length; i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("text", texts[i]); map.put("imageId", imageIds[i]); data.add(map); } SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item, new String[] { "text", "imageId" }, new int[] { R.id.textView1, R.id.imageView1 }); // 绑定适配器 listView.setAdapter(adapter); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>效果如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout>效果如下:
运行效果如下:
实战项目:制作出如下图所示布局:
package com.farsight.listview02; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleAdapter; public class Android_13_ListView02Activity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); int imageIds[] = {R.drawable.emoticon_02, R.drawable.emoticon_03, R.drawable.emoticon_04}; double bookPrices[] = {99.99, 87.99, 99.00}; String bookNames[] = {"java", "c++", "c#"}; //ctrl + shift + o 快速导包 ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String,Object>>(); for (int i = 0; i < bookPrices.length; i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("imageId", imageIds[i]); map.put("name", bookNames[i]); map.put("price", bookPrices[i]); data.add(map); } SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item, new String[]{"imageId", "price", "name"}, new int[]{R.id.imageView1, R.id.textView2, R.id.textView1}); listView.setAdapter(adapter); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"> </ListView> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="购买" android:layout_gravity="right"/> </LinearLayout>效果如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="30dp" android:orientation="vertical" android:gravity="center_horizontal"> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="10dp" > <Button android:id="@+id/button1" android:layout_width="60dp" android:layout_height="wrap_content" android:text="-" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/button2" android:layout_width="60dp" android:layout_height="wrap_content" android:text="+" /> </LinearLayout> </RelativeLayout>效果如下:
[4]自定适配器的步骤
(1)定义类继承BaseAdapter
(2)在BaseAdapter的子类中,需要声明三个属性:1.item布局文件的索引
2.数据(链表或者数组)
3.布局加载器(LayoutInflater inflater = LayoutInflate.from(context))
功能:解析item项的布局,生成item项的视图对象
View view = inflater.inflate(id, null);
(3)重写四个方法:1.getCount() 系统调用该方法,得到item项的数量,item项数量取决于链表(数组)的长度
2.getItem(int position) 系统调用该方法,得到第position项的数据对象
3.getItemId(int position) 系统调用该方法,得到item的id号
4.getView(int position, ..., ...) 系统调用该方法,得到第position项的视图对象
在控件上绑定数据
(4)如果用户修改ListView上显示的数据,那么需要使用adapter.notifyDataSetChanged方法刷新适配器,更新视图对象。
用户在调用notifyDataSetChanged方法时,系统会自动调用getView方法。
案例一:
package com.farsight.baseadapter01; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.ListView; public class Android_15_BaseAdapter01Activity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); MyItemData data[] = {new MyItemData("01", "btn01"), new MyItemData("02", "btn02")}; // // 使用自定义适配器 // // 1.自定义类继承BaseAdapter。(BaseAdapter为所有适配器的父类) MyAdapter adapter = new MyAdapter(this, R.layout.item, data); Log.e("Test", "listView = " + listView); Log.e("Test", "adapter = " + adapter); listView.setAdapter(adapter); } }
package com.farsight.baseadapter01; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.TextView; public class MyAdapter extends BaseAdapter { //1.item项的布局文件 //2.每个item项显示的数据 int id; MyItemData[] data; //布局加载器 //功能:解析布局文件,生成视图view对象 //布局加载器工具对象从上下文中取出 LayoutInflater inflater; public MyAdapter(Context context, int id, MyItemData data[]) { // TODO Auto-generated constructor stub this.id = id; this.data = data; this.inflater = LayoutInflater.from(context); } //系统自动调用该方法,需要知道listView中item项的数量 @Override public int getCount() { // TODO Auto-generated method stub return data.length; } //系统自动调用该方法,需要得到第position的item项的数据对象 @Override public Object getItem(int position) { // TODO Auto-generated method stub return data[position]; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } //系统自动调用该方法,得到第position项的视图对象 @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub //解析布局文件,生成视图对象 View view = inflater.inflate(id, null); TextView tv = (TextView) view.findViewById(R.id.textView1); tv.setText(data[position].getTextViewData()); Button btn = (Button) view.findViewById(R.id.button1); btn.setText(data[position].getButtonData()); return view; } }案例二:
package com.farsight.baseadapter02; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ListView; public class Android_16_BaseAdapter02Activity extends Activity implements OnClickListener { Book book01 = new Book(R.drawable.emoticon_02, "java", 99.99, 3); Book book02 = new Book(R.drawable.emoticon_03, "c++", 88.99, 1); Book book03 = new Book(R.drawable.emoticon_04, "c#", 99.00, 1); Book books[] = {book01, book02, book03}; String bookNames[] = new String[3]; double bookPrices[] = new double[3]; int bookNumbers[] = new int[3]; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); MyAdapter adapter = new MyAdapter(this, books, R.layout.item); listView.setAdapter(adapter); findViewById(R.id.button1).setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub for (int i = 0; i < bookNames.length; i++) { bookNames[i] = books[i].getName(); bookPrices[i] = books[i].getPrice(); bookNumbers[i] = books[i].getNumber(); } Intent intent = new Intent(this, PayActivity.class); intent.putExtra("name", bookNames); intent.putExtra("price", bookPrices); intent.putExtra("number", bookNumbers); startActivity(intent); } }
package com.farsight.baseadapter02; public class Book { private int imageId; private String name; private double price; private int number; public Book(int imageId, String name, double price, int number) { super(); this.imageId = imageId; this.name = name; this.price = price; this.number = number; } public int getImageId() { return imageId; } public void setImageId(int imageId) { this.imageId = imageId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public void subNumber(){ if(this.number > 1) this.number--; } public void addNumber(){ this.number++; } }
package com.farsight.baseadapter02; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; public class MyAdapter extends BaseAdapter { int id; Book books[]; LayoutInflater inflater; public MyAdapter(Context context, Book books[], int id) { // TODO Auto-generated constructor stub this.inflater = LayoutInflater.from(context); this.books = books; this.id = id; } @Override public int getCount() { // TODO Auto-generated method stub Log.e("Test", "count = " + books.length); return books.length; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return books[position]; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.item, null); Log.e("Test", "view " + position); ImageView imageView = (ImageView) view.findViewById(R.id.imageView1); imageView.setImageResource(books[position].getImageId()); TextView tvName = (TextView) view.findViewById(R.id.textView1); tvName.setText(books[position].getName()); TextView tvPrice = (TextView) view.findViewById(R.id.textView2); tvPrice.setText(String.valueOf(books[position].getPrice())); TextView tvNumber = (TextView) view.findViewById(R.id.textView3); tvNumber.setText(String.valueOf(books[position].getNumber())); Button btnSub = (Button) view.findViewById(R.id.button1); btnSub.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Book book = books[position]; book.subNumber(); //刷新适配器 //系统自动调用getView方法 notifyDataSetChanged(); } }); Button btnAdd = (Button) view.findViewById(R.id.button2); btnAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub books[position].addNumber(); notifyDataSetChanged(); } }); return view; } }
package com.farsight.baseadapter02; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; public class PayActivity extends Activity implements OnItemClickListener { ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>(); SimpleAdapter adapter; TextView tvPrice; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_pay); ListView listView = (ListView) findViewById(R.id.listView1); tvPrice = (TextView) findViewById(R.id.textView2); Intent intent = this.getIntent(); String names[] = intent.getStringArrayExtra("name"); double prices[] = intent.getDoubleArrayExtra("price"); int number[] = intent.getIntArrayExtra("number"); for (int i = 0; i < number.length; i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", names[i]); map.put("number", number[i]); map.put("price", prices[i]); data.add(map); } adapter = new SimpleAdapter(this, data, R.layout.pay_item, new String[] { "name", "number" }, new int[] { R.id.textView1, R.id.textView2 }); listView.setAdapter(adapter); tvPrice.setText("总价:" + getPrice()); listView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub //删除用户点击的item项的数据对象 data.remove(arg2); //刷新适配器 adapter.notifyDataSetChanged(); tvPrice.setText("总价:" + getPrice()); } private double getPrice(){ double priceAll = 0; for (int i = 0; i < data.size(); i++) { HashMap<String, Object> map = data.get(i); double price = Double.parseDouble(map.get("price").toString()); int number = Integer.parseInt(map.get("number").toString()); priceAll += price*number; } return priceAll; } }
5.GridView 网格视图
一格为一个item项。使用适配器填充内容。
使用方式和ListView完全相同。例如适配器,监听接口等等。
属性:numColumns 列数
6.对话框和Menu,详见代码
对话框:
package com.farsight.dialog; import android.app.Activity; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.TextView; public class Android_18_DialogActivity extends Activity implements OnClickListener { TextView tvInfo; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.button1).setOnClickListener(this); findViewById(R.id.button2).setOnClickListener(this); tvInfo = (TextView) findViewById(R.id.textView1); } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v.getId() == R.id.button1) { // 导入AlertDialog下的Builder Builder builder = new Builder(this); builder.setTitle("退出"); builder.setMessage("是否退出当前应用程序"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { // 当用户点击对话框按钮时,系统调用该方法 @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub finish(); } }); builder.setNegativeButton("取消", null); builder.create(); // 创建对话框 builder.show(); // 显示对话框 } else if (v.getId() == R.id.button2) { Builder builder = new Builder(this); builder.setTitle("注册"); final View view = LayoutInflater.from(this).inflate( R.layout.dialog, null); // 设置对话框正文视图 builder.setView(view); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub EditText etUser = (EditText) view .findViewById(R.id.editText1); EditText etPass = (EditText) view .findViewById(R.id.editText2); String user = etUser.getText().toString(); String pass = etPass.getText().toString(); tvInfo.setText(user + ":" + pass); } }); builder.setNegativeButton("取消", null); builder.create(); builder.show(); } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号" android:textAppearance="?android:attr/textAppearanceLarge" /> <EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" > <requestFocus /> </EditText> </LinearLayout> <LinearLayout android:id="@+id/linearLayout3" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码" android:textAppearance="?android:attr/textAppearanceLarge" /> <EditText android:id="@+id/editText2" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" /> </LinearLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="退出" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout>Menu:
package com.farsight.menu; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; public class Android_19_MenuActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } //用户点击menu按钮时,系统自动调用该方法,创建选项菜单 @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub //添加子菜单 SubMenu subMenu01 = menu.addSubMenu(1, 1, 10, "选项一"); //向选项一添加二级菜单 subMenu01.add("01"); subMenu01.add("02"); subMenu01.add("03"); menu.addSubMenu(1, 2, 2, "选项二"); menu.addSubMenu(1, 3, 3, "退出"); return super.onCreateOptionsMenu(menu); } //用户点击菜单项时调用 @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub if(item.getItemId() == 3){ finish(); } return super.onOptionsItemSelected(item); } }
7.特殊控件
Toast温馨提示 AlertDialog对话框 Menu菜单
8.自定义控件
继承View类,重写onDraw方法
package com.farsight.myview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class MyView extends View implements Runnable { // 画笔对象 Paint paint = new Paint(); // 位图对象 Bitmap bitmap; int speed = 10; int rectX = 40; int bitmapX = 0; int bitmapY = 0; int bitmapWidth; int bitmapHeight; public MyView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub // 载入图片资源,生成位图对象 bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.emoticon_04); //得到图片宽 bitmapWidth = bitmap.getWidth(); //得到图片的高 bitmapHeight = bitmap.getHeight(); new Thread(this).start(); } // canvas画布对象 @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); // 得到自定义控件的宽高 // this.getWidth(); // this.getHeight(); // 设置画布颜色 canvas.drawColor(Color.WHITE); // 设置画笔颜色 paint.setColor(Color.BLACK); // 画线 canvas.drawLine(20, 20, 140, 20, paint); // 画矩形 paint.setStyle(Style.FILL); canvas.drawRect(rectX, 40, 60 + rectX, 100, paint); // 改变矩形x轴坐标 // 移动矩形 rectX += speed; // 修正 if (rectX + 60 > this.getWidth()) { rectX = this.getWidth() - 60; } // 设置画笔的样式:空心(stroke),实心(fill)。默认实心。 // 设置为空心画笔 paint.setStyle(Style.STROKE); canvas.drawRect(120, 120, 200, 200, paint); // 消除锯齿 paint.setAntiAlias(true); // 画圆 canvas.drawCircle(150, 150, 60, paint); // 绘制位图 canvas.drawBitmap(bitmap, bitmapX, bitmapY, paint); } //用户触摸到图片 boolean isOnBitmap; int subX, subY; // 当用户触摸到该控件,系统自动调用该方法 // 参数event为触摸事件 @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub // 得到用户触摸点坐标 int x = (int) event.getX(); int y = (int) event.getY(); Log.e("Test", "(" + x + "," + y + ")"); // 得到用户触摸动作 if (event.getAction() == MotionEvent.ACTION_DOWN) { // 按下 if(x >= bitmapX && x <= bitmapX+bitmapWidth && y >= bitmapY && y <= bitmapY+bitmapHeight){ isOnBitmap = true; subX = x-bitmapX; subY = y-bitmapY; } } if (event.getAction() == MotionEvent.ACTION_UP) { // 松开 Log.e("Test", "action_up"); isOnBitmap = false; } if (event.getAction() == MotionEvent.ACTION_MOVE) { // 滑动 if(isOnBitmap){ bitmapX = x-subX; bitmapY = y-subY; } } return true; } @Override public void run() { // TODO Auto-generated method stub while (true) { // 当用户调用此方法,系统会自动调用onDraw方法 this.postInvalidate(); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
容器控件:
1.布局控件
[1]线性布局LinearLayout:orientation
graviy, padding (gravity重心: 指控件内容相对于控件的位置,一共9个方位 -->
<!-- 默认 left|top , 其它分别是 right|top, right|bottom, center_vertical|right ... -->
<!-- padding内间距:配合重心使用,对位置进行微调。例如重心为right|top,那么只收到paddingRight 和 paddingTop的影响 -->)
layout_gravity, layout_margin (<!-- layout_gravity相对重心 : 指当前控件相对于父控件的位置-->
<!-- 相对重心受到父控件orientation的影响 -->
<!-- 如果父控件的orientation为vertical,那么相对重心只有left center_horizental right -->例如
<!-- 如果父控件的orientation为horizontal,那么相对重心只有top center_vertical bottom -->
<!-- layout_margin外间距配合相对重心使用,对位置进行微调。 -->
<!-- 例如相对重心为right,那么外间距一定是marginRight -->)
layout_weight 权重,对剩下的空间进行分配
[2]相对布局RelativeLayout:相对于父控件位置:layout_alignPrent... 有9个位置(layout_centerVertical="true"、layout_alignParentRight、layout_centerHorizontal、layout_centerInParent、layout_alignParentBottom、layout_alignParentLeft、layout_alignParentTop),配合layout_margin进行微调
相对于其它控件位置:方 layout_above, 下方layout_below, 左方layout_toLeftOf, 右方layout_toRightOf
边缘对齐:layout_alignTop, layout_alignBottom, layout_alignRight, layout_alignLeft, layout_alignBaseLine基线对齐,例如:layout_alignLeft="@id/button1"
[3]帧布局FrameLayout:layout_gravity(不受任何限制), layout_margin 分层的布局
[4]布局使用的方式:三种布局灵活组合嵌套使用。
容器控件 -------(重点)
[1]ListView 列表视图
[2]适配器Adapter概念:控制ListView中显示的内容和布局
[3]适配器Adapter分类:1.系统适配器
ArrayAdapter 用来显示简单布局
SimpleAdapter 用来显示复杂布局
SimpleCursorAdapter 用来显示数据库中的记录
2.自定义适配器
继承BaseAdapte类,重写基本适配器
相关文章推荐
- toj4121. Muxiaokui's Problem
- 构建一个基于UIView的类别
- FineUi导出时禁用ajax即EnableAjax="false"出现问题的解决方法
- 关于UI功能解锁,UI特效动画,UI tips的再思考
- HDU1005 Number Sequence
- 常用bluetooth协议
- 常用bluetooth协议
- 深入浅出 Java Concurrency (20): 并发容器 part 5 ConcurrentLinkedQueue
- String StringBuffer StringBuilder区别
- Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Query was empty
- Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Query was empty
- 深入浅出 Java Concurrency (19): 并发容器 part 4 并发队列与Queue简介
- (L1)AudioService AudioManagerInternal , Ringer mode, stream uid
- CF 129C Statues
- autolayout 动态计算高度时 UILabel的preferredMaxLayoutWidth设置
- 关于uitableviewcell的accessoryType属性
- easyui删除多行问题
- UI线程与handle
- ajax调用期间添加蒙层blockUI
- 关于UIBarButtonItem的一点札记