【Android】【移动应用开发】基础知识
文章目录
- 一. AndroidMainifest.xml文件的结构
- 二. Android的四大组件
- 三. 基础界面组件与布局
- 四. 高级界面组件与布局
- 五. 菜单和对话框
- 六. 服务和消息广播
- 七. 数据的存储与访问
- 八. 多媒体应用开发
- 常用功能类
- 常用资源文件
一. AndroidMainifest.xml文件的结构
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android" <!--定义Android命名空间-->
package="com.example.tong_xun_lu"> <!--指定appJava程序的包名-->
<uses-permission android:name="android.permission.CALL_PHONE"/> <!--权限定义-->
<application
android:icon="@mipmap/ic_launcher" <!--指明App安装后显示的图标-->
android:label="@string/app_name" <!--指明App安装后显示的文字信息-->
android:theme="@style/Theme.AppCompat.Light.NoActionBar"> <!--指明App的主题风格-->
<activity
android:name=".MainActivity" <!--指明activity对应的类名(启动的主文件)-->
android:label="QQ" <!--指明该name指定的Activity运行后的标签名-->
android:screenOrientation="unspecified" <!--横屏竖屏设置-->
android:exported="false" /> <!--拒绝被别的APP启动该Activity-->
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <!--表明此activity是作为App的入口-->
<category android:name="android.intent.category.LAUNCHER" /> <!--决定App是否显示在程序列表里-->
<data android:mimeType="video/mpeq"
android:scheme="http"(URI协议) android:host="www.nnutc.edu.cn"(主机)
android:port="8080"(端口) android:path="/web"(路径)/> <!--用于指定一个URL和数据类型-->
</intent-filter>
</activity>
<activity android:name=".addActivity"></activity> <!--增加addActivity,注意要加点-->
</application>
</manifest>
二. Android的四大组件
(一) Activity(活动)
🔰Activity是Android App的表现层,显示可视化的用户界面,并且接收与用户交互所产生的界面事件;
🔰子类Activity需要实现的方法:
1)onCreate(Bundle)
:初始化Activity。使用setContentView(int)方法将布局资源定义到用户界面上;使用findViewById(int)在用户界面中检索需要编程交互的小部件;
2)onPause()
:处理当离开Activity时要做的事情。
(二) BroadcastReceiver(广播接收器)
🔰BroadcastReceiver是用来接收并相应广播消息的组件,他不含任何用户界面,不做任何事情,仅是接受广播并作出相应的反应;
🔰使用时,可以用Context.registerReceiver()方法在程序代码中动态地注册这个类的使用实例,也可以通过AndroidMainifest.xml中的<receiver>
标签中静态声明;
(三) Service(服务)
🔰Service没有可视化用户界面,但需要长时间在后台运行的应用;
🔰使用时,每个Service类在AndroidMainifest.xml中有相应的<service>
声明;Service可以通过Context.startService()和Context.bindService()启动;
(四) ContentProvider(内容提供者)
🔰 ContentProvider是Android提供的一种标准的共享数据机制,App通过它访问其他App私有数据;
三. 基础界面组件与布局
(一) 组件共用属性
属性值 说明 android:id=“@+id/tiaoshi” ID号,是组件的唯一标识 android:layout_width=“wrap_content” 组件宽度
wrap_content
:大小适应文本内容
match_parent
:大小适应父组件大小android:layout_height=“wrap_content” 组件高度
wrap_content
:大小适应文本内容
match_parent
:大小适应父组件大小android:layout_weight=“5” 设置权重,即让一行或一列的组件按比例显示 android:drawableLeft=“@mipmap/suo”
android:drawableRight
android:drawableTop
android:drawableBottom设置编辑框文本的左边,右边,上边,底部显示的drawable
如:在密码输入框前加个锁android:drawablePadding 设置编辑框文本与drawable的间隔,与drawableLeft等一起使用,可以设置为负数,单独使用没有效果 android:layout_marginLeft=“30dp”
android:layout_marginRight
android:layout_marginTop
android:layout_marginBottom设置编辑框与手机边缘之间的间距 (外边距) android:background=“#369733” 设置Image View的背景颜色或图片
(二) 文本显示组件【TextView】
🔰具备基本的显示文本功能,可设置文本大小,位置,颜色等属性;
效果如下:
属性值 说明 android:text=“hello world!” 显示文本内容 btn.setText("你好");
android:textSize=“20sp” 文本大小,单位sp android:textColor=“#973030” 文本颜色 android:textStyle=“normal” 设置字形
bool 粗体, italic 斜体, normal 正常android:lines=“2” 设置文本的行数 android:autoLink=“web” 设置是否当文本为:URL链接(all, web),E-mail(email),电话号码(phone),Map(map)时,文本显示可单击的链接 android:gravity=“center” 设置文本框内文本的对齐方式
top / bottom / left / right /
center_horizontal(横向中央位置对齐)android:layout_gravity=“center” 组件本身相对于父组件的显示位置
(三) 按钮组件【Button】
🔰Button是TextView的子类,所以TextView上的很多属性可以直接应用到Button上;对于Button操作主要是按下后执行何种操作;>
效果如下:
属性名 说明 android:clickable=“true” 设置是否允许点击按钮 ,true/false btn.setClickable(boolean)
android:background=“#980F0F” 通过资源文件设置颜色 android:onClick 设置点击事件 setOnClickListener(OnClickListener)
1. 按钮点击监听事件
bt = (Button) this.findViewById(R.id.rgWhcd);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 功能代码
}
});
(四) 线性布局【LinearLayout】
🔰可以使用水平(Horizontal) 或 垂直(Vertical) 两种方式放置组件;
属性名 说明 android:orientation=“vertical” 设置线性布局的方向 horizontal(水平)
vertical(垂直)
(五) 编辑框组件【EditText】
🔰EditText是TextView的子类,主要操作是用户与AndroidApp进行数据传输的窗口;
效果如下:
属性名 说明 android:hint=“密码” 设置编辑框内容为空时显示的文本 android:inputType=“phone” 设置编辑框中限制输入的类型:(number—整数,numberDecimal—小数点,date—日期,text—文本,phone—拨号键盘,textPassword—密码,textVisiblePassword—可见密码,textUri—网址) android:maxLength=“10” 限制显示的文本长度,超出部分不显示 android:digits=“123456789” 设置允许输入那些字符
(六) 图像显示组件【ImageView】
🔰用于显示图片,图片可来自资源文件,Drawable对象和ContentProvider;
属性名 说明 android:adjustViewBounds=“true” 设置Image View是否自动调整边界来适应显示图片的宽长比, true/false android:maxHeight=“20dp” 设置Image View的最大高度 android:maxWidth=“20dp” 设置Image View的最大宽度 android:scaleType=“matrix” 设置Image View所显示的图片如何缩放或移动以适应Image View的大小 android:src=“@mipmap/beijing” 设置Image View所显示的图像路径 🔰
src
指ImageView上显示的内容,按图片大小填充,不拉伸;background
指的是背景,会进行拉伸;
(七) 相对布局【RelativeLayout】
🔰它可以在屏幕大小不同,分辨率不同的Android终端屏幕上友好显示的一种布局方式;
1. 设置组件与组件之间的关系和位置的相关属性
属性名 | 说明 |
---|---|
android:layout_above=“@id/shuru” | 将该组件的底部至于给定的ID组件的上面 |
android:layout_below=“@id/shuru” | 将该组件的底部至于给定的ID组件的下面 |
android:layout_toLeftOf=“@id/shuru” | 将该组件的右边缘与给定的ID组件的左边缘对齐 |
android:layout_toRightOf=“@id/shuru” | 将该组件的左边缘与给定的ID组件的右边缘对齐 |
2. 设置组件与组件之间对齐方式的相关属性
属性名 | 说明 |
---|---|
android:layout_alignBaselineabove=“@id/shuru” | 将==该组件的基线与给定ID组件的基线对齐 == |
android:layout_alignTop=“@id/shuru” | 将该组件的顶部与给定ID组件的顶部对齐 |
android:layout_alignBottom=“@id/shuru” | 将该组件的底部与给定ID组件的底部对齐 |
android:layout_alignLeft=“@id/shuru” | 将该组件的左边缘与给定ID组件的左边缘对齐 |
android:layout_alignRight=“@id/shuru” | 将该组件的右边缘与给定ID组件的右边缘对齐 |
3. 设置组件与父组件之间对齐方式的相关属性
属性名 | 说明 |
---|---|
android:layout_alignParentTop=“true” | 将该组件的顶部与父组件的顶部对齐 |
android:layout_alignParentBottom=“true” | 将该组件的底部与父组件的底部对齐 |
android:layout_alignParentLeft=“true” | 将该组件的左边缘与父组件的左边缘对齐 |
android:layout_alignParentRight=“true” | 将该组件的右边缘与父组件的右边缘对齐 |
4. 设置组件方向的相关属性
属性名 | 说明 |
---|---|
android:layout_centerHoriaontal=“true” | 将该组件置于水平方向的中央 |
android:layout_centerVertical=“true” | 将该组件置于垂直方向的中央 |
android:layout_centerInParent=“true” | 将该组件置于水平方向和垂直方向的中央 |
(八) 单选按钮【RadioButton】
🔰在布局中直接定义
RadioButton
组件,如果界面有多个RadioButton
则表示可以多个,或全部选中;
🔰与RadioGroup
配合使用,这种方式定义下的RadioButton
只可以选中一个;
🔰一般RadioButton
组件必须放在RadioGroup
中才能达到效果;
效果如下:
🔰Radio Group的常用属性和方法
属性名/方法名 说明 android:orientation=“horizontal” 设置里面的RadioButton摆布方式;
horizontal(水平)
vertical(垂直)void clearCheck() 清除单选按钮中所有单选按钮的选中状态 int getCheckedRadioButtonId() 返回该单选按钮组中所选按钮的标识id,如果没有勾选则返回-1 void setOnCheckedChangeListener() 注册一个当该按钮组中的单选按钮勾选状态发生改变时所要用的回调函数
1. 单选按钮监听事件
// 三选一,点击那个,就那个显示在标签上
RadioGroup zu = this.findViewById(R.id.zu);
RadioButton nan = this.findViewById(R.id.nan);
RadioButton nv = this.findViewById(R.id.nv);
RadioButton renyao = this.findViewById(R.id.renyao);
TextView wenzi = this.findViewById(R.id.wenzi);
zu.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i){
case R.id.nan:
wenzi.setText(nan.getText());
break;
case R.id.nv:
wenzi.setText(nv.getText());
break;
case R.id.renyao:
wenzi.setText(renyao.getText());
break;
}}});
(九) 复选框组件【CheckBox]
🔰用于实现多个选项同时被选中的功能,是Button的子类支持Button的所有属性
效果如下:
🔰多选按钮一般都是通过按钮的监听事件来监听。
(十) 下拉列表框【Spinner】
🔰是ViewGroup的间接子类,因此可以作为容器使用;
🔰在value下的strings.xml文件中添加数组作为数据来源;
效果如下:
属性/方法名 说明 android:spinnerMode 列表框的模式
dialog:对话框风格的窗口
dropdown:下拉菜单风格的窗口android:entries=“@array/shuzu” 使用数组资源设置改下拉列表的列表项目 android:dropDownWidth=“200px” 设置下拉列表框的宽度 android:dropDownVerticalOffset=“60px” 设置列表框的水平垂直距离
下拉列表框整体往下移*单位android:prompt=“@string/biaoti” 设置对话框模式列表框的标题,只能引用string.xml中的资源id,不能直接写字符串 android:dropDownSelector=“#F3A0A0” 列表框被选中时的背景 android:popupBackground=“#F3A0A0” 设置列表框的背景 android:dropDownHorizontalOffset 设置列表框的水平偏移距离 void setSelection(int n) 默认下拉列表框的第一项为选中项目,用这个方法指定第n个条目为选中条目 Object getSelectedItem() 返回列表框中选中项
1. 下拉列表步骤及事件监听
🔰下拉列表的使用一般按如下步骤进行:
- 在布局文件中定义控件
<Spinner android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/dd"/>
- 在Activity中引用
Spinner spinner = (Spinner)this.findViewById(R.id.dd);
- 创建一个适配器(Array Adapter)为Spinner提供数据,Array Adapter中的数据来源于字符串数组和XML两种方式;
方法一:使用字符串数组作为数据来源String[] provinces = new String[] {"江苏省", "浙江省", "上海市"}; // 设置Array Adapter ArrayAdapter <String> weekArray = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,provinces); // 三个参数分别为Context,布局文件,数组
方法二:使用XML作为数据来源,内容放到values目录下的strings.xml资源文件中
<resources> <string-array name="provinces_array"> <item>江苏省</item> <item>浙江省</item> <item>上海省</item> </string-array> </resources>
设置Array Adapter
ArrayAdapter provinceArray = ArrayAdapter.createFromResource(this, R.array.provinces_array, android.R.layout.simple_spinner_item); provinceArray.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- 将适配器与Spinner相关联
spinner.setAdapter(provinceArray);
- 创建一个监听器
class SpinnerListener implements AdapterView.OnItemSelectedListener { @Override public void onItemSelected(AdapterView<?>arg0, View arg1, int arg2, >long arg3) { String selected = arg0.getItemAtPosition(arg2).toString(); Toast.makeText(MainActivity.this, "你所在的省份是:" + selected, Toast.LENGTH_LONG).show(); }
- 绑定监听器
spinner.setOnItemSelectedListener(new SpinnerListener());
🔰如果开发者使用Spinner时己经可以确定列表选择框里的列表项,则完全不需要编写代码,也不需要设置适配器,直接使用android:entries属性来设置数组资源作为下拉列表框的列表项目,即可以省略(3)和(4)步骤。
(十一) 评分条【RatingBar】
🔰用星型来表示评分等级,设置时默认可以选择三种不同的风格;
效果如下:
属性 说明 android:isIndicator=“false” 设置是否可以与用户交互(默认true表示不可交互)
设置用户是否可以点击android:rating=“1.5” 默认的评分数,一开始就有的评分数 android:stepSize=“1.0” 点击一次增长的长度 android:numStars=“5” 表示星星数量 style=“?android:ratingBarStyleIndicator” 设置风格 ?android:ratingBarStyle
大号星星?android:ratingBarStyleIndicator
正常星星?android:ratingBarStyleSmall
小号星星float getRating() 获取当前评分,与参数rating一致
1. 星级进度改变时监听事件
// 用RatingBar.OnRatingBarChangeListener()实现星级进度改变时触发事件
RatingBar pingfen = this.findViewById(R.id.pingfen);
TextView buchang = this.findViewById(R.id.bu);
pingfen.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
buchang.setText("你的评分结果为:"+pingfen.getRating()+"");
}});
(十二) 帧布局【FrameLayout】
🔰它是一种在Android终端屏幕上开辟一块空白区域的布局方式,放置在空白区域的组件必须对其到屏幕的左上角;
🔰帧布局的大小由子元素中尺寸最大的那个来决定;
1.【TabHost】组件
🔰继承自FrameLayout,是带Tab选项卡的容器,包含
TabWidget
和FrameLayout
两部分;
🔰TabWidget
是每个Tab选项卡标签按钮;FrameLayout
是每个Tab选项卡的内容;
2. 定义布局文件
🔰Tab选项卡的用户界面布局文件的设计需要遵循下表的要求定义;
属性 说明 TabHost 可自定义id TabWidget 必须设置 android:id
为@android:id/tabs
FrameLayout 必须设置为 android:id
为@android:id/tabcontent
3. 选项卡标签位置放置
1)放置用户界面顶部
布局内容需要用【LinearLayout来布局】;
2)放置用户界面底部
布局内容需要用【RelativeLayout】来布局,并且在【TabWidget】内添加android:layout_alignParentBottom="true"
4. TabSpec常用方法
方法名 | 说明 |
---|---|
setIndicator(CharSequence label | 用于指定选项卡显示的标签名 |
setIndicator(CharSequence label, Drawable icon) | 用于指定选项卡显示的标签名及图片 |
setIndicator(View view) | 用于指定选项卡显示的标签View |
setContent(int viewId) | 用于指定选项卡显示的内容,通常在布局文件中定义 |
setContent(Intent intent) | 用于指定选项卡显示的内容,通常Inter用来封装启动另一个Activity |
setCurrentTab(int index) | 用于指定默认选项卡 |
5. 考试系统案例
🔰布局代码
<TabHost
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/kaoshiXT">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@android:id/tabcontent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/danxuan"
android:orientation="vertical">
<!-- 单选布局-->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/duoxuan1"
android:orientation="vertical">
<!-- 多选布局-->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/jianda"
android:orientation="vertical">
<!-- 简答题布局-->
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
🔰Java代码
TabHost tabHost = (TabHost) findViewById(R.id.kaoshiXT); // 获取TabHost对象
tabHost.setup(); // 通过setup()方法加载启动Tab Host
tabHost.addTab(tabHost.newTabSpec("tab01").setIndicator("单选题").setContent(R.id.danxuan));
tabHost.addTab(tabHost.newTabSpec("tab01").setIndicator("多选题").setContent(R.id.duoxuan1));
tabHost.addTab(tabHost.newTabSpec("tab01").setIndicator("简答题").setContent(R.id.jianda));
tabHost.setCurrentTab(2); // 指定2号选项卡为默认选项卡(选项卡自动0,1,2排序)
(十三) 表格布局【TableLayout】
🔰该布局是由一系列行和列组成的网格,在这些网格的单元格中可以显示View组件;
🔰它是和TableRow配合使用的一种常用的布局管理方式,每个TableRow对应表格里的一行,TableRow的内容由单元格中的View组件组成;
🔰有多少个TableRow 就有多少行;
🔰全局属性(列属性,写在TableLayout里面)
属性名 说明 android:stretchColumns="* " 设置允许被拉伸的列的序号 android:shrinkColumns="* " 设置允许收缩的列的序号
可以设置多个列,但必须用逗号隔开android:collapseColumns=“1, 2” 设置要隐藏的列的序号 🔰单元格属性(单元格内书写)
属性名 说明 android:layout_column=“1” 指定该单元格在第几列显示 android:layout_span=“2” 合并2个单元格,即该组件占据2个单元格 🔰在使用TableLayout布局设计APP界面布局时,需要注意以下几点:
- 如果直接在TabLayout中添加组件(只添加一个),那么该组件占满一行;
- 如果一行上要放置多个组件,就必须添加TabRow容器,并将组件放置在TabRow容器中;
- TableRow中组件个数决定了该行有多少列,列的宽度由该列中最宽的单元格决定;
- TableRow的layout_width属性默认是match_parent; layout_height属性默认是wrap_content;
- 整个表格布局的宽度取决于父容器的宽度;
- 整个表格的行数由TableRow的数目及单独组件数目决定,列数由TableRow中最多个组件数决定;
🔰如果需要增加间隔线,可以在两个组件之间添加View,并设置该View的layout_height和background属性;
<View android:layout_height='2dp' android:background='#f00f00'/>
🔰实例
<!--表格布局-->
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="*"
android:stretchColumns="*">
<!-- 第一列-->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<!-- 单元格1 ,2, 3, 4, 5-->
</TableRow>
<!-- 第二列-->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<!-- 单元格1 ,2, 3, 4, 5-->
</TableRow>
<!-- 第三列-->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<!-- 单元格1 ,2, 3, 4, 5-->
</TableRow>
</TableLayout>
四. 高级界面组件与布局
(一) Adapter适配器基础
🔰Adapter是一个接口。在进行高级界面设计时,需要使用Adapter将数据源绑定到指定的View上。常见的ListView,GridView等都需要用到Adapter。
🔰常用子类有ListAdapter,BaseAdapter,ArrayAdapter,SimpleAdapter,SimpleCursorAdapter等。
1. ListAdapter
🔰ListAdapter是一个直接继承于Adapter的接口类,它是ListView和数据之间的接口,通常数据来源于一个Cursor(游标),用于显示ListAdapter中的数据;
2. BaseAdapter
🔰BaseAdapter是ListAdapter和SpinnerAdapter接口的抽象类,通过重写View getView(int position, View convertView, ViewGroup parent),int getCount(),long getItemId(int position)和Object getItem(int position)四个方法,可以实现复杂的用户界面布局;
3. ArrayAdapter
🔰ArrayAdapter是继承与BaseAdapter的一个具体类。默认情况下,ArrayAdapter绑定每个对象的字符串值到系统默认布局的TextVIew或开发者自定义的TextView上,每行只能显示一个文本;
🔰常用的构造方法:public ArrayAdapter(Context context, int resource, T[] object)
- 第一个参数为上下文;
- 第二个参数包含一个TextView, 用来填充ListView的每一行布局资源;
- 第三个参数为ListView上每一行具体要显示的数据;
🔰实际运用:在List View部分有实际运用;
1) Android 系统提供的布局资源及功能说明
布局资源 | 功能 |
---|---|
android.R.layout.simple_list_item_1 | 每一项只有一个TextView |
android.R.layout.simple_list_item_multiple_choice | 每一项有一个复选框,需要用setChoiceMode()方法设置选择模式(ListView.CHOICE_MODE_MULTIPLE【多选模式】) |
android.R.layout.simple_list_item_checked | 每一项有一个选择项,需要用setChoiceMode()方法设置选择模式(ListView.CHOICE_MODE_MULTIPLE【多选模式】) |
android.R.layout.simple_list_item_single_choice | 每一项有一个单选按钮,需要用setChoiceMode()方法设置选择模式(ListView.CHOICE_MODE_SINGLE 【单选模式】) |
4. SimpleAdapter
🔰SimpleAdapter是继承与BaseAdapter的一个具体类。它可以根据开发者的要求在每一行上显示图片,文本等复杂的布局对象,可以自定义出各种效果显示在ListView的每一行上;
🔰构造方法:public SimpleAdapter(Context context, List<?extends Map<String, ?>>data, int resource, String[] from, int[] to);
- 参数1为上下文;
- 参数2为用HashMap(String, Object)构造的List;
- 参数3为ListView上显示的每行布局文件的ID;
- 参数4为HashMap中所有键构成的字符串数组;
- 参数5为ListView上每一行布局文件中对应组件ID构成int型数组;
🔰运用顺序:
- 在主布局文件上布局LIst View组件;
- 新建一个布局文件item,布局一行显示的自定义效果;
- Java代码:
ListView lv = this.findViewById(R.id.lv); int imgid[] = {R.mipmap.caocao, R.mipmap.guanyu, R.mipmap.huangzhong, R.mipmap.liubei}; String itemname[] = {"曹操", "关羽", "黄忠", "刘备"}; // 下面7行代码用于为 SimpleAdapter 准备 HashMap 构成的 List 数据集 ArrayList<HashMap<String, Object>>itemlist = new ArrayList<>(); for (int i=0; i<imgid.length; i++) { // HashMap 构成 List 数据集 HashMap<String, Object> map= new HashMap<>(); map.put("itemimg", imgid[i]); map.put("itemname", itemname[i]); itemlist.add(map);} // 用于指定数据源与 ListView 的每一行中每个显示项对应的键 String[] from = {"itemimg", "itemname"}; // 用于指定 ListView 的每一行中每个显示项对应键的值填充到对应组件的ID int[] to={R.id.img, R.id.name}; // Simple Adapter 装配数据 SimpleAdapter simpleAdapter=new SimpleAdapter(this, itemlist, R.layout.item,from,to); // 将Adapter与ListVIew关联 lv.setAdapter(simpleAdapter);
5. SimpleCuisorAdapter
🔰SimpleCuisorAdapter用于绑定数据库中的数据,它有以下的构造方法。
``
(二) 显示模板【ListView】
🔰以列表方式显示内容,必须包含三个关键元素:
- ListView 中每一行的View;
- 填入View中的数据可以是被映射的字符串,图片或基本组件;
- 连接数据与ListView的Adapter;
<ListView android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/lv"/>
public class MainActivity extends AppCompatActivity { private ArrayAdapter adapter; private String[] item = {"周一", "周二", "周三", "周四", "周五", "周六", "周天"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView lv = this.findViewById(R.id.lv); // 为ArrayAdapter装配数据 adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_single_choice, item); // 将Adapter与ListVIew关联 lv.setAdapter(adapter); // 设置选择模式(单选模式) lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); // 设置单击监听事件(单选项) lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { // 单击某项,转为Text View类型 TextView tv = (TextView)view; Toast.makeText(MainActivity.this, tv.getText().toString()+":"+item[i],Toast.LENGTH_SHORT).show(); // tv.getText().toString():获取Text View上的文本信息 // item[i]:获取item数组中下标为i的元素 } }); --------------------------------------------------------------------------------- // 设置选择模式(多选模式) lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); // 设置单击监听事件(多选项) lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { // 采用布尔数组判断 SparseBooleanArray checked = lv.getCheckedItemPositions(); String str = ""; for (int j=0; j<item.length;j++) { if (checked.get(j)){ // 如果该位置被选中 str+=item[j]; } } Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } }); }}
1. ListView 设置监听事件
🔰单击,调用setOnItemClickListener()方法;
ListView lv = this.findViewById(R.id.lv); lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { } });
🔰长按,调用setOnItemLongClickListener()方法;
ListView lv = this.findViewById(R.id.lv); lv.setOnItemLongClickListener(new >AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) { return false; } });
- 参数1表示事件发生的AdapterView;
- 参数2表示单击或长按的ListView的某一项View;
- 参数3表示单击或长按的这一项在Adapter中的位置;
- 参数4表示单击或长按的这一项在ListView中的位置;
(三) Intent触发器
🔰在Android系统的四个核心组件中,除了Contentprovider以
外,其他三个核心组件(Activity、Service、Broadcast
receiver)实际上都是被一个叫做Intent的异步消息来激活的。
🔰激活的组件可以是Android系统自身提供的,也以是开发者
自定义的,其激活方式有显式Intent和隐式Intent两种。
🔰一个Intent对象可以包含以下六个信息:
- ComponentName(组件名称):指明Intent对象的组件名称,是一个可选项,如果被设置,Intent对象就显式指定了要转向的组件。
- Action(动作):指明Intent要完成的一个动作,是在Intent-Filter中指定字符串常量;该字符可以在App的配置文件中定义,也可以是系统自带的。Intent不用直接指明这个组件。交给Android去根据IntentFilter做匹配筛选,选择符合的组件去启动
Action常用常量和功能说明
常量值 功能说明 android.intent.action.MAIN 应用程序入口 android.intent.action.VIEW 显示数据给用户 android.intent.action.DIAL 电话拨号并显示拨号用户界面 android.intent.action.CALL 直接打电话 android.intent.action.SEND 直接发送短信 android.intent.action.SENDTO 选择对象发短信
- Data(数据):通常用于向系统提供数据,即Action需要的数据,一般用URL和对应的MIME类型来表示,也是在IntentFIlter 中定义的。例如,如果动作是ACTION_VIEW,则需要提供访问目标URI(用http://URI表示)数据。
- Category(类别):用于为Action提供额外的附加类别信息,也是IntentFilter中的字符串常量;一个Intent对象只能设置一个Action,但是可以设置多个Category。Category和Action通常在IntentFilter中使用,用于实现隐式Intent。Category可以直接使用系统定义的,也可以由开发者自己定义。
常量值 功能说明 android.intent.category.LAUNCHER 程序最优先启动的Activity android.intent.category.HOME 程序启动后显示的第一个界面
- Extras(扩展域):用于Intent对象附加一个或多个键值对信息,该键值对是一个Bundle对象。
- Flags(标志):用于告诉Android如何启动Activity,启动后如何处理。
🔰可用IntentFilter过滤不满足条件的组件。
1. IntentFilter
🔰IntentFilter负责过滤所提供的组件功能。
🔰IntentFilter是由动作(Activity),类别(Category)和数据(Data)构成的一种过滤筛选机制。
2. 显式Intent
🔰显式Intent:通过指定目标组件名称来启动组件,并且每次启动的组件只能有一个。
🔰一般情况下由于开发者不知道其他应用程序的组件名称,所以显式Intent通常用于启动应用程序内部组件;
🔰在Activity中通过调用startActivity()或startActivityForResult()方法,在方法参数中传递Intent对象,实现不同Activity间的切换和数据传递。
🔰显示Intent启动Activity:
- 实现直接指定需要打开的Activity对应类。
例如:单击Button可以实现从A_Activity跳转到B_Activity,需创建两个对应的Java文件和对应的布局文件;tvAdd=findViewById(R.id.tvadd); tvAdd.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // 显示Intent启动Activity // MainActivity.this 目前的文件 AddActivity.class 需要打开的文件,以class结尾 Intent intent = new Intent(MainActivity.this, AddActivity.class); MainActivity.this.startActivity(intent); } });
3. 隐式Intent
🔰隐式Intent:不指定要启动的目标组件名称,而是指定Intent的Action、Data或Category等;
🔰通常用隐式Intent激活其他应用程序中的组件;
🔰在启动组件时,会去匹配AndroidManifest.xml 相关组件的Intent-filter,并逐一匹配出满足属性的组件,当不止一个满足时就会弹出一个让用户选择启动哪个目标组件的对话框。
🔰隐式Intent启动Activity:
- 隐式启动是指Android根据过滤规则自动匹配对应的Intent,不需要明确指明。可以启动App自身的Activity,也可以是内置的,或者第三方App提供。
🔰在AndroidMainfest.xml中添加AddActivity中的intent filter属性,将categroy的属性设为
android.intent.category.DEFAULT
。<activity android:name=".add_layout" android:exported="false" > <intent-filter> <action android:name="app.java.MYACTION"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
🔰在MainActivity.java中点击文本监听事件设置Intent发送的Action为
app.java.MYACTION
add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); // Action 的 name 与 xml 中的匹配 intent.setAction("app.java.MYACTION"); MainActivity.this.startActivity(intent); } });
🔰如果Activity支持接收隐式Intent,就一定要在intent filter中加入category属性值"android.intent.category.DEFAULT“。
🔰如果开发的APP要明确拒绝被别的APP启动某一个Activity,就需要在配置清单文件的Activity标签中设置exported的属性值为false。
Intent调用其他常用组件
4. 取消程序名称显示
🔰没有取消之前:
🔰在AndroidMainfest.xml中修改theme样式为android:theme=“@style/Theme.AppCompat.NoActionBar”,其效果如下:
🔰:在AndroidMainfest.xml中修改theme样式为android:theme=“@style/Theme.AppCompat.Light.NoActionBar”,其效果如下:
5. Intent调用其他常用组件
// 打电话
// 直接打电话
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
// 拨电话
// 打开拨打电话的UI
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
// 打开指定网页
// 使用浏览器打开百度的首页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
// 发短信
// 向10086发送Hello内容短信
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("tel:10086"));
intent.putExtra("ama_boby", "Hello");
MainActivity.this.startActivity(intent);
6. Intent传递数据
🔰当一次传递一个数据时,可以直接调用Intent的putExtra()方法存入数据;在获得Intent后调用getXXXExtra()方法获得对应的数据。
A_Activity.java 文件 add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, add_layout.class); String s = add.getText().toString(); // 存入数据 intent.putExtra("edts", s); startActivity(intent); } }); ----------------------------------------------------------------- B_Activity.java 文件 // 获取对应的数据 Intent intent = this.getIntent(); // 传入字符串,名字与上方要一样 String s = intent.getStringExtra("edts"); text.setText(s);
🔰当一次传递多个数据时,可以使用Bundle对象作为容器,通过调用Bundle的putXXX()方法先将数据存储到Bundle中,接着调用Intent的putExtras()方法将Bundle存入Intent中,然后在获得Intent以后调用getExtras()获得Bundle容器,最后调用其getXXX()方法获取对应的数据。
A_Activity.java 文件 add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, add_layout.class); Bundle bundle = new Bundle(); String zh = zhanghao.getText().toString(); String mm = mima.getText().toString(); // 利用Bundle存储多个数据 bundle.putString("zhanghao", zh); bundle.putString("mima", mm); // 存入Intent intent.putExtras(bundle); startActivity(intent); } }); ----------------------------------------------------------------- B_Activity.java 文件 // 获取对应的数据 Intent intent = this.getIntent(); // 获得Bundle容器 Bundle bundle = intent.getExtras(); // 获取对应数据 String zhangh = bundle.getString("zhanghao"); String mim = bundle.getString("mima"); text1.setText(zhangh); text2.setText(mim);
(四) 碎片化组件【Fragment】
🔰Fragment碎片化组件,用于提高代码重用性,改善用户体验和适应大屏幕的需求;
🔰
1. Fragment 布局文件的创建
- 参数1是需要加载的布局文件名;
- 参数2为返回的VIew对象;
- 参数3为true表示表示将root作为根对象返回,否则为false表示将这个root对象的布局参数属性附加到根布局对象上。
(五) View的左右滑屏切换【ViewPager】
🔰 ViewPager手势滑动完成View的左右滑屏切换,可以作为引导页,图片轮播等功能。
🔰继承了ViewGroup类,也是一个容器类,可在其中添加其他的View类。
🔰相关实例内容请看【Android——APP引导页,图片轮播功能实现】
1. PagerTitleStrip
🔰是ViewPage的一个关于当前页,上一页,下一页非交互性指示器,相当于每个页面的标题。
2. PagerTabStrip
🔰PagerTabStrip是ViewPage的一个关于当前页,上一页,下一页交互性指示器,会由一条下划线提示当前在那一页,且单击Tab时,会跳转到该页面。
(六) 左右轮播及上下轮播【ViewFlipper】
🔰ViewFlipper 一般用于图片的切换,当然也可以添加用户自定义的View 或其他 View 对象,并实现View的切换。
🔰ViewAnimator 相关方法及功能说明
方法 功能 setInAnimation 设置View进入屏幕时使用的动画,可以直接传入Animation对象,也可以传入定义的Animation文件的 setOutAnimation 设置VIew退出屏幕时使用的动画,使用方法和setInAnimation方法一样 showNext 显示FrameLayout里面的下一个View showPrevious 显示Framelayout里面的上一个View 🔰ViewFilpper 相关方法及功能说明
方法 功能 setFlipInterval 设置View切换的时间间隔。单位:毫秒
2000毫秒 ==2秒startFlipping 开始进行View的切换,切换会循环进行 stopFlipping 停止View切换 setAutoStart 设置是否自动开始,如果为true,则当ViewFlipper显示的时候View的切换会自动开始 🔰自动轮播也可以根据用户需求,通过手势来实现图片的轮播效果。即当用户向左滑屏时,图片向左滚动切换。实例:【手势实现左右滑屏切换】
1. 左右轮播图
1)已知图片资源个数
🔰布局代码
<ViewFlipper android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/flipper" android:flipInterval="2000"> <!--切换时长2s--> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@mipmap/retouch_20210209121016"/> ……该部分设置需要轮播的图片资源 </ViewFlipper>
🔰功能代码(在 onCreate()方法中设置 )
ViewFlipper viewFlipper = findViewById(R.id.flipper); viewFlipper.startFlipping(); // 开始进行Image View的切换
2)图片资源个数未知
🔰布局代码
<ViewFlipper android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/flipper" android:flipInterval="2000"/> <!--切换时长2s-->
🔰功能代码(在 onCreate()方法中设置 )
ViewFlipper viewFlipper = findViewById(R.id.flipper); // 添加资源 ImageView imageView1 = new ImageView(this); imageView1.setImageResource(R.mipmap.a); …… 添加图片资源 //将Image View 对象加载到viewFlipper上 viewFlipper.addView(imageView1); …… // 实现轮播效果 viewFlipper.startFlipping();
2. 上下轮播
🔰res文件夹右键,新 建 Directory 文件 夹 , 取名为anim;
🔰anim文件夹右键,新建两个Animation文 件 , 分别取名为anim_comein.xml, anim_getout.xml;
anim_comein.xml <?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="1000"/> </set> ______________________________________ anim_getout.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="0" android:toYDelta="-100%p" android:duration="1000"/> </set>
android:toXDelta="100%"
: 表示自身的100%,也就是从View自己的位置开始;
android:toXDelta="80%p"
: 表示父层View的80%,是以它父层View为参照的。
🔰布局代码
<ViewFlipper android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/flipper" android:inAnimation="@anim/anim_comein" <!--进入时动画效果--> android:outAnimation="@anim/anim_getout" <!--离开时动画效果--> android:flipInterval="2000"> <!--切换时长2s--> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@mipmap/retouch_20210209121016"/> ……该部分设置需要需要轮播的图片资源 </ViewFlipper>
🔰功能代码(在 onCreate()方法中设置 )
ViewFlipper viewFlipper = findViewById(R.id.flipper); viewFlipper.startFlipping(); // 实现轮播效果
(七) 【RecyclerView】
🔰RecyclerView 是 Android 5.0 开始推出的用来替代 ListView 和 GrindView 的组件;
1. 导入RecyclerView包
1、导入RecyclerView包:
build
—>Edit Libraries and Dependencies
;
2、选 中 app , 点 击 DeclaredDependencies 中 的 + 号 , 选 择Library Dependency;
3、输入recycler查找相关包,选择第一个,点击OK等待系统自动下载并加载
2. RecyclerView.LayoutManager
🔰RecyclerView.LayoutManager是一个抽象类,它包含下面的
三个子类:1、LinearLayoutManager:线性布局管理器
• LinearLayoutManager类有两种常用的构造方法。
- 第一种构造方法格式如下:
LinearLayoutManager(Context context) // context参数为上下文,实现的是默认的垂直布局 mRecycleView.setLayoutManager(new LinearLayoutManager(this));
- 第二种构造方法格式如下:
LinearLayoutManager( Context context, int orientation, boolean reverseLayout) // 第一个参数context为上下文,第二个参数orientation为布局显示方式,第三个参数reverseLayout为是否反转。 LinearLayoutManager linerLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true); mRecycleView.setLayoutManager(linerLayoutManager);
orientation参数值及功能说明
参数值 功能 LinearLayoutManager.VERTICAL 不反转的垂直布局:数据从上往下加载(新数据在底部)
反转的垂直布局:数据从下向上加载(新数据在顶部)LinearLayoutManager.HORIZONTAL 不反转的水平布局:数据从左到右加载(新数据在右)
反转的水平布局:数据从右向左加载(新数据在左)2、StaggeredGridLayoutManager: 错列网格布局管理器
• 构 造方法格式如下:StaggeredGridLayoutManager(intspanCount,int orientation) // 第 一个参数 spanCount 为要显示的列数 , 第二个参数orientation为显示的方向 StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL); mRecycleView.setLayoutManager(staggeredGridLayoutManager;
3、GridLayoutManager:网格布局管理器
• 既可以设置列数,也可以设置方向,还可以设置加载数据是否反 转 , 其功能可以理解 为 LinearLayoutManager 和StaggeredGridLayoutManager结合体。
• 它有两种构造方法:
- 第一种构造方法格式如下:
GridLayoutManager(Context context, int spanCount) // 第一个参数context为上下文,第二个参数spanCount为显示列数,默认显示方向为垂直布局
- 第二种构造方法格式如下:
GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) // 第一个参数context为上下 文 , 第二个 参 数 spanCount 为显示列数 , // 第三个 参 数orientation为显示方向,第四个参数reverseLayout为是否反转。 GridLayoutManager gridLayoutManager=new GridLayoutManager(this,3,GridLayoutManager.VERTICAL,true); mRecycleView.setLayoutManager(gridLayoutManager);
五. 菜单和对话框
(一) 菜单
1. ContextMenu (上下文菜单)
🔰ContextMenu (上下文菜单) :在某个组件或视图上长按(超过2s)弹出;
🔰菜单设置:
1.1 在Activity中添加onCreateContextMenu()方法:
》白位置右键 – Generate – Override Methods – 输入contextmenu,选择onCreateContextMenu()
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText editText = this.findViewById(R.id.rv); // 为组件添加加ContextMenu this.registerForContextMenu(editText); } @Override // 参数1加载的上下文菜单; 参数2与菜单相关的组件; 参数3菜单的附加信息; public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { // 填充菜单资源 MenuInflater inflater = MainActivity.this.getMenuInflater(); // 参数1是待转换菜单xml; 参数2是菜单对象; inflater.inflate(R.menu.main_menu, menu); super.onCreateContextMenu(menu, v, menuInfo); }
2.1 设置Xml文件菜单项
1)res右键–Directory–menu–新建main_menu.xml文件
2)menu右键–New–Menu Resource File, 新建一个名为main_menu.xml文件main_menu.xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/gbackcolor"> <item android:id="@+id/bgreen" android:title="背景绿色"/> <item android:id="@+id/bblue" android:title="背景蓝色"/> </group></menu>
🔹菜单的XML文件包含menu、group和item三个元素;
- menu:定义一个菜单,可包含一个或多个
<group>
和<item>
元素;- group:对菜单进行分组,可以以组的形式操作菜单项,也可以省略
属性 说明 android:id 设置菜单组的id android:orderInCategory 定义该组菜单在总菜单中的默认次序,整数值 android:checkableBehavior 定义该组菜单是否可选:none(默认值,不可选)\all(多选)\single(单选) android:visible 设置该组菜单是否可见,true或false android:enabled 设置该组菜单是否可用,true或false
- item:代表菜单中的一个选项。常用属性有id、icon和title等
属性 说明 android:id 设置菜单项的id android:title 设置菜单项的标题 android:icon 设置菜单项的图标 android:alphabeticShortcut 设置菜单项的字母快捷键 android:numericShortcut 设置菜单项的数字快捷键 android:checkable 设置菜单项是否可选,true或false android:checked 设置菜单项是否为选中状态,true或false android:visible 设置菜单项是否可见,true或false 2.2 直接使用Java代码在onCreateContextMenu()中添加
菜单项public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { menu.add(0, 0, 4, "背景绿色"); menu.add(0, 1, 2, "背景蓝色"); menu.add(1, 2, 1, "前景蓝色"); menu.add(1, 3, 3, "前景绿色"); super.onCreateContextMenu(menu, v, menuInfo); }
1)上下文菜单一般运用方式
• 实现性别选择功能(ContextMenu上下文菜单);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = this.findViewById(R.id.rv);
this.registerForContextMenu(editText); }
// 创建上下文菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("性别");
menu.add(0, 0, 0, "男");
menu.add(0, 1, 1, "女"); }
// 单击上下文菜单后的实现
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
editText.setText("男"); break;
case 1:
editText.setText("女"); break; }
return super.onContextItemSelected(item); }
2. OptionsMenu (选项菜单)
🔰 OptionsMenu (选项菜单) :最常见的菜单,分为Icon按钮、Item按钮和overflow按钮;
🔰public boolean onCreateOptionsMenu(Menu menu);
在该方法中完成菜单初始化;
🔰
public boolean onOptionsItemSelected(@NonNull MenuItem item);
菜单选项被选中时触发,在该方法中完成事件处理。
3. SubMenu (子菜单)
🔰 SubMenu (子菜单):将功能相同和相似的分组进行多级显示,但子菜单不能再嵌套子菜单;
SubMenu常用方法及功能说明
方法名 功能说明 subMenu.setHeaderIcon(R.mipmap.ic_launcher_round); 设置菜单头的图标 subMenu.setHeaderTitle(“选择居住的城市”); 设置菜单头的标题 subMenu.setIcon(R.mipmap.ic_launcher); 设置子菜单图标 🔰
public boolean onCreateOptionsMenu(Menu menu);
SubMenu创建;
🔰public boolean onOptionsItemSelected(@NonNull MenuItem item);
菜单选项被选中时触发,在该方法中完成事件处理。
1)ActionBar
🔰setShowAsAction()
方法用于设置Action Bar中menu的显
示方式,显示方式一共有五种,它们可以混合使用
显示方式
参数值 实例 SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW SHOW_AS_ACTION_NEVER SHOW_AS_ACTION_ALWAYS SHOW_AS_ACTION_IF_ROOM SHOW_AS_ACTION_WITH_TEXT
4. PopupMenu(弹出式菜单)
🔰 PopupMenu(弹出式菜单) :用于在指定的VIew下显示一个弹出菜单,其菜单选项通常由XML菜单资源文件生成。
PopupMenu的相关方法及功能说明
方法名 说明 PopupMenu(Context context, View anchor) 第一个参数表示Activity,第二个参数表示弹出菜单显示在指定anchor控件的下方或上方 MenuInflater.inflate(int menuResId, PopupMenu.getMenu()) 加载XML菜单资源到弹出菜单对象中 setOnMenuItemClickListener() 设置弹出菜单项的单击事件 show() 弹出菜单 dismiss() 关闭菜单 🔰使用步骤:
- 在res/menu文件创建XML菜单资源文件;
- 在Activity中绑定Text View的单击监听事件;
(二) 对话框
🔰 Android提供普通(含提示消息和按钮)、列表、单选、多选、等待、进度条、编辑和自定义等多种形式的对话框。
🔰 Dialog 直接子类有 AlertDialog( 提示对话框 ) 和CharacterPickerDialog(字符选择对话框);
🔰 间接子类有DatePickerDialog (日期选择对话框) 、TimePickerDialog ( 时间选择对话框 ) 和ProgressDialog (进度对话框)等;
1. AlertDialog( 提示对话框 )
🔰AlertDialog提示对话框可以生成四种预定义的对话框:
- 带消息和按钮的提示对话框;
- 带列表和按钮的列表对话框;
- 带单选列表和按钮的列表对话框;
- 带复选列表和按钮的列表对话框;
🔰AlertDialog提示对话框需要用AlertDialog.Builder来创建
AlertDialog.Builder 的常用方法及功能
方法名 功能 create() 创建对话框 setIcon(Drawable icon) 为对话框设置图标 setTitle(DharSequence title) 为对话框设置标题 setItems(CharSequence[] items, DialogInterface.OnClickListener listener ) 设置对话框显示的列表项 setMessage(CharSequence message) 为对话框设置消息内容 setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener ) 给对话框添加”取消“按钮 setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener ) 给对话框添加”中立“按钮 setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener ) 给对话框添加”确定“按钮 setMultiChoiceItems(CharSequence[] items, boolean[] checkdItems, DIalogInterface.OnMultiChoiceClickListener listener) 设置对话框显示的复选列表项 setSingleChoiceItems(CharSequence[] items, int checkedItem, DialogInterface.OnClickListener listener) 设置对话框显示的单选列表项 setView(View view) 为对话框设置自定义样式 show() 显示对话框 🔰创建对话框通常直接在Java代码中实现,不需要设计创建界面布局,通常由以下五个步骤:
- 创建AlertDialog.Builder对象;
- 调用setIcon()、setTitle()或setCustomTitle()等设置对话框标题栏的图标、标题等;
- 调用setMessage()方法设置对话框中显示的消息内容或调用setItems()、setSingleChoiceItems()、setMultiChoiceItems()方法设置不同类别的对话框;
- 调用setPositive/Negative/NeutralButton()方法设置确定、取消或中立按钮;
- 调用create()、show()方法创建对话框对象并显示出来。
1)带消息和按钮的提示对话框
🔰创建对话框通常直接在Java代码中实现,不需要设计创建界面布局;
AlertDialog.Builder allertDang = new AlertDialog.Builder(this);// 创建
allertDang.setTitle("课程评价调度"); //设置标题
allertDang.setMessage("你喜欢这门课吗?"); //设置显示信息
allertDang.setIcon(R.mipmap.ic_launcher); //设置图标
// 设置积极按钮,通常为确定
allertDang.setPositiveButton("非常喜欢", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 选择积极按钮后执行的操作
}});
// 设置消极按钮,通常为取消
allertDang.setNegativeButton("还行", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {}});
// 设置中立按钮
allertDang.setNeutralButton("喜欢", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {}});
AlertDialog dialog = allertDang.create(); // 创建对话框
dialog.show();// 显示对话框
2)带列表和按钮的列表对话框
🔰不需要界面布局,但实现时需要先定义在对话框中列表显示
的内容,列表显示的内容通常定义为字符串数组
final String counse[] = new String[] {"大学语文", "大学英语", "大学体育", "大学物理"};
AlertDialog.Builder allertDang = new AlertDialog.Builder(this);// 创建
allertDang.setTitle("你喜欢那门课程?"); //设置标题
allertDang.setIcon(R.mipmap.ic_launcher); //设置图标
// 设置列表项对话框
allertDang.setItems(counse, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(MainActivity.this, counse[i], Toast.LENGTH_SHORT).show();
} });
allertDang.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 设置积极按钮,通常为确定
}});
allertDang.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 设置消极按钮,通常为取消
}});
AlertDialog dialog = allertDang.create(); // 创建对话框
dialog.setCanceledOnTouchOutside(false); // 设置单击对话框外部时,对话框不消失
dialog.show();// 显示对话框
3)带单选列表和按钮的单选列表对话框
其余代码与带列表和按钮的列表对话框相同,只需要修改setItems方法为setSingleChoiceItems()。
private int coureseId=0;
// 设置列表项对话框 参数1列表项数组; 参数2默认选中列表项的下标,从0开始; 参数3对应的监听事件;
allertDang.setSingleChoiceItems(counse, 3, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
coureseld = i;
} });
4)带复选列表和按钮的复选列表对话框
其余代码与带单选列表和按钮的列表对话框相同,只需要修改setSingleChoiceItems()方法为setMultiChoiceItems()
private boolean[] coureseSlected = new boolean[] {false, false, false,false};
private String temp = "";
// 设置列表项对话框 参数1列表项数组; 参数2默认复选框被选中的列表项布尔型数组; 参数3对应的监听事件;
allertDang.setMultiChoiceItems(counse, coureseSlected, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i, boolean isChecked) {
if (isChecked){ temp = temp+counse[i]+","; }
} });
5)自定义对话框
- 自定义一个
dialog_login.xml
布局文件,设置布局;- 写功能代码
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View loginVIew = layoutInflater.inflate(R.layout.dialog_layout, null);
AlertDialog.Builder loginDialog = new AlertDialog.Builder(this);
loginDialog.setTitle("用户登录");
loginDialog.setIcon(R.mipmap.ic_launcher);
loginDialog.setView(loginVIew); // 为对话框设置自定义View
loginDialog.setPositiveButton("登录", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 登录按钮功能代码
} });
loginDialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 取消按钮功能代码
} });
AlertDialog dialog = loginDialog.create(); // 创建对话框
dialog.setCanceledOnTouchOutside(false); // 设置单击对话框外部时,对话框不消失
dialog.show();// 显示对话框
6)提示对话框一般运用方式
2. ProgressDialog(进度条对话框)
🔰ProgressDialog(进度条对话框)类继承自AlertDialog,它和ProgressBar(进度条)有着异曲同工之处,都是用于显示执行进度;不同的是ProgressDialog以对话框的形式展示出来。
🔰ProgressDialog对话框进度的改变同样与ProgressBar一样,也需要使用线程来控制。
1)进度条对话框创建
1.直接采用new ProgressDialog( )创建
ProgressDialog dialog = new ProgressDialog(this); dialog.show(); //调用ProgressDialog的静态方法show( )创建并显示,此种方法只能创建默认的圆形条样式。
ProgressDialog dialog = ProgressDialog.show(this,"提示", "正在登陆中"); // /只能是圆形条,可以通过show()方法的参数设置title和Message提示内容。
ProgressDialog dialog2=ProgressDialog.show(this,"提示","正在登录中",false); //使用静态方式创建并显示,只能是圆形条,最后一个参数boolean型,用于设置是否是不明确的状态。 ProgressDialog dialog3=ProgressDialog.show(this,"提示","正在登录中",false,true); //使用静态方式创建并显示,只能是圆形条,最后一个参数boolean型,用于设置是否进度条是可以取消的。
方法名 功能 getMax() 获取对话框进度条最大值 getProgress() 获取对话框当前进度值 getSecondaryProgress() 获取对话框第二进度条的值 setMax(int max) 设置对话框进度条的最大值 setMessage(CharSequence message) 设置对话框提示信息文字 setIcon(Drawable Icon) 设置对话框进度条图标 setIndeterminate(boolean inde) 设置对话框进度条是否明确 setProgress(int value) 设置对话框进度条当前进度值 setProgressStyle(int style) 设置对话框进度条的样式 setSecondaryProgress(int seconday) 设置对话框第二进度条的值 setTitle(CharSequense message) 设置对话框进度条对话框标题 setCancelable(Boolean flag) 设置是否可以按退回键取消对话框进度条 setButton(CharSequence text, DialogInterface, OnClickListener listener) 设置对话框进度条上的按钮及提示信息和事件 show() 显示进度条对话框 cancel() 取消进度条对话框 dismiss() 取消进度条对话框
2)进度条对话框的一般运用方式
3. DataPickerDialog(日期选择对话框)
🔰DatePickerDialog类中提供了下列4种构造方法:
public DatePickerDialog (Context context){ }
public DatePickerDialog(Context context, int themeResId){}
public DatePickerDialog(Context context, OnDateSetListener listener, int year, int month, int dayOfMonth){}
public DatePickerDialog(Context context, int themeResId, OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth){}
- context表示上下文;
- themeResId表示日期选择对话框的样式;
- listener表示日期选择时的监听事件;
- year表示日期选择器默认年份;
- month表示日期选择器默认月份;
- dayOfMonth表示日期选择器默认天;
日期选择对话框的样式 效果 DatePickerDialog.THEME_HOLO_LIGHT 图1 DatePickerDialog.THEME_HOLO_DARK 图2 DatePickerDialog.THEME_DEVICE_DEFAULT_LIGHT 图3 DatePickerDialog.THEME_DEVICE_DEFAULT_DARK 图4 DatePickerDialog.THEME_TRADITIONAL 图5
🔰使用步骤:
- 创建DataPickerDialog选择日期后的监听事件
- 获取DataPickerDialog对象,并实现相关功能;
4. TimePickerDialog(时间选择对话框)
🔰TimePickerDialog类中提供了下列2种构造方法:
public TimePickerDialog(Context context, OnTimeSetListener listener, int hourOfDay, int minute, boolean is24HourView)
public TimePickerDialog(Context context, int themeResId, OnTimeSetListener listener, int hourOfDay, int minute, boolean is24HourView)
- context表示上下文;
- themeResId表示时间选择对话框的样式;
- listener表示时间选择时的监听事件;
- hourOfDay表示时间选择器默认小时;
- minute表示时间选择器默认分钟;
- is24HourView表示时间选择器时否使用24小时制;
时间选择对话框的样式 效果 DatePickerDialog.THEME_HOLO_LIGHT 图1 DatePickerDialog.THEME_HOLO_DARK 图2 DatePickerDialog.THEME_DEVICE_DEFAULT_LIGHT 图3 DatePickerDialog.THEME_DEVICE_DEFAULT_DARK 图4 DatePickerDialog.THEME_TRADITIONAL 图5
🔰使用步骤:
- 创建TimePickerDialog选择时间后的监听事件;
- 获取TimePickerDialog对象,并实现相关功能;
六. 服务和消息广播
(一) Service
1. Service简介
🔰Service是Android的四大组件之一,没有用户界面、不能直接与用户交互、通常在后台执行耗时操作的应用组件。
🔰主要用途有两个:
- 后台运行:通过启动一个服务,可以在不显示界面的情况下在后台运行指定的任务,这样可以不影响用户做其他事情。
- 跨进程访问:通过 AIDL ( Android InterfaceDefinition Language)可以实现在不同进程之间的通信。
2. Service生命周期
🔰Service的启动和关闭有以下两种方式:
🔹1. 启动式:通过其他组件调用 startService() 方法启动Service,通过其他组件调用stopService()方法或Service本身调用stopSelf()方法关闭Service。当Service被停止时,系统会销毁它,这种方式调用简单,控制方便。
》🔹但一旦启动了Service,除了再次调用或关闭Service外就再没有办法对Service内部状态进行操作控制,缺乏灵活性。也就是说通过该方式启动的Service与启动它的组件没有关联,既使启动它的组件退出了,Service也仍然在后台运行。
🔹2. 绑定式:通过其他组件(客户)调用bindService()方法启动Service,其他组件(客户)可以通过一个IBinder接口与Service进行通信,也可以通过调用unbindService()方法关闭Service。
》🔹这种方式可以通过IBinder接口获取Service,对Service状态进行检测。即通过该方式启动的Service与启动它的组件(客户)绑定在一起,组件(客户)一旦退出,Service也随之关闭。
开启获取电话状态权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
开启录音权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
开启SD卡写入权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3. 设置服务
(二) BroadcastReceiver
1. BroadcastReceiver简介
🔰BroadcastReceiver也是Android的四大组件之一,通常一旦产生某个事件时就可以发送一个广播,应用程序使用BroadcastReceiver接收广播后就会知道系统产生了什么事件,同时也可以根据相应的事件作出相应的处理。
🔰BroadcastReceiver本质上可以认为就是一个监听器,但是通常的监听器是程序级别的,当程序退出时监听器也会随之关闭;BroadcastReceiver是系统级别的监听器,只要与该监听器匹配的Intent被广播出来,BroadcastReceiver就会被激发并根据相应的操作进行处理。
🔰BroadcastReceiver有两种类型:
- 普通广播:无序广播,可以同一时间被所有与广播Intent匹配的接收者同时接收,接收者之间相互不会有影响。
- 有序广播:按照一定优先级进行消息的接收,首先发送到与广播Intent匹配的优先级最高的接收者那里,然后再从前面的接收者传播到下一个优先级的接收者那里。优先级高的接收者也可以终止这个广播。优先级取值可通过-1000~1000,数值越大,优先级越高。
2. BroadcastReceiver生命周期
🔰每次广播到来时 , 会重新创建BroadcastReceiver 对象,并且调用 onReceive() 方法 ,执行完以后 , 该对象即被销毁。
🔰 onReceive() 方法在 10 秒内没有执行完毕, Android 会认为该程序无响应 。所以在BroadcastReceiver 里不能做一些比较耗时的操作,否侧会弹出 ANR(Application NoResponse) 的对话框。
(三) AlarmManager
🔰Android系统中有一个AlarmManager的对应服务程序——AlarmManagerServie,该服务程序用于提供闹铃服务,它主要维护应用程序注册下来的各类闹铃并适时地设置即将触发的闹铃给闹铃设备,并且一直监听闹铃设备,一旦有闹铃触发或者是闹铃事件发生,AlarmManagerServie就会遍历闹铃列表找到相应的注册闹铃并发出广播。
🔰AlarmManager的主要方法:
🔰Alarm的type主要类型:
七. 数据的存储与访问
🔰各类应用开发中,数据存储访问方式有三类:文件、数据库和网络(云存储)。
🔰Android存储方式总体也分为以上三类,包含以下五种:
- SharedPreference存储访问机制
存储简单配置信息,只能存储Long、Float、Integer、String和Boolean五种,以键值存储在XML中;- 文件存储访问机制
采用java.io.*库提供的I/O接口实现文件读写,需在res/目录下适当子目录创建和存储;- SQLite数据库数据存储访问机制
轻量级嵌入式数据库引擎,支持SQL语言,并占用较少存;- ContentProvider共享数据机制
提供标准方法接口,实其他应用保存和读取ContentProvider各种数;- 网络数据存储访问机制
Android网络存储使用HTTP协议,采用J2SE包。🔰五种方式各有优缺点,根据实际开发情况选择。数据较少时,建议使用SharedPreference;数据量较大时,可选择文件或数据库存储。
🔰Android平台设备的存储器,包括内存、内部存储器和外部存储器:
🔹内存即Memory,当系统运行和App运行时必须将程序的核心模块加载到内存中;
🔹内部存储器即InternalStorage,它的空间十分有限,是Android系统本身和系统应用程序主要的数据存储所在位置,一旦内部存储空间耗尽,Android平台设备也就无法使用了,开发者应该尽量避免在编码时使用内部存储空间;
🔹外部存储器即ExternalStorage,它和SD卡没有必然的联系,通常包含公有目录和私有目录两类子文件夹。
🔰Android系统的目录结构中有三个重要的文件夹:
🔹data文件夹:即内部存储器对应的文件夹,存放所有安装的App文件;
🔹storage文件夹:即外部存储器对应的文件夹,不同设备不同,一般该文件夹内有一个sdcard文件夹。
🔹mnt文件夹:同storage文件夹。因内存空间有限,Google建议将App数据存储在外部存储器该目录下。
(一) SharedPreferences存储访问机制
🔰SharedPreferences的常用方法
方法名 功能说明 boolean contains(String key) 判断SharedPreferences是否包含特定key的数据 SharedPreferences.Editor edit() 返回一个Edit对象用于操作SharedPreferences Map<String, ?>getAll() 获取SharedPreferences数据里全部的key-value对 getXXX(String key, XXX defValue) 获取SharedPreferences数据指定key所对应的value, 如果该key不存在,返回默认值defValue。其中XXX可以是Boolean, float, int, long, String等基本类型 的值
🔰Editor的常用方法
方法名 功能说明 SharedPreferences.Editor clear() 清除SharedPreferences里所有的数据 boolean commit() 当Editor编辑完成后,调用该方法可以提交修改,而且必须要调用这个方法数据才能修改 SharedPreferences.Editor putXXX(String key, boolean XXX) 向SharedPreferences存入指定的key对应的数据。其中XXX可以是是Boolean, float, int, long, String等基本类型 的值 SharedPreferences.Editor remove(String key) 删除SharedPreferences里指定的key对应的数据项 🔰SharedPreferences存储数据四个步骤:
- 获取SharedPreferences对象
通过Context类中的getSharedPreferences(String name,int mode)方法,它的操作权限属于整个应用程序,每个Activity可以对应多个xml存储文件,由第一个参数name为文件名保存在系统中(名称不需要带后缀xml,保存文件时系统自动加后缀),第二个参数mode表示文件的操作模式,其值及功能如表所示。SharedPreferences sp = getSharedPreferences("loginconfig", Context.MODE_PRIVATE);
文件操作模式及功能
方法名 功能说明 Context.MODE_PRIVATE 为默认操作模式,代表该文件是私有数据,只能应用程序本身使用,在该模式下,写入的内容会覆盖原文件的内容。 Context.MODE_APPEND 该模式会检查文件是否存在,如果存在就向文件中追加内容,否则就创建新文件 Context.MODE_WORLD_READABLE 表示当前文件可以被其他应用程序读取 Context.MODE_WORLD_WRITEABLE 表示当前文件可以被其他应用程序写入
- 通过SharedPreferences对象的edit()方法获得SharedPreferences.Editor对象;
SharedPreferences.Editor editor = sp.edit();
- 通过Editor对象的putXXX()方法,将不同类型的数据以key-value键值对的形式存储;
editor.putString("loginname", username);//用户名 editor.putString("loginpwd", password);//密码 editor.putBoolean("loginsave", issave);//保存密码 editor.putBoolean("loginauto", isauto);//自动登录
- 完成以上步骤后,此时的数据仍然在内存中,需要通过Editor对象的commit()方法提交数据,也就是将数据保存到xml文件中。
editor.commit();
🔰SharedPreferences读取数据四个步骤:
- 获取SharedPreferences对象实例:(与存储相同)
SharedPreferences sp = getSharedPreferences("loginconfig", Context.MODE_PRIVATE);
- 读取数据:
1)读取单一数据时,利用getString()方法,读取已经保存
在文件中的用户名和密码;
String uname = sp.getString("username", "admin"); // 当不能读出时,默认值为admin
2)读取全部数据时,利用getAll()方法,再遍历map;public Map<String, String> reads(){ SharedPreferences sp = getSharedPreferences("loginconfig", Context.MODE_PRIVATE); String content = ""; Map<String, ?> allContent = sp.getAll(); for(Map.Entry<String, ?> entry: allContent.entrySet()) { content += (entry.getKey() + entry.getValue()); } return content; }
- 定义read()方法,读出数据:
public void read() { SharedPreferences sp = getSharedPreferences("DengLu", Context.MODE_PRIVATE); String uname = sp.getString("loginname", ""); String upwd = sp.getString("loginpwd", ""); boolean jizhu1 = sp.getBoolean("loginsave", false); boolean zidong1 = sp.getBoolean("loginauto", false); if (jizhu1) { //如果前次登录选择了保存密码, 则将用户名和密码读出后,显示在对应位置 zhanghao.setText(uname); mima.setText(upwd); } if (zidong1) { //如果前次选择了自动登录, 则开启程序后直接跳转到InfoActivity Intent intent = new Intent(MainActivity.this, InfoActivity.class); MainActivity.this.startActivity(intent); } }
- onCreate()方法中初始化对象:
SharedPreferences存储访问机制
(二) 文件存储访问机制
🔰Java提供了一套完整的IO流体系用来对文件进行操作,包括FileInputStream、FileOutputStream等,通过这些IO流可以非常方便地访问磁盘上的文件。
🔰Android同样支持以流的方式来访问Android平台设备存储上的文件,包括设备本身的存储设备(内部存储器,InternalStorage)或外接的存储设备(外部存储器,ExternalStorage)。
🔰另 外Android中 的Context类对象提供了openFileOutput()、openFileInput()两个方法分别获得输入流和输出流,从而实现文件的读写操作。
1. Java IO流
🔰File类以及FileInputStream、FileOutputStream、FileReader及FileWriter处理字节流和字符流。
方法 说明 File(FIle dir, String name) dir 为FIle 对象类型的目标路径,name 为文件名或目录 File(String path) path 为新File对象的路径 File(String dirPath, String name) dirPath 为指定文件路径,name为文件名或目录名 File(URI uri) 使用URI指定路径创建新的FIle对象
2. 读写内部存储器的文件数据
🔰Android中Context类提供两种方法打开数据文件IO流:
FileInputStream openFileInput(String name)
:打开应用程序的数据文件下的name文件对应的输入流;FileOutputStream openFileOutput(String name, int mode)
:打开应用程序的数据文件下的name文件对应的输出流。🔰另外Context类还提供下表所示的常用方法。这些方法都是通过上下文对象Context获取的,新创建的文件和目录都属于本应用程序所有。只要应用程序被卸载,这些文件或目录都会被清空。
🔰Context类与文件操作有关的方法
方法名 功能说明 File getFilesDir() 返回本应用程序的数据文件夹的绝对路径。在这里获取到的是”/data/data/<包名>/files/"目录,返回File对象 File getCacheDir() 返回本应用程序默认的缓存文件存放路径。用于获取”/data/data/<包名>/cache/“目录,返回File对象 File getExternalCacheDir() 返回本应用程序在外部存储的存储目录。用于获取"/cache/"目录, 返回File对象 String[] fileList() 返回本应用程序的数据文件夹的全部文件 Boolean deleteFile(String) 删除本应用程序的数据文件夹下的指定文件 File getDatabasePath(String name) 返回以openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory)方法创建的数据库的绝对路径 File getFileStreamPath(String name) 返回以openFileOutput(String , int)方法创建的文件的绝对路径
3. 读写外部存储器的文件数据
🔰Android应用开发中常使用Environment类获取外部存储器目录。在访问外部存储器之前一定要先判断外部存储器是否已经是可使用状态(即已挂载或可使用),并且需要在AndroidManifest.xml配置文件中添加外部存储读和写的权限。
<!-- 在SD卡中创建与删除文件的权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 向SD卡中写入数据的权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
🔰外部存储状态表示
静态常量 功能说明 String MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除 String MEDIA_CHECKING 正在检查存储媒体 String MEDIA_MOUNTED 存储媒体已经挂载,并且挂载点可读写 String MEDIA_MOUNTED_READ_ONLY 存储媒体已经挂载,挂载点只读 String MEDIA_NOFS 存储媒体是空白或是不支持的文件系统 String MEDIA_REMOVED 存储媒体被移除 String MEDIA_SHARED 存储媒体正在通过USB共享 String MEDIA_UNMOUNTABLE 存储媒体无法挂载 String MEDIA_UNMOUNTED 存储媒体没有挂载
🔰系统其他标准目录
静态变量 功能说明 public static String DIRECTORY_ALARMS 系统提醒铃声存放的标准目录 public static String DIRECTORY_DCIM 相机拍摄照片和视频的标准目录 static String DIRECTORY_DOWNLOADS 下载的标准目录 static String DIRECTORY_MOVIES 电影存放的标准目录 static String DIRECTORY_MUSIC 音乐存放的标准目录 static String DIRECTORY_NOTIFICATIONS 系统通知铃声存放的标准目录 static String DIRECTORY_PICTURES 图片存放的标准目录 static String DIRECTORY_PODCASTS 系统广播存放的标准目录 static String DIRECTORY_PINGTONES 系统铃声存放的标准目录
🔰Environment类的常用方法
方法名 功能说明 FIle getDataDirectory() 获得android data 的目录 File getDownloadCacheDirectory() 获得下载缓存目录 File getExternalStorageDirectory() 获取外部存储媒体目录 File getExternalStoragePublicDiectory(String type) 获取特定类型文件的上一级外部存储目录 String getExternalStorageState() 获取当前外部储存媒体的状态 File getRootDirectory() 获取Android的根目录 static boolean isExternalStorageEmulated() 判断设备的外部存储媒体是否是内存模拟的,是则返回true static boolean isExternalStorageEmulated(File path) 判断指定文件目录的外部存储媒体是否是内存模拟的,是则返回true static boolean isExternalStorageRemovable() 判断设备的外存是否可拆卸,如SD卡,是则返回true static boolean isExternalStorageRemovable(File path) 判断指定目录下的外存是否可拆卸,如SD卡,是则返回true 🔹 第1步:AndroidMainFest.xml中添加读写SD卡权限;
🔹第2步:判断Android设备上是否已插入SD卡:
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
🔹第3步:调用Environment.getExternalStorageDirectory()获得SD卡根目录;
File SDCardRoot=Environment.getExternalStorageDirectory();
🔹第4步:读写SD卡中的文件;
4. 读写资源文件数据
🔰Android系统的资源文件可以分为两种:
- 第一种是res/raw目录下的资源文件,这类资源文件会在R.java里面自动生成该资源文件的ID;
- 第二种是assets目录下存放的原生资源文件,它不会被映射到R.java文件中,所以不能通过R.XXX.ID的方式访问。
1) res目录下的资源文件
🔰要在res目录下放置数据文件,通常需要手动在该目录下创建raw目录,然后把数据文件复制到该目录下。
🔰例如下面代码表示读出raw目录下的test文件。
2) assets目录下的资源文件
🔰使用Android Studio创建项目时,开发环境不会自动创建assets目录,如果开发者需要使用这个文件夹存储原生资源文件,就需要在项目的res/main文件下手动创建assets文件夹,创建完成后将需要使用的原生资源文件复制到该文件夹中即可。
🔰例如下面代码表示定义一个方法读出assets目录下的fileName文件。
(三) SQLite数据库数据存储访问机制
🔰轻量级嵌入式数据库引擎,支持SQL语言,并占用较少存;
🔰SQLite数据库系统采用的是动态数据类型,使用时会根据存入的具体值自动判断其数据类型。
🔰通常SQLite包含NULL、INTEGER(整数)、REAL( 浮点数 ) 、 TEXT( 字符串文本 ) 和BLOB(二进制对象)五种数据类型,因为其采用动态数据类型,所以对于varchar、char等其他数据类型也同样可以保存。比如可以在INTEGER类型的字段中存放字符串类型。
🔰SQLite通过文件来保存数据库,一个文件就是一个数据库,一个数据库中可以包含多个表,每个表里又可以有多条记录,每条记录又由多个字段构成,每个字段可以指定其数据类型(主键对应的字段必须指定数据类型)和对应的值。
1. 手动创建数据库的两种途径
1) 直接在CMD命令窗口中手动创建
(四) ContentProvider共享数据机制
🔰提供标准方法接口,实其他应用保存和读取ContentProvider各种数;
(五) 网络数据存储访问机制
🔰Android网络存储使用HTTP协议,采用J2SE包。
八. 多媒体应用开发
🔰Android的多媒体核心框架是OpenCore,兼顾了跨平台的移植性,也有较好的稳定性;
🔰主要包含两大方面:PVPlayer(媒体播放)和PVAuthor(媒体记录),并以SDK的形式提供给开发者;
常用功能类
(一) 消息提示框机制【Toast】
🔰可以在用户做了某种操作后,给用户一些提示消息。该提示信息不能被用户操作,提示后自动消失;
效果如下:
Toast.makeText(this,"成功",Toast.LENGTH_LONG).show();
this
:为当前activity;
"成功"
:为要显示的字符串;
Toast.LENGTH_LONG
:为内容显示的时间,也可以自定义;
🔰创建并显示Toast有两种方式:
1) 默认Toast:btnLogin = (Button) this.findViewById(R.id.btnLogin); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String sUserName=edtUserName.getText().toString(); String sPWD=edtPWD.getText().toString(); if(sUserName.equals("2021")&&sPWD.equals("2021")){ //默认Toast Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_LONG).show(); }else { Toast.makeText(MainActivity.this,"QQ号或密码错误,请重新输入!",Toast.LENGTH_LONG).show(); } } });
2) 自定义Toast:(显示图片)
btnLogin = (Button) this.findViewById(R.id.btnLogin); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String sUserName=edtUserName.getText().toString(); String sPWD=edtPWD.getText().toString(); if(sUserName.equals("2021")&&sPWD.equals("2021")){ //定义Toast Toast toast = new Toast(MainActivity.this); //定义一个ImageView ImageView imageView = new ImageView(MainActivity.this); //定义显示的图片 imageView.setImageResource(R.drawable.ic_launcher_background); //定义一个LinearLayou,也可以是其他的布局 LinearLayout layout = new LinearLayout(MainActivity.this); //布局显示方式 layout.setOrientation(LinearLayout.HORIZONTAL); //将ImageView放到layout中 layout.addView(imageView); //设置view toast.setView(layout); //设置显示时间 toast.setDuration(Toast.LENGTH_LONG); toast.show(); }else { Toast.makeText(MainActivity.this,"QQ号或密码错误,请重新输入!",Toast.LENGTH_LONG).show(); } } });
(二) 倒计时函数【CountDownTimer】
CountDownTimer的常用方法和功能说明
方法名 | 功能说明 |
---|---|
CountDownTimer(long time, long interval) | 构造方法,time表示从开始调用到start()到倒计时完成并调用onFinish()方法的总时间; interval表示调用onTick()方法的间隔时间,单位为毫秒 |
cancel() | 取消倒计时 |
onFinsih() | 抽象方法,倒计时完成被调用 |
start() | 倒计时开始 |
onTick(longtime) | 抽象方法,每个间隔时间interval一到就会调用一次,time表示剩余时间 |
倒计时器的实现
- 创建一个继承CountDownTimer的内部类MyCount,并重写方法
- 给按钮设置监听事件
具体实现及效果看【移动应用开发实践案列】
(三) 消息处理机制
🔰案例:输入数字,计时到等于输入数字
public class MainActivity extends AppCompatActivity {
TextView tv;
Button bt;
EditText edit;
int i = 1;
// 创建Handler对象用于处理消息
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tv.setText(msg.arg1+"");
}};
// 创建Runnable用于在子线程中实现功能需求
Runnable runnable = new Runnable() {
@Override
public void run() {
// 判断输入数字是否等于i
// Integer.parseInt(edit.getText().toString()) 获取输入的数字,转换成int类型
while (i<= Integer.parseInt(edit.getText().toString())) {
Message msg = handler.obtainMessage();
msg.arg1=i;
handler.sendMessage(msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();}
i++;}}};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = this.findViewById(R.id.text);
bt = this.findViewById(R.id.anniu);
edit = this.findViewById(R.id.edit);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 创建子线程
Thread thread = new Thread(runnable);
// 启动子线程
thread.start();
}});}
(四) 横竖屏设置
1.AndroidMainfest.xml中修改screenOrientation属性:
<activity
android:name=".MainActivity"
android:screenOrientation="landscape"></activity>
属性值 | 说明 |
---|---|
unspecified | 默认值,由系统根据设备来判断显示方向 |
landscape | 横屏显示 |
portrait | 竖屏显示 |
user | 用户当前首先的方向 |
begind | 和该 Activity 下面的那个 Activity 的方向一致(在 Activity 堆栈中的) |
sensor | 有物理感应器来决定,用户旋转设备会导致屏幕的横竖屏切换 |
nosensor | 忽略物理感应器,用户旋转设备不会导致屏幕的横竖屏切换 |
2. MainActivity.java中用功能代码实现:
🔷在需要横屏显示的Activity中的Oncreate()方法中增加如下代码:
setRequestedOrientation(Activitylnfo.SCREEN_ORIENTATION_LANDSCAPE);
(五) 滚动视图设置
🔷HorizontalScrollView(水平滚动视图)布局容器,使用它可以实现左右+
滚动来显示内容;
🔷ScrollView(垂直滚视图)布局容器,使用它可以实现上下滚动来显示内容;
🔷HorizontalScrollView和ScrollView都是FrameLayout的子类,它们的使用方法一样;
(六) ProgressBar进度条
🔷提示用户后台App的执行进度,提高界面友好性;
属性 / 方法 说明 android: max 设置进度条的最大值 android: progress 设置当前第一进度值 android:secondaryProgress 设置当前第二进度值设置是否显示 synchronized int getMax() 获取进度条的最大值 synchronized int getProgress() 获取当前第一进度值 synchronized int getSecondaryProgress() 获取当前第二进度值 synchronized void setMax(int max) 设置进度条的最大值 synchronized void setProgress(int progress) 设置第一进度值 synchronized void setSecondaryProgress(int secondaryProgress) 设置第二进度值 🔷Android系统中内置了多种不同风格的进度条,在布局文件中通过style属性值来设置ProgressBar的风格;
🔷系统内置了多种不同风格的进度条,在布局中通过style属性来设置。style属性属性值如下:
属性值 说明 style=‘@style/Widget.AppCompat.ProgressBar.Horizontal’ style=‘@style/Widget.AppCompat.ProgressBar’ style=‘@android:style/Widget.ProgressBar.Horizontal’ style=‘@android:style/Widget.ProgressBar.Inverse’
(七) 开关
🔰ToggleButton开关按钮,Switch开关,两个组件都是继承自CompoundButton。
1. 开关按钮【ToggleButton】
属性 | 说明 |
---|---|
android:disabledAlpha=“0.5” | 设置按钮禁用时的透明度 |
android:textOff=“关闭” | 设置按钮没有被选中时显示的文字 |
android:textOn=“开启” | 设置按钮被选中时显示的文字 |
2. Switch开关
属性 | 说明 |
---|---|
android:showText=“false” | 设置on/off 的时候是否显示文字 |
android:splitTrack=“false” | 是否设置一个间隙,让滑块与底部图片分隔 |
android:switchPadding=“2dp” | 设置滑块内文字的间隔 |
android:switchMinWidth=“20dp” | 设置开关的最小宽度 |
android:track=“@mipmap/tupian” | 设置开关背景图片 |
android:thumb=“@mipmap/tupian” | 设置开关滑块图片 |
3. 开关监听事件
ImageView img = this.findViewById(R.id.img);
Switch sw = this.findViewById(R.id.sw);
sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
img.setImageResource(R.mipmap.nanhai);
} else {
img.setImageResource(R.mipmap.maozua);
}
}
});
常用资源文件
1. string.xml(定义字符串)
<resources>
<string name="app_name">Tong_Xun_Lu</string>
<string name="app_name1">Shu_Ju_Ku</string>
</resources>
2. colors.xml(定义颜色)
🔰
#RGB
:红绿蓝三原色值,最小为0,最大为f;
🔰#ARGB
透明度,红绿蓝三原色值,最小为0,最大为f;<resources> <color name="purple_200">#FFBB86FC</color> <color name="purple_500">#FF6200EE</color> <color name="purple_700">#FF3700B3</color> </resources>
3. arrays.xml(定义数组)
<resources>
<!--定义普通类型数组-->
<string-array name = "palnets">
…………
</string-array>
<!--定义字符串数组-->
<string-array name = "palnets">
<item>Venus</item>
<item>Venus</item>
</string-array>
<!--定义整数数组-->
<integer-array name = "numbers">
<item>100</item>
<item>200</item>
</integer-array>
</resources>
4. dimen.xml(定义尺寸)
<resources>
<dimen name="cwidth">320px</dimen>
<dimen name="double_density">2dp</dimen>
<dimen name="fontsize">16sp</dimen>
</resources>
单位 | 说明 |
---|---|
px(像素) | 相当于实际屏幕的像素,该单位不推荐用于尺寸单位 |
dp/dip(密度无关像素) | 与屏幕密度无关的尺寸单位,dp是一种简单地解决view在不同大小屏幕上显示问题的解决方案 |
sp | 与dp相似,它能够跟随着系统字体大小变化,所以它更加适合作为字体大小的单位 |
5. styles.xml(定义样式,模板)
<resources>
<style name="text_font">
<item name = "android:textColor">#05b</item>
<item name = "android:textSize">18sp</item>
</style>
</resources>