Android-UI:按钮监听&文字/图片/进度条&动态变更&dialog&布局&自定义布局/控件/响应事件
Android:layout_width和layout_height指定空间的宽度和高度,可选值有:
fill_parent,match_parent 由父布局决定控件大小,推荐使用match_parent
wrap_parent由内容决定控件大小
按钮监听的两种写法:
1. 用匿名类注册监听器
public class MainActivity extends Activity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "You click the button", Toast.LENGTH_SHORT).show(); } }); } }
2. 用实现接口的方式注册监听器:
public class MainActivity extends Activity implements OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button=(Button)findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()) { case R.id.button: Toast.makeText(MainActivity.this, "You click the button", Toast.LENGTH_SHORT).show(); break; default: break; } } }
注意导入包为
import android.view.View.OnClickListener;
否则将出现报错: MainActivity不是抽象的, 并且未覆盖OnClickListener中的抽象方法onClick(View)
<EditText>控件
在layout.xml文件中可添加<EditText>控件允许用户输入和编辑内容:
android:hint属性可指定提示性文本;
android:maxLine属性可指定EditText最大行数,超过该行数文本向上滚动,不会继续拉伸;
在活动的.java代码中,先通过findViewById和类型转换获得EditText类实例editText,再调用editText.getText().toString()可获取EditText中输入内容的字符串。
<ImageView>控件
在layout.xml文件中添加<ImageView>控件
<ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"/>
wrap_content保证图片显示完整尺寸,android:src指定展示/drawable目录下的ic_launcher图片文件。
可在活动中动态变更ImageView中的图片:
在MainActivity中声明私有成员
private ImageView imageView;
在onCreate()中添加:
imageView = (ImageView) findViewById(R.id.image_view);
在按钮监听事件中:
case R.id.button: imageView.setImageResource(R.drawable.a); break;
运行程序,点击按钮,ImageView显示图片由b变为a。
<ProgressBar>控件
在layout.xml中添加<ProgressBar>控件,可展示旋转进度条;
<ProgressBar>的style属性可指定为水平进度条,android:max属性可设置进度最大值:
style="?android:attr/progressBarStyleHorizontal"
android:max="100"/>
在活动代码中可动态更改进度条进度:
case R.id.button: int progress = progressBar.getProgress(); progress = progress+10; progressBar.setProgress(progress);
控件可见性
Android:visiblity属性可指定控件的可见性,可选:visibility(默认,可见)、invisible(不可见但占据原位置和大小)、gone(不可见且不占据屏幕空间);
在活动中,实例progressBar可调用getVisibility()判断可见性,调用setVisibility方法,传入View.VISIBLE、View.INVISIBLE、View.GONE参数控制可见性,例:点击按钮改变进度条的可见性:
case R.id.button: if(progressBar.getVisibility() == View.GONE) { progressBar.setVisibility(View.VISIBLE); } else { progressBar.setVisibility(View.GONE); }
AlertDialog
AlertDialog可以在当前界面弹出对话框,置顶于所有界面元素之上,屏蔽其他空间的交互能力,一般用于提示重要内容或警告信息。在活动代码中添加:
case R.id.button: AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this); dialog.setTitle("This is Dialog"); dialog.setMessage("Something important."); dialog.setCancelable(false); dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.show();
通过Alert.Dialog创建AlertDialog实例;
设置标题、内容、可否取消;
setPositiveButton()设置确定按钮点击事件,setNegativeButton()设置取消按钮点击事件;
调用show()显示对话框;
ProgressDialog可在界面弹出对话框,屏蔽其他空间的交互能力,一般用于表示当前操作比较耗时,让用户耐心等待。在活动代码中添加:
case R.id.button: ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setTitle("This is ProgressDialog"); progressDialog.setMessage("Loading..."); progressDialog.setCancelable(true); progressDialog.show();
构建ProgressDialog对象,设置标题、内容、可否取消;
调用show()显示对话框;
如果setCancelable()传入false,则对话框不能通过Back键取消,需要在代码中控制:数据加载完毕后调用ProgressDialog的dismiss()方法关闭对话框。
LinearLayout布局将所包含的空间在线性方向上依次排列;
android:orientation指定为vertical时,控件在垂直方向排列,指定为horizontal时,控件在水平方向排列;
android:orientation默认情况下为horizontal;
注意:LinearLayout排列方向为horizontal时,内部空间不能将宽度指定为match_parent,否则单独空间会将水平方向占满,同理vertical时控件高度不能指定为match_parent。
android:gravity指定控件中文字的对齐方式;
android:layout_gravity指定控件在布局中的对齐方式,可选值与android:gravity类似;
LinearLayout排列方向为horizontal时,只有垂直方向上的对齐方式生效;
LinearLayout排列方向为vertical时,只有水平方向上的对齐方式生效。
android:weight指定控件所占大小的比例;
系统将LinearLayout下所有控件指定的layout_width求和得到总值,每个控件所占大小比例则为各自的layout_width除以总值;
例如,将android:layout_width指定为0dp,控件宽度就由android:weight决定。控件1和控件2的android:layout_weight都指定为1,双方将在水平方向平分宽度,指定为3和2,双方在水平方向各占屏幕的3/5和2/5;
推荐布局:EditText控件的layout_width指定为0dp,android:weight指定为1,Button控件layout_width指定为wrap_content,不指定layout_weight,则Button宽度仍按照wrap_content计算,EditText占满剩余空间。
RelativeLayout:相对布局,通过相对定位的方式设置控件处在布局的位置。
可通过将控件的android:layout_alignParentLeft, layout_alignParentTop, layout_alignParentRight, layout_alignParentBottom, layout_centerInParent属性赋值为”true”,使控件与父布局的四角对其或居中显示;
可通过将控件的android:layout_above, layout_below, layout_toLeftOf, layout_toRightOf的属性赋值为另一个控件的id引用(如”@id/button3”),使当前控件位于另一控件的上下左右侧;
注意:引用另一控件id时,该控件一定要定义在被引用控件的后面;
可设置控件的android:layout_alignLeft, layout_alignRight, layout_alignTop, layout_alignBottom属性使控件的左、右、上、下边缘与另一控件的左右上下边缘对齐。
FrameLayout:所有控件都摆放在布局左上角,没有任何定位方式。
TableLayout:允许使用表格的方式排列控件;
TableRow表示在表格中添加一行,TableRow中添加控件表示在该行中加入一列;
TableRow中的空间不能指定宽度;
设计表格时应尽量使每一行拥有相同的列数,当表格的某行一定要有不相等的列数时,需要通过设置控件的android:layout_span属性合并单元格处理:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TableRow> <TextView android:layout_height="wrap_content" android:text="Account:" /> <EditText android:id="@+id/account" android:layout_height="wrap_content" android:hint="Input your account"/> </TableRow> <TableRow> <TextView android:layout_height="wrap_content" android:text="Password:"/> <EditText android:id="@+id/password" android:layout_height="wrap_content" android:inputType="textPassword"/> </TableRow> <TableRow> <Button android:id="@+id/login" android:layout_height="wrap_content" android:layout_span="2" android:text="Login"/> </TableRow> </TableLayout>
运行程序,login按钮占据两列空间:
因为TableRow中无法指定控件宽度,所以上图控件并没有充分利用屏幕宽度;
可通过修改android:stretchColumns属性对某一列进行拉伸以自动适应屏幕宽度:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="1">
android:strechColumns=”0”->拉伸第一列 android:strechColumns=”1”->拉伸第二列
运行程序
控件和布局的继承结构:
View:Android中一种最基本的UI组件,可以再屏幕上绘制一块矩形区域并相应该区域的各种事件,所有控件都直接或间接继承自View;
ViewGroup:一种特殊的View,包含很多子View和子ViewGroup,是一个用于防止控件和布局的容器,所有布局都直接或间接继承自ViewGroup;
在布局中引入自定义布局
例:引入自定义标题栏布局
创建标题栏布局title.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/title_bg"> <Button android:id="@+id/title_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dip" android:background="@drawable/back_bg" android:text="Back" android:textColor="#fff"/> <TextView android:id="@+id/title_text" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="Title Text" android:textColor="#fff" android:textSize="24sp"/> <Button android:id="@+id/title_edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dip" android:background="@drawable/edit_bg" android:text="Edit" android:textColor="#fff"/> </LinearLayout>
android:background为布局或控件指定背景,可使用颜色或图片填充
android:layout_margin指定控件在上下左右方向上偏移的距离,也可用layout_marginLeft, layout_marginTop等单独指定
在主活动布局activity_main.xml中引入自定义的标题栏(其他需要引入标题栏的布局也只需添加):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/title" /> </LinearLayout>
(其他需要引入标题栏的布局也只需添加include语句)
在MainActivity.java中隐藏系统自带的标题栏:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); }
运行程序:
创建自定义控件
例:创建自定义标题栏控件
新建TitleLayout.java作为自定义标题栏控件:
public class TitleLayout extends LinearLayout { public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.title, this); } }
重写父类LinearLayout的构造函数
调用LayoutInflator.from()构建LayoutInflator对象
调用inflate()动态加载标题栏布局,接受参数1:要加载的布局文件id 参数2:给加载好的布局添加父布局(这里指定为TitleLayout)
在activity_main.xml中添加自定义控件:
<com.example.lily.uicustomviews.TitleLayout android:layout_width="match_parent" android:layout_height="wrap_content" />
添加自定义控件时不能省略包名,需要指明完整类名
运行程序:获得与引入布局方式相同的效果。
可给自定义添加响应事件,例:
在titleLayout.java的onCreate()方法中,为自定义标题栏的两个按钮注册点击事件:
Button titleBack = (Button) findViewById(R.id.title_back); Button titleEdit = (Button) findViewById(R.id.title_edit); titleBack.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { ((Activity)getContext()).finish(); } }); titleEdit.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getContext(), "You clicked Edit Button", Toast.LENGTH_SHORT).show(); } });
运行程序:点击Edit按钮弹出Toast文本,点击Back按钮销毁当前活动;
通过这种方法在需要引入自定义标题栏的布局中引入TitleLayout,按钮点击事件已经自动实现,省去编写重复代码的工作。