1、利用代码来构建UI
nameContainer = new LinearLayout(this);
nameContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
nameContainer.setOrientation(LinearLayout.HORIZONTAL);
TextView nameLbl = new TextView(this);
nameLbl.setText("Name: ");
nameContainer.addView(nameLbl);
2、TextView控件:TextView控件知道如何显示文本,但是不允许进行编辑。
如果知道TextView的内容将包含一个URL或者Email,可以将其autoLink属性设置为email|web,这样这段Text就将突出显示,并且点击这个Text可以调出相应程序进行处理。
autoLink可选值包括:web,email,phone,map,none,all
代码中:setAutoLinkMask Linkify.EMAIL_ADDRESSES|Linkify.WEB_ADDRESSES
注意需要在设置Text之前设置autoLink,autoLink不影响之前设置的Text
也可以调用Linkify.addLinks(tv, Linkify.ALL);方法进行设置(tv为一个TextView)
3、EditText控件:是TextView的子类,可编辑文本,默认行为是在一行上显示文本并且根据需要增加行数,但是如果将singleLine属性设置为true,可以强制用户输入一行内容。
inputType:textAutoCorrect:自动更正拼写错误
textCapWords:将单词转换为大写
textMultiline:多行键入
android:hint="your hint text here"提示文本,代码中使用CharSequence或资源ID调用setHint()
4、AutoCompleteTextView控件:具有自动完成功能的TextView
android:layout_width="fill_parent" android:layout_height="wrap_content" /> AutoCompleteTextView actv = (AutoCompleteTextView) this.findViewById(R.id.actv); ArrayAdapter android.R.layout.simple_dropdown_item_1line, new String[] {"English", "Hebrew", "Hindi", "Spanish", "German", "Greek"}); actv.setAdapter(aa); 这类控件包含两部分:文本视图控件和显示建议控件。要使用这样的控件,必须创建该控件,创建建议列表并告知控件,还可能告知控件如何显示建议。也可以为建议控件创建第二个控件,然后将两个控件相关联。 5、MultiAutoCompleteTextView控件:AutoCompleteTextView控件仅为文本视图的完整文本提供建议,MultiAutoCompleteTextView控件可以根据设置的令牌规则在句子中的任何地方开始建议 android:layout_width="fill_parent" android:layout_height="wrap_content" /> MultiAutoCompleteTextView mactv = (MultiAutoCompleteTextView) this .findViewById(R.id.mactv); ArrayAdapter android.R.layout.simple_dropdown_item_1line, new String[] {"English", "Hebrew", "Hindi", "Spanish", "German", "Greek" }); mactv.setAdapter(aa2); mactv.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); 其中CommaTokenizer为在遇到逗号后开始建议。 6、Button控件:下面将介绍1.6之前的点击处理事件代码,及新版本的代码 Button btn = (Button)this.findViewById(R.id.ccbtn1); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(“http://www.androidbook.com”)); startActivity(intent); } }); 新: public void myClickHandler(View target) { switch(target.getId()) { case R.id.ccbtn1: … 注意新版本中View代表Button,可以为多个Button设置同一个处理函数。 7、ImageButton控件:在XML中用src设置图像,在代码中用setImageResource设置。 android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick=”myClickHandler” android:src=”@drawable/icon” /> ImageButton btn = (ImageButton)this.findViewById(R.id.p_w_picpathBtn); btn.setImageResource(R.drawable.icon); 可以为按钮指定透明背景,结果是一个可单击的图像。 为ImageButton使用选择器:选择器的xml文件必须位于/res/drawable文件夹下。 android:drawable="@drawable/button_pressed" /> android:drawable="@drawable/button_focused" /> 将选择器xml设置成src的属性值 选择项顺序很重要,默认值在最后。 8、ToggleButton控件:在On状态下显示一个绿条(文本设置为On),在Off状态下显示灰条(文本设置为Off)。 android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Toggle Button" android:textOn=”Stop” android:textOff=”Run”/> 9、CheckBox控件:调用setChecked()或toggle()来管理复选框的状态。调用isChecked来获取它的状态。 CheckBox fishCB = (CheckBox)findViewById(R.id.fishCB); if(fishCB.isChecked()) fishCB.toggle(); // flips the checkbox to unchecked if it was checked fishCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton arg0, boolean isChecked) { Log.v("CheckBoxActivity", "The fish checkbox is now " + (isChecked?"checked":"not checked")); }}); 在Android1.6以后可以直接在xml布局文件中定义android:onClick属性: public void myClickHandler(View view) { switch(view.getId()) { case R.id.steakCB: Log.v("CheckBoxActivity", "The steak checkbox is now " + (((CheckBox)view).isChecked()?"checked":"not checked")); } } 10、RadioButton控件:可以在单选组内包含非单选按钮view android:layout_width="wrap_content" android:layout_height="wrap_content"> android:layout_width="wrap_content" android:layout_height="wrap_content"/> android:layout_width="wrap_content" android:layout_height="wrap_content"/> android:layout_width="wrap_content" android:layout_height="wrap_content"/> android:layout_width="wrap_content" android:layout_height="wrap_content"/> RadioButton的点击处理函数与CheckBox大致一样,唯一不同的是其实现的是RadioGroup.OnCheckedChangeListener类,而CheckBox实现的是CompoundButton.OnCheckedChangeListener类。 通过getCheckedRadioButtonId()方法获取当前选择的RadioButton,如果没有选择则返回-1。代码中调用RadioGroup的clearCheck()方法清除所有选择。 RadioGroup radGrp = (RadioGroup)findViewById(R.id.radGrp); RadioButton newRadioBtn = new RadioButton(this); newRadioBtn.setText("Pork"); radGrp.addView(newRadioBtn); 11、ImageView控件:图像来源可能来自于文件、ContentProvider或图形对象等资源,甚至可以仅指定一种颜色。 android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> android:layout_width="125dip" android:layout_height="25dip" android:src="#555555" /> android:layout_width="wrap_content" android:layout_height="wrap_content" /> android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/manatee02" //图像超出最大大小后居中并拉伸图像 android:scaleType="centerInside" //最大大小 android:maxWidth="35dip" android:maxHeight="50dip" /> ImageView imgView = (ImageView)findViewById(R.id.p_w_picpath3); imgView.setImageResource( R.drawable.icon ); //多种设置方法(如inputstream),网络图像通过此方法设置 imgView.setImageBitmap(BitmapFactory.decodeResource( this.getResources(), R.drawable.manatee14) ); //mnt:SD卡中 imgView.setImageDrawable( Drawable.createFromPath("/mnt/sdcard/dave2.jpg") ); //只能设置本地资源,网络资源不能用此方法 imgView.setImageURI(Uri.parse("file://mnt/sdcard/dave2.jpg")); 12、DatePicker和TimePicker控件: DatePicker dp = (DatePicker)this.findViewById(R.id.datePicker); dateDefault.setText("Date defaulted to " + (dp.getMonth() + 1) + "/" + dp.getDayOfMonth() + "/" + dp.getYear()); dp.init(2008, 11, 10, null); TimePicker tp = (TimePicker)this.findViewById(R.id.timePicker); java.util.Formatter timeF = new java.util.Formatter(); timeF.format("Time defaulted to %d:%02d", tp.getCurrentHour(), tp.getCurrentMinute()); tp.setIs24HourView(true); tp.setCurrentHour(new Integer(10)); tp.setCurrentMinute(new Integer(10)); 另外还有模态窗口版本的DatePickerDialog和TimePickerDialog。 13、AnalogClock和DigitalClock控件:这两个控件只能显示当前时间,他们只是时钟。AnalogClock为数字显示,DigitalClock为仪表盘显示。 14、MapView控件:使用地图,相应activity必须扩展自MapActivity。 android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="myAPIKey" /> 15、列表控件是扩展了android.widget.AdapterView类的,包括ListView,GridView,Spinner和Gallery,AdapterView实际上扩展了android.widget.ViewGroup,这意味着ListView,GridView等都是容器,适配器的用途是为AdapterView管理数据,并为其提供子视图。 16、SimpleCursorAdapter(Context context, int childLayout, Cursor c, String[] from, int[] to) 此适配器将游标中的行转换成容器控件上(如ListView)的子视图。ListView调用适配器的getView()方法,使用适配器构造函数中的子视图创建相关行,把结果集中的一条结果放入子视图中的相应位置。如果一个ListView一次显示10行,则仅仅会实例化10几个子视图,而不会把结果集中的所有结构都实例化为子视图。 17、适配器不一定用于列表,其左侧容器可以是一个相册,右侧结果集可以是一组图像。 18、ArrayAdapter:ArrayAdapter是Android中最简单的适配器,它专用于列表控件。 ArrayAdapter android.R.layout.simple_list_item_1, new string[]{"Dave","Satya",”Dylan”}); 没有传递from和to,这里假设子视图只为textView android:layout_width="wrap_content" android:layout_height="wrap_content" /> Spinner spinner = (Spinner) findViewById(R.id.spinner); ArrayAdapter R.array.planets, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); ArrayAdapter支持动态修改底层数据,相关方法有add(),insert(),remove(),sort() 19、ArrayAdapter CursorAdapter:也需要在ListView中使用,通过游标向列表提供数据。 SimpleAdapter:通常用于使用静态数据(可能来自资源)填充列表。 ResourceCursorAdapter:扩展了CursorAdapter,知道如何从资源创建视图。 SimpleCursorAdapter:扩展了ResourceCursorAdapter,从游标中的列创建TextView/ImageView视图,这些视图在资源中定义。 20、ListView控件:通常编写一个扩展自android.app.ListActivity的Activity,这样如果想让ListView占满全屏,甚至不需要设置layout Cursor c = managedQuery(People.CONTENT_URI,null, null, null, People.NAME); String[] cols = new String[] {People.NAME}; int[] views = new int[] {android.R.id.text1}; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, c, cols, views); this.setListAdapter(adapter); public void onItemClick(AdapterView> adView, View target, int position, long id) { Log.v("ListViewActivity", "in onItemClick with " + ((TextView) target).getText() + ". Position = " + position + ". Id = " + id); Uri selectedPerson = ContentUris.withAppendedId( People.CONTENT_URI, id); Intent intent = new Intent(Intent.ACTION_VIEW, selectedPerson); startActivity(intent); } 注意ID来源可能不明确。 调用notifyDataSetChanged()方法来让Adapter更新ListView。 21、使用ListView添加其它控件:如果希望向主要布局中添加更多控件,可以提供你自己的布局XML文件。 android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight=”1” /> 注意ListView的id必须为@android:id/list,必须设置ListView的高度(android:layout_height="0dip"及android:layout_weight=”1”),这样ListView就会占据父容器中的所有空间,此方法为按钮留出了空间,这样按钮就会始终显示在屏幕上。 22、public class ListViewActivity3 extends ListActivity { private static final String TAG = "ListViewActivity3"; private ListView lv = null; private Cursor cursor = null; private int idCol = -1; private int nameCol = -1; private int notesCol = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //上个练习中设置的xml布局文件 setContentView(R.layout.list); lv = getListView(); cursor = managedQuery(People.CONTENT_URI, null, null, null, People.NAME); String[] cols = new String[] { People.NAME }; idCol = cursor.getColumnIndex(People._ID); nameCol = cursor.getColumnIndex(People.NAME); notesCol = cursor.getColumnIndex(People.NOTES); int[] views = new int[] { android.R.id.text1 }; //simple_list_item_multiple_choice为Android预置的文件,其中用到专门用于 //ListView的TextView的子类CheckedTextView,其ID为text1 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice, cursor, cols, views); this.setListAdapter(adapter); //这样用户就可以选择行,默认为CHOICE_MODE_NONE //还有一个选项为CHOICE_MODE_SINGLE, //此时需要android.R.layout.simple_list_item_single_choice lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); } public void doClick(View view) { int count = lv.getCount(); SparseBooleanArray viewItems = lv.getCheckedItemPositions(); for (int i = 0; i < count; i++) { if (viewItems.get(i)) { cursor.moveToPosition(i); long id = cursor.getLong(idCol); String name = cursor.getString(nameCol); String notes = cursor.getString(notesCol); Log.v(TAG, name + " is checked. Notes: " + notes + ". Position = " + i + ". Id = " + id); } } } } 23、在新版本中读取ListView(2.3) public class ListViewActivity4 extends ListActivity { private static final String TAG = "ListViewActivity4"; private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI; private SimpleCursorAdapter adapter = null; private ListView lv = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list); lv = getListView(); //只取出我们想要的列,这是正确方法 String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; Cursor c = managedQuery(CONTACTS_URI, projection, null, null, ContactsContract.Contacts.DISPLAY_NAME); String[] cols = new String[] { ContactsContract.Contacts.DISPLAY_NAME }; int[] views = new int[] { android.R.id.text1 }; adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice, c, cols, views); this.setListAdapter(adapter); lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); } public void doClick(View view) { //getCheckedItemIds方法要求适配器中的基础数据保持稳定,所以先 //调用 hasStableIds方法 //在实际项目中,可能需要更智能的操作,比如启动一个后台线程 //来重试,以及显示一个对话框表明操作正在处理 if (!adapter.hasStableIds()) { Log.v(TAG, "Data is not stable"); return; } long[] viewItems = lv.getCheckedItemIds(); for (int i = 0; i < viewItems.length; i++) { Uri selectedPerson = ContentUris.withAppendedId(CONTACTS_URI, viewItems[i]); Log.v(TAG, selectedPerson.toString() + " is checked."); } } } 24、在Android SDK安装目录/platforms/ 25、GridView控件:网格使用的适配器是ListAdapter android:id="@+id/dataGrid" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10px" android:verticalSpacing="10px" android:horizontalSpacing="10px" android:numColumns="auto_fit" android:columnWidth="100px" android:stretchMode="columnWidth" android:gravity="center" /> //注意扩展自Activity public class GridViewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gridview); GridView gv = (GridView) findViewById(R.id.gridview); Cursor c = managedQuery(People.CONTENT_URI, null, null, null, People.NAME); String[] cols = new String[] { People.NAME }; int[] views = new int[] { android.R.id.text1 }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, c, cols, views); // 注意ListView为activity.setAdapter() gv.setAdapter(adapter); } } 26、ListView继承自ListActivity,所以可以在onCreate方法中不用设置layout,而GridView 继承自Activity,所以需要设置layout。GridView 的每一行实际为一个简单view,这个简单view为一个list。 27、Spinner控件 android:id="@+id/spinner" android:prompt=”@string/spinnerprompt” android:layout_width="wrap_content" android:layout_height="wrap_content" /> public class SpinnerActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.spinner); Spinner spinner = (Spinner) findViewById(R.id.spinner); // createFromResource:从xml资源文件中提取列表 ArrayAdapter .createFromResource(this, R.array.planets, android.R.layout.simple_spinner_item); //设置下拉显示效果 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); } } 28、Gallery控件:是一种可以水平滚动的列表控件,焦点始终位于列表中央,此控件通常在触摸模式下用作相册。可以通过自定义适配器显示图片。 29、自定义适配器:扩展BaseAdapter抽象类,可以通过自定义适配器通过缓存技术来改进性能。 public class GridViewCustomAdapter extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gridviewcustom); GridView gv = (GridView) findViewById(R.id.gridview); ManateeAdapter adapter = new ManateeAdapter(this); gv.setAdapter(adapter); } public static class ManateeAdapter extends BaseAdapter { private static final String TAG = "ManateeAdapter"; private static int convertViewCounter = 0; private Context mContext; private LayoutInflater mInflater; static class ViewHolder { ImageView p_w_picpath; } private int[] manatees = { R.drawable.manatee00, R.drawable.manatee01, R.drawable.manatee02, R.drawable.manatee03, R.drawable.manatee04, R.drawable.manatee05, R.drawable.manatee06, R.drawable.manatee07, R.drawable.manatee08, R.drawable.manatee09, R.drawable.manatee10, R.drawable.manatee11, R.drawable.manatee12, R.drawable.manatee13, R.drawable.manatee14, R.drawable.manatee15, R.drawable.manatee16, R.drawable.manatee17, R.drawable.manatee18, R.drawable.manatee19, R.drawable.manatee20, R.drawable.manatee21, R.drawable.manatee22, R.drawable.manatee23, R.drawable.manatee24, R.drawable.manatee25, R.drawable.manatee26, R.drawable.manatee27, R.drawable.manatee28, R.drawable.manatee29, R.drawable.manatee30, R.drawable.manatee31, R.drawable.manatee32, R.drawable.manatee33 }; private Bitmap[] manateeImages = new Bitmap[manatees.length]; private Bitmap[] manateeThumbs = new Bitmap[manatees.length]; public ManateeAdapter(Context context) { Log.v(TAG, "Constructing ManateeAdapter"); this.mContext = context; mInflater = LayoutInflater.from(context); for (int i = 0; i < manatees.length; i++) { manateeImages[i] = BitmapFactory.decodeResource( context.getResources(), manatees[i]); manateeThumbs[i] = Bitmap.createScaledBitmap( manateeImages[i], 100, 100, false); } } @Override public int getCount() { Log.v(TAG, "in getCount()"); return manatees.length; } public int getViewTypeCount() { Log.v(TAG, "in getViewTypeCount()"); return 1; } public int getItemViewType(int position) { Log.v(TAG, "in getItemViewType() for position " + position); return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; Log.v(TAG, "in getView for position " + position + ", convertView is " + ((convertView == null) ? "null" : "being recycled")); if (convertView == null) { convertView = mInflater.inflate(R.layout.gridp_w_picpath, null); convertViewCounter++; Log.v(TAG, convertViewCounter + " convertViews have been created"); holder = new ViewHolder(); holder.p_w_picpath = (ImageView) convertView .findViewById(R.id.gridImageView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.p_w_picpath.setImageBitmap(manateeThumbs[position]); return convertView; } @Override public Object getItem(int position) { Log.v(TAG, "in getItem() for position " + position); return manateeImages[position]; } @Override public long getItemId(int position) { Log.v(TAG, "in getItemId() for position " + position); return position; } } } 30、ScrollView是设置带有垂直滚动条的View容器的控件,ProgressBar和RatingBar控件类似于滑块,第一个用于直观的显示某项操作的进度,而二个用于显示评价的星级,Chronometer控件是一个累积的计时器,如果希望显示一个倒计时器,可以用CountDownTimer类。WebView是一种显示HTML的特殊视图。 31、使用样式: 对于Text,可以直接设置HTML样式: ,,,(上标),(下标),(删除线),,,