1 理解UI
1.1 UI的定义
- 全称user interface, 意为: 用户界面。
- UI由View和ViewGroup组成。
- View类是所有视图(包括ViewGroup)的根基类。
- View在屏幕上占据一片矩形区域, 并会在上面进行内容绘制。
- ViewGroup包含一些View或ViewGroup, 用于控制子View的布局。
1.2 View的API结构
1.3 UI的组成
- 界面的整体布局(layout)
- 组成可视界面的各个UI组件(Component)
2 UI事件
2.1 理解UI事件
- 当用户通过手指触摸UI时, 系统会自动创建对应的Event对象。
- Android中提供了多种方式拦截处理不同类型的事件。
- 视图本身就可以处理发生在该视图上的事件。
2.2 使用UI事件
3 常用的简单Component
3.1 TextView 文本视图
3.2 EditText 文本输入框
3.3 Button 按钮
3.4 ImageView 图片视图
3.5 CheckBox 多选
他们的监听事件是这个类:
3.6 RadioGroup/RadioButton 单选框
实现的是这个监听接口
3.7 菜单 Component
代码如下:
方式1 :硬编码方式
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//参数1表示组id 参数2表示菜单唯一表示 参数3表示排序 参数4表示文本
//点击菜单按钮就可以显示出来
menu.add(0, 1, 0, "新增");
menu.add(0, 2, 0, "删除");
return super.onCreateOptionsMenu(menu);
}
方式2:加载菜单文件的方式
首先右击res文件夹 生成menu文件。
option_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/add" android:title="添加2"/>
<item android:id="@+id/delete" android:title="删除2"/>
</menu>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//加载菜单文件的方式
//1 得到菜单加载器对象
MenuInflater menuInflater=getMenuInflater();
//2 加载菜单文件
menuInflater.inflate(R.menu.option_menu, menu);
return super.onCreateOptionsMenu(menu);
}
选中菜单项事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.add){
Toast.makeText(this, "新增", 0).show();
}else if(item.getItemId()==R.id.delete){
Toast.makeText(this, "删除", 0).show();
}
return super.onOptionsItemSelected(item);
}
3.7 ContextMenu : 上下文菜单
效果图如下:
3.8 进度条Component
代码如下:
<LinearLayout
android:id="@+id/ll_loadding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载中..." />
</LinearLayout>
<ProgressBar
android:id="@+id/pb_progress_loadding"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:progress="30"/>
<SeekBar
android:id="@+id/sb_progress_loadding "
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
private LinearLayout ll_loadding;
private ProgressBar pb_progress_loadding;
private SeekBar sb_progress_loadding;
private OnSeekBarChangeListener onSeekBarChangeListener=new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.e("TAG", "离开滑杆");
//获取SeekBar的进度数
int progress=sb_progress_loadding.getProgress();
//设置ProgressBar进度数
pb_progress_loadding.setProgress(progress);
if(progress==sb_progress_loadding.getMax()){
//INVISIBLE 不可见但是占用空间 gone不可见但是不占用空间
//ll_loadding.setVisibility(View.INVISIBLE);//如果sb_progress_loadding最大了则ll_loadding不可见
ll_loadding.setVisibility(View.GONE);
}else{
ll_loadding.setVisibility(View.VISIBLE);//可见
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Log.e("TAG", "按下滑杆");
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
Log.e("TAG", "滑杆移动");
}
};
3.9 对话框Component
3.9.1 AlertDialog : 警告框
效果如下:
语法如下:
代码如下:
/**
* 显示一般AlertDialog
* @param v
*/
public void showAD(View v){
new AlertDialog.Builder(this)
.setTitle("删除数据")
.setMessage("你确定删除数据吗?")
.setPositiveButton("删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "已经删除", 0).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "取消删除", 0).show();
}
})
.show();
}
单选列表
/**
* 显示单选列表AlertDialog
*/
public void showLD(View v){
final String [] items={"红","黄","蓝","绿"};
new AlertDialog.Builder(this)
.setTitle("指定背景颜色")
//参数2表示默认选中的元素
.setSingleChoiceItems(items, 2, new DialogInterface.OnClickListener() {
//参数2 表示传过来选中的元素的下标
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,items[which] , 0).show();
//点击后移除对话框
dialog.dismiss();
}
}).show();
}
3.9.2 自定义AlertDialog
代码如下:
//显示自定义AlertDialog
public void showCD(View v){
View view=View.inflate(this,R.layout.dialog_view, null);
final EditText ETuserName=(EditText) view.findViewById(R.id.userName);
final EditText ETpassword=(EditText) view.findViewById(R.id.password);
new AlertDialog.Builder(this)
.setView(view)
.setNegativeButton("取消",null)
.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String username=ETuserName.getText().toString();
String password=ETpassword.getText().toString();
Toast.makeText(MainActivity.this,"userName="+username+",password="+password , 0).show();
}
})
.show();
}
3.9.3 ProgressDialog : 带进度Dialog
/**
* 显示圆形进度ProgressDialog
*/
public void showPD(View v){//回调方法:是在主线程中完成的
final ProgressDialog pdialog=ProgressDialog.show(this, "数据加载", "数据加载中...");
//模拟做一个长时间的工作
//要注意长时间的工作不能在主线程中做,得要启动分线程完成。
new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pdialog.dismiss();//方法在分线程中执行,但内部使用Handler实现主线程移除Dialog
//不能在分线程中直接更新UI 但是可以间接 比如上面的pdialog.dismiss()
//runOnUiThread是在分线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {//在主线程中执行
Toast.makeText(MainActivity.this,"加载完成" , 0).show();
}
});
}
}.start();
}
/**
* 显示水平进度ProgressDialog
* @param v
*/
public void showPD2(View v){
//创建Dialog
final ProgressDialog pd=new ProgressDialog(this);
//设置样式
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//显示
pd.show();
//启动分线程 加载数据 显示进度 当加载完成后移除Dialog
new Thread(new Runnable() {
@Override
public void run() {
int count=20;
pd.setMax(20);
for(int i=1;i<=count;i++){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
pd.setProgress(pd.getProgress()+1);
}
//然后移除
pd.dismiss();
}
}).start();
}
3.9.4 DateDialog : 日期Dialog和TimeDialog : 时间Dialog
/**
* 显示DatePickerDialog
* @param v
*/
public void showDateAD(View v) {
//创建日历对象
Calendar calendar = Calendar.getInstance();
//得到当前的年月日
int year = calendar.get(Calendar.YEAR);//得到年份
int monthOfYear = calendar.get(Calendar.MONTH)+1;//月 月份+1 因为是从0开始的
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);//得到日
Log.e("TAG", year+"-"+monthOfYear+"-"+dayOfMonth);
new DatePickerDialog(this, new android.app.DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
Log.e("TAG", year+"--"+monthOfYear+"--"+dayOfMonth);
}
}, year, monthOfYear, dayOfMonth).show();
}
/**
* 显示时间
* @param v
*/
public void showTimeAD(View v) {
Calendar c = Calendar.getInstance();
int hourOfDay = c.get(Calendar.HOUR_OF_DAY); //得到小时
int minute = c.get(Calendar.MINUTE); //得到分钟
Log.e("TAG", hourOfDay+":"+minute);
new TimePickerDialog(this, new OnTimeSetListener() {
boolean bool=true;
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
if(bool){
Log.e("TAG", hourOfDay+"::"+minute);
bool=false;
}
}
}, hourOfDay, minute, true).show();
}