11月8日Android学习笔记
发布时间:
本文字数:1,905 字 阅读完需:约 4 分钟
框架的导入
在当前项目的build.gradle
的dependencies
中加入框架即可,如下例所示
build.gradle
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.squareup.picasso:picasso:2.5.2' //导入的框架
}
加载网络图片
-
导入
picasso
框架implementation 'com.squareup.picasso:picasso:2.5.2'
-
设置网络权限
在AndroidManifest.xml
中添加<uses-permission android:name="android.permission.INTERNET"/>
,申请网络权限 如下例:<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET"/> .........
-
加载图片
Picasso.with(context).load(bean.getPic()).into(holder.iv);
tips
listview当中包含button类型,需要在item布局外层添加这个属性,避免被抢占焦点
android:descendantFocusability="blocksDescendants"
如下例
item_detailgv.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:padding="10dp">
启动模式
支持四种属性值:
- standard :标准模式,默认的启动模式。
- singleTop : 栈顶单例模式
- singleTask : 栈内单例模式
- singleInstance:全局单例模式
为什么activity会有加载模式呢?加载模式有什么用呢?
activity的加载模式,就是负责管理实例化,加载activity的方式,并可以控制activity和task之间的加载关系。
【standard模式】
标准启动模式,当启动目标activity的时候都会创建一个新的实例,并且将当前的activity放在栈顶。 这个模式不会启动新的task。新的activity会被添加到原来的task当中。
【singleTop模式】
在栈顶就重用,否则就用新的。
当需要启动的目标activity已经位于栈顶的时候,系统就不会创建新的目标activity的实例,而是直接复用已有的
activity的实例。
原理:主要是因为他调用了activity类的onNewIntent()
方法,可以在该方法当中刷新页面数据。
举例:短信编辑页面
【singleTask模式】
采用这个模式的activity在task栈内只有一个实例,当系统使用这个模式启动目标activity时,可以分为三种情况。
(1).如果将要启动的目标activity不存在,系统将会创建目标activity的实例,并且将他放到task栈顶。
(2).如果将要启动的目标activity已经位于task栈顶,此时就和singleTop的模式的行为是相同的。
(3).如果将要启动的目标activity已经存在,但是没有位于task栈顶,系统将会把位于该activity上面的所有
activity都移出task栈,从而是的目标activity就转入栈顶。
singleTop和singleTask的区别:
singleTop模式每次只检测当前栈顶的activity是否是希望我们创建的,如果是就不用创建了,复用就可以了。
singleTask模式会检测栈中所有的activity的对象,找到就提到栈顶,将前面挡住的全部销毁
举例:手机浏览器
【singleInstance模式】
在这中加载模式下,系统保证无论从哪个task中启动目标activity,只会创建一个目标activity的实例,并且会使用
一个全新的task的栈来装载这个task的实例。
使用这种模式启动目标activity,也可以分为两种情况:
(1)如果将要启动的目标activity不存在,系统会先创建一个全新的task,加载创建目标activity的实例,并且会有一个
全新的task的栈来装载这个目标activity。
(2)如果将要启动的目标activity已经存在,无论它位于哪个应用程序中,无论他位于哪个task中,系统将会把这个
activity所在的task放置在前台,从而使这个activity显示出来。
注意:
采用singleInstance的模式加载的activity使用位于栈顶,并且在栈中只有这个activity。
举例: 来电显示页面,有道取词页面
intent
可以通过setAction进行页面跳转
Intent的概念和作用:
- 用于封装程序的调用“意图”
- 实现了两个activity之间的数据交互
- 各种应用程序组件(activity,service,broadcastReceiver)之间通信的重要媒介。
Intent的七大属性
- ComponentName :主要用于访问activity,进行显示意图的访问。
- action :表示想要启动的activity想要完成什么动作。进行隐士意图的访问。
- category :为action增加附加类别的信息。它是action大动作中的小动作。
- data :保存需要传递的数据的Uri格式。 Uri:统一资源标识符
- type :区分文件类型
- extras :保存需要传递的额外数据。
- flags :动态的配置activity的启动模式。
【ComponentName】:用于指定启动的组件
核心代码:
//完整的显示意图的跳转方法:
Intent intent3 = new Intent();
ComponentName cName = new ComponentName(MainActivity.this, SecondActivity.class);
intent3.setComponent(cName);
startActivity(intent3);
【action】:某个activity能够完成什么“动作”
intent当中定义的关于action的实参。
ACTION_MAIN:(android.intent.action.MAIN) Android的程序的入口
ACTION_VIEW:(android.intent.action.VIEW) 显示指定的数据
ACTION_EDIT:(android.intent.action.EDIT) 编辑指定的数据
ACTION_DIAL:(android.intent.action.DIAL) 显示拨号面板界面
ACTION_CALL:(android.intent.action.CALL) 直接呼叫data中所带的号码
ACTION_ANSWER:(android.intent.action.ANSWER) 接听来电
ACTION_SEND:(android.intent.action.SEND) 向其他人发送数据(彩信,email)
ACTION_SENDTO:(android.intent.action.SENDTO) 向其他人发送短信
ACTION_SEARCH:(android.intent.action.SEARCH) 执行搜索
ACTION_GET_CONTENT:(android.intent.action.GET_CONTENT) 让用户选择数据,并且返回所选数据
【Category】:类别属性
指明了执行action的分类,是action的子动作。
category常用的属性值:
CATEGORY_DEFAULT(android.intent.category.DEFAULT):Android系统中默认的执行方式,
按照普通的activity的执行方式来执行。
CATEGORY_HOME(android.intent.category.HOME):回到主屏页面
CATEGORY_LAUNCHER(android.intent.category.LAUNCHER):设置该组件为当前应用程序中优先级最高的activity,
通常是与ACTION_MAIN配合使用的。
CATEGORY_PREFERENCE:设置该组件为preference。
CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。
action和category在清单文件当中注册时,都是添加在activity的子元素<intent-fileter>
当中的。
这个元素中可以包含多个action属性和多个category属性。
在应用程序中创建一个intent的属性时,只能设置一个action的属性,因为他使用的是setAction(str)的方法。
但是可以包含多个category的属性,因为他是使用addCategory(str)的方法的。
注意set和add的区别理解
【Data】:通常用于向action属性提供数据。
Data属性的值是一个uri的对象,URI的格式: scheme://host:port/path
scheme: 协议
host: 主机号
port: 端口号
path: 路径
系统内置的data属性的常量:
- tel: 号码的数据格式,后面跟着电话号码
- mailto: 邮件的数据格式,后面跟着邮件收件人的地址
- smsto: 短信的数据格式,后面跟着短信接受的号码
- content:// 内容数据格式,后面跟着需要读取的内容(结合内容提供者)
- file:/// 文件数据格式,后面跟着文件的路径,要有三个斜线。
- geo://lat,lon 经纬度数据格式,在地图上显示该经纬度指定的地址。
public void home(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
public void dial(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL); //Intent.ACTION_DIAL
Uri uri = Uri.parse("tel:18511698819");
intent.setData(uri);
startActivity(intent);
}
public void browser(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data = Uri.parse("http://www.baidu.com/");
intent.setData(data);
startActivity(intent);
}
public void map(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data = Uri.parse("geo://34.009,152.890");
intent.setData(data);
startActivity(intent);
}
public void video(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/and.mp4");
intent.setDataAndType(uri, "video/*");
startActivity(intent);
}
public void music(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/fly.mp3");
intent.setDataAndType(uri, "audio/*");
startActivity(intent);
}
public void sms(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
Uri uri = Uri.parse("smsto:18511690019");
intent.setData(uri);
intent.putExtra("sms_body", "今天的天气好晴朗!!");
startActivity(intent);
}
public void sendEmail(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
String bcc[] = {"[email protected]"};
String cc[] = {"[email protected]","[email protected]"};
intent.putExtra(Intent.EXTRA_BCC, bcc);
intent.putExtra(Intent.EXTRA_CC, cc);
intent.putExtra(Intent.EXTRA_SUBJECT, "今天的天气好晴朗");
intent.putExtra(Intent.EXTRA_TEXT, "一起出去玩吧~~");
intent.setType("message/*");
startActivity(intent);
}
读取Assets
- 通过
context.getAssets()
获取AssetManager
对象 - 通过
assetManager.open(fileName)
获取输入流 - 使用
ByteArrayOutputStream
接收输入流并转成字节数组或者字符串
示例
/**
* 传入文件的路径 xzcontent/xzcontent.json
* @param fname
* @return
*/
public String getAssetJson(String fname){
//获取Asset文件管理者
AssetManager assetManager = context.getAssets();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//打开文件
try {
InputStream is = assetManager.open(fname);
//读流的数据
int hasRead = 0;
byte[] buf = new byte[1024];
while ((hasRead = is.read(buf))!=-1){
baos.write(buf, 0, hasRead);
}
baos.flush();
is.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return baos.toString();
}
读取assets中的图片
使用BitmapFactory将byte数组转换为Bitmap对象,然后setImageBitmap即可
如下例
// 读取asset文件夹当中的图片,显示在imageview上
String fname = "xzlog/" + dao.getLogoname() + ".png";
byte[] bytes = assetsUtils.getAssetByteArray(fname);
//将字节数组转换成位图对象
Bitmap bitmap =
BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
vholder.iv.setImageBitmap(bitmap);