Android
一、开发环境的搭建
平台架构:Linux Kernel、Libraries、Application Framework、Applications。
Java环境、安装AndroidStudio、创建AVD(Android虚拟设备)
https://developer.android.google.cn/studio/index.html 需要科学上网。
项目结构:
manifests 是程序总配置文件
java 中是各种java代码,一个activity就是一个页面
res 中是各种资源。
二、UI
1、UI组件结构
所有UI组件都成为View,一般分为:用于显示数据的组件;用于容纳组件的组件。
2、数据单位
px 像素 对应屏幕上的实际像素点;
in 英寸 屏幕物理长度单位;
mm 毫米 屏幕物理长度单位;
pt 磅 屏幕物理长度单位;
dp 与密度无关的像素 逻辑长度单位,在160dpi屏幕上,1dp=1px=1/160英寸。随着密度变化,对应的像素数量也变化,但并没有直接的变化比例;
dip 与dp相同,多用于Google示例;
sp 与密度和字体缩放度无关的像素,与dp类似,但是可以根据用户的字体大小首选项进行缩放。
3、布局
布局为UI提供了一个可视化的结构,比如:在XML中声明UI元素;在运行时实例化布局元素。
线性布局(Linear Layout),按照水平或垂直的方向布局
相对布局(RelativeLayout),相对其他组件的布局方式
layout_above将该控件的底部置于给定ID的控件之上
layout_below将该控件的顶部置于给定ID的控件之下
layout_toLeftOf将该控件的右边缘和给定ID的控件左边缘对齐
layout_toRightOf将该控件的左边缘和给定ID的控件右边缘对齐
layout_alignBaseline将该控件的底部边缘和给定ID的控件底部边缘对齐
layout_alignLeft将该控件的左边缘和给定ID的控件左边缘对齐
layout_alignRight将该控件的右边缘和给定ID的控件右边缘对齐
layout_alignTop将该控件的顶部边缘和给定ID的控件顶部边缘对齐
表格布局(TableLayout),按行列布局
帧布局(FrameLayout),组件从屏幕的左上角坐标布局组件。添加的每个子空间都被放在布局的左上角,并覆盖在前一子控件的上层。不能为子元素指定位置。后一个子元素将会直接在前一个子元素之上进行覆盖填充,把他们部分或全部挡住(除非后一个子元素透明)
绝对布局(AbsoluteLayout),绝对布局,已被废弃
网格布局(GridLayout),相比LinearLayout布局的优点:可以同时在XY轴方向上进行对齐;可以多层布局嵌套;稳定的支持一些支持自由编辑布局的工具
三、组件
https://developer.android.google.cn/reference API参考文档
1、Toast
显示文本:提示信息——当用户执行某个操作后,自动显示,过一会儿自动消失。
Toast.makeText(context, 显示的内容, 时间的长短).show() context可以是Activity的实例或者使用getApplicationContext()得到。时间长短为:Toast.LENGTH_LONG Toast.LENGTH_SHORT
显示图片:
Toast t = new Toast(this);
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.photo4);
t.setView(imageView);
t.show();
可以加上t.setText("")进行图文显示。
2、TextView
向用户显示文本和选择性地允许编辑他。一个TextView是一个完整的文本编辑器,但是基本的类配置为不允许编辑;参考EditText配置文本试图编辑的一个子类。允许用户复制TextView价值的部分或全部粘贴在其他地方,设置XML属性android:textIsSelectable为true或者调用setTextIsSelectable(true)。
常见属性查询API文档。
3、EditText
public class EditText extends TextView
是一个非常重要的组件,可以说它是用户和Android应用进行数据传输的窗户,有了它就等于有了一扇和Android应用传输的门,通过它用户恶意爸数据传给Android应用,然后得到我们想要的数据。
EditText是TextView的子类,所以TextView的方法和特性同样存在于EditText中。
输入变化事件:addTextChangedListener(TextWatcher)
监听回车键:setOnEditorActionListener
选取文本:Editable editable = editText.getText(); Selection.setSelection(editable,1, editable.length());
4、Button
public class Button extends TextView
代表一个按钮部件,可以按下按钮,或点击,由用户来执行一个动作。
OnClickListener事件,实现View.OnClickListener接口;使用内部类;自定义方法,配置adnroid: onclick属性。
配置透明的Button:style="?android:attr/borderlessButtonStyle"
配置style:Android:background
使用XML的drawable selector
ImageButton:显示一个按钮和一个图像,可以按下或由用户点击。默认情况下,一个ImageButton看上去就像一个普通的按钮,与标准按钮背景颜色变化在不同按钮的状态。表面的按钮上的图像通过android:定义XML元素的src属性或setImageResource(int)方法。删除标准按钮背景图像,定义您自己的背景图像或设置背景颜色是透明的。显示不同的按钮状态(专注、选择等),可以定义不同的形象状态。
5、ImageView
public class ImageView extends View
显示一个任意的图像,比如一个图标。ImageView类可以加载图像从不同来源,负责计算图像的测量,这样就可以用于任何布局管理器,并提供各种显示选项(缩放,着色)
android:src:设置View的drawable(图片或者颜色,但是需要指定View的大小
android:adjustViewBounds:是否保持宽高比。需要与MaxWidth、MaxHeight一起用。
android:maxHeight:设置View的最大高度,单独使用无效。
示例:设置图片固定大小,并保持图片宽高比:
设置setAdjustViewBounds=true;
设置maxWidth、MaxHeight;
设置layout_width和layout_height=wrap_content;
android:maxWidth:设置View最大宽度。
scaleType属性:
android:scaleType设置图片的填充方式。值:
matrix 用矩阵来绘制,动态缩小放大图片来显示
fitXY 把图片不按比例扩大/缩小到View的大小显示
fitStart 把图片按比例扩大/缩小至View的宽度,显示在View的上部分位置
fitCenter 把图片按比例扩大/缩小至View的宽度,居中显示
fitEnd 把图片按比例扩大/缩小至View的宽度,显示在View的下部分位置
center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示
centerCrop 按比例扩大图片的size居中显示,使得图片长/宽等于或大于View的长/宽
centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使图片长/宽等于或小于View 的长/宽
android:tint 将图片渲染成指定颜色
6、CheckBox
public class CheckBox extends CompoundButton
复选框允许用户选择一个或多个选项从一组选项中。通常情况下,应该垂直列出表中的每个选项。
final CheckBox checkBox = (CheckBox) findViewById(R.id.checkbox_id);
if (checkBox.isChecked()){ checkBox.setChecked(false);}
需要实现(implements)CompoundButton.OnCheckedChangeListener接口。
一组复选框允许用户选择多个项目,每个复选框是分开管理的,必须为每个复选框注册监听事件。
即onClick属性。
7、RadioButton
单选按钮允许用户从一组选项中选择一个。
创建每个单选按钮选项,创建一个RadioButton在你的布局。然而,由于单选按钮是相互排斥的,必须使用RadioGroup将他们分组。
触发事件:onRadioButtonClicked
8、ToggleButton
一个切换按钮允许用户改变两国之间的设置。
你可以添加一个基本的开关按钮布局与toggleButton对象。
ToggleButton和开关控制的子类CompoundButton和功能以同样的方式,这样你就可以实现他们的行为一样。
使用CompoundButton.OnCheckedChangeListener.
switch为新增的开关按钮。
9、RatingBar
基于SeekBar和ProgressBar的扩展,用星级来显示等级评定。使用RatingBar的默认大小时,用户可以触摸/拖动或使用键来设置评分,有两种央视(小风格ratingBarStyleSmall,大风歌ratingBarStyleIndicator),大的适合指示,不适用于用户交互。
当使用可以支持用户交互的RatingBar时,无论将控件(widgets)放在左边还是右边都不合适。只有当布局的宽被设置为wrap_content时,设置的星星数量(setNumStars(int)或者在XML的布局文件中定义)将显示出来。
事件处理:RatingBar.OnRatingBarChangeListener。回调函数,星级进度改变时修改客户端的星级。
XML属性中android:isIndicator,表示RatingBar是否是一个指示器(是否可以更改)
android:numStars星星数量。
android:rating默认评分,必须是浮点类型
android:stepSize评分的步长,也必须是浮点类型。
10、Spinner
提供一个快速的方法从一组选择一个值。默认状态下显示当前选择的值,触摸显示下拉列表。
通过创建数组适配器来控制下拉列表。
适配器构造方法有两种:(上下文,下拉列表里的布局,显示的组件ID,数据)/(上下文,数据,布局)
通过adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)设置每个下拉选项的视图
通过spinner.setAdapter(adapter)添加适配器
11、AutoCompleteTextView
如果想为用户提供建议类型,可以使用EditText的子类AutoCompleteTextView。为了实现自动完成,必须制定一个(@link android.widget.Adapter)提供建议的文本。有几个可用的适配器类型,根据数据来自哪里。
12、ProgressBar
进度条
java.lang.Object
android.view.View
android.widget.ProgerssBar
在某些操作的进度中的可视显示器,为用户呈现操作的进度,还有一个次要的进度条,用来显示中间的进度,比如流媒体播放的缓冲区速度。一个进度条也可以不确定进度。不确定模式下显示循环动画。通常用于任务长度未知。进度条即一个表示运转的过程。
展示方式有两种:表盘形式,条形填充形式。
重要属性:max(最大值)、progress(当前进度值)、secondaryProgress(第二条进度值)、progressBarStyle(默认样式)、progressBarStyleHorizontal(水平)
重要方法:getMax() 返回范围上限;getProgress() 返回当前进度值;getSecondaryProgress() 返回次要进度值,incrementProgressBy(in diff) 指定增加的进度,即步长;isIndeterminate() 指示进度是否在不确定模式下;setIndeterminate(boolean indeterminate) 设置不确定模式;setVisibility(int v) 设置是否可视
对话框进度条
ProgressDialog
标题进度条
在setContentView方法之前设置:requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
然后使用setProgressBarIndeterminateVisibility(true);显示标题进度条
自定义进度条
在res/drawable/下创建一个layer-list,设置ProgressBar的android:indeterminateDrawable属性
13、AlertDialog
对话框(Dialog)。
需求背景:在Android界面弹出对话框,询问用户或让用户选择。
AlertDialog.Builder builder = new AlertDialog.Builder(this);
setTitle("提示"); setMessage("内容"); setIcon(R.mipmap.ic_lanuncher); builder.show();生效
// 正面的按钮
builder.setPositiveButton("是", new DialogInterface.OnClickListener(){ @Override onClick事件});
// 反面按钮
builder.setNegativeButton();
// 中立按钮
builder.setNeuteralButton()
列表对话框
setItems(items, new DialogInterface.OnClickListener(){ });设置多个选项。
多选列表对话框
setMultiChoiceItems(items, boolean[] checkItems, new DialogInterface.OnMultiChoiceClickListener(){ });
多项单选列表对话框
setSingleChoice(items, int checkedItem, new DialogInterface.OnClickListener(){ })
自定义对话框
嵌套一个新的布局:setView(R.layout.layout_name);(android5.0之后支持)
需要实例化布局文件:final View view = getLayoutInflater().inflate(R.layout.login_layout, null);
14、TimePickerDialog
需要继承DialogFragment,实现TimePickerDialog.OnTimeSetListener接口。重写onCreateDialog方法,返回一个TimePickerDialog对象。
15、DatePickerDialog
时间选择对话框。创建类继承DialogFragment。重写onCreateDialog()方法,返回一个TimePickerDialog对象。实现DatePickerDialog的OnDateSetListener接口来接受一个回调,设置日期。
16、TimePicker
时间控件
17、DatePicker
日期控件
四、高级组件
1、GridView
用来以网格方式排列视图,与矩阵类似,当屏幕上有很多元素(文字、图片或其他元素)需要显示时,可以使用该组件。
numColumns="auto_fit" GridView的列数设置为自动
columnWidth="90dp" 每列的宽度,也就是Item的宽度
stretMode="columnWidth" 缩放于列宽大小同步
verticalSpacing="10dp" 两行之间的边距
horizontalSpacing="10dp" 两列之间的边距
自定义适配器:
创建一个类,继承BaseAdapter类
实现四个方法:
getCount()获取要显示的选项总数
getItem()获取每一个选项
getItemId()获取选项ID
getView()该方法用来为每一个选项生成视图(ImageView等),会被多次调用。
图文排列
需要一个新建布局将图文合并,然后实例化布局得到一个view再放入GridView。
2、ListView
列表视图以垂直列表的凡事列出需要显示的列表项。
常用XML属性
cacheColorHint="#00000000" 设置拖动背景色为透明
dividerHeight="30px" listview的item之间的高度
divider="@drawable/ic_launcher" listview的item之间的北京或者说是颜色
fadingEdge="vertical" 上边和下边有黑色的阴阳,值为none的话就没有阴影
drawSelecotOnTop="false" 点击某条记录不妨,颜色会在记录的后面,成为背景色
scrollbars="horizontal | none" 只有值为horizontal|vertical的时候,才会显示滚动条,并且会自动隐藏和显示
fastScrollEnabled="true" 快速滚动效果,配置这个属性,在快速滚动的时候旁边会出现一个小方块的快速滚动效果,自动显示和隐藏
listSelector="@color/pink" listView的item选中时的颜色
entries="@array/citys" 设置列表填充的内容
ListActivity
public class ListActivity extends Activity
提供了一个列表项的视图来显示数据,可以绑定指定的数据源,比如数据或数据库游标,给用户提供一种选项选择。
布局默认是由一个单一的在屏幕中心的全屏幕的列表,用setcontentview()在oncreate()设置您自己的自定义屏幕布局视图布局,必须包含一个列表视图的对象ID:"@android:id/list"
可选:您的自定义视图可以包含任何类型,显示另一个视图对象列表视图是空的,必须包含一个视图对象的ID:android:id/empty
onListItemClick是事件处理。
单选和多选模式
单选:ArrayAdapter<String> aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, arr);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); lv.setAdapter(aa);
多选:ArrayAdapter<String> aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, arr);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); lv.setAdapter(aa);
ListView实现图文列表
使用SimpleAdapter建立复杂的列表项:
SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
运行环境,Map组成的List。在列表中的每个条目对应列表中的一行,每一个map中应该包含所有在from参数中指定的键,一个定义列表项的布局文件的资源ID。布局文件将至少应包含那些在to中定义的ID,一个将被添加到Map映射上的键名,将绑定数据的视图的ID。跟from参数对应。这些应该全是TextView
使用BaseAdapter实现更灵活的列表:
实现复杂的列表布局,由于BaseAdapter是一个抽象类,使用该类需要自己写一个适配器继承该类。依然需要实现四个方法。
优化:
使用ListView的宽高固定,避免内容变化导致ListView重新渲染;重复使用convertView;使用ViewHolder提高在容器中查找组件的效率(用于保存第一查找的组件,避免下次重复查找)。
ListView刷新分页
当前Activity implements OnScrollListener
实现接口的方法
listView注册滚动监听
Adapter中添加增加数据的函数
获得2页以后的数据后,adapter增加数据,并刷新。notifyDataSetChanged();
3、ExpandableListView
一个视图显示垂直滚动两集列表中的条目。不同于列表,允许两个层次:组织单独可以扩展为显示其子项。
比如在手机设置中,对于分类有很好的效果。
整体思路:
要给ExpandableListView设置适配器,那么必须先设置数据源。
数据源,就是此处的适配器类ExpandableAdapter,此方法继承了BaseExpandableListAdapter,它是ExpandableListView的一个子类。需要重写多个方法。
数据源中用到了自定义的View布局,此时根据需求,来设置组和子项的布局样式。getChildView()和getGroupView()方法设置自定义布局。
数据源设置好,直接给ExpandableListView.setAdapter()即可实现收缩功能。
4、ImageSwitcher TextSwitcher
是Android中控制图片展示效果的一个控件,如幻灯片效果。粗略理解就是ImageView的选择器。
原理:ImageSwitcher有两个子View:ImageView,当左右滑动的时候,就在这两个ImageView之间来回切换以显示图片。
创建ImageSwitcher是通过工厂实现的:ViewFactory。(implements ViewSwitcher.ViewFactory)重写其makeVIew方法。
本身还需要implements View.OnTouchListener,重写onTouch方法(触屏事件)。
TextSwitcher与ImageSwitcher一样。
5、ViewFlipper
屏幕切换指的是在同一个Activity内屏幕间的切换,最常见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面;一个个性化设置页面。
ViewFlipper extends ViewAnimator
java.lang.Object
android.view.View
android.view.ViewGroup
android.widget.FrameLayout
android.widget.ViewAnimator
android.widget.ViewFlipper
简单的ViewANimator之间,两个或两个以上的view加上动画效果
一个时间只有一个子组件
如果需要,每个自组件能自动翻转之间在固定的时间间隔
该类继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果。
和动画相关的函数:
setInAnimation:设置View进入屏幕时候使用的动画,有两个版本,一个接受单个参数(android.view.animation.Animation),另一个接受两个参数(Context, int)分别为Context对象和定义Animation的resourceID。
setOutAnimation:设置View退出屏幕时候使用的动画,参数同上
showNext:调用该函数来显示FrameLayout里面的下一个View
showPrevious:调用该函数来显示FrameLayout里面的上一个View
定义四个动画:
in_leftright.xml左到右进入屏幕、out_leftright.xml左到右退出屏幕、in_rightleft.xml右到左进入屏幕、out_rightleft.xml右到左退出屏幕。直接在res中添加目录存放。其中使用translate(移动)控件,需要的属性为:xmlns:android="http://schemas.android.com/apk/res/android"、android:duration="3000"(时间)、android:fromXDelta="-100%p"(从哪儿)、android:toXDelta="0"(到哪儿)。
6、Menu
Options menu and action bar
选项菜单,创建步骤:覆盖Activity的onCreateOptionMenu(Menu menu)方法,当菜单第一次被打开时调用;调用Menu的add()方法添加菜单项(MenuItem),同时可以调用MenuItem的setIcon()方法来为菜单项设置图标;当菜单项(MenuItem)被选择时,覆盖Activity的onOptionsItemSelected(MenuItem item)来响应事件。
可以直接代码设置菜单项,也可以直接通过xml布局文件(配置文件)设置。
Context menu
上下文菜单,与上下文环境有关。思想类似于Windows中的右键单击弹出的快捷菜单。操作时要长时间按住某个控件不放。创建步骤:覆盖Activity的onCreateContextMenu(Menu menu)方法,调用Menu的add()方法添加菜单项;覆盖Activity的onContextItemSelected(MenuItem item)来响应事件;调用registerForContextMenu()方法来为视图注册上下文菜单。
Popup menu
弹出式菜单,是停靠在一个View上的一个模式菜单。如果View对象下方有空间,那么弹出菜单将显示在停靠对象的下方,否则会显示在上方。在API级别11和更高版本上才有效。
7、ViewPager
是谷歌官方提供的一个兼容低版本安卓设备的软件包,里面包含了安卓3.0以上可以使用的api。而Viewpager就是其中之一。从简单的导航到页面菜单等一应俱全。使用时需要PagerAdapter适配器。
使用ViewPager实现页面切换
ViewPager可以使视图滑动,分三个步骤:在布局文件中加入一些配置;加载要显示的页卡;在Activity里实例化ViewPager组件,并设置他的Adapter(就是PagerADapter,方法与ListView一样的)。
实现一个PagerAdapter,覆盖以下方法:
instantiateItem(ViewGroup, int) 实例化页卡
destroyItem(ViewGroup, int, Object) 删除页卡
getCount() 返回页卡数量
isViewFromObject(View, Objcet) 判断两个对象是否相等
getPageTitle(int position) 设置标签显示的标题
设置指示标签的属性
pagerTabStrip.setTabIndicatorColor() 指示器的颜色
pagerTabStrip.setBackgroudColor() 背影色
pagerTabStrip.setTextColor(Color.WHITE) 字体颜色
//需要加入的配置
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<android.support.v4.view.PagerTabStrip
android:id="@+id/pagertab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
/**
*注意:
*这里ViewPager和PagerTabStrip都要吧包名写全,不然会ClassNotFound
*API中:在布局xml吧PagerTabStrip当作ViewPager的一个子标签来用,不能拿出来,否则会报错
*在PagerTabStrip标签中可以用属性android:layout_gravity=TOP|BOTTOM来指定title的位置
*如果要显示出PagerTabStrip某一页的title,需要在ViewPager的adapter中实现getPageTitle(int)
*方法。
*/
//加载页卡
LayoutInflater lf = getLayoutInflater().from(this)
view1 = lf.inflate(R.layout.layout1, null)
view2 = lf.inflate(R.layout.layout2, null)
view3 = lf.inflate(R.layout.layout3, null)
viweList = new ArrayList<View>();
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
程序首次启动的引导页实现
8、PopupWindow
Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:AlertDialog的位置固定,而PopupWindow的位置可以随意。按照位置有无偏移氛围偏移和无偏移;按照参照物的不同,可以分为相对于某个控件和相对于父控件。
showAsDropDown(View anchor) 相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff) 相对某个空间的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y) 相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移。
创建PopupWindow
contentView 指定PopupWindow的内容;width指定PopupWindow的width;height指定PopupWindow的height;
PopupWindow mPopupWindow = new PopupWindow(popupWindow, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
设置相关属性:
mPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_black));
mPopupWindow.getBackgound().setAlpha(100);
mPopupWindow.setAnimationStyle(R.style.popwin_anim_style); 设置动画效果
设置点击窗口外边窗口消失
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);
mPopupWindow.setTouchable(true);
防止虚拟软键盘被弹出菜单遮住
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
显示和关闭PopupWindow
显示弹窗:
mPopupWindow.showAsDropDown(v); 相对某个控件的位置(正左下方),无偏移
mPopupWindow.showAsDropDown(v, 50, 50); xy方向各偏移50
mPopupWindow.showAtLocation(v, Gravity.CENTER, 0, 0); 相对于父控件的位置,无偏移
mPopupWindow.showAtLoaction(v, Gravity.BOTTON, 0, 50; 相对于父控件的位置,有偏移
关闭弹窗:
mPopupWindow.dismiss()
获取设备屏幕尺寸
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
mScreenHeight = dm.heightPixels;
mScreenWidth = dm.widthPixels;
9、Notification
实在你的应用常规界面之外展示的消息。当app让系统发送一个消息的时候,消息首先以图标的形式显示在通知栏。要查看消息的详情需要进入通知抽屉(notificationdrawer)中查看。通知栏和通知抽屉都是系统层面控制的,可以随时查看,不限制于app。
Notification作为UI中很重要的组成部分,拥有自己专属的设计准则。
有两种显示方式,取决于android版本以及notification drawer的状态:
普通视图:是标准显示方式
notification最高64dp,即使创建了宽视图风格的,在未展开的情况下也是以普通大小显示出来。由:标题、大图标、通知内容、通知数据、小图标、发布时间组成。可以调用setWhen()设置一个明确的时间。默认是系统收到通知的时间。
宽式图:指你的notification被展开时会显示更大的视图,这种风格是android4.1之后才有的新特性。
只有当notification被展开的时候这种宽视图的才会出现,通过手势操作可以展开一个普通的notification(如果能展开的话)。这种风格的notification从android4.1后才开始支持。只比普通视图多了 详情区域 。
宽视图氛围:大图标风格(详情区显示一个最高256dp的bitmap)、文字风格(详情区显示一段文字)、消息盒子风格(显示几行文字)。
创建Notification
将notification的一些UI信息以及相关动作赋予NotificationCompat.Builder对象,然后通过NotificationCompat.Builder.build()来获得notification对象自己;然后调用NotificationManager.notify()向系统转交这个通知。一个对象需要包含如下内容:小图标(setSmallIcon()获取)标题(setContentTitle()获取)详情文字(setContentText()获取)除此之外,其余内容可选。
要活的一个能展开的宽视图掩饰的通知首先创建一个普通的builder对象,然后调用Builder.setStyle()。
管理Notifications
当需要多次发出通知对于相同类型的时间,你应该避免使一个全新的通知。相反,应该考虑更新之前的通知,通过改变它的一些值或者通过添加,或者两者都有。
通过调用NotificationManager.notify(ID, notification)时所使用的ID来更新它。为了更新你之前发布的通知,需要更新或者创建一个NotificationCompat.Builder对象,从之前的通知中创建一个Notification对象,然后发布它使用你之前使用的ID。如果之前的通知仍然可见,系统将直接更新通知的内容,如果不可见,一条新的通知将被创建。
通知会一直存在,直到:用户手动一条一条清除通知,或者使用清除所有;用户点击通知,且创建这条通知时使用了setAutoCancle();为一个指定ID的通知调用了cancel();调用了cancelAll()方法。
动作与行为(可选)
至少添加一种行为:允许用户通过点击notification进入一个activity中进行更多的查看或者后续操作。一个通知可以提供多种动作,而且也应该让用户点击一个通知之后总能有相应的相应动作,通常是打开一个activity。还可以在通知中添加能响应点击事件的button。
在通知内部,一个动作本身是被定义在一个PendingIntent中,PendingIntent包含了一个用于启动app中activity的intent。要将PendingIntent和一个手势联系起来,需要调用合适的NotificationCompat.Builder方法。比如你想在点击notification文字的时候启动activity,你需要调用NotificationCompat.Builder的setContentIntent()来添加PendingIntent。启动一个activity是notification动作响应中最普遍的一类。
显示进度通知
通知可以包含一个动态的进度指示器,用来显示当前操作的进度。如果你能估计这个操作总共有多久,以及任何时间点上的完成度,那么你可以用一个“确定”格式的指示器(进度条)。如果没法估计操作的长度,用“不确定”格式的指示器。进度条指示器是实现了ProgressBar来执行显示的。调用setProgress()方法来使用进度条指示器开始于Android4.0。在之前的版本,你必须创建自己的通知布局来包含ProgressBar视图。
显示一个已知长度的进度条指示器:通过调用setProgress() setProgerss(max, progress, false)给你的通知加上进度条。然后发布通知。然后随着操作的进度,增加进度值,然后更新通知。操作结束的时候,进度值应该等于最大值。通常的方式是调用setProgress()来设置最大值为100,然后增加进度完成的百分比。
可以在操作完成的时候显示进度条,也可以移除掉。这样的情况下,需要更新通知的文本,显示操作已经完成。调用setProgress(0,0,false)来移除进度条。
显示一个持续的活动指示器:使用setProgress(0,0,true)方法来给你的通知添加不确定的活动指示器,然后发布通知。除非指定动画效果,否则指示器的样式都一样。
操作开始的时候发布通知,这个动画将一直执行,直到你修改通知,操作完成的时候,调用setProgress(0,0,false)来更新通知区一处活动指示器。除非想让操作完成时动画效果还在继续。当操作完成时更新通知里的文本。
自定义通知视图
通过RemoteViews对象来定义通知的外观。与常规通知相似,但是基于定义在XML文件的RemoteViews对象来操作的。
自定义通知的可用高度是取决于通知视图的。正常的视图布局高度限制在64dp,可展开视图的布局高度限制在256dp。
为了定义自己的通知布局,从扩充XML文件获取一个RemoteViews对象的实例开始。然后类似于调用setContentTitle()方法一样。我们需要调用setContent()。为了能设置更多细节,使用RemoteViews对象的方法来设置更多内容。
创建一个单独的XML文件,用来定义通知的布局,可以使用任何想用的名字,但后缀必须是.xml;在应用中,使用RemoteViews对象的方法来给你的通知设置文本和图标,通过diaoyongsetContent()把你的RemoteViews对象放到NotificationCompat.Builder里面。避免使用背景图像,因为文本会受影响。
RemoteViews对象页包含一些方法来给你添加Chronometer和ProgressBar。
注意:使用自定义的通知条时,特别要注意你自定义的通知条在不同方向与分辨率的设备上是如何工作的。不要吧通知条做的太复杂,确保它的灵活性。
为自定义的通知文本使用样式资源:自定义通知条总是使用样式资源定义文本。通知的背景颜色会变得与设备当前版本的android有很大的反差。使用样式文本能很好的解决。
注意:Notification的自定义布局是RemoteViews,和其他RemoteViews一样,自定义视图布局文件中,仅支持FrameLayout、LinearLayout、RelativeLayout三种布局控件和AnalogClock、Chronometer、Button、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView和AdapterViewFlipper这些显示控件,不支持这些类的子类或Android提供的其他控件,否则会引起ClassNotFoundException一场。带按钮的布局相应点击事件在3.0以下版本不起作用。
10、样式和主题
样式
是给View或Window指定外观和格式的属性集合。样式能够指定高、边距、字体颜色、字体尺寸、背景颜色等属性。样式被定义在一个与布局xml文件分开的xml资源文件中。Android中的样式与web设计中的层叠式样式表类似,允许与内容分开设置。
使用掩饰属性:style="@style/CodeFont"
定义样式要创建一个样式集,就要把一个XML文件保存在项目目录中的res/values目录中。XML文件的名字是随意的。但必须用.xml扩展名,并且保存在res/values文件夹中,根结点必须是<resources>
对于要创建的每个样式,都要在这个XML文件中添加一个<style>元素,并用name属性唯一的标识这个样式,然后给样式的每个属性添加一个<item>元素,这个元素的name属性用于声明样式的属性名,属性值被放在一组<item>之间。给<item>元素的值能够是字符串、十六进制颜色、另一个资源类型的引用、依赖样式属性的其他值。
<resources>元素的每个子元素在编译时都要被转换成一个应用程序资源对象,通过<style>元素的name属性值来引用。<style>元素中的parent属性是可选的,它指定了另一个样式的资源ID,当前样式可以继承这个指定样式的属性,然后如果需要,可以覆写被继承的样式属性。把XML中定义的一个样式用作一个Activity或应用程序的主题与给一个View对象定义样式完全相同。
样式继承性
<style>元素中的parent属性可以继承一个既存的样式属性,然后只定义需要改变和添加的属性。你能够继承自己定义的样式,也可以继承平台内置的样式。如果想要继承自己定义的样式,就不必使用parent属性,但是要把想要继承的样式名做新样式名的前缀。
主题
是应用于整个Activity或应用程序的样式,而不是一个独立的View对象。当一个样式被用作主题时,Activity或应用程序中的每个View对象都会使用它所支持的每个样式属性。
11、自定义组件
用于构建更复杂的UI视图
自定义组件的三种方式:
组合现有的Android默认提供的组件:继承ViewGroup或其子类Layout类等布局类进行组合;
调整现有Android默认提供的组件:继承View的子类具体类;
完全自定义组件:继承View基类,里面界面及事件完全由自己控制。
实现自定义组件
配合XML属性资源文件方式:
第一步:attrs.xml文件。首先写出自定义组件的类文件,然后将这个类里需要外界传入值的属性定义成一个属性资源文件。在工程里的../res/values/目录下创建一个attrs.xml文件。
//attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView">
<attr name="textColor" format="color"></attr>
<attr name="textSize" format="dimension"></attr>
<attr name="text" format="string"></attr>
</declare-styleable>
</resources>
其中attr子元素:
定义具体的属性,format表示这个属性的值的类型,类型如下:
reserence:参考指定Theme中资源ID,这个类型的意思就是你传的值可以使引用资源
string:字符串,如果想可以直接写也可以用"@string/test"应用资源的方式,可以写成format="string|reference"
Color:颜色
boolean:
dimension:尺寸值
float
integer
fraction:百分数
enum:枚举
flag:位或运算
declare-styleable子元素
定义一个styleable对象,每个styleable对象就是一组attr属性的集合,注意这里的name属性并不是一定要和自定义雷鸣相同,只是为了好区分对应类的属性而已
上面的属性资源文件定义了该属性之后,到底是那个自定义View组件中来使用的属性,属性到底能发挥什么作用,就不归属性资源文件关了。属性资源所定义的属性到底可以返回什么作用,取决于自定义组件的代码实现。
第二步:在自定义类里引用attrs文件里定义的属性为自己的属性设置值
第三步:使用自定义组件,并设置属性
ScrollView嵌套ListView、GridView的冲突
重写onMeasure方法达到使ListView适应ScrollView的效果。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}