UI理解
UI由View和ViewGroup组成,其是父子关系。View类是所有视图(包括ViewGroup)的根基类。View在屏幕上占据一片矩形区域,并会在上面进行内容绘制。ViewGroup包含一些View或ViewGroup,用于控制子View的布局
View结构
UI事件
当用户通过手指触摸UI时, 系统会自动创建对应的Event对象。Android中提供了多种方式拦截处理不同类型的事件。视图本身就可以处理发生在该视图上的事件。
图中事件源表示发生事件的视图对象。事件常用的有点击、长按…等。事件监听器即new的监听器对象,常用事件监听器接口如下:
View.OnClickListener onClick()
View.OnLongClickListener onLongCLick()
View.OnTouchListener onTouch()
View.OnCreateContextMenuListener onCreateContextMenu()
View.OnFocusChangeListener onFocusChange()
View.OnKeyListener onKey()
给视图添加事件监听方式:view.seton…Listener(listener)
常用组件
简单UI组件
TextView 文本视图
EditText 可编辑视图,重要属性:hint、inputType
Button 按钮,是TextView的子类,仅多了背景图片,称多状态图片
ImageView 图片视图,重要属性:background(背景)、src(前景)
CheckBox 多选框
RadioGroup 单选择框组 父类是LinearLayout
RadioButton 单选泽框
菜单Menu
OptionMenu 在底部显示
如何触发Menu的显示?——点击menu键
如何向Menu中添加健MenuItem?——重写onCreateOptionMenu()、menu.add()或者加重菜单文件
如何在选择某个MenuItem时进行响应?——重写
onOptionsItemSelected(),根据itemId响应
ContextMenu 正中间显示
如何触发Menu的显示?
——长按某个视图,view.setOnCreateContextMenuListener(this)
如何向Menu中添加MenuItem?
——重写onCreateContextMenu,menu.add()
如何在选择某个MenuItem时进行响应?
——重写onContextItemSelected(),根据itemId响应
进度条
ProgressBar a.圆形(默认);b.水平
SeekBar
对话框
API结构 Dialog——AlertDialog——DataPickerDialog、ProgressDialog、TimePickerDialog
AlertDialog a.一般的;b.自定义布局的;c.带单选列表的
ProgressDialog 圆形进度 show();水平进度
补充注意点
模拟做一个长时间的工作不能在主线程中进行,必须启动分线程完成 new Thread(){
public void run(){
//下面的代码在分线程执行
}
}.start();
或者
new Thread(new Runnable(){
public void run(){
//下面的代码在分线程执行
}
}).start();
根据id查找View对象
a.查找当前界面中的View对象:findViewById(id)
b.查找某个View对象的子view:view.findViewById(id)
不能在分线程直接更新UI
【可通过runOnThread方法实现】。
runOnUiThread方法是在分线程中执行,但是其中的run方法在主线程执行
runOnUiThread(new Runnable() {
@Override
public void run() {
更新UI操作
}
});
dismiss()方法移除ui方法可在分线程执行,但是该方法内部使用handler实现主线程移除dialog。
常用布局
布局本身是不能显示出任何数据, 它可以包含一些子视图, 并控制子视图的布局.常用布局如下
一、LinearLayout线性布局 用来控制其子View以水平或垂直方式展开显示
二、RelativeLayout相对布局 用来控制其子View以相对定位的方式进行布局显示
三、FrameLayout帧布局 每一个子View都代表一个画面,默认以屏幕左上角作为( 0,0 )坐标,按定义的先后顺序依次逐屏显示后面出现的会覆盖前面的画面。通过子VIew的android:layout_gravity属性来指定子视图的位置
【Gravity:控制当前视图的内容或子视图与自己的关系,Layout_gravity:控制当前视图自己】
四、GridView布局
五、ListView
1.ListView理解
一种用来显示多个可滑动项(Item)列表的的ViewGroup。需要使用Adapter将集合数据和每一个Item所对应的布局动态适配到ListView中显示
显示列表: listView.setAdapter(adapter)
更新列表: adapter.notifyDataSetChanged()
Data && Item Layout——> Adapter ——>ListView
2.Adapter使用
1).ArrayAdapter:显示简单文本列表,集合数据为List或String[]
ArrayAdapter(Context context,int resource,T[]objects)
2).SimpleAdapter:显示复杂列表,集合数据必须是List<Map<String,Object>>类型。
SimpleAdapter(Context context,List<?extends Map<String,?>> data,
int resource,String[] from,int[] to)
3).BaseAdapter(抽象的):显示复杂列表,集合数据可以是任意类型的集合List
int getCount:得到集合数据的个数,决定了显示多少行
Object getItem(int position):根据position得到对应的数据对象
View getView(int position,View convertView,ViewGroup parent):根据position返回一个带数据item视图对象,
position:下标
convertView:可复用的item视图对象,可能为null,可能有值。
为null时表示没有可复用的,我们必须加装一个item的布局文件,并赋值给convertView。不为null,直接复用此视图对象。
4). SimpleCursorAdapter: 显示复杂的列表。集合数据是数据库查询结果集。
5).给ListView的Item设置监听
item的点击监听:listView.setOnItemClickListener(listener)
item的长按监听:listView.setOnItemLongClickListener(listener)
- 优化
1).内存中最多存在n+1个convertView对象
2).只有convertView为null时,才去加载item的布局文件
常用属性
通用属性
id
layout_width
layout_height
textSize
background(图片/颜色)
layout_gravity 控件本身相对于父视图的位置
gravity 指定控件中内容的基本位置
内边距padding
外边距margin 【内边距和外边距可用于所有视图】
仅针对相对布局
相对布局是最灵活, 强大,也是学习难度最大的布局。相对布局属性比较多。
兄弟视图之间: 同方向对齐, 反方向对齐
与父视图之间: 同方向对齐, 居中
1)相对于兄弟视图
同方向——align属性
反方向——to Left、Right/above/below属性
- 相对于父视图
同方向——alignParent属性
居中——centerInParent/centerVertical/centerHorizontal
仅针对线性布局
orientation
weight【要等比例划分,分谁,谁为0dp。Weight按比例即可】
详解:
layout_weight(权重)的值=0(默认值): 指定多大空间就占据多大的空间
0: 将父视图中的可用空间进行分割, 值越大权重就越大, 占据的比例就会越大
Layout_weight的使用场景:
将布局的宽度或高度平均分成几个等份;
垂直方向上占用中间所有空间 或 水平方向上占用中间所有空间;
style和Theme
style
多个视图标签属性的集合,在写布局时, 当多个视图有不少相同的属性时, 可以把这些相同的属性放在一起。
好处:复用标签属性
目标:布局文件中的视图标签
例如,在styles.xml中定义成一个Style,
而在布局文件中使用@style/style_name统一引用。例如,@style/MyStyle
系统样式:Android也定义了系统样式,可以使用系统样式: @android:style/xxx
Theme
本质也是style,在styles.xml中定义, 在manifest.xml中引用
好处:复用标签属性
目标:整个应用或者Activity,在功能清单文件中引用
系统常用主题:
@android:style/Theme.Light.NoTitleBar : 没有标题
@android:style/Theme.Light.NoTitleBar.Fullscreen: 全屏
@android:style/Theme.Dialog : 对话框
目标:整个应用或者Activity,在功能清单文件中引用
系统常用主题:
@android:style/Theme.Light.NoTitleBar : 没有标题
@android:style/Theme.Light.NoTitleBar.Fullscreen: 全屏
@android:style/Theme.Dialog : 对话框
实践问题
1、apk默认为竖屏下载时,如需修改为默认下载后界面横屏显示,操作如下:
在application标签的需要横屏的对应activity标签中增加属性设置。
<activity
android:name="com.pax.paydroid.tester.ui.PaydroidTesterActivity"
android:launchMode="singleInstance"
android:label="@string/title_activity_paydroid_tester"
android:theme="@style/PayDroidAppTheme.NoActionBar"
android:screenOrientation="portrait" <!-默认横屏显示-->
android:configChanges="mcc|mnc|orientation|screenSize|locale|layoutDirection|keyboard">
</activity>
2、apk中某个activity界面显示的内容超过设备屏幕区域,且不能滑动。可以使用ScrollView包含需要滑动的布局内容,即可滑动显示activity的内容。例如:
// 外层无ScrollView时,界面无法进行滑动显示,增加ScrollView后界面可以滑动显示
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_setting"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.pax.tcptest.SettingActivity">
<RelativeLayout
android:id="@+id/rlmobile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="6dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="6dp">
<TextView
android:id="@+id/mobile"
style="@style/title"
android:text="启动数据网络"/>
<TextView
style="@style/content"
android:layout_below="@id/mobile"
android:text="允许通过移动网络存取数据"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/mobile_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"/>
</RelativeLayout>
<View style="@style/line"/>
<LinearLayout
android:id="@+id/llip"
style="@style/container">
<TextView
style="@style/title"
android:text="IP地址"/>
<TextView
android:id="@+id/ip"
style="@style/content"
android:text="124.172.162.188"/>
</LinearLayout>
<View style="@style/line"/>
<LinearLayout
android:id="@+id/llport"
style="@style/container">
<TextView
style="@style/title"
android:text="端口"/>
<TextView
android:id="@+id/port"
style="@style/content"
android:text="60180"/>
</LinearLayout>
<View style="@style/line"/>
<RelativeLayout
android:id="@+id/rllength"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="6dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="6dp">
<TextView
android:id="@+id/len"
style="@style/title"
android:text="数据长度(Bytes,勾选为随机长度)"/>
<TextView
android:layout_below="@id/len"
android:id="@+id/length"
style="@style/content"
android:text="1024"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/random"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>