Android学习
页面布局
一般都在 layout
文件夹内。
一个布局文件,一般对应一个 Activity
,在代码中通过
1 | setContentView(R.layout.first_layout); |
布局的分类
LinearLayout 线性布局
一种使用单个水平行(horizontal)或垂直行(vertical)来组织子项的布局。它会在窗口长度超出屏幕长度时创建一个滚动条。
1 |
|
Relative Layout 相对布局
让您能够指定子对象彼此之间的相对位置(子对象 A 在子对象 B 左侧)或子对象与父对象的相对位置(与父对象顶部对齐)。
1 | android:layout_toLeftOf="" ——该组件位于引用组件的左方 |
1 |
|
FrameLayout 帧布局
帧布局(FrameLayout)直接继承了ViewGroup组件;
帧布局容器为每一个加入其中的组件都创建了一个空白的区域,这个区域我们称之为一帧,所有每个组件都占据一帧,这些都会根据gravity属性执行自动对齐。
常用XML属性及相关的方法:
XML属性 | 相关方法 | 说明 |
---|---|---|
android:foreground | setForeground(Drawable) | 设置该帧布局容器的前景图像 |
android:foregroundGravity | setForegroundGravity(int) | 定义绘制前景图像的gracity属性 |
基本控件
字体sp、其他dp
扩展: 设置大小的单位(字体,也包括控件大小)
dp: 设备独立像素,不同设备有不同的显示效果,这个和设备硬件有关,不依赖像素。
px: 像素,在 不同设备显示的效果相同。
pt: 标准的长度单位,简单易用,单位换算1pt=1/72英寸。
sp: 用于字体显示。
TextView
属性
id | 设置一个组件id,通过findViewById()的方法获取到该对象,然后进行相关设置 |
---|---|
layout_width | 组件宽度 wrap_content: 控件的大小根据里面的内容大小而定,内容越小,则空间越小,反之亦然。 match_panett: 控件大小填满整个父容器 |
layout_height | 组件高度 |
text | **设置文本内容 ** 将字符串放置在value文件夹的strings.xml文件下 在activity_main.xml中使用@string/来调用这个字符串资源,”“号代表string定义的name |
background | 背景颜色(或背景图片) |
textColor | 设置字体颜色 将颜色配置在colors.xml文件中 activity_main.xml中,用@color/*进行调用 |
textStyle | 设置字体样式 |
textSize | 字体大小 |
gravity | 内容的对齐方向 center: 居中对齐,位于容器横向和纵向的中央 left: 向左对齐,位于容器左边 right: 向右对齐,位于容器右边 bottom:向底对齐,位于容器底部 top: 向顶对齐,位于容器顶部 center_vertical: 位置置于容器的纵向中央部分 center_horizontal: 位置置于容器的横向中央部分 fill_vertical: 纵向延伸填满容器 fiil_horizontal: 横向延伸填满容器 fiil:纵向和横向延伸填满容器 |
autoLink | autoLink的属性可以将符合指定格式的文本转换为可单击的超链接形式 |
drawableTop | TextView上部出现一个图片 |
TextView实现跑马灯的效果
1 | android:singleLine="true" |
TextView 实现删除线的效果
1 | textview.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG ); //中间横线 |
TextView 一行,最多显示10个字符,剩余的用…代替:
1 | mTitleTxt.setSingleLine();// 单行显示mTitleTxt.setMaxEms(10);// 最大十个字符mTitleTxt.setEllipsize(TextUtils.TruncateAt.END);// 剩余的以...结尾 |
TextView 展示字母的时候,明明是小写,但界面上看到的都是大写 解决方案
1 | 添加属性: |
Button
Java-“this”和”类名.this”以及”类名.class”的区分和详解
组合 | 用法说明 |
---|---|
this | 指代当前对象的引用 |
类名.class | 指向每个类对应的唯一类对象(类型为Class) |
类名.this | 内部(可以是匿名内部类)类调用外部类的对象时使用,即在内部类中使用时: 外部类对象是外部类名.this,内部类对象则是this |
属性
属性 | 作用 |
---|---|
android:text=”” | 设置bottom上显示的文字 |
android:textSize=”” | 设置bottom上的文字大小 |
android:textColor=”” | 设置bottom上的文字颜色 |
android:padding=”” | 设置bottom的内边距 |
android:weight=”” | 权重 |
<corners android:radius="" /> | 设置边框样式为圆角 |
<stroke android:width="" android:color="" /> | 设置边框线条粗细及颜色 |
实现点击后字体颜色改变
这里我们将不同功能用不同的xml文件存放,当编写的代码较多时,这样设置有助于检查和修改代码。
https:////upload-images.jianshu.io/upload_images/18962003-ab2c58dd20ef6d4a.png
activity_main.xml
1 |
|
shape_rectangle.xml
1 |
|
edit_text_color.xml
1 |
|
text_color.xml
1 |
|
MainActivity.java
1 | package com.android; |
按钮点击事件
内部类实现
内部类实现的方法是: 创建一个内部类实现OnClickListener接口并重写onClick()方法,在方法中写入点击事件的逻辑。内部类写完之后需要为按钮设置setOnClickListener(Listener listener)属性,在参数中传入之前创建好的内部类对象即可。使用这种点击事件的好处,当按钮较多时可以在onClick(View v)方法中使用switch语句case属性设置各自不同的点击事件逻辑。
1 | protected void onCreate(Bundle savedInstanceState) { |
匿名内部类实现
当按钮较少或者只有一个按钮时,就不需要再单独创建一个类实现OnClickListener接口了,可以直接创建OnClickListener的匿名内部类传入按钮的setOnClickListener()参数中。
1 | protected void onCreate(Bundle savedInstanceState) { |
Activity本身实现事件接口
除了以上两种方法,还可以在主类中实现该接口,然后重写onClick()方法,这里需要注意的是,button.setOnCLickListener(this);方法中接收了一个参数this,这个this代表的是该Activity的引用。由于Activity实现了OnClickListener接口,所以这里this代表了OnClickListener的引用,在方法中传入this就代表该控件绑定了点击事件的接口。
1 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{ |
EditText
属性
hint | 输入框显示的提示文本 |
---|---|
textColorHint | 输入框显示的提示文本的颜色 |
inputType | 限制用户的输入类型 |
capitalize | 英文大写设置 |
minLines | 最小行数 |
maxLines | 最大行数 |
SingleLine | 单行不换行 |
注意
inputType: 限制用户的输入类型
值如下:
text | 普通字符 |
---|---|
textCapCharacters | 普通字符 |
none | 普通字符 |
textCapSentences | 字符串中的第一个字母大写 |
textCapWords | 字符串中的每个单词的首字母大写 |
textMultiLine | 多行输入 |
textImeMultiLine | 输入法多行 |
textUri | 格式为: URI |
textShortMessage | 格式为: 短消息 |
textShortMessage | 格式为: 长消息 |
textEmailAddress | 格式为: 电子邮件地址 |
textEmailSubject | 格式为: 邮件主题 |
textPostalAddress | 格式为: 邮政 |
textPersonName | 格式为: 姓名 |
textPassword | 格式为: 不可见密码 |
textVisiblePassword | 格式为: 可见密码 |
textFilter | 格式为: 文本筛选 |
textWebEditText | 格式为: 作为网页表单的文本 |
number | 格式为: 数字 |
numberSigned | 格式为: 有符号数字 |
numberDecimal | 格式为: 浮点数 |
textPhonetic | 格式为: 拼音输入 |
phone | 键盘为: 拨号 |
date或者datetime | 键盘为: 日期 |
time | 键盘为: 时间 |
textAutoCorrect | 前两个自动完成 |
textAutoComplete | 前两个自动完成 |
textNoSuggestions | 不进行提示 |
capitalize:英文大写设置
sentences | 字符串的第一个字母大写 |
---|---|
words | 字符串中用空格区分单词,每个单词的首字母大写 |
characters | 字符串中每一个英文字母都大写 |
RadioButton和RadioGroup
RadioGroup基本属性
1)orientation: 排列方式
1 | 若值为horizontal,则为横向,水平排列: |
2)checkedButton: 默认选中
直接调用已经放入在radiogroup中且已有id的radiobutton即可默认选中此项。
RadioButton基本属性
1)checked: 选中状态
若为true则默认被选中,false则默认不被选中。
2)text等相关属性:
text是按钮的文本内容;
textSize是文本字体大小;
textColor是文本字体颜色······
这些属性和TextView一致。
3)button: 按钮属性
若button的值设为”@null”则不显示前面的圆形按钮,只显示文本内容本身
android:button=”@null”
CheckBox
属性
checkbox和radiobutton的属性基本一致。
1)checked: 是否被默认选中
android:checked=”true”
2)text等相关属性:
3)button: 按钮属性
若button的值设为”@null”则不显示前面的方形按钮,只显示文本内容本身
**CheckBox和RadioButton区别: **
RadioButton | CheckBox |
---|---|
选中后,通过点击无法变为未选中 | 选中后,通过点击可以变为未选中 |
只能同时选中一个 | 能同时选中多个 |
大部分UI框架中,默认圆形表示 | 大部分UI框架中,默认方形表示 |
ImageView
属性
属性名 | 关联方法 | 描述 |
---|---|---|
:adjustViewBounds | setAdjustViewBounds(boolean) | 设置该属性为真可以在ImageView调整边界时保持图片的纵横比例.需要与maxWidth、MaxHeight一起使用,否则单独使用没有效果. |
:baseline | setBaseline(int) | 视图内基线的偏移量. |
:baselineAlignBottom | setBaselineAlignBottom(boolean) | 如果为true,将父视图基线与ImageView底部边缘对齐. |
:cropToPadding | setCropToPadding(boolean) | 如果为真,会剪切图片以适应内边距的大小,与ImageView的paddingXXX和scrollX|Y属性配合使用. |
:maxHeight | setMaxHeight(int) | 视图最大高度. |
:android:maxWidth | setMaxWidth(int) | 视图最大宽度. |
:scaleType | setScaleType(ImageView.ScaleType) | 控制为了使图片适合 ImageView 的大小,应该如何变更图片大小或移动图片. |
:src | setImageResource(int) | 设置可绘制对象作为 ImageView 显示的内容. |
:tint | setImageTintList(ColorStateList) | 为图片设置渲染颜色. |
android:tintMode | setImageTintMode(PorterDuff.Mode) | 图片渲染的混合模式. |
注意:
scaleType缩放类型设置:
1 | fitXY:对图像的横向与纵向进行独立缩放,使得该图片完全适应ImageView,但是图片的横纵比可能会发生改变 |
导入网络图片
在bulid.gradle中添加
1 | repositories |
最后
1 | Glide.with(this).load(图片地址).into(图片控件); |
ListView
属性
1 | // transcript模式: 当ListView显示完成之后,新增一条新Item,ListView的处理模式(不显示新Item/自动滚动到新Item)。 |
- 需要自定义适配器继承BaseAdapter、重写方法
GridView
属性
android:columnWidth | 每列的宽度 |
---|---|
android:numColumns=”auto_fit” | 列数根据屏幕大小自动适应 |
android:verticalSpacing | 垂直方向的间距(行间距) |
android:horizontalSpacing | 水平方向间距(列间距) |
android:stretchMode=”columnWidth|spacingWidth” | 表示缩放模式(与列宽大小同步和行宽大小同步) |
android:cacheColorHint=”#00000000” | 去除拖动时默认的黑色背景 |
android:listSelector=”#00000000” | 去除选中时的黄色底色 |
android:scrollbars=”none” | 隐藏GridView的滚动条 |
android:fadeScrollEnabled=”true” | 设置为true就可以实现滚动条的自动隐藏和显示 |
android:fastScrollEnabled=”true” | GridView出现快速滚动的按钮(至少滚动4页才会显示) |
android:numColumns=”” | 设置列数 |
- 需要自定义适配器继承BaseAdapter、重写方法
ScrollView与HorizontalScrollView
属性
1 | android:scrollbars |
RecyclerView
RecyclerView 的基本用法
打开 app/build.gradle 文件,在 dependencies 闭包中添加如下内容(会爆红,但没没事)
1 | implementation 'com.android.support:design:28.0.0' |
基本操作
1 | recyclerView = (RecyclerView) findViewById(R.id.recyclerView); |
可以看到对RecylerView的设置过程,比ListView要复杂一些,这也是RecylerView高度解耦的表现,虽然代码抒写上有点复杂,但它的扩展性是极高的。
在了解了RecyclerView的一些控制之后,紧接着来看看它的Adapter的写法,RecyclerView的Adapter与ListView的Adapter还是有点区别的,RecyclerView.Adapter,需要实现3个方法:
①onCreateViewHolder()
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
②onBindViewHolder()
这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。
③getItemCount()
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。
看这篇文章:https://blog.csdn.net/qq_39539367/article/details/80338177
WebView
简介
WebView
是一个基于 webkit
引擎、展现 web
页面的控件。
Android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。
作用
- 显示和渲染Web页面
- 直接使用html文件(网络上或本地assets中)作布局
- 可和JavaScript交互调用
WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。
使用介绍
一般来说Webview可单独使用,可联合其工具类一起使用,所以接下来,我会介绍:
- Webview类自身的常见方法
- Webview的最常用的工具类: WebSettings类、WebViewClient类、WebChromeClient类
- Android 和 Js的交互
Webview类常用方法
加载url
加载方式根据资源分为三种
1 | //方式1. 加载一个网页: |
WebView的状态
1 | //激活WebView为活跃状态,能正常执行网页的响应 |
关于前进 / 后退网页
1 | //是否可以后退 |
常见用法: Back键控制网页后退
- 问题: 在不做任何处理前提下 ,浏览网页时点击系统的”Back”键,整个 Browser 会调用 finish()而结束自身
- 目标: 点击返回后,是网页回退而不是推出浏览器
- 解决方案: 在当前Activity中处理并消费掉该 Back 事件
1 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
清除缓存数据
1 | //清除网页访问留下的缓存 |
常用工具类
WebSettings类
- 作用: 对WebView进行配置和管理
- 配置步骤 & 常见方法:
配置步骤1: 添加访问网络权限(AndroidManifest.xml)
这是前提!这是前提!这是前提!
1 | <uses-permission android:name="android.permission.INTERNET"/> |
配置步骤2: 生成一个WebView组件(有两种方式)
1 | //方式1: 直接在在Activity中生成 |
配置步骤3: 进行配置-利用WebSettings子类(常见方法)
1 | //声明WebSettings子类 |
常见用法: 设置WebView缓存
- 当加载 html 页面时,WebView会在/data/data/包名目录下生成 database 与 cache 两个文件夹
- 请求的 URL记录保存在 WebViewCache.db,而 URL的内容是保存在 WebViewCache 文件夹下
- 是否启用缓存:
1 | //优先使用缓存: |
- 结合使用(离线加载)
1 | if (NetStatusUtil.isConnected(getApplicationContext())) { |
注意:每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize()
WebViewClient类
- 作用: 处理各种通知 & 请求事件
- 常见方法:
常见方法1: shouldOverrideUrlLoading()
- 作用: 打开网页时不调用系统浏览器, 而是在本WebView中显示;在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作。
1 | //步骤1. 定义Webview组件 |
常见方法2: onPageStarted()
- 作用: 开始载入页面调用的,我们可以设定一个loading的页面,告诉用户程序在等待网络响应。
1 | webView.setWebViewClient(new WebViewClient(){ |
常见方法3: onPageFinished()
- 作用: 在页面加载结束时调用。我们可以关闭loading 条,切换程序动作。
1 | webView.setWebViewClient(new WebViewClient(){ |
常见方法4: onLoadResource()
- 作用: 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
1 | webView.setWebViewClient(new WebViewClient(){ |
常见方法5: onReceivedError()
- 作用: 加载页面的服务器出现错误时(如404)调用。
App里面使用webview控件的时候遇到了诸如404这类的错误的时候,若也显示浏览器里面的那种错误提示页面就显得很丑陋了,那么这个时候我们的app就需要加载一个本地的错误提示页面,即webview如何加载一个本地的页面
1 | //步骤1: 写一个html文件(error_handle.html),用于出错时展示给用户看的提示页面 |
常见方法6: onReceivedSslError()
- 作用: 处理https请求
webView默认是不处理https请求的,页面显示空白,需要进行如下设置:
1 | webView.setWebViewClient(new WebViewClient() { |
WebChromeClient类
- 作用: 辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等。
- 常见使用:
常见方法1: onProgressChanged()
- 作用: 获得网页的加载进度并显示
1 | webview.setWebChromeClient(new WebChromeClient(){ |
常见方法2: onReceivedTitle()
- 作用: 获取Web页中的标题
每个网页的页面都有一个标题,比如www.baidu.com这个页面的标题即”百度一下,你就知道”,那么如何知道当前webview正在加载的页面的title并进行设置呢?
1 | webview.setWebChromeClient(new WebChromeClient(){ |
常见方法3: onJsAlert()
- 作用: 支持javascript的警告框
一般情况下在 Android 中为 Toast,在文本里面加入\n就可以换行
1 | webview.setWebChromeClient(new WebChromeClient() { |
常见方法4: onJsConfirm()
- 作用: 支持javascript的确认框
1 | webview.setWebChromeClient(new WebChromeClient() { |
常见方法5: onJsPrompt()
- 作用: 支持javascript输入框
点击确认返回输入框中的值,点击取消返回 null。
1 | webview.setWebChromeClient(new WebChromeClient() { |
WebView与JavaScript的交互
具体请看我写的文章: 最全面 & 最详细的 Android WebView与JS的交互方式 汇总
注意事项: 如何避免WebView内存泄露?
不在xml中定义 Webview ,而是在需要的时候在Activity中创建,并且Context使用 getApplicationgContext()
1 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PAnetT, ViewGroup.LayoutParams.MATCH_PAnetT); |
在 Activity 销毁( WebView )的时候,先让 WebView 加载null内容,然后移除 WebView,再销毁 WebView,最后置空。
1 |
|
实例
- 目标: 实现显示”www.baidu.com“、获取其标题、提示加载开始 & 结束和获取加载进度
- 具体实现:
步骤1: 添加访问网络权限
这是前提!这是前提!这是前提!
AndroidManifest.xml
1 | <uses-permission android:name="android.permission.INTERNET"/> |
步骤2: 主布局
activity_main.xml
1 |
|
步骤3: 根据需要实现的功能从而使用相应的子类及其方法(注释很清楚了)
MainActivity.java
1 | package com.example.carson_ho.webview_demo; |
Demo地址
源代码: Carson_Ho的Github-WebviewDemo
总结
- 本文全面介绍了
Webview
,总结如下
https://upload-images.jianshu.io/upload_images/944365-6e249d5a3cc7d343.png
示意图
链接: https://www.jianshu.com/p/3c94ae673e2a
Toast
使用Toast来显示消息提示框非常简单,只需要一下三个步骤:
创建一个Toast对象。通常有两种方法: 一种是使用构造方式进行创建;
1 | Toast toast=new Toast(this); |
另一种是调用Toast类的makeText()方法创建。
1 | Toast toast=Toast.makeText(this,"要显示的内容",Toast.LENGTH_SHORT); |
调用Toast类提供的方法来设置该消息提示框的对齐方式、页边距、显示的内容等等。
常用的方法如下:
1 | //用于设置消息提示框持续的时间,参数通常使用Toast.LENGTH_LONG或Toast.LENGTH_SHORT |
AlertDialog
AlertDialog的六种实现方式
1、创建AlertDialog.Builder对象
2、调用Builder对象的setTitle方法设置标题,setIcon方法设置图标
3、调用Builder相关方法如setMessage方法、setItems方法、setSingleChoiceItems方法、setMultiChoiceItems方法、setAdapter方法、setView方法设置不同类型的对话框内容。
4、调用setPositiveButton、setNegativeButton、setNeutralButton设置多个按钮
5、调用Builder对象的create()方法创建AlertDialog对象
6、调用AlertDialog对象的show()方法将对话框显示出来
创建AlertDialog.Builder对象
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ApplyDialog;
实例化对象的方法:
AlertDialog.Builder builder =newAlertDialog.Builder(this);//实例化
调用Builder对象的setTitle方法设置标题,setIcon方法设置图标
builder.setTitle(“Material Design Dialog”);
builder.setIcon(R.mipmap.ic_launcher);
调用Builder不同方法设置不同类型的对话框内容。
1.setMessage() 设置对话框内容为简单文本内容
builder.setMessage(“Hello World”);
https://upload-images.jianshu.io/upload_images/9724079-98e8da21451f7a88.png
简单文本弹窗
2.setItems() 设置文本框内容为简单列表项
finalString [] Items = {“google”,”twitter”,”line”,”QQ”,”weixin”};
builder.setItems(Items, null);
https://upload-images.jianshu.io/upload_images/9724079-e5e61ba0aa6ccdb6.png
简单列表项弹窗
3.setSingleChoiceItems() 设置对话框内容为单选列表项
finalString [] Items = {“google”,”twitter”,”line”,”QQ”,”weixin”};
builder.setSingleChoiceItems(Items, 0,null); //0 为默认选中哪个
https://upload-images.jianshu.io/upload_images/9724079-27a69dc9adfa9cba.png
单选列表项弹窗
4.setMultiChoiceItems() 设置对话框内容为多选项列表
finalString [] Items = {“google”,”twitter”,”line”,”QQ”,”weixin”};
builder.setMultiChoiceItems(Items, new boolean[]{true, false, false, false, false},null); //设置一个数组代表是否勾选
https://upload-images.jianshu.io/upload_images/9724079-6838f7c6c7d7eb0d.png
多选列表项弹窗
5.setAdapter() 设置对话框内容为自定义列表项
finalString [] Items = {“google”,”twitter”,”line”,”QQ”,”weixin”};
builder.setAdapter(newArrayAdapter(MainActivity.this,android.R.layout.activity_list_item,android.R.id.text1,Items),null);//此处涉及到系统自带布局和自定义布局,以后详述,此处使用系统自带布局activity_list_item为一个列表布局)
https://upload-images.jianshu.io/upload_images/9724079-0215d85ceea3059a.png
自定义列表项弹窗
6.setView() 设置对话框为自定义View
Viewview =View.inflate(MainActivity.this,R.layout.login,null);
builder.setView(view);
https://upload-images.jianshu.io/upload_images/9724079-662b1a888760dd8c.png
自定义View弹窗
调用setPositiveButton、setNegativeButton、setNeutralButton设置多个按钮
三个按钮跟普通按钮没有什么区别,只是名字有不同,从上到下分别代表确定,否定,和中立
builder.setPositiveButton(“确定”, null);
builder.setNegativeButton(“取消”, null);
builder.setNeutralButton(“跳过”,null);
调用Builder对象的create()方法创建AlertDialog对象
builder.create();
调用AlertDialog对象的show()方法将对话框显示出来
builder.show();
链接: https://www.jianshu.com/p/d3874b8e3ee5
ProgressBar与ProgressDialog
ProgressBar
ProgressBar是Android下的进度条,也是为数不多的直接继承于View类的控件,直接子类有AbsSeekBar和ContentLoadingProgressBar,其中AbsSeekBar的子类有SeekBar和RatingBar
ProgressBar的使用注意:
- 1、ProgressBar有两个进度,一个是android:progress,另一个是android:secondaryProgress。后者主要是为缓存需要所涉及的,比如在看网络视频时候都会有一个缓存的进度条以及还要一个播放的进度,在这里缓存的进度就可以是android:secondaryProgress,而播放进度就是android:progress。
- 2、ProgressBar分为确定的和不确定的,上面说的播放进度、缓存等就是确定的。相反地,不确定的就是不清楚、不确定一个操作需要多长时间来完成,这个时候就需要用的不确定的ProgressBar了。这个是由属性android:indeterminate来控制的,如果设置为true的话,那么ProgressBar就可能是圆形的滚动条或者水平的滚动条(由样式决定)。默认情况下,如果是水平进度条,那么就是确定的。
- 3、ProgressBar的样式设定其实有两种方式,在API文档中说明的方式如下:
- Widget.ProgressBar.Horizontal
- Widget.ProgressBar.Small
- Widget.ProgressBar.Large
- Widget.ProgressBar.Inverse
- Widget.ProgressBar.Small.Inverse
- Widget.ProgressBar.Large.Inverse
使用的时候可以这样: style=”@android:style/Widget.ProgressBar.Small”。另外还有一种方式就是使用系统的attr,上面的方式是系统的style:
- style=”?android:attr/progressBarStyle”
- style=”?android:attr/progressBarStyleHorizontal”
- style=”?android:attr/progressBarStyleInverse”
- style=”?android:attr/progressBarStyleLarge”
- style=”?android:attr/progressBarStyleLargeInverse”
- style=”?android:attr/progressBarStyleSmall”
- style=”?android:attr/progressBarStyleSmallInverse”
- style=”?android:attr/progressBarStyleSmallTitle”
ProgressBar几种比较常用的属性:
布局中设置:
1 | android:progress="50"——第一显示进度 |
使用Java代码设置:
1 | setProgress(int) //设置第一进度 |
ProgressBar常见的几种样式
- 横向progressBarStyleHorizontal
1 | <ProgressBar |
效果图:
https://upload-images.jianshu.io/upload_images/8077710-64c9683e319a801a.png
- 横向Widget.ProgressBar.Horizontal
1 | <ProgressBar |
效果图:
https://upload-images.jianshu.io/upload_images/8077710-7e11fecb254949e5.png
- 圆形:progressBarStyleLarge
1 | <ProgressBar |
效果图:
https://upload-images.jianshu.io/upload_images/8077710-85316f164892ab66.png
- 圆形:普通
1 | <ProgressBar |
效果图:
https://upload-images.jianshu.io/upload_images/8077710-99788da628dd73d9.png
- 圆形:progressBarStyleSmall
1 | <ProgressBar |
效果图:
https://upload-images.jianshu.io/upload_images/8077710-15f5cdfbcb9bd6f0.png
自定义进度条修改进度的颜色
在布局文件中的style属性就是设置进度条样式的
1 | <ProgressBar |
实际上面的背景文件是位于@android:style/Widget.ProgressBar.Horizontal,既上面的布局可以写成
1 | <ProgressBar |
查看系统中的水平进度条风格文件
1 | <style name="Widget.ProgressBar.Horizontal"> |
上面的android:progressDrawable属性是设置进度条背景,进入查看
1 |
|
可以看到,上面文件中的3个item标签分别是设置: 进度条、第二进度条、第一进度条的背景色。这里我们在drawable文件夹下新建一个pb_pd_sp_blog.xml文件,将上面的代码复制进来,并修改背景色。
1 |
|
https:////upload-images.jianshu.io/upload_images/8077710-577bc82764f7413e.png
自定义进度条多种属性
我们不但可以修改进度的颜色,也可以修改其他属性我们可以自定义实现如下效果
布局中的属性设置
1 | <ProgressBar |
drawable文件夹下的pb_pd_sp_downloadxml定义
1 |
|
效果图:
https://upload-images.jianshu.io/upload_images/8077710-e7863485c7666ac9.png
链接: https://www.jianshu.com/p/f613571addb5
ProgressDialog
ProgressDialog的创建方式有两种,一种是new ProgressDialog,一种是调用ProgressDialog的静态方法show()创建并显示,这种进度条只能是圆形条。
https://upload-images.jianshu.io/upload_images/11881598-4513061544a34ed3.png
1 | ProgressDialog dialog = ProgressDialog.show(this, "提示", "正在登陆中…", true, false, null); |
常用方法
- setProgressStyle: 设置进度条风格,风格为圆形,旋转的。
- setTitlt: 设置标题
- setMessage: 设置提示信息;
- setIcon: 设置标题图标;
- setIndeterminate: 设置ProgressDialog 的进度条是否不明确;这个属性对于ProgressDailog默认的转轮模式没有实际意义,默认下设置为true,它仅仅对带有ProgressBar的Dialog有作用。修改这个属性为false后可以实时更新进度条的进度。
- setCancelable: 设置ProgressDialog 是否可以按返回键取消;
- cancelListner:当前Dialog强制取消之后将会被执行,通常用来清理未完成的任务。
- setButton: 设置ProgressDialog 的一个Button(需要监听Button事件);
- show: 显示ProgressDialog。
- cancel: 删除progressdialog
- dismiss: 删除progressdialog 作用和cancel相同
- setMax(int)、getMax: 设置最大进度条的值
- setProgress(int)、getProgress: 更新进度条,当然一般都需要Handler的结合来更新进度条
- incrementProgressBy(int)增加进度条
- setProgressDrawable: 设置progress发生变化时的进度指示条的背景图
链接: https://www.jianshu.com/p/a9855cdc4712
延伸: 自定义Dialog
https://blog.csdn.net/sakurakider/article/details/80735400
PopupWindow
PopupWindow的相关函数
构造函数:
1 | //方法一: |
首要注意: 看这里有四个构造函数,但要生成一个PopupWindow最基本的三个条件是一定要设置的: View contentView,int width, int height ;少任意一个就不可能弹出来PopupWindow!!!!
所以,如果使用方法一来构造PopupWindow,那完整的构造代码应该是这样的:
1 | View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.popuplayout, null); |
有关为什么一定要设置width和height的原因,我们后面会讲,这里说一下为什么样强制设置contentView;很简单的原因是因为PopupWindow没有默认布局,它不会像AlertDialog那样只setTitle,就能弹出来一个框。PopupWindow是没有默认布局的,它的布局只有通过我们自己设置才行。由于方法三中,含有了这三个必备条件,不用单独设置contentview或者width、height,所以构造方法三是用的最多的一个构造方法。
最后,方法四中的focusable变量不是必须的,有关它的方法和意义,我们会在下一篇中细讲。
显示函数
显示函数主要使用下面三个:
1 | //相对某个控件的位置(正左下方),无偏移 |
这里有两种显示方式:
1、显示在某个指定控件的下方
showAsDropDown(View anchor):
showAsDropDown(View anchor, int xoff, int yoff);
2、指定父视图,显示在父控件的某个位置(Gravity.TOP,Gravity.RIGHT等)
showAtLocation(View panett, int gravity, int x, int y);
其它函数
1 | public void dismiss() |
这几个函数里,这篇只会用到dismiss(),用于不需要的时候,将窗体隐藏掉。
基本组件
Activity
生命周期
典型情况下生命周期
https://img-blog.csdn.net/20180610102358370
(1)onCreate: 表示Activity正在被创建,做一些初始化动作,只在创建时调用一次。
(2)onStart: 表示Activity正在被启动,这时Activity已经可见,但不在前台,用户看不到也无法交互。
(3)onResume: 表示Activity已经可见,并出现在前台开始活动。
(4)onPause: 表示Activity正在停止,做一些快速的轻量级回收任务。因为新Activity的onResume方法要等当前Activity的onPause方法调用之后才会调用。此时用户回到原Activity的话,onResume方法会被调用,但在onPause方法停留时间极短,用户很难重现这一场景。当前Activity被部分遮挡时,如弹出一个弹窗,onPause方法被调用,onStop方法不被调用(这一情况经验证,没有看到onPause被调用)。
(5)onStop: 表示Activity即将停止,做一些快速的轻量级回收任务。Activity采用透明主题时,onStop方法不会被调用。
(6)onDestroy: 表示Activity即将被销毁,做一些回收工作和最终的资源释放,只调用一次。
(7)onRestart: 表示Activity正在重新启动,一般是在Activity从不可见变为可见时调用。区别于onStart方法,否则不能知道是正常流程还是从onPause方法恢复的。一般是用户行为导致的,如按Home键返回桌面,或者打开了一个新的Activity,然后又切换回原来的Activity。
(1)运行状态
当一个活动处于返回栈栈顶时,它就处于运行状态。极端情况下系统才会回收这种状态的活动,因为回收运行状态的活动,将会带来极差的用户体验。
(2)暂停状态
当一个活动不处于栈顶,且部分可见时(如在它之上有一个对话框显示),它处于暂停状态。一般情况下系统也是不愿意回收暂停状态的活动的,因为它仍旧部分可见,回收它,也会造成极差的用户体验。
(3)停止状态
当一个活动不处于栈顶,且完全不可见时,进入停止状态。这时系统仍然会为这种活动保存相应的状态和成员变量,但这是不安全的,因为当需要内存时,暂停状态的活动随时可能被回收。
(4)销毁状态
当一个活动被移除返回栈后,它就进入了销毁状态。系统最倾向于回收这种状态的活动,以保证内存充足。
(1)完整生存期
活动在onCreate()到onDestroy()方法之间所经历的,就是完整生存期。一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,在onDestroy()方法中完成释放内存的操作。
(2)可见生存期
活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即使有可能无法和用户交互。我们可以通过这两个方法,合理地管理那些对用户可见的资源,如在onStart()方法中对资源进行加载,在onStop()方法中,对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。
(3)前台生存期
活动在onResume()到onPause()之间的所经历的,就是前台生存期。在前台生存期内,活动总是处于运行状态,是可以与用户交互的。
standard模式正常回调过程:
onCreate –> onStart –> onResume –> Activity运行 –> onPause –> onStop –> onDestroy
onCreat-onDestroy对:
在Activity创建和销毁时调用,只调用一次。
onStart-onStop对:
可见不在前台时调用onStart方法,不可见且不在前台时调用onStop方法。随着用户操作或者屏幕亮灭,这两个方法可能会被多次调用。在onStop状态,让Activity重新回到前台,如果应用没有因为内存不足被杀死,那么调用
onRestart-> onStart->onResume->Activity运行。如果应用进程被系统杀死了,那么要从onCreate方法重新开始。
onResume-onPause对:
可见且在前台时调onResume方法,可见不在前台时调onPause方法。随着用户操作或者屏幕亮灭,这两个方法可能会被多次调用。在onPause状态,让Activity重新回到前台,那么只调用onResume方法,即onResume->Activity运行。
惯性:
onCreate->onStart->onResume->Activity运行,会按顺序执行到Activity运行。停止时会执行onPause->onStop,onDestroy方法用户操作时调用。(questionNo: onDestroy方法在结束进程时会调用吗?是惯性到onDestroy吗?answer: 手动结束应用进程时,会onPause->onStop,但不会调用onDestroy方法。 )
详情: https://blog.csdn.net/hystudio_lzu/article/details/80629571
Fragment
Fragement 概述
Fragement 与 Activity 生命周期关系 : Fragement 嵌入到 Activity 组件中才可以使用, 其生命周期与 Activity 生命周期相关.
stop 与 destroy 状态 : Activity 暂停 或者 销毁的时候, 其内部嵌入的所有的 Fragement 也会执行 暂停 或者 销毁 操作;
活动状态: 只有当 Activity 处于活动状态的时候, 我们才能操作 Fragement;
Fragement 特征 :
- Fragement 与 Activity 交互 : Fragement 调用 getActivity() 获取其 所嵌入的 Activity, Activity 获取 FragementManager 的findFragementById() 或 findFragementByTag() 获取 Fragement;
- Activity 增删 Fragement : Activity 调用 Fragement 的 add(), remove(), replace() 等方法 添加 删除 替换 Fragement;
- Fragement 与 Activity 对应关系 : 一个 Activity 中可以嵌入多个 Fragement, 一个 Fragement 可以嵌入多个 Activity;
-生命周期受 Activity 影响: Fragement 的生命周期 受 Activity 生命周期控制;
Fragement 作用 : Fragement 是为了 Android 中 平台电脑 UI 设计, 开发者不用设计 非常负责的 界面, 只需要设计好模块, 对UI 组件进行分组和 模块化的设计和开发, 简化了 UI 组件;
Fragement 可复用性 : 同一个 app 应用, 可以在不同的 Activity 中加载同一个 Fragement;
Fragement 类 和 方法介绍
Fragement 相关类介绍
Fragement 子类 :
DialogFragement : 对话框界面的 Fragement, 显示一个浮动的对话框, 这个对话框可以方便的与 Activity 进行交互, Activity 可以管理这个 Fragment;
- ListFragement : 列表界面的 Fragement, 显示一个条目列表, 该列表可以设置一个适配器, 提供了许多管理 列表的函数;
- PerformanceFragement : 选项设置界面的 Fragement, 该Fragment 创建 类似与 设置 应用程序时很管用;
- WebViewFragement : WebView 界面的 Fragement;
Fragement 生命周期相关方法介绍
onCreate() :
1 | onCreate(Bundle savedInstanceState) |
- 回调时机 : 在创建 Fragement 的时候回调;
- 参数解析 : Bundle savedInstance, 用于保存 Fragment 参数 , Fragement 也可以 重写 onSaveInstanceState(Bundle outState) 方法, 保存Fragement状态;
- 执行的动作 : 获取 Frgement 显示的内容, 以及 启动Fragment 传入的参数 , 调用 getArguments() 获取键值对;
onCreateView() :
1 | onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); |
- 回调时机 : Fragement 绘制界面组件 的时候回调, 该方法返回 View, 这个View就是 Fragement 本身;
- 参数解析 : inflater 布局加载器, 是上下文传入, 不用自己创建; container 加载组件的父容器;
- 执行的操作 : 使用 inflate 布局加载器 加载布局文件, 并未组件设置显示的值 ;
onPause() :
- 回调时机 : Fragement 暂停的时候, 即进入后台的时候 回调;
Fragment 创建
Fragment 创建 :
- 参数准备 : 创建一个 Bundle 对象, 并向其中设置参数 :
1 | Bundle bundle = new Bundle(); |
- 创建 Fragment 对象 : 使用 new MyFragment() 创建对象, 并 调用 myFragment.setArguments(bundle) 方法传入参数;
- MyFragment myFragment = new MyFragment();
- myFragment.setArguments(bundle);
Fragment嵌入Activity方式 : Fragment 添加到 Activity 中才能显示, 以下是将 Fragment 嵌入 Activity 的方式;
- 布局文件嵌入 : 在布局文件中 使用
<Fragment />
元素, 通过定义 android:name = “com.example.MyFragment” 属性指定 Fragment 类; - 代码方式嵌入 : 调用 FragmentTransaction 对象的 add() 方法向 Activity 中添加 Fragment;
Fragment 与 Activity 通信
Fragment 获取 Activity : 调用 Fragment 对象的 getActivity()方法, 即可获取 Fragment 嵌入的 Activity 对象;
Activity 获取 Fragment :
- Fragment 属性 : 在布局文件中, 可以为
<Fragment />
元素指定 android:id 和 android:tag 属性; - 获取方法 : 调用 Activity 的 findFragmentById(int id) 或者 findFragmentByTag(String tag)方法;
Fragment 向 Activity 传递数据 : 将 Activity 当作 接口子类对象 , Fragment 中调用 Activity 中的接口方法;
- Fragment 定义接口 : 在 Fragment 内部定义一个 Callback 接口 ;
- Activity 实现该接口 : MyActivity extends Activity implement MyFragment.Callback ;
- Fragment 中获取该接口对象 : 在Fragment 中定义一个 Callback 全局变量, 然后在 onAttach(Activity activity) 方法中, 将 activity 强转为 Callback 对象 ;
- 调用接口方法 : 上面获取了 Callback 对象, 即Activity对象, 调用 Activity 中的 接口方法 , 就能在 Fragment 中调用 Activity 对应的方法了;
Activity 向 Fragment 传递数据 :
- 创建 Bundle 数据包 : 创建一个 Bundle 对象, 把要存放的键值对 放到这个对象中;
- 设置 Bundle 对象给 Fragment : 调用 Fragment 对象的 setArguments(Bundle bundle) 方法, 将 Bundle 对象设置给 Fragment;
Fragment 事务管理
FragmentManager 功能 : FragmentManager 对象 可以通过 activity.getFragmentManager()获取;
- 获取指定 Fragment : 通过 findFragmentById() 或者 findFragmentByTag() 方法获取指定 Fragment;
- 弹出栈 : 通过调用 popBackStack(), 将 Fragment 从后台的 栈 中弹出;
- 监听栈 : 通过调用 addOnBackStackChangeListener 注册监听器, 监听 后台栈变化;
FragmentTransaction 对象获取途径 :
- 获取 FragmentManager 对象 : 调用 Activity 的 getFragmentManager() 获取 FragmentManager 对象;
- 获取 FragmentTansaction 对象 : 调用 FragmentManager 对象的 beginTransaction() 方法获取 FragmentTransaction 对象;
FragmentTransaction(Fragment 事务)作用 : 对 Fragement 进行 增, 删 , 改 操作需要 FragmentTransaction 对象进行操作, 开启 这个事务, 获取 事务对象, 然后执行对 Fragment 的操作, 最后提交事务;
- 开启事务 : 调用 Fragement 对象的 beginTransaction() 方法可以获取 FragementTransaction 对象;
- 操作碎片 : FragmentTransaction 对象 中 包含了 add(), remove(), replace() 等方法;
- 提交操作 : 当执行完 Fragement 的操作之后, 可以调用 FragementTransaction 对象的 commit() 方法提交修改;
addToBackStack()方法作用 : 该方法是 FragementTransaction 的方法, 在提交事务前调用该方法, 可以将 事务中执行的操作 添加到 back 栈中, 用户按下 回退键, 修改过的 Fragement 会 回退到 事务执行之前的状态 ;
Fragment 生命周期
Fragment 状态
活动状态 : Fragment 处于前台, 可见 , 可以获取焦点 ;
暂停状态 : Fragment 嵌入的Activity 也处于暂停状态, 即 Fragment 处于后台, 可见 , 失去焦点 ;
停止状态 : Fragement 嵌入的 Activity 处于停止状态, 不可见 , 失去焦点 ;
销毁状态 : Fragement 所在的 Activity 被销毁, 执行了 onDestroy() 方法, 此时 Fragement 被 完全删除 ;
Fragement 生命周期相关方法
https://img-blog.csdn.net/20140802132139900
红色方法 与 Activity 相对应, 蓝色方法 是 自身对应的方法, 棕色方法 单独对应;
onAttach() : 嵌入, Fragement 被嵌入到 Activity 时回调该方法, 只会调用一次;
onCreate() : 创建, Fragement 创建的时候回调该方法, 只会回调一次;
onCreateView() : 绘制, 在 Fragement 绘制的时候回调该方法, 该方法会返回 绘制的 View 组件;
onActivityCreated() : 界面创建, Fragement 所嵌入的 Activity 创建完成回调该方法;
onStart() : 启动, Fragement 启动时回调, 此时Fragement可见;
onResume() : 激活, Fragement 进入前台, 可获取焦点时激活;
onPause() : 暂停, Fragement 进入后台, 不可获取焦点时激活;
onStop() : 停止, Fragement 不可见时回调;
onestroyView() : 销毁组件, 销毁 Fragement 绘制的 View 组件时回调;
onDestroy() : 销毁, 销毁 Fragement 回调;
onDetach() : 移除, Fragement 从 Activity 中移除的时候回调;
https://blog.csdn.net/dai_zhenliang/article/details/38554273