关于Android开发的笔记【持续更新中】
Android开发
Android开发基于 xml 和 Java 实现,xml进行图形化的展示,java用于事务的处理,以及监听事件,进行图形化界面的改变
第一章、Android 项目初认识
一、Android项目的目录结构
第二章、基础方法、属性
一、布局
1. 常见布局
在Android中提供了几个常用布局:
- LinearLayout 线性布局
- 指子控件以水平或垂直方式排列,正如其名字一样,这个布局中的所有控件在线性方向上依次排列。
- RelativeLayout 相对布局
- 相对布局 RelativeLayout 允许子元素指定它们相对于其父元素或兄弟元素的位置。
- FrameLayout 帧布局
- 所有放在布局里的控件,都按照层次堆叠在屏幕的左上角。后加进来的控件覆盖前面的控件。
- 默认所有的控件都是左上对齐。控件可以通过android:layout_gravity属性控制自己在父控件中的位置。
- AbsoluteLayout 绝对布局
- 通过自己设定的绝对位置而进行物体位置的设置
- 一般很少会使用此布局:
- 开发的应用需要在很多的机型上面进行一个适配,当机型的尺寸不一样时,就可能出现偏移和变形。
- TableLayout 表格布局
- 它是由多个TableRow对象组成,每个TableRow可以有0个或多个单元格,每个单元格就是一个View。这些TableRow,单元格不能设置layout_width,宽度默认是fill_parent的,只有高度layout_height可以自定义,默认是wrap_content。
- 单元格可以为empty,并且通过android:layout_column可以设置index值实现跳开某些单元格。在TableRow之间
- 添加View,设置layout_height以及背景色,就可以实现一条间隔线。android:layout_span可以设置合并几个单元格;
- GridLayout 网格布局
- 网格布局管理器。它以矩形网格形式对容器的组件进行布置,把容器按行列分成大小相等的矩形网格,一个网格中放置一个组件,组件宽高自动撑满网格。
属性 | 作用 |
---|---|
android:columnCount | 最大列数 |
android:rowCount | 最大行数 |
android:orientationGridLayout | 中子元素的布局方向 |
android:alignmentModealignBounds | 对齐子视图边界 alignMargins :对齐子视距内容,默认值 |
android:columnOrderPreserved | 使列边界显示的顺序和列索引的顺序相同,默认是true |
android:rowOrderPreserved | 使行边界显示的顺序和行索引的顺序相同,默认是true |
android:useDefaultMargins | 没有指定视图的布局参数时使用默认的边距,默认值是false |
android:layout_column | 指定该单元格在第几列显示 |
android:layout_row | 指定该单元格在第几行显示 |
android:layout_columnSpan | 指定该单元格占据的列数 |
android:layout_rowSpan | 指定该单元格占据的行数 |
android:layout_gravity | 指定该单元格在容器中的位置 |
android:layout_columnWeight | (API21加入)列权重 |
android:layout_rowWeight | (API21加入) 行权重 |
android:layout_gravity的值
android:layout_gravity | 作用 |
---|---|
center | 不改变元素的大小,仅居中 |
center_horizontal | 不改变大小,水平居中 |
center_vertical | 不改变大小,垂直居中 |
top | 不改变大小,置于顶部 |
left | 不改变大小,置于左边 |
bottom | 不改变大小,置于底部 |
right | 不改变大小,置于右边 |
start | 不改变大小,根据系统语言,置于开始位置 |
end | 不改变大小,置于结尾 |
fill | 拉伸元素控件,填满其应该所占的格子 |
fill_vertical | 仅垂直方向上拉伸填充 |
fill_horizontal | 仅水平方向上拉伸填充 |
clip_vertical | 垂直方向上裁剪元素,仅当元素大小超过格子的空间时 |
clip_horizontal | 水平方向上裁剪元素,仅当元素大小超过格子的空间时 |
注意:
使用layout_columnSpan
、layout_rowSpan
时要加上layout_gravity
属性,否则没有效果;另外item在边缘时宽高计算会出现错误,需要我们手动设置宽高,否则达不到想要的效果
二、常用的基本控件
-
TextView
-
文本控件,它主要是为了显示一些文本信息。
-
对文本进行处理的方法:
// 获取文本对象 TextView textView = findViewById(R.id.info_text); // 使文本变成可修改样式的字符串 Spannable s = (Spannable) textView.getText(); // 获取一个加粗效果的样式 StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); // 对文本设置加粗;第一个参数:样式;第二个参数:应用的样式开始的位置;第三个参数:应用的样式结束的位置;第四个参数:指明前两个数字的含义; s.setSpan(boldSpan, 0, 4, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
android:autoLink="" // 可以用来设置自动识别文字内容(如果值为web,则会点击改文字会自动跳转到链接所指目标网址)
-
-
ImageView
-
显示图片的控件,图片可以是网络图片,可以是资源文件图片,所谓资源文件图片,就是你把图片复制到项目的drawable或者是mipmap中来引用。
-
根据不同的行为,切换不同的图片(xml文件实现方式)
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 当点击时触发 --> <item android:state_pressed="true" android:drawable="@drawable/picture1"/> <!-- 当聚焦时触发 --> <item android:state_focused="true" android:drawable="@drawable/picture2"/> <!-- 默认 --> <item android:drawable="@drawable/picture3"/> </selector>
需要在显示的xml文件中引用改配置文件
-
通过代码方法进行实现(java文件实现方式)
/*通过代码,设置按钮状态*/ public stateListDrawable setbg(){ // 获取绘制状态列表 StateListDrawable bg = new StateListDrawable(); // 得到将要更换的图片 Drawable normal = this.getResources().getDrawable(R.drawable.picture1); Drawable selected = this.getResources().getDrawable(R.drawable.picture2); Drawable pressed = this.getResources( ).getDrawable(R.drawable.picture3); //View.PRESSED_ENABLED_STATE_SET // 设置响应状态的显示文件 bg .addState(new int[] { android.R.attr.state_pressed,android.R.attr.state enabLed ]}, pressed); // View.ENABLED_FOCUSED_STATE_SET bg.addState(new int[] { android.R.attr.state_enabled,android.R.attr.state_focused }, selected); // View.ENABLED_STATE_SET bg.addstate(new int[] i android.R.attr.state_enabled }, normal); // view.FOCUSED_STATE_SET bg.addState(new int[] { android.R.attr.state_focused }, selected); // view.EMPTY_STATE_SET // 默认状态时 bg.addstate(new int[] i,normal ); return bg; }
-
ImageView属性的设置:
android:maxHeight 设置lmageView的最大高度 android:maxWidth 设置lmageView的最大宽度 android:src 设置lmageView所显示的Drawable对象的ID android:scaleType 设置所显示的图片如何缩放或移动以适应lmageView的大小 android:adjustViewBounds 设置lmageView是否调整自己的边界来保持所显示图片的长宽比 -
android:scaleType属性,有如下属性值可以选择:
atrix 从左上角开始绘制图片,超过imageView的部分裁掉 tXY 缩放图片,不保持纵横比 tStart 保持纵横比缩放图片,并且将图片放在lmageView的左上角。 tCenter 保持纵横比缩放图片,缩放完成后将图片放在lmageView的中央。fitEnd:保持纵横比缩放图片,缩放完成后将图片放在lmageView的右下角。center:把图片放在lmageView的中央,但是不进行任何缩放,大图片裁剪。 nterCrop 保持纵横比缩放图片,以使图片能完全覆盖ImageView,居中显示裁掉图片多余部分 nterInside 大图片保持纵横比缩放后居中,小图片不缩放直接居中
-
-
-
Button
- 普通的,未经修改样式的按钮
-
按钮控件,可以对其设置属性来改变样式。
android:drawableLeft=""可以为其左边添加一张图片
-
在按钮的左侧添加图片后
-
- 普通的,未经修改样式的按钮
-
ImageButton
- 图片按钮组件
-
ToggleButton
-
按钮组件可以为其设置开关时显示的文字
android:textOn=“开”;当按钮点开时,文字显示为开
android:textOff=“关”;当按钮关闭时,文字显示为关
-
-
Switch
- 按钮组件
- 按钮组件
-
RadioGroup
- 单选按钮组件
- 实现RadioButton需要一个RadioGroup是单选组合框多个RadioButton
- RadioButton的事件处理:
- setOnCheckedChangeListener()方法注册单选按钮的监听器
- 采用控件相对应的两个事件监听器RadioGroup.OnCheckedChangeListener和View.OnClickListener来处理对RadioGroup和RadioButton的事件也可以采用在XML布局文件中指定处理方法的方式
- 对应监听的实现:
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { RadioButton r = findViewById(checkedId); // 编写相应的事件处理 } });
-
CheckBox
- 复选按钮,可以进行多选的按钮,默认以矩形表示。.与RadioButton相同,它也有选中或者不选中双状态。
- 先在布局文件中定义多选按钮,然后对每一个多选按钮进行事件监听setOnCheckedChangeListener,通过isChecked来判断选项是否被选中,作出相应的事件响应。
// 主提交按钮 buttonSumbit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (button.isChecked()) { // 编写相应的事件处理 } } });
-
Toast
-
Toast通知是在窗口表面弹出的一个简短的小消息,只填充消息所需要的空间,并且用户当前的Activity依然保持可见性和交互性。
-
Toast是一个在屏幕上显示片刻的提示消息,但是Toast不能获得焦点,不能够与用户进行交互。
-
标准的Toast通知水平居中显示在屏幕底部附近。
-
Toast的样式设置
-
默认样式
Toast // 参数一:显示的上下文;参数二:显示的内容;参数三:显示的时间长短 // getApplicationContext()方法表示得到当前应用程序的上下文 .makeText(getApplicationContext(), "默认的Toast样式", Toast.LENGTH_SHORT) .show(); // 进行显示
-
自定义位置显示样式
toast = Toast.makeText(getApplicationContext(), "自定义位置的Toast样式", Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); // 设置位置;参数一:常量设置其大概位置;参数二:相对于x轴的偏移量;参数三:相对于y轴的偏移量; toast.show();
-
Toast中携带图片
toast = Toast.makeText(getApplicationContext(), "带图片的Toast样式", Toast.LENGTH_SHORT); // 获取当前布局 LinearLayout toastView = (LinearLayout) toast.getView(); // 添加一个ImageView组件,使其放置到将要显示的布局中去 ImageView imageCodeProject = new ImageView(getApplicationContext()); // 将图片资源添加到ImageView组件中 imageCodeProject.setImageResource(R.drawable.picture); // 将ImageView组件防止到将要显示的布局中去 toastView.addView(imageCodeProject); // 设置显示位置 toast.setGravity(Gravity.CENTER, 0, 0); toast.show();
-
完全自定义的Toast
- 新建一个xml(custom.xml)文件
<?xml version="1.0" encoding="utf-8"?> <!-- 线性布局,为其设置id属性,方便以后进行对其操作 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llToast" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#755757"> <!-- 标题信息 --> <TextView android:id="@+id/tvTitleToast" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1dp" android:gravity="center" android:textColor="#eee"/> <!-- 此用来存放显示的图片以及文字内容 --> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:layout_marginLeft="1dp" android:layout_marginRight="1dp" android:background="#aaa" android:orientation="vertical" android:padding="15dp"> <ImageView android:id="@+id/tvImageToast" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> <TextView android:id="@+id/tvText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:textColor="#f000"/> </LinearLayout> </LinearLayout>
- 在java文件中
// 得到填充器,进行内容的填充 LayoutInflater inflater = getLayoutInflater(); // 参数一:填充要设定的文件(即上面所写的xml文件),参数二:根节点,整个布局里面的根节点 View layout = inflater.inflate(R.layout.custom, (ViewGroup) findViewById(R.id.llToast)); // 获取布局中定义的标题TextVIew组件,并将其填充文字 TextView title = layout.findViewById(R.id.tvTitleToast); title.setText("Attention"); // 获取ImageView组件,进行设置其图片路径 ImageView image = layout.findViewById(R.id.tvImageToast); image.setImageResource(R.drawable.picture); // 获取TextView组件,进行填充文字 TextView text = layout.findViewById(R.id.tvText); text.setText("完全自定义的Toast"); // 进行Toast的设定 Toast toast = new Toast(getApplicationContext()); // 设置Toast的位置,第一个参数可以有多个,同时起作用 toast.setGravity(Gravity.RIGHT|Gravity.TOP, 12, 40); // 设置toast的显示时长 toast.setDuration(Toast.LENGTH_LONG); // 设置toast显示的内容,即我们所设置的根节点 toast.setView(layout); // 进行显示 toast.show();
- 新建一个xml(custom.xml)文件
-
-
-
EditText
-
EditText是程序用于和用户进行交互的另一个重要特性,它允许用户在控件里输入和编辑内容。
-
其一些对应控件属性
android:editable 是否可编辑 android:gravity 控件位置,默认为TOP android:height 控件高度 android:hint 未输入信息时的提示内容 android:inputType 设置文本类型,便于打开对应的键盘 android:lines 设置控件显示行数 android:numeric 设置为数字输入方式 android:password 以点"”代替文本 android:phoneNumber 设置为电话号码输入方式 android:maxLine 指定EditText的最大行数为两行,这样当输入的内容超过两行时,文本就会向上滚动,而EditText则不会继续拉伸。 android:imeOptions 设置键盘显示的附加功能(actionGo:回车;actionNext:下一步;actionSearch:搜索;actionSend:发送;actionDone:完成) android:scrollHorizontally 超宽是否显示横拉条 android:textColor 设置文本颜色 android:textColorHighlight 选中后的文本颜色,默认蓝色 android:textColorHint 提示文本颜色,默认灰色 android:textSize 文本大小 android:textStyle 字形(bold、italic、bolditalic) android:typeface 文本字体(normal、sans、serif、monospace) android:width 设置宽度 -
对应常用方法(java文件中)
方法 功能 Text(Context context) 构造方法,创建文本编辑框对象 ext() 获取文本编辑框的文本内容 ext(CharSequence text) 设置文本编辑框的文本内容
-
-
ProgressBar
-
不同代码片段其对应不同的样式
<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyleLarge"/>
<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyleSmall"/>
<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyleSmallTitle"/>
<ProgressBar android:id="@+id/bar" android:layout_width="300dp" android:layout_height="10dp" style="@android:style/Widget.ProgressBar.Horizontal" android:progress="0" android:max="100"/>
-
处理进度条的方法:
private Handler handler = new Handler();
-
获取进度条:
ProgressBar progressBar = findViewById(R.id.bar);
-
进行进度条的处理:
// 定义一个常量,用于判断进度条是否已完成,在进度条满时则停止 private int i = 0; // 由于进度条需要多线程来完成,故先创建一个线程对象 private Runnable runnable = new Runnable() { @Override public void run() { i ++; if (i == 100) { // 移除当前runnable事件 handler.removeCallbacks(this); } // 设置进度条的进度 progressBar.setProgress(i); // 进行多重回调 handler.postDelayed(this, 100); } }; // 第一个参数:线程对象;第二个参数:每次执行毫秒数; handler.postDelayed(runnable, 100);
-
-
ListView
- 列表框
-
MapView
- 地图
-
CalendarView
- 日历
-
Spinner
- 下拉列表
-
WebView
- 网页浏览器视图
其共有的一些属性
android:id | 为该组件添加一个资源id,即标识符,可以通过id来找到该布局或者控件。 |
---|---|
android:layout_width | 布局的宽度,用wrap_content表示组件的实际宽度,match_parent表示填充父容器 |
android:layout_height | 布局的长度,用wrap_content表示组件的实际长度,match_parent表示填充父容器 |
android:orientation | 布局中的排列方式,有两种方式:horizontal水平,vertical竖直,如果不设置则默认水平显示 |
android:gravity | 控制组件所包含的子元素的对齐方式 |
android:layout_gravity | 控制该组件在父容器里的对齐方式 |
android:background | 为该组件添加一个背景图片或者背景颜色,颜色常以六位的十六进制表示 |
android:layout_margin | 外边距,布局或控件距离外部元素的边距 |
android:layout_padding | 内边距,布局或控件距离内部元素的边距 |
android:layout_weight | 权重,除了被显示占据的空间以外的的空间,然后根据权重的大小来分配空间,使用权重通常会把分配该权重方向的宽度设置为0dp,如果未设置0dp,则该控件会占据指定的宽度,然后再加上根据权重来分配的空间 |
1. 组件属性设定
第一类:属性值为true或false
// 居中
android:layout_centerHrizontal="true" // 水平居中
android:layout_centerVertical="true" // 垂直居中
android:layout_centerInparent="true" // 相对于父元素完全居中
//相对于父组件
android:layout_alignParentBottom="true" // 贴紧父元素的下边缘
android:layout_alignParentLeft="true" // 贴紧父元素的左边缘
android:layout_alignParentRight="true" // 贴紧父元素的右边缘
android:layout_alignParentTop="true" // 贴紧父元素的上边缘
第二类:属性值必须为id的引用名“@id/id-name”
// 相对于给定ID控件
android:layout_below="@id/xxx" // 在某元素的下方
android:layout_above="@id/xxx" // 在某元素的的上方
android:layout_toLeftOf="@id/xxx" // 在某元素的左边
android:layout_toRightOf="@id/xxx" // 在某元素的右边
android:layout_alignTop="@id/xxx" //本元素的上边缘和某元素的的上边缘对齐
android:layout_alignLeft="@id/xxx" //本元素的左边缘和某元素的的左边缘对齐
android:layout_alignBottom="@id/xxx" //本元素的下边缘和某元素的的下边缘对齐
android:layout_alignRight="@id/xxx" //本元素的右边缘和某元素的的右边缘对齐
第三类:属性值为具体的像素值,如30dp,40px
// 指定移动像素
android:layout_marginBottom="30dp" // 离某元素底边缘的距离
android:layout_marginLeft="30dp" // 离某元素左边缘的距离
android:layout_marginRight="30dp" // 离某元素右边缘的距离
android:layout_marginTop="30dp" // 离某元素上边缘的距离
第四类:其它属性
android:gravity="center_horizontal|bottom" // 设置内部子控件的显示位置,居中,上下左右都可以
android:layout_alignParentStart="true" // 设置是否紧贴父布局开始的位置
android:layout_alignParentEnd="true" // 设置是否紧贴父布局结束的位置
android:layout_toStartOf="@+id/xxx" // 设置位于某个id控件的开始位置
android:layout_toEndOf="@+id/xxx" // 设置位于某个id控件的结束位置
android:layout_alignStart="@+id/xxx" // 设置和某个id的控件的开始位置位于一条线上
android:layout_alignEnd="@+id/xxx" // 设置和某个id的控件的结束位置位于一条线上
android:layout_alignWithParentIfMissing="true" // 如果找不到其他子控件,就相对于父控件布局
android:ignoreGravity="@id/xxx" // 传入子控件的id
第三章、对应的事件处理及响应
一、常用的一些方法
方法 | 作用 |
---|---|
findViewById(R.id.xx) | 根据id进行查询该组件(参数为你设定组件的id) |
textView.setText() | 可以设置TextView中文本内容(参数为字符串) |
textView.setTextColor(Color.BLUE) | 设置TextView中文本颜色(此时设置为蓝色) |
textView.setTextSize() | 设置TextView中文本大小(参数问float类型) |
button.setOnClickListener() | 为按钮添加点击响应事件(实现见下) |
Log.i() | 实现日志功能的输出(更多方法见下) |
imageView.setImageDrawable(view.getDrawable()) | 更改图片资源文件 |
1. 日志信息的输出方法:
-
Log.i是打印输出日志的,这个函数在项目中的主要作用就是,你能够查看你想要知道的一些参数数据,而且可以帮你找到程序的运行出错的位置。
-
Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v("","");
-
Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择.
-
Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
-
Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。
-
Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。
2. Intent的使用
Android的有三个基本组件——Activity
,Service
和BroadcastReceiver
,它们都是通过Intent机制激活的,而不同类型的组件有传递Intent的不同方式。
-
要激活一个新的Activity,或者让一个现有的Activity执行新的操作,可以通过调用Context.startActivity()或者Activity.startActivityForResult()方法。这两个方法需要传入的Intent参数也称为Activity Action Intent(活动行为意图),根据Intent对象对目标Activity描述的不同,来启动与之相匹配的Activity或传递信息。
-
要启动一个新的服务,或者向一个已有的服务传递新的指令,调用Context.startService()方法或调用Context.bindService()方法将调用此方法的上下文对象与Service绑定。
-
通过Context.sendBroadcast()、Context.sendOrderBroadcast()和Context.send-StickBroadcast()这三个方法可以发送BroadcastIntent。BroadcastIntent发送后,所有已注册的拥有与之相匹配IntentFilter的BroadcastReceiver就会被激活。这种机制被广泛运用于设备或系统状态变化的通知,一个常见的例子是,当Android的电池电量过低时,系统会发送Action为BATTERY_LOW的广播,接着任何可匹配该Action的IntentFilter注册的BroadcastReceiver都会各自运行自定义的处理代码,比如关闭设备的WIFI和GPS以节省电池消耗。
注意:
Intent一旦发出,Android都会准确找到相匹配的一个或多个Activity、Service或Broadcast-Receiver作为响应。所以,不同类型的Intent消息不会出现重叠:BroadcastIntent消息只会发送给BroadcastReceiver,而绝不可能发送给Activity或Service。由startActivity()传递的消息也只可能发送给Activity,由startService()传递的Intent只可能发送给Service。
3. 简单的页面切换功能(Intent实现)
显示启动
- 第一种调用方式实现界面跳转
// 从param1跳转到param2,
// 第一个参数为从某个页面开始跳转,第二个参数为将要跳转到的页面
Intent intent = new Intent(param1, param2);
// 例如:
Intent intent = new Intent(this, SecondActivity.class);
// 最后要执行
this,startActivity(intent);
- 第二种调用方式实现界面跳转
// 第一个参数为从某个页面开始跳转,第二个参数即为将要跳转的全类名
//(包名加类名)
Intent intent = new Intent();
intent.setClassName(this, "com.cn.android.SecondActivity");
startActivity(intent);
- 第三种调用方式实现界面跳转
Intent intent = new Intent();
ComponentName componentName = new ComponentName(this, SecondActivity.class);
intent.setComponent(componentName);
startActivity(intent);
隐式启动
- xml文件配置
<!--
xml文件中的配置
(当有两个intent-filter中的内容完全相同时,会显示让你挑选打开的界面)
-->
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="action.nextActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- java文件中代码
Intent intent = new Intent();
intent.setAction("action.nextActivity");
startActivity(intent);
// 简化写法
Intent intent = new Intent("action.nextActivity");
startActivity(intent);
4. 为按钮点击事件响应的代码
- 第一种方式,匿名内部类方式
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 实现点击事件的响应函数
}
});
- 第二种方式,在外部编写继承类
class MyClick implements View.OnClickListener {
@Override
public void onClick() {
// 实现点击事件的响应函数
}
}
- 第三种方式
- xml文件中
<!--
在编写Button组件的时候添加属性
android:onClick="myOnClick"
-->
<!-- 例如: -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮"
android:onClick="myOnClick"/>
- java文件中
// 在java文件中编写此方法即可(方法名必须与组件属性中定义的方法名对应)
public void myOnClick(View view) {
// 其对应setOnClickListener=方法的编写
}
二、Activity的生命周期
-
启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
-
当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
-
当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
-
当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
-
用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
-
当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
-
用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
三、引入外部布局
- 可以先新建一个布局
- 在另一个布局中引入这个新建的布局需要加入如下代码片段
<include layout="@layout/activity_new"/>
注意: 引入的布局需要设置其为包裹内容,否则会引起主界面的内容损失
四、资源文件的目录类型及其作用
目录 | 资源类型 |
---|---|
animator/ | 存放定义属性动画的xml文件 |
anim/ | 存放定义补建动画的xml文件 |
color/ | 存放定义颜色值的xml文件 |
drawable/ | 存放位图文件(.png、.jpg、.gif、.9.png),或者是被编译成以下可描述画资源类型的xml文件 |
layout/ | 存放定义用户界面布局的xml文件 |
menu/ | 存放定义应用程序菜单的xml文件,如选项菜单、上下文菜单、或子菜单 |
raw/ | 存放任意原生格式的文件 |
values/ | 存放包含简单值的xml文件,如字符串、整数以及颜色等 |
xml/ | 放在这个目录下的任意xml文件,都可以在运行时通过调用Resources.getXML()方法来读取 |
五、屏幕尺寸、像素密度、分辨率
六、Fragment的使用
1. Fragment简介
Fragment是一种可以嵌入在活动中的UI片段,能够让程序更加合理和充分地利用大屏幕的空间,出现的初衷是为了适应大屏幕的平板电脑,可以将其看成一个小型Activity,又称作Activity片段。
使用Fragment可以把屏幕划分成几块,然后进行分组,进行一个模块化管理。Fragment不能够单独使用,需要嵌套在Activity中使用,其生命周期也受到宿主Activity的生命周期的影响。
- onAttach():Fragment和Activity相关联时调用。可以通过该方法获取Activity引用,还可以通过getArguments()获取参数。
- onCreate():Fragment被创建时调用
- onActivityCreated():当Activity完成onCreate()时调用
- onStart():当Fragment可见时调用。
- onResume():当Fragment可见且可交互时调用
- onPause():当Fragment不可交互但可见时调用。
- onStop():当Fragment不可见时调用。
- onDestroyView():当Fragment的UI从视图结构中移除时调用。
- onDestroy():销毁Fragment时调用。
- onDetach():当Fragment和Activity解除关联时调用。
Fragment生命周期会经历:运行、暂停、停止、销毁。
- 运行状态:碎片可见时,关联活动处于运行状态,其也为运行状态
- 暂停状态:活动进入暂停状态,相关联可见碎片就会进入暂停状态
- 停止状态:活动进入停止状态,相关联碎片就会进入停止状态,或者通过FragmentTransaction的remove()、replace()方法将碎片从从活动中移除,但如果在事务提交之前调用addToBackStack()方法,这时的碎片也会进入到停止状态。
- 销毁状态:当活动被销毁,相关联碎片进入销毁状态。或者调用FragmentTransaction的remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,碎片也会进入到销毁状态。
2. Fragment的生命周期
3. Fragment特点:
- Fragment必须放置在Activity中使用,不能独立存在
- Fragment具有自己的生命周期,但它的生命周期也直接受所在的Activity生命周期的影响
- 一个Activity中可以包含多个Fragments,每个Fragment都定义自己的布局,并在生命周期中的回调方法中定义的动作
- Fragments之间是相互独立的
- 代码复用。适用于模块化的开发,一个Fragment可以被多个Activity嵌套,有个共同的业务模块就可以复用了
4. Fragment的回调方法:
- Fragment状态之间转换时的回调方法如下:
- onAttach()在Fragment对象添加到Activity中时调用。onCreate()创建Fragment对象时调用。
- onCreateView()在Fragment绘制用户界面时调用。
心 - onActivityCreated()所在Activity和Fragment的UI界面创建时调用。
- onStart()在任何UI变化时,Fragment开始变为可视状态时调用。
- onResume()在Fragment开始变为运行状态时调用。
- onPause()在Fragment运行状态结束,线程挂起,所在Activity不再是前台界面时调用。
- onSavelnstanceState()在Fragment运行状态结束,保存UI状态时调用时。
- onStop()在可见状态结束时调用。
- onDestroyView()在Fragment视图被删除时调用。
- onDestroy()在Fragment生命周期结束时调用
5. Activity生命周期对Fragment生命周期的影响
- Activity的声生命周期,直接影响Fragment的生命周期。
- 在Activity状态转换时,生命周期中每一个回调方法的调用,都导致其中的Fragments对应的回调方法的调用。
- 生命周期对应示例:
public class TextViewFragment extends Fragment { // 当fragment被加载时 @Override public void onAttach(@NonNull Context context) { super.onAttach(context); Log.d("TextViewFragment", "onAttach..."); } // 当fragment被初始化时 @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("TextViewFragment", "onCreate..."); } // 当fragment被加载界面时 @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d("TextViewFragment", "onCreateView..."); return inflater.inflate(R.layout.fragment_text, container, false); } // 当Activity完成所有fragment的加载时 @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Log.d("TextViewFragment", "onActivityCreated..."); } }
- 运行结果如下:
TextViewFragment: onAttach…
TextViewFragment: onCreate…
TextViewFragment: onCreateView…
TextViewFragment: onActivityCreated…
6. 基于回调的事件处理机制
- 不同控件有不同的回调方法,常见的android回调方法有
- onKeyDown:手机键盘被按下的事件
- onKeyUp:手机键盘按键抬起的事件
- onTouchEvent:屏幕的触摸事件
- onTrackBallEvent:手机中轨迹球的事件
- onFocusChanged:焦点改变事件,当某个控件重写了该方法后,焦点发生变化时,会自动调用该方法来处理焦点改变的事件
前面介绍的前面各个方法都可以在View及Activity中重写,onFocusChanged却只能右view中重写。
-
Fragment的动态添加
<!-- 占位用的布局 --> <LinearLayout android:id="@+id/listFragment" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"/>
-
在MainActivity中的onCreate方法中添加如下代码片段
// 创建一个片段管理器 FragmentManager fm = getSupportFragmentManager(); // fm .beginTransaction() // 开启一个事务 .add(R.id.listFragment, new ListViewFragment()) // 进行添加;第一个参数:要添加到哪一个容器中,第二个参数:选择进行操作的类 .commitNow(); // 进行提交
-
创建一个类(ListViewFragment.class)使之继承Fragment
public class ListViewFragment extends Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_imageview, container, false); } }
-
-
案例:
-
创建一个新的xml文件(fragment_text.xml)在xml文件中引入fragment标签
<!-- name属性,定义对其内容或者行为进行处理所用到的类(完整类名) --> <fragment android:id="@+id/text_fragment" android:name="com.cn.fragmentdemo.TextViewFragment" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
-
新创建一个java类(TextViewFragment .java)继承Fragment
public class TextViewFragment extends Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // 第一个参数选择要填充的内容,第二个参数填充到的地方,第三个参数是否直接显示在父容器里面 return inflater.inflate(R.layout.fragment_text, container, false); } }
-
7. 横竖屏的处理
DisplayMetrics dm = new DisplayMetrics();
// 获取当前屏幕横纵向的像素
getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels; // 获取宽像素
int screenHeight = dm.heightPixels; // 获取高像素
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.listFragment);
// 实现竖屏时加载Fragment片段
if (screenWidth > screenHeight) { // 横屏
if (fragment != null) {
// 取消片段的加载
fm.beginTransaction().remove(fragment).commitNow();
}
} else { // 竖屏
if (fragment == null){
// 加载片段
fm.beginTransaction().add(R.id.listFragment, new ListViewFragment()).commitNow();
}
}
-
实现点击图片进行更换的操作
public void OnClick(View v) { imageView.setImageDrawable(v.getDrawable()); }
8. Fragment与Activity之间的通信
-
在Fragment中定义一个接口以及一个方法
public interface ListViewEvent { void onImageClickListener(ImageView view); } public void setListViewEvent(ListViewEvent listViewEvent) { this.listViewEvent = listViewEvent; }
-
在Activity中实现此接口并继承方法
public class MainActivity extends AppCompatActivity implements ListViewFragment.ListViewEvent { @Override public void onImageClickListener(ImageView view) { img_fra.setImageDrawable(view.getDrawable()); } }
-
Fragment添加监听,事件处理环节调用事件处理接口,具体操作由Activity进行。
for (int i = 0; i < img.length; i ++) { ImageView iv = (ImageView) this.getActivity().findViewById(img[i]); iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listViewEvent.onImageClickListener((ImageView) v); } }); }
-
Activity 的onAttachFragment方法中,调用Fragment设置接口的方法,将自身引用传入
@Override public void onAttachFragment(@NonNull Fragment fragment) { super.onAttachFragment(fragment); if (fragment instanceof ListViewFragment) { ListViewFragment lvf = (ListViewFragment) fragment; lvf.setListViewEvent(this); } }
如果文中有什么错误,欢迎指出。以免更多的人被误导。