阅读前,请浏览此处上方目录。
———————————————————————————————————————————————————
在学校里听老师讲课,总会让学生误会程序员的主要工作不是界面美化,那都是美工做得事情。但随着移动开发的不断发展,在软件开发的过程中,界面设计和功能开发同样重要。界面美观的应用不仅可以大大增加用户粘性,还可以帮我们吸引更多新用户。如果善用UI控件,可以做出让人赏心悦目的应用。
Android应用绝大部分UI组件都放在android.widget包及其子包、android.view包及其子包中,Android应用的所有UI都继承了View类。View类还有一个重要的子类,ViewGroup,但ViewGroup通常作为其他组件其他组件的容器使用。Android的所有UI组件都是建在View、ViewGroup基础之上,ViewGroup是View的子类,因此ViewGroup也可以被当成View使用。但由于ViewGroup是一个抽象类,因此实际使用中通常总是使用ViewGroup的子类来作为容器,例如各种布局管理器。
LinearLayout 是最常用的布局,它会把容器里面的组件一个挨一个的排列起来,LinearLayout 可以控制各组件横纵向排列(通过android:orientation属性控制)。设置排列方式可以设置为 android:orientation="vertical" (垂直排列),android:orientation="horizontal"(水平排列)。还有一个XML属性是 android:gravity对齐方式,有很对齐方式。学习LinearLayout还有另外一个重要属性android:layout_weight,这个属性允许我们使用比例方式来指定控件的大小,在手机屏幕适配性方面起到非常重要的作用。
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="right" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="按钮" /> </LinearLayout>
TableLayout继承了LinearLayout,因此它的本质依然是线性布局管理器。表格布局采用行、列的形式来管理UI组件,TableLayout并不需要明确声明包含多少行多少列,而是通过添加TableRow来控制表格的行数和列数。每次向TableLayout中添加一个TableRow,该TableRow就是一个表格行。接下来示范:
<TableRow> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮2" /> </TableRow> <TableRow> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮3" /> </TableRow> </TableLayout>
TableLayout 还有三个属性需要认知,
FrameLayout 相对于其他布局管理器来说比较简单,但应用的场景也减少。FrameLayout直接继承了ViewGroup组件,为每个加入其中的组件创建一个空白区域,把组件一个个地叠加在一起。
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Button" android:id="@+id/button" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/a4"/> </FrameLayout>
显然两个组件重叠在左上角,这种布局可能用到的地方可以不多。
RelativeLayout也是一种比较常用布局,相对布局容器内子组件的位置总是相对于兄弟组件、父容器来决定的,因此这种布局方式被称为相对布局。
以下是只能设为boolean值得属性:
android:layout_centerHorizontal |
控制该子组件是否位于布局容器的水平居中 |
android:layout_centerVertical |
控制该子组件是否位于布局容器的垂直居中 |
android:layout_centerInParent |
控制该子组件是否位于布局容器的中央位置 |
android:layout_alignParentTop | 控制该子组件是否与布局容器顶端对齐 |
android:layout_alignParentBottom | 控制该子组件是否与布局容器低端对齐 |
android:layout_alignParentLeft | 控制该子组件是否与布局容器左端对齐 |
android:layout_alignParentRight | 控制该子组件是否与布局容器右边对齐 |
android:layout_above | 控制该子组件位于给出ID组件的上方 |
android:layout_below | 控制该子组件位于给出ID组件的下方 |
android:layout_toLeftOf | 控制该子组件位于给出ID组件的左侧 |
android:layout_toRightOf |
控制该子组件位于给出ID组件的右侧 |
android:layout_alighTop | 控制该子组件与给出ID组件的上边界对齐 |
android:layout_alighBottom |
控制该子组件与给出ID组件的下边界对齐 |
android:layout_alighLeft | 控制该子组件与给出ID组件的左边界对齐 |
android:layout_alighRight |
控制该子组件与给出ID组件的右边界对齐 |
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!--定义按钮Bt1位于父容器中间--> <Button android:id="@+id/bt1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="按钮1" /> <!--定义Bt2位于按钮Bt1上方--> <Button android:id="@+id/bt2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@id/bt1" android:layout_alignLeft="@id/bt1" android:text="按钮2" /> <!--定义Bt3位于按钮Bt1下方--> <Button android:id="@+id/bt3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/bt1" android:layout_alignLeft="@id/bt1" android:text="按钮3" /> <!--定义Bt4位于按钮Bt1左方--> <Button android:id="@+id/bt4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/bt1" android:layout_alignTop="@id/bt1" android:text="按钮4" /> <!--定义Bt2位于按钮Bt1右方--> <Button android:id="@+id/bt5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/bt1" android:layout_toRightOf="@id/bt1" android:text="按钮5" /> </RelativeLayout>
GridLayout的作用类似于HTML中的Table标签,它把整个容器划分成rows*columns个网格,每个网格可以放置一个组件。除此之外也可以设置一个组件横跨多少列、纵跨多少行。
首先要说的是GridLayout与LinearLayout布局一样,也分为水平和垂直两种方式,默认是水平布局:
android:orientation | horizontal 水平 vertical 垂直 |
第二就是GridLayout的属性:
android:rowCount | 设置该网格的列数量 |
android:columnCount | 设置该网格的行数量 |
android:layout_rowSpan | 设置该子组件在容器纵跨几行 |
android:layout_columnSpan | 设置该子组件在容器横跨几行 |
【实例】计算器界面:
<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:columnCount="4" android:orientation="horizontal" android:rowCount="6"> <TextView android:layout_columnSpan="4" android:layout_gravity="fill" android:background="#000" android:gravity="right" android:text="0" android:textColor="#fff" android:textSize="80dp" /> <Button android:id="@+id/bt1" android:text="AC" /> <Button android:id="@+id/bt2" android:text="+/-" /> <Button android:id="@+id/bt3" android:text="%" /> <Button android:id="@+id/bt4" android:text="+" /> <Button android:id="@+id/bt5" android:text="7" /> <Button android:id="@+id/bt6" android:text="8" /> <Button android:id="@+id/bt7" android:text="9" /> <Button android:id="@+id/bt8" android:text=" - " /> <Button android:id="@+id/bt9" android:text="4" /> <Button android:id="@+id/bt10" android:text="5" /> <Button android:id="@+id/bt11" android:text="6" /> <Button android:id="@+id/bt12" android:text="*" /> <Button android:id="@+id/bt13" android:text="1" /> <Button android:id="@+id/bt14" android:text="2" /> <Button android:id="@+id/bt15" android:text="3" /> <Button android:id="@+id/bt16" android:text="/" /> <Button android:id="@+id/bt17" android:layout_columnSpan="2" android:layout_gravity="fill" android:text="0" /> <Button android:id="@+id/bt18" android:text="." /> <Button android:id="@+id/bt19" android:text="=" /> </GridLayout>当0需要横跨2列时
android:layout_columnSpan="2" android:layout_gravity="fill"
AbsoluteLayout绝对布局犹如div指定了absolute属性,用X,Y坐标来指定元素的位置!
该布局目前已经淘汰,知道就行了!
-----------------------------------------------------
TextView是Android中最简单的控件,它主要用于界面显示一段文本信息,有点类似Swing编程中的JLabel,但又比JLabel强大。还有些 样式、文本转换autoLink和autoText、文本超长ellipsize等等不一一多说。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Text" /> </LinearLayout>
EditText 是程序中用于和用户进行交互十分重要的控件,它允许用户在控件里输入和编辑内容,应用的场景最常见就是输入账号密码。
EditText 与 TextView非常相似,他甚至与TextView共用了绝大部分XML属性和方法,他们之间最大的区别就是:EditText 可以接受用户的输入。
【实例】简单登录界面
账号密码同样输入songsong123时在密码框就会显示点点,这是android:inputType的功能。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入账号" android:id="@+id/editText" /> <EditText android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" android:id="@+id/editText2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登 录" android:textAllCaps="false" android:id="@+id/button" /> </LinearLayout>EditText 还有另外一种情况就是随着输入内容越来越多,EditText在界面中会被不断拉长,导致界面变得非常凌乱,这时我们就应该使用android:maxLines来限制布局走形的情况出现。或者使用 android:maxLength来限制字数都可以达到目的。
android:maxLines="1" android:maxLength="10"
Button是程序用于和用户交互的一个重要控件,Button继承了TextView。它主要是在UI界面上生成一个按钮,该按钮可以供用户单击,当用户单击按钮时,就会触发onClick时间。
实例依然是刚刚那个:
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登 录" android:textAllCaps="false" android:id="@+id/button" />在Java代码中:
public class MainActivity extends Activity { private Button button; private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.text4); button = (Button) findViewById(R.id.button); editText = (EditText) findViewById(R.id.editText); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String str = editText.getText().toString(); Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show(); } }); }
ImageView是继承自View组件,主要功能不仅用于显示ImageView,而且还可以显示任何Drawable对象。
<ImageView android:id="@+id/imageView" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/a4"/>
ImageView所支持的android:scaleType属性可指定如下属性
【实例】图片的动态切换:
通过单击ImageView的setImageResource()方法动态完成切换图片:
public class MainActivity extends ActionBarActivity { int[] images = new int[]{ R.drawable.img1, R.drawable.img2, R.drawable.img3, }; private ImageView img1; int currentImg = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img1 = (ImageView) findViewById(R.id.img1); img1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { img1.setImageResource(images[++currentImg % images.length]); } }); }
RadioButton和CheckBox是用户界面中最普通的UI控件,他们都继承了Button类,因此都可直接调用Button支持的各种属性和方法。RadioButton和CheckBox和普通Button不同的是他们多了个可选中的功能android:checked属性。RadioButton和CheckBox的不同点在于一组RadioButton只能选中一个,因此RadioButton通常要与RadioGroup一起使用,用于一组单选按钮。
【实例】获取用户信息的简单实例:
界面布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="songsong.com.imageviewtext.MainActivity2"> <TextView android:id="@+id/tv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="性别:" /> <RadioGroup android:id="@+id/rg1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:id="@+id/male" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="男" /> <RadioButton android:id="@+id/female" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女" /> </RadioGroup> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="喜欢的颜色:" /> <CheckBox android:id="@+id/checkBox1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="红色" /> <CheckBox android:id="@+id/checkBox2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="蓝色" /> <TextView android:id="@+id/tv3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="性别为男"/> <TextView android:id="@+id/tv4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="喜欢的颜色是:"/> </LinearLayout>java代码为:
public class MainActivity2 extends ActionBarActivity { RadioGroup radioGroup; TextView show; CheckBox checkBox1; CheckBox checkBox2; TextView showbox; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); radioGroup = (RadioGroup) findViewById(R.id.rg1); show = (TextView) findViewById(R.id.tv3); checkBox1 = (CheckBox) findViewById(R.id.checkBox1); checkBox2 = (CheckBox) findViewById(R.id.checkBox2); showbox = (TextView) findViewById(R.id.tv4); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { String tip = checkedId == R.id.male ? "性别为男" : "性别为女"; show.setText(tip); } }); checkBox1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { String str = showbox.getText().toString(); showbox.setText(str + checkBox1.getText().toString()); } } }); checkBox2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { String str = showbox.getText().toString(); showbox.setText(str + checkBox2.getText().toString()); } } }); } }
进度条也是UI界面中一种非常实用的空间,通常用于向用户显示某些耗时操作完成的百分比。进度条可以动态显示进度,因此避免长时间执行某个耗时操作时,让用户感觉程序失去了响应,从而更好提高用户的友好性。
通过style属性可以为ProgressBar指定风格:
ProgressBar常用的XML属性:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="songsong.com.imageviewtext.ProgressBarText"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/progressBar" /> </LinearLayout>【实例】最简单的ProgressBar的布局:
当数据加载完成时,我们就需要另外一个属性android:visibility进行指定
也可以在代码中设置setVisibiliy():
【实例】ProgressBar进度条隐藏
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="songsong.com.imageviewtext.ProgressBarText"> <ProgressBar style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:id="@+id/probar2" /> <Button android:id="@+id/bt1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="GONE隐藏/显示"/> <Button android:id="@+id/bt2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="增加进度"/> </LinearLayout>java文件的代码:
public class ProgressBarText extends ActionBarActivity { ProgressBar progressBar; Button bt1; Button bt2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_progress_bar_text); progressBar = (ProgressBar) findViewById(R.id.probar2); bt1 = (Button) findViewById(R.id.bt1); bt2 = (Button) findViewById(R.id.bt2); bt1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (progressBar.getVisibility() == View.GONE) { progressBar.setVisibility(View.VISIBLE); } else { progressBar.setVisibility(View.GONE); } } }); bt2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int progress = progressBar.getProgress(); if (progress>=100){ progressBar.setVisibility(View.GONE); Toast.makeText(getApplicationContext(),"加载完成",Toast.LENGTH_SHORT).show(); }else { progress = progress + 10; progressBar.setProgress(progress); } } }); } }【实例】显示在标题上的进度条
public class TitleProgressBar extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置窗口特征:启用显示进度的进度条 requestWindowFeature(Window.FEATURE_PROGRESS); //① //设置窗口特征:启用不显示进度的进度条 // requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); //② setContentView(R.layout.activity_title_progress_bar); Button bn1 = (Button) findViewById(R.id.bn1); Button bn2 = (Button) findViewById(R.id.bn2); bn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setProgressBarIndeterminateVisibility(true); //显示不带进度的进度条 setProgressBarVisibility(true); //显示带进度的进度条 setProgress(4500); } }); bn2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setProgressBarIndeterminateVisibility(false); //显示不带进度的进度条 setProgressBarVisibility(false); //显示带进度的进度条 } }); } }
【实例】该程序的界面布局中需要两个组件:一个ImageView用于显示图片,一个SeekBar用于动态改变图片的透明度,界面布局如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="songsong.com.imageviewtext.SeekBarTest"> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="200dp" android:scaleType="fitCenter" android:src="@drawable/img1" /> <SeekBar android:id="@+id/sbk1" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="255" android:progress="255" android:thumb="@drawable/black" /> </LinearLayout>程序为拖动条绑定一个监听器,当滑块位置发生改变时动态改变ImageView的透明度。
public class SeekBarTest extends Activity { ImageView imageView; SeekBar seekBar; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_seek_bar); seekBar = (SeekBar) findViewById(R.id.sbk1); imageView = (ImageView) findViewById(R.id.imageView1); //当拖动条的滑块位置发生变化的时候触发该方法 seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { imageView.setImageAlpha(progress);//动态改变透明度 } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } }效果:
【实例】创建简单对话框,界面只有一个按钮,在代码中为此按钮绑定监听器:
public class AlertDialogText extends Activity { protected void onCreate(Bundle savedInstanceState) { ... //为按钮绑定单击事件 public void onClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(AlertDialogText.this); builder.setTitle("简单的标题"); //设置对话框标题 builder.setMessage("对话框的内容\n,这是测试"); //设置对话框内容 builder.setIcon(R.drawable.black); //设置对话框图标 builder.setCancelable(false); //可否取消 builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { //为builder添加确定按钮 @Override public void onClick(DialogInterface dialog, int which) { } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { //为builder添加取消按钮 @Override public void onClick(DialogInterface dialog, int which) { } }); builder.show(); } }); } }效果:
上面这种样式是最简单的,AlertDialog还提供了如下6中方法来指定对话框的内容:
【实例】用setView来设置登录界面:
1、定义界面布局login.xml
<?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:id="@+id/lg" android:padding="30dp"> <EditText android:id="@+id/et1" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入账号" /> <EditText android:id="@+id/et2" android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/et3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/bt2" android:layout_width="220dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_weight="1" android:text="短信验证" /> </LinearLayout> </LinearLayout>2、在MainActivity代码中写:
public class ViewAlertDialogText extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_alert_dialog_text); findViewById(R.id.bt1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LinearLayout lg = (LinearLayout) getLayoutInflater().inflate(R.layout.login, null); new AlertDialog.Builder(ViewAlertDialogText.this) .setTitle("登录界面") .setIcon(R.drawable.black) .setView(lg) .setCancelable(false) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .show(); } }); } }在主布局文件中仅有一个按钮,代码就不贴出来了。以下是效果图:
ProgressDialog和AlertDialog有点类似,但ProgressDialog一般用来表示当前操作比较耗时,让用户耐心等待。创建ProgressDialog进度对话框有如下两种方式:
为了对进度对话框的进度条进行设置,ProgressDialog包含了如下常用的方法:
【实例】ProgressDialog简单实例
public class ProgressDialog_text extends Activity { final static int MAX_PROGRESSS = 100; //最大的进度值 private int[] data = new int[50]; //模拟填充长度为100的数组 int progressStatus = 0; //记录对话框的完成的百分比 int hasData = 0; ProgressDialog pd2; //定义一个负责更新进度的handler Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 0x123) { //表明消息是由该程序发送的 pd2.setProgress(progressStatus); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_progress_dialog_text); } //调用静态方法显示环形进度条btn1 public void showSpinner(View source) { ProgressDialog.show(this, "任务执行中", "任务执行中,请稍等", false, true); } //显示进度的进度条btn2 public void showProgress(View source) { progressStatus = 0; //将进度条的完成进度重设为0 hasData = 0; //重新开始填充数组 pd2 = new ProgressDialog(this); pd2.setMax(MAX_PROGRESSS); //设置最大值 pd2.setTitle("任务完成百分比"); //设置对话框标题 pd2.setMessage("耗时任务的完成百分比"); //设置内容 pd2.setCancelable(false); //设置是否响应back键 pd2.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //设置样式 pd2.setIndeterminate(false); //设置对话框是否显示进度 pd2.show(); new Thread() { public void run() { while (progressStatus < MAX_PROGRESSS) { progressStatus = MAX_PROGRESSS * doWork() / data.length; //获取耗时操作的完成百分比 handler.sendEmptyMessage(0x123); //发送空消息到Handler } if (progressStatus >= MAX_PROGRESSS) { pd2.dismiss(); //如果认为完成,关闭对话框 } } }.start(); } //模拟一个耗时的操作 public int doWork() { data[hasData++] = (int) (Math.random() * 100); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } return hasData; } }布局界面为两个按钮:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="showSpinner" android:text="环形进度条" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="showProgress" android:text="显示进度的进度条" /> </LinearLayout>效果图:
菜单是用户界面中最常见的元素之一。在Android中,菜单被分为如下三种,选项菜单(OptionsMenu)、上下文菜单(ContextMenu)和子菜单(SubMenu)。
常用方法:
需要重写的方法:
add(int groupid,int itemid,int order,charSequence title)方法的四个参数,依次是:
【实例】如何为Android应用添加菜单和子菜单。
该程序的java代码如下:
public class MainActivity extends Activity { // 定义字体大小菜单项的标识 final int FONT_10 = 0x111; final int FONT_12 = 0x112; final int FONT_14 = 0x113; final int FONT_16 = 0x114; final int FONT_18 = 0x115; // 定义普通菜单项的标识 final int PLAIN_ITEM = 0x11b; // 定义字体颜色菜单项的标识 final int FONT_RED = 0x116; final int FONT_BLUE = 0x117; final int FONT_GREEN = 0x118; private EditText edit; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edit = (EditText) findViewById(R.id.edt1); } @Override public boolean onCreateOptionsMenu(Menu menu) { SubMenu fontMenu = menu.addSubMenu("字体大小"); fontMenu.setIcon(R.drawable.font); fontMenu.setHeaderIcon(R.drawable.font); fontMenu.add(0, FONT_10, 0, "10号字体"); fontMenu.add(0, FONT_12, 0, "12号字体"); fontMenu.add(0, FONT_14, 0, "14号字体"); menu.add(0, PLAIN_ITEM, 0, "普通菜单项"); SubMenu colorMenu = menu.addSubMenu("字体颜色"); colorMenu.setIcon(R.drawable.color); colorMenu.setHeaderIcon(R.drawable.color); colorMenu.setHeaderTitle("选择文字颜色"); colorMenu.add(0, FONT_RED, 0, "红色"); colorMenu.add(0, FONT_GREEN, 0, "绿色"); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case FONT_10: edit.setTextSize(10 * 2); break; case FONT_12: edit.setTextSize(12 * 2); break; case FONT_14: edit.setTextSize(14 * 2); break; case FONT_RED: edit.setTextColor(Color.RED); break; case FONT_BLUE: edit.setTextColor(Color.BLUE); break; case FONT_GREEN: edit.setTextColor(Color.GREEN); break; case PLAIN_ITEM: Toast toast = Toast.makeText(MainActivity.this, "您单击了普通菜单项", Toast.LENGTH_SHORT); toast.show(); break; } return true; } }上面程序中添加了三个菜单的代码,其中有两个菜单带有子菜单。运行程序,单击Menu按键,将会看到效果:
接下来是上下文菜单:当用户长按该组件时显示上下文菜单,首先要学会开发上下文菜单的步骤:
【实例】通过长按组件改变组件的背景颜色:
public class OtherActivity extends Activity { //为每个菜单定义一个标识 final int Menu1 = 0x111; final int Menu2 = 0x112; final int Menu3 = 0x113; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_other); textView = (TextView) findViewById(R.id.txt); registerForContextMenu(textView); //为textView绑定事件 } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { //创建上下文菜单时触发该方法 menu.add(0, Menu1, 0, "红色"); menu.add(0, Menu2, 0, "绿色"); menu.add(0, Menu3, 0, "蓝色"); menu.setGroupCheckable(0, true, true); //将3个菜单项设置为 单选项 menu.setHeaderTitle("选择背景色"); //设置标题 } @Override public boolean onContextItemSelected(MenuItem item) { //创建上下文菜单项被单击时触发该方法 switch (item.getItemId()) { case Menu1: item.setCheckable(true); textView.setBackgroundColor(Color.RED); break; case Menu2: item.setCheckable(true); textView.setBackgroundColor(Color.GREEN); break; case Menu3: item.setCheckable(true); textView.setBackgroundColor(Color.BLUE); break; } return true; } }效果如下:
接下来还要学习的是使用XML文件定义菜单:android提供了两种创建菜单的方式,一种是在Java代码中创建,另外一种是使用XML资源文件定义。我之前做的都是java代码中创建,但在java代码中定义菜单会有很多不足的地方。
用于android studio在创建android项目时,会默认在res目录下新建menu子目录,并在该子目录下提供menu_main.xml菜单资源文件,由此可见,android更推荐使用XML资源文件来定义菜单。
- checkableBehavior:指定改组菜单的选择行为。none不选、all多选、single单选。
- menuCategory:对菜单进行分类,指定菜单的优先级。container、system、secondary、alternative。
- visible:指定该组菜单是否可见。
- enable:指定该组菜单是否可用。
需要注意的是:<item.../>元素用于定义菜单项,<item.../>元素又可包含<menu.../>元素,位于<item.../>元素内部的<menu.../>元素就代表子菜单。
【实例】使用XML资源文件定义 选项菜单 和 上下文菜单。
首先为选项菜单编写XML资源文件:menu_main.xml,在<menu.../>元素里包含三个<item.../>子元素,这表明该菜单里有三个菜单项。第一、第三菜单项都包含子菜单。
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="songsong.com.menutext.MenuText_XML"> <item android:title="字体大小"> <menu> <group android:checkableBehavior="single"> <item android:id="@+id/font_10" android:title="10号字体" /> <item android:id="@+id/font_11" android:title="11号字体" /> <item android:id="@+id/font_12" android:title="12号字体" /> </group> </menu> </item> <item android:id="@+id/putongitem" android:title="普通菜单"></item> <item android:id="@+id/Font_color" android:title="字体颜色"> <menu> <group> <item android:id="@+id/ren_font" android:title="红色" /> <item android:id="@+id/blue_font" android:title="蓝色" /> <item android:id="@+id/green_font" android:title="绿色" /> </group> </menu> </item> </menu>接下来定义该应用上下文菜单的资源文件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/red" android:alphabeticShortcut="r" android:title="红色" /> <item android:id="@+id/blue" android:alphabeticShortcut="b" android:title="蓝色" /> <item android:id="@+id/green" android:alphabeticShortcut="g" android:title="绿色" /> </group> </menu>定义了上面两份菜单资源后,接下来可以在Activity中的onCreateOptionsMenu、onCreateContextMenu方法中加载这两份菜单资源。
public class MenuText_XML extends Activity { private TextView txt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_menu_text__xml); txt = (TextView) findViewById(R.id.txt); registerForContextMenu(txt); //为上下文菜单绑定事件txt } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.menu_main, menu); //绑定选项菜单R.menu.menu_main return super.onCreateOptionsMenu(menu); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.context, menu); //绑定上下文菜单R.menu.context menu.setHeaderTitle("请选择背景色"); } @Override public boolean onOptionsItemSelected(MenuItem item) { //选项菜单被单击后回调的方法 if (item.isCheckable()) { //是否选中 item.setCheckable(true); //设置为选中 } switch (item.getItemId()) { case R.id.font_10: txt.setTextSize(10 * 2); break; case R.id.font_11: txt.setTextSize(11 * 2); break; case R.id.font_12: txt.setTextSize(12 * 2); break; case R.id.putongitem: Toast toast = Toast.makeText(MenuText_XML.this, "你点击了普通菜单项", Toast.LENGTH_SHORT); toast.show(); break; case R.id.ren_font: txt.setTextColor(Color.RED); break; case R.id.blue_font: txt.setTextColor(Color.BLUE); break; case R.id.green_font: txt.setTextColor(Color.GREEN); break; } return true; } @Override public boolean onContextItemSelected(MenuItem item) { //上下文菜单被单击时触发该方法 item.setCheckable(true); switch (item.getItemId()) { case R.id.red: item.setCheckable(true); txt.setBackgroundColor(Color.RED); break; case R.id.blue: item.setCheckable(true); txt.setBackgroundColor(Color.BLUE); break; case R.id.green: item.setCheckable(true); txt.setBackgroundColor(Color.GREEN); break; } return true; } }代码运行效果和上个实例的一样:
最后一种是PopupMenu弹出式菜单:PopupMenu会在指定的组件上弹出一个列表,它的菜单选项来自Menu资源。以下是创建步骤:
【实例】简单的PopupMenu使用
先定义Menu资源文件XML:
<?xml version="1.0" encoding="UTF-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/search" android:icon="@android:drawable/ic_menu_search" android:title="查找" /> <item android:id="@+id/add" android:icon="@android:drawable/ic_menu_add" android:title="添加" />- <item android:id="@+id/edit" android:icon="@android:drawable/ic_menu_edit" android:title="编辑">- <menu> <item android:id="@+id/copy" android:title="复制" /> <item android:id="@+id/cut" android:title="剪切" /> <item android:id="@+id/paste" android:title="粘贴" /> </menu> </item> <item android:id="@+id/exit" android:title="隐藏菜单" /> </menu>然后在代码中定义:
public class PopupMenuText extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_popup_menu); final Button bt1 = (Button) findViewById(R.id.bt1); bt1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final PopupMenu popup = new PopupMenu(PopupMenuText.this, bt1); popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu()); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.exit: popup.dismiss();// 隐藏该对话框 break; default: Toast toast = Toast.makeText(PopupMenuText.this, "您单击了【" + item.getTitle() + "】菜单项", Toast.LENGTH_SHORT); // 使用Toast显示用户单击的菜单项 toast.show(); } return true; } }); popup.show(); //showing popup menu } }); } }效果:
本段内容参考与:http://www.cnblogs.com/yc-755909659/p/4290784.html
2.11.1.ActionBar介绍
活动条(ActionBar)是Android3.0的重要更新之一,ActionBar位于传统标题栏title bar的位置,也就是显示在屏幕的顶部。对于Android平板设备来说屏幕更大它的标题使用ActionBar来设计可以展示更多丰富的内容,方便操控。
2.11.2.ActionBar功能
2.11.3.如何使用
2.11.3.1、添加ActionBar
最新的Android版本已经默认启用了ActionBar,因此只要在AndroidManifest.xml文件的SDK配置中指定该应用的目标版本高于11,默认就会启用ActionBar。
2.11.3.2、取消ActionBar
如果希望关闭ActionBar,则可以设置该应用的主题为NoActionBar。
<<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light.NoActionBar" > ... </application>一旦关闭了ActionBar,该Android应用就不能使用ActionBar。在实际项目中,通常推荐使用代码来控制ActionBar的显示、隐藏。
ActionBar actionBar = getActionBar(); actionBar.show(); //显示 actionBar.hide(); //隐藏
2.11.3.3、修改Action Bar的图标和标题
默认情况下,系统会使用<application>或者<activity>中icon属性指定的图片来作为ActionBar的图标,但是我们也可以改变这一默认行为。如果我们想要使用另外一张图片来作为ActionBar的图标,可以在<application>或者<activity>中通过logo属性来进行指定,而标题中的内容使用label属性来指定。
<activity android:name=".MainActivity" android:logo="@drawable/black" android:label="ActionBar学习"> ... </activity>效果如下:
2.11.3.4、添加Action按钮,显示选项菜单项
Android不再强制要求手机必须提供MENU按键,这样可能导致用户无法打开选项菜单。为了解决这个问题Android提供ActionBar作为解决方案。
ActionBar还可以根据应用程序当前的功能来提供与其相关的Action按钮,这些按钮都会以图标或文字的形式直接显示在ActionBar上。当然,如果按钮过多,ActionBar上显示不完,多出的一些按钮可以隐藏在overflow里面,点击一下overflow按钮就可以看到全部的Action按钮了。
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/select_id" android:icon="@drawable/a5" android:showAsAction="always" android:title="查询" /> <item android:id="@+id/baohu_id" android:icon="@drawable/a6" android:showAsAction="always" android:title="保护" /> <item android:id="@+id/delete_id" android:icon="@drawable/a7" android:showAsAction="always" android:title="删除" /> </menu>相对定义Menu选项菜单项新增了android:showAsAction属性,该属性可有空子将这些菜单项显示在ActionBar上。了解一下支持的参数值:
在MainActivity.java文件中重写onCreateOptionsMenu方法:
public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.menu_main, menu); return super.onCreateOptionsMenu(menu); }现在重新运行一下程序,结果如下图所示:
2.11.3.5、响应Action按钮的点击事件
接着在Activity中重写onOptionsItemSelected()方法,通过方法传入的MenuItem参数,我们可以调用它的getItemId()方法和menu资源中的id进行比较,从而辨别出用户点击的是哪一个Action按钮。
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.select_id: Toast.makeText(this, "你点击了“查询”按键!", Toast.LENGTH_SHORT).show(); return true; case R.id.baohu_id: Toast.makeText(this, "你点击了“保护”按键!", Toast.LENGTH_SHORT).show(); return true; case R.id.delete_id: Toast.makeText(this, "你点击了“删除”按键!", Toast.LENGTH_SHORT).show(); return true; default: return super.onOptionsItemSelected(item); } }【实例】通过Action Bar图标进行导航
启用ActionBar图标导航的功能,可以允许用户根据当前应用的位置来在不同界面之间切换。比如,A界面展示了一个列表,点击某一项之后进入了B界面,这时B界面就应该启用ActionBar图标导航功能,这样就可以回到A界面。
为了将应用程序图标转变成可以点击的图标,可以调用以下方法:
先来看看效果:
实例中,通过点击action按钮,启动另一个Activity(TwoActivity),发现TwoActivity的程序图标多了个向左的箭头,点击是返回父Activity(MainActivity)。
第一步:MainActivity.java通过点击“查询”action按钮创建TwoActivity:
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.select_id: Intent intent = new Intent(this, TwoActivity.class); //启动TwoActivity startActivity(intent); return true; ... }第二步:为TwoActivity添加setDisplayHomeAsUpEnabled可被点击和显示左箭头,然后为程序图标添加点击事件:
1、在TwoActivity的onCreate中:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_two); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); //设置为true }2、需要在AndroidManifest.xml中配置父Activity:
<activity android:name=".TwoActivity" android:label="@string/title_activity_two" android:parentActivityName=".MainActivity"> </activity>3.、对程序图标点击事件进行处理:
</pre><pre name="code" class="java">public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Intent upIntent = NavUtils.getParentActivityIntent(this); if (NavUtils.shouldUpRecreateTask(this, upIntent)) { TaskStackBuilder.create(this) .addNextIntentWithParentStack(upIntent) .startActivities(); } else { upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); NavUtils.navigateUpTo(this, upIntent); } return true; } return super.onOptionsItemSelected(item); }其中,调用NavUtils.getParentActivityIntent()方法可以获取到跳转至父Activity的Intent,然后如果父Activity和当前Activity是在同一个Task中的,则直接调用navigateUpTo()方法进行跳转,如果不是在同一个Task中的,则需要借助TaskStackBuilder来创建一个新的Task。
2.11.3.6、添加Action View
为了在ActionBar上添加Action View,可以来用如下两种方式:
【实例】标题上的搜索和时钟
本实例在菜单资源文件中定义两个Action Item,但这两个Action Item都是使用Action View。资源文件代码如下(menu_main.xml):
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="songsong.com.actionbartest.ActionViewTest"> <item android:id="@+id/search" android:actionViewClass="android.widget.SearchView" android:orderInCategory="50" android:showAsAction="always" /> <item android:id="@+id/progress" android:actionLayout="@layout/clock" android:orderInCategory="100" android:showAsAction="always" /> </menu>定义界面布局资源为@layout/clock
<?xml version="1.0" encoding="utf-8"?> <AnalogClock xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> </AnalogClock>该界面布局文件仅仅定义了AnalogClock,这表明该ActionBar的第二个Action View只是一个模拟闹钟。效果如下:
2.11.3.7、Overflow按钮
Overflow按钮是显示在ActionBar右边的三个点,其意为“更多”,当actionbar上面显示内容满了的时候将会自动填充进Overflow列表。但更多时候,如果手机有Menu按键的情况下,Overflow按钮是不显示的。所有如果要想在有Menu手机中显示,就要加入一段大神已经写好的代码:
public class ActionViewTest extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { ... setOverflowShowingAlways();//调用方法 } <pre name="code" class="java">private void setOverflowShowingAlways() { try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if (menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } } catch (Exception e) { e.printStackTrace(); } }}
2.11.3.9、让Overflow中的选项显示图标
为了让Action按钮在Overflow中能显示图标,就要在Activity中重写onMenuOpened()方法
@Override public boolean onMenuOpened(int featureId, Menu menu) { if (featureId == Window.FEATURE_ACTION_BAR && menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { } } } return super.onMenuOpened(featureId, menu); }显示图标是由MenuBuilder这个类的setOptionalIconsVisible变量来决定的,如果我们在overflow被展开的时候将这个变量赋值为true,那么里面的每一个Action按钮对应的图标就都会显示出来了。
2.11.3.10添加导航Tabs :暂未完成
2.11.3.11添加下拉列表导航:暂未完成
【实例】ListView简单的使用
第一步,在Layout_main.xml中定义ListView控件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="#f00" android:dividerHeight="2px" android:entries="@array/books" android:headerDividersEnabled="false"></ListView> </LinearLayout>
第二步,在Java文件中:
public class ArrayAdapterTest extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_arrayadaptertest); ListView ls = (ListView) findViewById(R.id.list); String arr1[] = new String[]{"坚持", "不懈", "努力", "到底"}; ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(ArrayAdapterTest.this, R.layout.array_item, arr1); ls.setAdapter(adapter1); } }
如果想要对ListView的外观、行为进行定制,就需要通过Adapter控制每个列表项的外观和行为。
Adapter适配器:Adapter本身只是一个接口,他常用的实现类如下:
刚刚的简单实例就用到了ArrayAdapter适配器
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(ArrayAdapterTest.this, R.layout.array_item, arr1); ls.setAdapter(adapter1);在创建ArrayAdapter时必须指定如下三个参数:
在最后为listView设定适配器 :ls.setAdapter(adapter1);
【实例】使用SimpleAdapter创建ListView
先定义界面布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="songsong.com.listviewtext.SimpleAdapterTest"> <ListView android:id="@+id/lv1" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </LinearLayout>下面是Activity代码:
public class SimpleAdapterTest extends Activity { private String[] title = new String[]{"我是标题1", "我是标题2", "我是标题3", "我是标题4"}; private String[] content = new String[]{"我是内容1", "我是内容2", "我是内容3", "我是内容4"}; private int[] ImageIds = new int[]{R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_simpleadaptertest); //创建一个List集合,List集合的元素是Map. List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>(); for (int i = 0; i < title.length; i++) { Map<String, Object> listItem = new HashMap<String, Object>(); listItem.put("A1", ImageIds[i]); listItem.put("A2", title[i]); listItem.put("A3", content[i]); listItems.add(listItem); } SimpleAdapter simpleAdapter = new SimpleAdapter( SimpleAdapterTest.this, listItems, R.layout.simple_item, new String[]{"A1", "A2", "A3"}, new int[]{R.id.img1, R.id.tv1, R.id.tv2}); ListView listView = (ListView) findViewById(R.id.lv1); listView.setAdapter(simpleAdapter); } }先要学习的是SimpleAdapter创建需要5个参数:
R.layout.simple_item对应的布局文件代码如下:
<?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" android:padding="15dp"> <ImageView android:id="@+id/img1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" /> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14dp" /> </LinearLayout> </LinearLayout>效果如下:
如果需要监听用户单击、选中某个列表项的时间,则可以通过AdapterView的setOnItemClickListener()方法来监听单击事件,setOnItemSelectedListener()方法来监听选中事件。
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { //第position项被单击时激发该方法 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { System.out.println(title[position] + "被单击了"); } }); listView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { //选中事件绑定监听器 @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { System.out.println(title[position] + "被选中了"); } @Override public void onNothingSelected(AdapterView<?> parent) { } });
【实例】扩展BaseAdapter实现不存储列表项ListView: 暂未写
Spinner组件与Swing编程中的Spinner不同,此处的Spinner其实就是一个列表选择框,不过Android的列表选择框并不需要显示下拉列表,而是相当于弹出一个菜单供用户选择。
以下是XML属性及其相关方法:
有两种定义Spinner的方式,第一种是定义数组资源:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Spinner android:layout_width="match_parent" android:layout_height="wrap_content" android:entries="@array/books" android:prompt="@string/tishi"></Spinner> <Spinner android:id="@+id/spinner_id" android:layout_width="match_parent" android:layout_height="wrap_content"></Spinner> </LinearLayout>
另外一种是java代码:
public class MainActivity extends Activity { Spinner spinner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spinner = (Spinner) findViewById(R.id.spinner_id); String[] data = {"坚持", "不懈", "努力", "奋斗"}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, data); spinner.setAdapter(adapter); } }效果如图:
取得用户的选择代码可以使用getSelectedItem()方法取得用户的选择,如下所示:
String sp = spinner.getSelectedItem().toString();
【实例】自定义标题栏
新建一个title.xml布局文件:
<?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="wrap_content" android:orientation="horizontal" android:background="#005"> <Button android:id="@+id/title_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="返回" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="标题" /> <Button android:id="@+id/title_edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="修改" /> </LinearLayout>修改layout_main.xml去使用title.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <include layout="@layout/title"></include> </LinearLayout>最后一步就是在MainActivity.java文件中隐藏系统自带的title:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); }效果如下:
为了要按钮能响应事件,需要修改代码,新建Java文件TitleLayout,并继承LinearLayout,代码如下
public class TitleLayout extends LinearLayout { public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.title, this); Button back = (Button) findViewById(R.id.title_back); back.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ((Activity) getContext()).finish(); } }); Button edit = (Button) findViewById(R.id.title_edit); edit.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getContext(), "edit", Toast.LENGTH_SHORT).show(); } }); } }然后要在layout_main.xml中重新定义title.xml文件
<songsong.com.zidingyikongjian.TitleLayout android:layout_width="match_parent" android:layout_height="wrap_content"> </songsong.com.zidingyikongjian.TitleLayout>效果如下:
——————————————————————
学习内容:
考察问题: