封面画师:画师JW 封面ID:77038942
Android简介
安卓是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成。
Android一词最早出现于法国作家利尔亚当(Auguste Villiers de l’Isle-Adam)在1886年发表的科幻小说《未来夏娃》(L’ève future)中。他将外表像人的机器起名为Android。
Android的Logo是由Ascender公司设计的,诞生于2010年,其设计灵感源于男女厕所门上的图形符号,于是布洛克绘制了一个简单的机器人,它的躯干就像锡罐的形状,头上还有两根天线,Android小机器人便诞生了。其中的文字使用了Ascender公司专门制作的称之为“Droid ” 的字体。Android是一个全身绿色的机器人,绿色也是Android的标志。颜色采用了PMS 376C和RGB中十六进制的#A4C639来绘制,这是Android操作系统的品牌象徵。有时候,它们还会使用纯文字的Logo。
内容摘录于百度百科——Android。
Android Studio
Android Studio 是开发 Android 应用程序的官方 IDE,基于 Intellij IDEA。
删除一个Module的方法:选中要删除的Module > Open Module Settings > 选中要删除的Module,然后点击"-" > 坚持磁盘目录下文件是否被删除,如果没有,删除即可。
java节点
解决:Build —> Clean Project
- Android Studio卡在“Waiting for target device to come online”:
后续补充:
这些方法没啥卵用,不用看了,可以试试选用Target不带有Google字样的x64模拟器。
解决:每种解决都可以试一下!!参考链接
- 将镜像改成x86_64然后新建一个模拟器。
- 打开AVD manager找到自己的模拟器,然后右击模拟器,选择Cold Boot Now,模拟器打开并提示一行信息,直接dismiss。
- 重启AS,重启系统。(注意:如果你是Win10 系统,重启的时候记得按住 shift 来禁用系统的强制签名)
- paltform-tools目录下adb kill-server,然后adb start-server。
- SDK tool 或paltform tool有更新,下载更新。
- 删除<Your_AVD_Directory>.android\avd\Pixel_XL_API_28.avd目录下.lock文件,然后重新载入。
- 打开AVD manager,选中模拟器,右击,wipe data,然后启动模拟器。
res节点
drawable目录
主要用于放置位图文件(PNG,JEPG或者GIF)、9-Patch图片文件、Shape Drawable、Drawable对象等XML资源文件。图片命名不能大写!!
layout目录
用于存储安卓的布局文件。
布局文件就是用于控制窗口中显示哪些内容。
mipmap目录
创建项目后会创建多个子目录(mipmap-mdpi、mipmap-hdpi、mipmap-xhdpi、mipmap-xxhdpi、mipmap-xxxhdpi)。用于储存不同分辨率的启动图标文件。
drawable和mipmap的区别:
- 9-Patch图片和Shape资源文件只能放在drawable目录中;
- 需要适应屏幕分辨率的图片推荐放在mipmap目录中,可以提高显示性能、占用内存更少;
values目录
主要用于保存字符串资源、样式资源、尺寸资源、颜色资源。
UI布局
View
我们一般不直接使用View类,而是使用View类的子类(比如TextView)。
View类位于android.view包中;View类的子类一般都用于android.widget包中。
常用属性:
1
| android:id = "@+id/user"
|
android:background 为组件设置背景(可以是图片资源也可以是颜色)
1
| android:background = "@mipmap/bg" //bg为图片资源名称,需要将资源放置于mipmap目录下
|
android:padding 为组件四周设置一样的内边距
衍生属性:
android:paddingLeft、android:paddingTop、android:paddingRight、android:paddingBottom
API 17以后:
android:paddingStart = android:paddingLeft
android:paddingEnd = android:paddingRight
ViewGroup
理解:若将View比作成整个窗户,那么ViewGroup就是窗户框。用于控制View如何摆放。
实际使用中经常使用ViewGroup的子类,如RelativeLayout、LinearLayout等。
ViewGroup控制其子组件分布时依赖的内部类:
ViewGroup.LayoutParams类和ViewGroup.MarginLayoutParams类。
ViewGroup.LayoutParams常用于设置布局高度和宽度。
ViewGroup.MarginLayoutParams用于控制子组件的外边距。
-
属性:android:layout_marginTop、android:layout_marginBottom、android:layout_marginLeft、android:layout_marginRight
API 17 以后:
android:layout_marginStart = android:layout_marginLeft
android:layout_marginEnd = android:layout_marginRight
-
属性值:通过尺寸变量或具体的值进行设置。
Android UI 组件的层次结构
所有的UI界面都是由View类、ViewGroup类或其子类组合而成的。
ViewGroup中可以包含多个View和ViewGroup,其中的ViewGroup又可以包含多个View和ViewGroup…
禁止套娃!!
控制UI界面
方法:使用XML布局文件控制UI界面(推荐)、在Java代码中控制UI界面、使用XML和Java代码混合控制UI界面、开发自定义的View。
使用XML布局文件控制UI界面
- 在Android应用的res/layout目录下编写XML布局文件(如activity_main.xml)
- 在Activity中使用以下Java代码显示XML文件中布局的内容
1
| setContentView(R.layout.activity_main);
|
android:layout_gravity 用来设置该view相对与父view 的位置,比如值为center将该view置于父view中间。
RelativeLayout
RelativeLayout:相对布局管理器
1
| <RelativeLayout></RelativeLayout>
|
使用相对布局需要一个参考点,所有的组件以参考点的位置为基准。
如果有根据组件间的相对位置来控制组件的摆放 的设计需求,那么此时就可以使用相对布局。
部分属性参考ViewGroup ,其他属性:
android:gravity 用于设置布局管理器中各个子组件的摆放方式
android:ignoreGravity 指定哪个子组件不受android:gravity的影响
RelativeLayout.LayoutParams
属性:相对布局管理器组件上设置的属性,而不是布局管理器上设置的属性。
| 属性名 |
作用 |
android:layout_above |
上方 |
android:layout_below |
下方 |
android:layout_toLeftOf |
左方 |
android:layout_toRightOf |
右方 |
| 属性名 |
作用 |
android:layout_alignParentBottom |
底部对齐 |
android:layout_alignParentLeft |
左对齐 |
android:layout_alignParentRight |
右对齐 |
android:layout_alignParentTop |
顶部对齐 |
| 属性名 |
作用 |
android:layout_alignBottom |
底部对齐 |
android:layout_alignLeft |
左对齐 |
android:layout_alignRight |
右对齐 |
android:layout_alignTop |
顶部对齐 |
| 属性名 |
作用 |
android:layout_centerHorizontal |
位于水平居中 |
android:layout_centerInparent |
位于中间位置 |
android:layout_centerVertical |
位于垂直居中 |
LinearLayout
LinearLayout:线性布局管理器
1
| <LinearLayout></LinearLayout>
|
将放入其中的组件按照水平或垂直的方向进行排列。
若其内部组件一个挨着一个(按行或列)排列到屏幕的边缘以后,剩下的组件将不会显示出来。
本身属性
android:orientation 设置线性布局内组件的排列方式
1 2 3
| //属性值:仅有两个
horizontal: 水平方向
vertical: 垂直方向
|
android:gravity 设置线性布局内组件的显示位置
属性值之间可以使用|分割,达到组合的效果,如:
1
| android:gravity = "right|bottom" //使布局管理器位于右下角
|
子组件属性
android:layout_weight 设置子组件所占的权重,即:组件占父容器剩余空间 的比例 默认值为0

gravity 和layout_gravity 的不同处
gravity是设置控件自身内部元素的对齐方式。比如一个TextView,则是设置内部文字的对齐方式。如果是ViewGroup组件如LinearLayout的话,则为设置它内部view组件的对齐方式。
layout_gravity是设置控件自身相当于父容器的对齐方式。比如,一个TextView设置layout_gravity属性,则表示这TextView相对于父容器的对齐方式。
FrameLayout
FrameLayout:帧布局管理器
1
| <FrameLayout></FrameLayout>
|
帧布局容器为每个加入其中的组件创建一个空白的区域 (称为一帧 ),每个子组件占据一帧,默认是把他们放在这块区域的左上角 ,但是我们也可以通过layout_gravity属性 ,指定到其他的位置。
帧布局会把组件按先后顺序一个一个地叠加在一起,上层的组件会覆盖底层的组件 ,不能 将底层的帧移到上层。
帧布局的大小由组件中最大的子组件决定 ,如果每个组件的大小一样大的话,那么同一时刻只能看到最上面的那个组件。
本身属性
前景图像:始终位于最上层的图像,其他组件无法将它盖住
android:foreground 为当前的帧布局管理器设置一个前景图像
属性值常为图片资源。
android:foregroundGravity 设置前景图像的位置
属性值之间可以使用|分割,达到组合的效果,如:
1
| android:foregroundGravity = "right|bottom" //使前景图像位于右下角
|
TableLayout
TableLayout:表格布局管理器
1
| <TableLayout></TableLayout>
|
表格布局由TableLayout类代表,其会采用行、列的形式来管理UI组件。
TableLayout通过添加TableRow、其它组件来控制表格的行数和列数,而不需要明确地声明包含多少行、多少列。
每次向TableLayout中添加一个TableRow,该TableRow就是一个表格行,TableRow也是容器,因此它也可以不断地添加其它组件,每添加一个子组件该表格就增加一列。若直接向TableLayout中添加组件,那么这个组件将直接占用一行。
在表格布局中,列的宽度由该列中最宽的那个单元格决定,整个表格布局的宽度则取决于父容器的宽度(默认总是占满父容器本身)。
列单元格常用的三种行为方式:
- Shrinkable。该列的所有单元格的宽度可以被收缩,以保证该表格能适应父容器的宽度。
- Stretchable。该列的所有单元格的宽度可以被拉伸,以保证组件能完全填满表格空余空间。
- Collapsed。该列的所有单元格会被隐藏。
1 2 3 4 5 6 7 8 9
| <!--定义一个表格布局,指定第2列允许收缩,第3列允许拉伸,第4列允许隐藏。-->
<!--列数是从0开始的-->
<TableLayout
android:id="@+id/tableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="1"
android:stretchColumns="2"
android:collapseColumns="3">
|
GridLayout
GridLayout:网格布局管理器
1
| <GridLayout></GridLayout>
|
GridLayout 布局是 Android 4.0 以后引入的新布局,和 TableLayout(表格布局) 有点类似,不过它功能更多,也更加好用:
- 可以自己设置布局中组件的排列方式
- 可以自定义网格布局有多少行,多少列
- 可以直接设置组件位于某行某列
- 可以设置组件横跨几行或者几列
本身属性
android:columnCount 指定网格最大列数
android:orientation 与线性布局属性一样,默认采用水平排列
android:rowCount 指定网格的最大行数
GridLayout .LayoutParams
属性:网格布局管理器组件上设置的属性,而不是布局管理器上设置的属性。
这些属性可以控制网格布局管理器上各子组件的分布。
| 属性名 |
含义 |
android:layout_column |
指定子组件位于网格的第几列 |
android:layout_columnSpan |
指定子组件横向跨几列 |
android:layout_columnWeight |
指定子组件在水平方向上的权重 |
android:layout_gravity |
指定子组件以什么方式占据网格空间 |
android:layout_row |
指定子组件位于网格的第几行 |
android:layout_rowSpan |
指定子组件纵向跨几行 |
android:layout_rowWeight |
指定子组件在垂直方向上的权重 |
1 2 3 4 5
| <!--从0开始计算,与表格布局类似-->
<!--设置组件位于第二行-->
android:layout_row = "1"
<!--设置组件位于第三列-->
android:layout_column = "2"
|
布局管理器的嵌套
嵌套原则
- 根布局管理器必须包含xmlns属性;
- 在一个布局文件中,最多只能有一个根布局管理器,如果需要有多个还需要使用一个根布局管理器将它们括起来;
- 不能嵌套地太深,如果嵌套太深,会影响性能。
不能套娃太深!!
基本UI组件
使用UI组件时注意字母的大小写!
使用UI组件时注意字母的大小写!
使用UI组件时注意字母的大小写!
文本框组件
属性
android:text 设置文本框中要显示的内容。
属性值为字符串资源(res/values/string.xml 进行设置)名称。
1
| android:text = "@string/demo" //字符串资源名为demo
|
android:textSize 设置字体大小,单位为sp
android:textColor 设置字体颜色
android:singleLine 设置文本框单行显示文字 属性值为true时,则单行显示
跑马灯——使用TextView内的属性实现
1 2 3 4 5 6 7 8 9 10 11 12
| <!--激活焦点,必须-->
android:focusable="true"
<!--单行显示,必须-->
android:singleLine="true"
<!--这里设置为超出文本后滚动显示,必须-->
android:ellipsize="marquee"
<!--TouchMode模式的焦点激活,必须-->
android:focusableInTouchMode="true"
<!--这个是设置滚动几次,这里是无限循环-->
android:marqueeRepeatLimit="marquee_forever"
<!--横向超出后是否有横向滚动条-->
android:scrollHorizontally="true"
|
除了添加这些属性外,还需要在对应的Activity中添加:
1 2 3 4 5 6
| protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv);
textView.setSelected(true); //必须
}
|
这只是简单实现页面中单个跑马灯,如果界面中有EditText等能获取焦点的组件时,这种方法会失效。具体操作可以参考:Android之跑马灯详解
编辑框
它是文本框组件的子类。
属性
android:hint 设置默认提示内容,属性值为字符串
android:inputType 设置输入内容类型,如:
1 2
| android:inputType = "textPassword" <!--设置输入类型为密码-->
android:inputType = "number" <!--设置输入类型为数字-->
|
android:drawableLeft 在编辑框左侧绘制一个图像,常用于图标的设置,属性值为图片资源,如:
1
| android:drawableLeft = "@mipmap/mr" <!--mr为图片资源名-->
|
android:drawableStart 在API 17后,android:drawableStart等同于android:drawableLeft的使用。
android:drawableBottom 在文字底部绘制图像
android:drawableRight 在文字右侧绘制图像
android:drawableEnd 在API 17后,android:drawableEnd等同于android:drawableRight的使用。
android:drawableTop 在文字顶部绘制图像
android:drawablePadding 设置文字与图像之间的距离,单位dp
android:lines 设置编辑框的最大行数,当超过设置的数值时,自动向上滚动
获取编辑框组件内容
首先需要给编辑框组件设置一个id,假设设置id为et,则在Activity中有:
1 2 3 4 5
| protected void onCreate(Bundle saveInstanceState){
...
EditText et = findViewById(R.id.et);
et.getText(); //这样就可以获取到编辑框中的内容
}
|
普通按钮
它是文本框组件的子类。
为普通按钮添加点击事件监听器
首先需要给按钮设置一个id,假设设置id为btn,则在Activity中有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| protected void onCreate(Bundle savedInstanceState) {
...
//根据Button ID绑定Button
Button mButton = findViewById(R.id.btn);
//按钮点击监听器
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//单击按钮后短时间内显示消息提示框
Toast.makeText(MainActivity.this, "单击了按钮", Toast.LENGTH_SHORT).show();
}
});
}
|
- 在Activity中编写一个包含View类型参数的方法。
1 2 3 4
| public void myClick(View view){
//编写要执行的动作代码
Toast.makeText(MainActivity.this, "单击了按钮", Toast.LENGTH_SHORT).show();
}
|
- 将
android:onClick属性指定为步骤(1)中的方法名。
1
| android:onClick = "myClick"
|
图片按钮
ImageButton和Button的异同:
相同点:
- 单击时都可以触发onClick事件。即:使用它们两个都可以生成一个可供点击的按钮,且点击时都会触发onClick事件。
不同点:
- ImageButton没有
android:text属性,而Button有。Button上的文字是在代码中指定的,而ImageButton上的文字是在制作图片时加上去的。
基本使用(属性)
android:src设置按钮要显示的图片,属性值为图片资源。假设图片名称为img且在mipmap目录下:
1
| android:src = "@mipmap/img"
|
android:background 为图片按钮设置一个背景。为图片按钮设置透明背景:
1
| android:background = "#0000"
|
全屏显示
设置界面全屏显示:
1 2 3 4 5 6
| protected void onCreate(Bundle savedInstanceState) {
...
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
...
}
|
单选按钮
基本使用(属性)
android:text 给单选按钮旁设置说明性文字
android:checked 设置单选按钮为默认选中状态 属性值为true,则表示为默认选中。
设置单选按钮组,并获取单选按钮组中选中项的值
如果我们需要设置单选按钮组,我们需要使用<RadioGroup></RadioGroup>将单选按钮们包裹起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <RadioGroup
android:id="@+id/radio_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保密"/>
</RadioGroup>
|
前提是需要给RadioGroup设置一个id,然后在对应的Activity中编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| RadioGroup radioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//根据radioGroup ID绑定radioGroup
radioGroup = findViewById(R.id.radio_1);
//获取单选按钮内容
radioGroup.setOnCheckedChangeListener(new RadioGroup
.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton radioButton = findViewById(checkedId);
CharSequence text = radioButton.getText();
Toast.makeText(MainActivity.this,"性别:"+text,
Toast.LENGTH_LONG).show();
}
});
}
|
添加其他按钮,并设置属性:
1 2 3 4 5 6
| <Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提交"
/>
|
在对应的Activity中进行编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| RadioGroup radioGroup;
protected void onCreate(Bundle savedInstanceState) {
...
radioGroup = findViewById(R.id.radio_1);
Button btn_1 = findViewById(R.id.btn_1);
btn_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int i = 0;i <radioGroup.getChildCount();i++){
RadioButton r = (RadioButton) radioGroup.getChildAt(i);
if (r.isChecked()){ Toast.makeText(MainActivity.this,r.getText(),Toast.LENGTH_LONG).show();
//当已经找到选中的单选按钮后就跳出循环,提高程序效率
break;
}
}
}
});
}
|
复选框
使用(本身属性)
设置多个复选框只需要使用多个<CheckBox />即可
android:text 给复选框旁设置说明性文字
android:checked 设置复选框为默认选中状态 属性值为true,则表示为默认选中。
获取选中的复选框的值
首先需要给要获取值的复选框设置id:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <CheckBox
android:id="@+id/box_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="唱"
/>
<CheckBox
android:id="@+id/box_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳"
/>
<CheckBox
android:id="@+id/box_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="rap"
/>
|
在对应的Activity中绑定点击响应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| CheckBox checkBox_1;
protected void onCreate(Bundle savedInstanceState) {
...
//根据id绑定一个复选框 box_1
checkBox_1 = findViewById(R.id.box_1);
checkBox_1.setOnCheckedChangeListener(new CompoundButton.
OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (checkBox_1.isChecked()){
//当box_1被选中后,短暂弹出带有复选框值的提示框
Toast.makeText(MainActivity.this,checkBox_1.getText(),
Toast.LENGTH_SHORT).show();
}
}
});
}
|
日期选择器
常将日期选择器的长宽设置成根据父容器变化。
如果添加日期选择器后发现日期没有显示完全,应该进入对应的Activity中修改继承的类。
将其修改为:Activity而不是默认的AppCompatActivity。
选择日期后,相应的给出我们选择的日期
1 2 3 4
| <DatePicker
android:id="@+id/datePicker_1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
|
这里的Activity继承的是Activity,而不是AppCompatActivity。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class DatepickerActivity extends Activity {
int year, month, day;
DatePicker datePicker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_datepicker);
datePicker = findViewById(R.id.datePicker_1);
Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
DatepickerActivity.this.year = year;
DatepickerActivity.this.month = month;
DatepickerActivity.this.day = day;
show(year,monthOfYear, dayOfMonth);
}
});
}
private void show(int year, int month, int day) {
String str = year + "年" + (month + 1) + "月" + day + "日";
//选择日期后弹出显示日期的提示框
Toast.makeText(DatepickerActivity.this, str, Toast.LENGTH_SHORT).show();
}
}
|
时间选择器
常将日期选择器的长宽设置成根据父容器变化。
选择时间后,相应的给出我们选择的时间
1 2 3 4
| <TimePicker
android:id="@+id/timePicker_1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class TimepickerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timepicker);
TimePicker timePicker = findViewById(R.id.timePicker_1);
//设置时间为24小时制
timePicker.setIs24HourView(true);
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
String str = hourOfDay + "时" + minute + "分";
//选择时间后弹出显示时间的提示框
Toast.makeText(TimepickerActivity.this, str, Toast.LENGTH_SHORT).show();
}
});
}
}
|
计时器
它是文本框组件的子类。
计时器默认的样式是 时:分:秒
如果我们想自定义时间格式,我们可以通过android:format属性进行设置。
%s表示时:分:秒的计时器格式
1
| android:format = "已用时间:%s"
|
计时器所需要的方法
| 方法名 |
含义 |
setBase() |
设置计时器的起始时间 |
setFormat() |
设置显示时间的格式 |
start() |
指定开始计时 |
stop() |
指定停止时间 |
setOnChronometerTickListener() |
为计时器绑定事件监听器,当计时器改变时触发该监听器 |
编写一个计数器
1 2 3 4
| <Chronometer
android:id="@+id/chronometer_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ChronometerActivity extends AppCompatActivity {
Chronometer chronometer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chronometer);
chronometer = findViewById(R.id.chronometer_1);
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.setFormat("%s");
chronometer.start();
chronometer.setOnChronometerTickListener(new Chronometer.
OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
//设置1分钟计时器
if (SystemClock.elapsedRealtime() - chronometer.getBase() >= 60000){
chronometer.stop();
}
}
});
}
}
|
高级UI组件
使用UI组件时注意字母的大小写!
使用UI组件时注意字母的大小写!
使用UI组件时注意字母的大小写!
进度条
安卓提供了两种进度条模式:水平进度条和圆形进度条。默认是圆形进度条。
属性
style 设置进度条的样式。
通过主题属性进行设置,如:
| 属性值 |
含义 |
| ?android:attr/progressBarStyleHorizontal |
细水平长条进度条 |
| ?android:attr/progressBarStyleSmall |
小圆形进度条 |
| ?android:attr/progressBarStyleLarge |
大圆形进度条 |
通过安卓给我定义的样式资源进行设置,如:
| 属性值 |
含义 |
| @android:style/Widget.ProgressBar.Horizontal |
粗水平长条进度条 |
| @android:style/Widget.ProgressBar.Large |
旋转画面的大圆形进度条 |
| @android:style/Widget.ProgressBar.Small |
旋转画面的小圆形进度条 |
android:max 设置进度条的最大值,属性值为具体数值,如:100
android:progress 设置进度条当前进度,属性值为具体数值,如:50
进度条更新流程:

模拟进度,实现进度条更新
1 2 3 4 5 6 7 8
| <ProgressBar
android:id="@+id/progressBar_1"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:layout_alignParentBottom="true"
android:layout_marginBottom="50dp"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
private int mProgress;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progressBar_1);
mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
if (msg.what == 0x111){ //耗时操作未完成
progressBar.setProgress(mProgress);
}else {
Toast.makeText(MainActivity.this, "耗时操作已完成!", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE); //设置进度条消失
}
}
};
//模拟耗时操作
new Thread(new Runnable() {
@Override
public void run() {
while (true){
mProgress = doWork();
Message message = new Message();
if (mProgress < 100){
message.what = 0x111; //耗时操作未完成
mHandler.sendMessage(message);
}else {
message.what = 0x110; //耗时操作已完成
mHandler.sendMessage(message);
break;
}
}
}
//模拟进度条更新
private int doWork(){
mProgress += Math.random()*10;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return mProgress;
}
}).start();
}
}
|
拖动条
它是进度条的子类。
属性
由于它是进度条的子类,因此它可以使用进度条<ProgressBar />的属性,除此之外:
android:thumb 设置拖动条的拖动按钮的样式,属性值可以是我们自定义的图片资源,也可以是安卓给我们提供的值。
拖动拖动条按钮,界面内容实时改变
1 2 3 4 5 6
| <SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:progress="5" />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class MainActivity extends AppCompatActivity {
SeekBar seekBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar = findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
//进度条改变时执行 progress:当前进度
@Override
public void onProgressChanged(SeekBar seekBar,
int progress, boolean fromUser) {
Toast.makeText(MainActivity.this, "进度改变:"+progress, Toast.LENGTH_SHORT).show();
}
//当我们触摸拖动条按钮时执行
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this, "开始触摸", Toast.LENGTH_SHORT).show();
}
//当我们停止触摸拖动条按钮时执行
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this, "停止触摸", Toast.LENGTH_SHORT).show();
}
});
}
}
|
拓展:设置图片透明度可用setAlpha()方法进行设置,参数为透明度。安卓中透明度最高为255。
图像视图参考下文。
星级评分条
属性
android:numStars 设置星级评分条中星级的个数。默认星级是5。属性值为整型,如:8。
android:rating 设置点亮星级的个数。属性值为浮点型。
android:stepSize 设置每次评分的步长。属性值为浮点型。默认为0.5。
android:isIndicator 设置RatingBar是否是一个指示器,即用户能否更改星级。默认为false,表示用户可以更改。
获取用户的选中结果
1 2 3 4 5 6 7
| <RatingBar
android:id="@+id/ratingbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="7"
android:rating="2"
android:stepSize="1"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class MainActivity extends AppCompatActivity {
RatingBar ratingBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ratingBar = findViewById(R.id.ratingbar);
//获取星级评分(选中了几颗星)
String rating = String.valueOf(ratingBar.getRating());
Toast.makeText(MainActivity.this, "Rating:"+rating, Toast.LENGTH_SHORT).show();
//获取每次至少改变的星级
String stepSize = String.valueOf(ratingBar.getStepSize());
Toast.makeText(MainActivity.this, "stepSize:"+stepSize, Toast.LENGTH_SHORT).show();
//获取进度
String progress = String.valueOf(ratingBar.getProgress());
Toast.makeText(MainActivity.this, "progress:"+progress, Toast.LENGTH_SHORT).show();
}
}
|
图像视图
属性
android:src 设置ImageView的内容,属性值是图片的地址。如:其中image1是图片名称
1
| android:src="@drawable/image1
|
android:src和android:background的区别:
- background通常指的都是背景,而src指的是内容。
- 当使用src填入图片时,是按照图片大小直接填充,并不会进行拉伸;而使用background填入图片,则是会根据ImageView给定的宽度来进行拉伸。
<ImageView />是正方形的。
android:layout_width和android:layout_height设置布局宽度和高度。同时可以改变内部图片的大小,而且是等比例缩放,图片不会存在拉伸的情况。
android:scaleType 控制图片如何resized/moved来匹对ImageView的size。属性值:
ImageView.ScaleType / android:scaleType值的意义区别,将属性值转换成下划线分割的大写单词即可。
参考链接:点击查看
| 属性值 |
含义 |
center |
按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示 |
centerCrop |
按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽) |
centerInside |
将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽 |
fitCenter |
把图片按比例扩大/缩小到View的宽度,居中显示 |
fitEnd |
把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置 |
fitStart |
把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置 |
fitXY |
把图片不按比例扩大/缩小到View的大小显示 |
matrix |
用矩阵来绘制,动态缩小放大图片来显示。 |
android:adjustViewBounds 参考链接:参考链接1 参考链接2
官方表述:Adjust the ImageView’s bounds to preserve the aspect ration of its drawable. 解释:调整ImageView的界限来保持图片纵横比不变。
adjustViewBounds不管是设置成true还是false,都是不会影响图片本身的比例的(长/宽)!
实际上,adjustViewBounds影响的是ImageView的比例(不是图片的比例),所以,对于adjustViewBounds的定义应该是这样:
调整ImageView的边界,使得ImageView和图片有一样的长宽比例。
android:maxWidth/android:maxHeight 设置ImageView可以显示的最大宽/高,但是在Android中,只用当设置android:adjustViewBounds="ture"的时候,maxWidth/maxHeight设置效果才能有效。
adjustViewBounds="ture"的时候,会将这个ImageView的android:scaleType属性设置为fitCenter,但是如果同时在XML文件中设置android:scaleType,则android:scaleType的优先级会更高,adjustViewBounds="ture"中对android:scaleType属性设置将会失效。这种情况,只有在Java代码中设置setAdjustViewBounds(true)的时候,才会生效。
android:tint 安卓着色器。将图片渲染成指定的颜色。
图像切换器
单击图片切换图片
1 2 3 4 5
| <ImageSwitcher
android:id="@+id/imageswitcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageSwitcher>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageSwitcher imageSwitcher = findViewById(R.id.imageswitcher);
//设置图片切换淡出
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this,android.R.anim.fade_out));
//设置图片进入
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this,android.R.anim.fade_in));
//指定视图工厂
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(R.drawable.image1);
return imageView;
}
});
//指定新的图片显示资源(单击图片切换图片)
imageSwitcher.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ImageSwitcher)v).setImageResource(R.drawable.image2);
}
});
}
}
|
实现左右滑动切换图片
1 2 3 4 5 6
| <ImageSwitcher
android:id="@+id/imageswitcher"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageSwitcher>
|
滑动动画文件,放置于res/anim目录下(anim需要自己新建):
向左推进:push_left_in.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
|
向左推出:push_left_out.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
|
向右推进:push_right_in.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
|
向右推出:push_right_out.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
|
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class MainActivity extends AppCompatActivity {
private int[] arrayPic = new int[]{R.drawable.image1,R.drawable.image2,
R.drawable.image3,R.drawable.image4};
private ImageSwitcher imageSwitcher;
private int index;
private float touchDownX;
private float touchUpX;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
imageSwitcher = findViewById(R.id.imageswitcher);
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(arrayPic[index]);
return imageView;
}
});
//触摸图像切换器,实现图像的切换
imageSwitcher.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//判断是否为按下
if(event.getAction() == MotionEvent.ACTION_DOWN){
touchDownX = event.getX();
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP){ //判断是否为抬起
touchUpX = event.getX();
if (touchUpX - touchDownX > 100){ //从左往右(向右推)
index = index == 0?arrayPic.length - 1 : index - 1;
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_right_in)); imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_right_out));
imageSwitcher.setImageResource(arrayPic[index]);
}else if (touchDownX - touchUpX > 100){ //从右往左(向左推)
index = index == arrayPic.length - 1?0 : index + 1;
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_left_in)); imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_left_out));
imageSwitcher.setImageResource(arrayPic[index]);
}
return true;
}
return false;
}
});
}
}
|
网格视图
可应用于相册。
属性
android:numColumns 设置网格布局的列数。属性值可以为整形,也可以是自动排列:auto_fit
android:verticalSpacing 设置垂直间距,单位dp。
android:horizontalSpacing 设置水平间距,单位dp。
android:stretchMode="columnWidth" 缩放与列宽大小同步
android:columnWidth 设置列宽度,单位dp。
适配器
连接后端数据和前端显示的接口,是数据和UI组件的一个重要纽带。主要在View上显示(一般是ListView)。可以看作是界面数据绑定的一种理解。它所操纵的数据一般都是一些比较复杂的数据,如数组,链表,数据库,集合等。适配器就像显示器,把复杂的东西按人可以接受的方式来展现。
使用者:ListView、GridView、Spinner、Gallery、ViewPage等都需要使用适配器来为其设置数据源。
常用的适配器
建议花费一定量的时间学习适配器
ArrayAdapter,SimpleAdapter,SimpleCursorAdapter 这三个都是继承BaseAdapter,BaseAdapter是一个抽象类,需要子类继承并实现其中的方法才能使用,常用于用户自定义适配器时,显示比较复杂的数据。
ArrayAdapter数组适配器是Android中最简单的适配器,专门用于显示列表控件,只能展示一行字。
SimpleAdapter的扩展性最好,可以定义各种各样的布局,添加ImageView、Button、CheckBox等,可以自定义出各种效果。使用SimpleAdapter的数据用一般都是HashMap构成的List,list的每一节对应ListView的每一行。HashMap的每个键值数据映射到布局文件中对应id的组件上。
SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,主要用来操作数据库。
BaseAdapter一般用于显示复杂的列表布局,由于BaseAdapter是一个抽象类,使用该类需要自己写一个适配器继承于该类,并重新一些方法。
适配器继承图:

具体使用和参数意义参考下列链接。
参考链接: 参考链接1 参考链接2 参考链接3
实现网格视图
实现网格视图,使用SimpleAdapter
准备工作:在drawable目录中放入9张图片,并命名为image1 ~image9。
1 2 3 4 5
| <GridView
android:id="@+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="3"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class MainActivity extends AppCompatActivity {
private int[] pic = new int[]{R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4, R.drawable.image5,
R.drawable.image6, R.drawable.image7, R.drawable.image8,
R.drawable.image9};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridView = findViewById(R.id.gridview);
List<Map<String, Object>> listitem = new ArrayList<Map<String, Object>>();
for (int i = 0; i < pic.length; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("image", pic[i]);
listitem.add(map);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, listitem, R.layout.cell, new String[]{"image"}, new int[]{R.id.image});
gridView.setAdapter(simpleAdapter);
}
}
|
利用网格视图,实现相册界面,使用BaseAdapter
准备工作:在drawable目录中放入9张图片,并命名为image1 ~image9。
1 2 3 4 5 6 7 8
| <GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:verticalSpacing="5dp"
android:columnWidth="100dp"
android:gravity="center"/>
|
这里的Activity继承的是Activity,而不是AppCompatActivity。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class MainActivity extends Activity {
private int[] pic = new int[]{R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4, R.drawable.image5,
R.drawable.image6, R.drawable.image7, R.drawable.image8,
R.drawable.image9};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridView = findViewById(R.id.gridview);
gridView.setAdapter(new ImageAdapter(this));
}
public class ImageAdapter extends BaseAdapter {
private Context context;
public ImageAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {return pic.length;}
@Override
public Object getItem(int position) {return null;}
@Override
public long getItemId(int position) {return 0;}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
//设置图像宽高
imageView.setLayoutParams(new GridView.LayoutParams(100, 90));
//设置图片缩放方式(保持纵横比缩放)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
//将获取的图片放入imageView
imageView.setImageResource(pic[position]);
return imageView;
}
}
}
|
下拉列表框
属性
android:entries 为下拉列表框指定列表项,属性值为数组资源。
假设在res/values目录下创建了数组资源文件arrays.xml:
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="ctype">
<item>全部</item>
<item>电影</item>
<item>图书</item>
<item>游戏</item>
</string-array>
</resources>
|
则在布局文件中有:
1 2 3 4 5
| <Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/ctype">
</Spinner>
|
除了这种方式,我们还可以使用适配器对下拉列表框的列表项进行设置。
使用适配器对下拉列表框的列表项进行设置,选择列表项后输出显示所选值
首先我们需要为Spinner设置一个id,假设id设置为spinner。
1 2 3 4 5
| <Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Spinner>
|
然后在Activity中进行编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String []ctype = new String[]{"全部","音乐","游戏","编程"};
//创建数组适配器
ArrayAdapter<String > adapter = new ArrayAdapter<>(this,android.R.layout.simple_spinner_item,ctype);
//为列表框设置下拉样式
adapter.setDropDownViewResource(android.R.layout.
simple_spinner_dropdown_item);
//将适配器和下拉列表框关联起来
Spinner spinner = findViewById(R.id.spinner);
spinner.setAdapter(adapter);
//获取下拉列表框的选项值
/*String str = spinner.getSelectedItem().toString();
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();*/
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
//根据选中项获取其值
String result = parent.getItemAtPosition(position).toString();
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) { }
});
}
}
|
列表视图
可应用于用户列表。
和下拉列表框一样,可以使用android:entries来给列表视图设置列表项。
具体步骤参考 下拉列表框 即可。
同样除了这种方式,我们还可以使用适配器对列表视图的列表项进行设置。
使用适配器对列表视图的列表项进行设置,点击获得列表项的所选值
首先需要给<ListView />设置一个id。
1 2 3 4
| <ListView
android:id="@+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] ctype = new String[]{"全部","音乐","游戏","编程"};
//设置适配器和viewlist的外观形式,可以有多种选择
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,ctype);
ListView listView = findViewById(R.id.listview);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String str = (String) parent.getItemAtPosition(position);
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
});
}
}
|
滚动视图
滚动视图可以在xml文件中添加,也可以在java文件中添加。
滚动视图默认是竖直的滚动,但我们也可以设置其他的滚动方式。
如果我们要设置水平方向的滚动,则需要使用<HorizontalScrollView />标记。
在一个滚动视图中,只能放置一个组件,如果想要放置多个,我们需要使用布局管理器把这些组件括起来。
使用xml文件创建滚动视图
准备:创建一个字符串资源,在res/values/strings.xml中创建:
1 2 3 4 5
| <resources>
<string name="app_name">scrollview</string>
<string name="content"> 安卓是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成。</string>
</resources>
|
创建竖直的滚动视图:
1 2 3 4 5 6 7 8 9
| <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/content"
android:textSize="30sp" />
</ScrollView>
|
创建水平的滚动视图:注意组件的长、宽设置
1 2 3 4 5 6 7 8 9
| <HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/content"
android:textSize="30sp" />
</HorizontalScrollView>
|
在滚动视图中创建多个组件:
1 2 3 4 5 6 7 8 9 10 11 12
| <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--TextView中属性省略-->
<TextView />
<TextView />
</LinearLayout>
</ScrollView>
|
使用java文件创建滚动视图
步骤:
- 使用构造方法ScrollView(Context c)创建一个滚动视图;
- 应用addView()方法添加组件到滚动视图中;
- 将滚动视图添加到布局管理器中。
在这里我们回创建一个带有图片和文字的滚动视图,因此需要我们先准备好图片资源和字符串资源。
假设我们已准备好图片资源并命名为image.jpg,同时我们需要把图片资源放置于res/drawable目录下。而我们使用的字符串资源就继续使用上文的content字符串资源。
根布局文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="vertical"
tools:context=".MainActivity">
</LinearLayout>
|
Activity文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取根布局管理器
LinearLayout ll = findViewById(R.id.ll);
//新建一个垂直的线性布局管理器
LinearLayout ll2 = new LinearLayout(MainActivity.this);
ll2.setOrientation(LinearLayout.VERTICAL);
//创建一个滚动视图对象
ScrollView scrollView = new ScrollView(MainActivity.this);
//将视图进行组合
ll.addView(scrollView);
scrollView.addView(ll2);
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(R.drawable.image);
ll2.addView(imageView);
TextView textView = new TextView(MainActivity.this);
textView.setText(R.string.content);
ll2.addView(textView);
}
}
|
选项卡
我们不能使用某个具体的组件在xml文件添加选项卡。
使用步骤
- 在布局文件中添加
TabHost、TabWidget和TabContent组件。TabHost和TabWidget在布局文件中有具体的标记,而对于TabContent我们需要使用FrameLayout来实现。
- 编写各标签页的XML布局文件。(如果我们选项卡有几个标签页,就需要编写几个布局文件,布局文件的内容就是我们需要在选项卡中显示的内容)
- 获取并初始化
TabHost组件。
- 为
TabHost对象添加标签页。
具体实例
准备:我们在选项卡中实现两张图片的切换,因此我们需要两张图片。假设这两张图片命名为image_left.jpg和image_right.jpg,并将它们放置在res/drawable目录下。
**我们首先编写各标签页的XML布局文件:**tab1.xml和tab2.xml
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/image_left"/>
</LinearLayout>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/image_right"/>
</LinearLayout>
|
编写根布局文件:
注意:在根布局文件中,TabHost、TabWidget和FrameLayout的id需要使用Android给我提供的,不能自己随意命名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@android:id/tabs"></TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
</TabHost>
|
在Activity文件中初始化TabHost组件,并为其添加标签页:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取TabHost对象
TabHost tabHost = findViewById(android.R.id.tabhost);
//对TabHost组件进行初始化
tabHost.setup();
//为TabHost添加标签页
//初始化LayoutInflater
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.tab1,tabHost.getTabContentView());
inflater.inflate(R.layout.tab2,tabHost.getTabContentView());
//为TabHost设置标签页及文字内容
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("图片1").setContent(R.id.left));
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("图片2").setContent(R.id.right));
}
}
|
Android布局与组件完