文章目录
Android
安卓开发者指南:https://developer.android.google.cn/guide
1 ListView
ListView是android中常用的一个控件,通常是以列表的形式展示数据,并且当加载的数据过多的时候可以分页加载,动态显示数据,通常是横向显示数据。ListView适合“自底向上”的开发模式,即从每个条目的显示组件,到对其进行控制的数据结构,最后通过Activity等进行使用。
应用场景
1.通讯录,短信列表
2.聊天联系人,聊天界面,好友动态
3.设置界面,各种列表界面
4.文件夹列表,应用列表等等
5.O2O美食外卖等商家列表、评论列表
ListView实践的三种效果
1.模拟异步请求网络数据
2.获取本机安装的软件
3.类似聊天页面实现
学习ListView需要学会的技能:
1.添加header rooter
2.实现ListView各种效果
3.绑定视图与数据
4.优化列表样式,加载性能优化
1.1 ListView展示列表数据
实现步骤:
-
在Layout创建ListView:activity_app_list,< ListView>标签
-
创建每一行的layout:item_app_list_view.xml,< ImageView>和< TextView> 标签
-
创建每一行的数据
public class AppLIstAdapter extends BaseAdapter中重写方法:
public int getCount():有多少条数据
public Object getItem(int position):返回当前position位置的这一条数据
public long getItemId(int position):返回当前position位置的这一条数据的ID
public View getView(int position,View convertView, ViewGroup parent):处理view–data填充数据的一个过程
-
用adapter(数据绑定至相应组件)将数据填充到每一行的视图中
appListView.setAdapter(new AppListAdapter(appNames));
1.2 获取系统已安装应用列表
- 获取应用列表
// 获取所有的应用信息
private List<ResolveInfo> getAppInfos() {
//手机系统中的主应用Intent
Intent intent = new Intent(Intent.ACTION_MAIN, null);
//应用程序显示在程序列表里的应用
intent.addCategory(Intent.CATEGORY_LAUNCHER);
//获取手机中的所有应用信息列表
return getPackageManager().queryIntentActivities(intent, 0);
}
- 绑定应用列表信息
List<ResolveInfo> mInfos;
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.item_app_list_view, null);
ImageView appIconImageView = (ImageView)convertView.findViewById(R.id.app_icon);
TextView appNameTextView = (TextView)convertView.findViewById(R.id.app_name);
//获取应用的名称并与布局View绑定
appNameTextView.setText(mInfos.get(position).activityInfo.loadLabel(getPackageManager()));
//获取应用的图标并与行布局View绑定
appIconImageView.setImageDrawable(mInfos.get(positin,activityInfo.loadIcon(getPackageManager()));
// 为图标添加点击事件,跳转到其他应用去。方法一
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String packageName = mInfos.get(position).activityInfo.packageName;//包名
String className = mInfos.get(position).activityInfo.name;
ComponentName componentName = new ComponentName(packageName,className);
final Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
}
});
// 方法二:在OnCreate下,appListView.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 重写onItemClick方法 });
// 长按:appListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){ 重写onItemLongClick方法 });
return convertView;
}
添加一个头部视图:
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View headerView = layoutInflater.inflate(R.layout.header_list_view,null);
appListView.addHeaderView(headerView);
优化列表,每次都要解析layout,再findViewById查找,实际上提供了缓存,进行优化。(优化列表的样式)
1.3 网络下载数据并显示
- 使用异步访问网络
- 解析获取json数据
创建类:LessonInfo.java:mName,mDescription;
创建类:LessonResult.java:mMessage,mStatus,List< LessonInfo> mLessonInfoList=new ArrayList< >();
mListView.setAdapter(new RequestDataAdapter(RequestDataActivity.this, lessonResult.getLessonInfoList()); - 加载数据到ListView
新建适配器RequestDataAdapter类,继承BaseAdapter重写其中的方法:
注意,在AndroidManifest中声明Activity,并且加入权限。
1.4 引用不同行布局
根据不同type下展示不同view视图。
ChatActivity.java中添加public static class ChatMessageAdapter extends BaseAdapter,重写四个方法,并且再实现public int getItemViewType(int position)根据不同类型返回不同视图,实现方法public int getViewTypeCount(){ return 2; }
添加类ChatMessage.java:
public class ChatMessage{
属性:mId,mFriendID,mName,mDate,mContent,boolean mIsComMessage;
带参构造方法
}
设计布局
2 CardView控件
2.1 介绍
1.Android5.0 之后新增
2.com.android.support:cardview-v7:26.1.0 独立引入
3.继承自FrameLayout,方便作为其他控件容器,添加3D阴影和圆角效果。
CardView常用属性
- cardBackgroundColor 设置背景色
- cardCornerRadius 设置圆角半径
- contentPadding 设置内部padding
- cardElevation 设置阴影大小
- cardUseCompatPadding 默认为false,用于5.0及以上,true则添加额外的padding绘制阴影
- cardPreventCornerOverlap 默认为true,用于5.0以下,添加额外的padding,防止内容和圆角重叠
2.2 demo
我的版本:
implementation ‘androidx.appcompat:appcompat:1.1.0’
implementation ‘androidx.cardview:cardview:1.0.0’
<androidx.cardview.widget.CardView>
2.3 手机适配之dimen
dimen是用来定义尺寸的资源文件,默认路径工程的 res\values\dimens.xml
可以在res下创建不同分辨率的values目录例如values-480x320、values-800x480、values-1920x1080等,并且在上述目录中可以分别创建尺寸文件, 这样在不同分辨率下,该目录下的dimens.xml会代替res/values/dimens.xml达到最佳的适配效果。
dimen定义的资源文件如何使用?
1、在工程的res\values\目录下创建一一个dimens.xml尺寸资源文件
2、添加一个布局文件,在此布局文件中添加一个按钮,使用尺寸资源文件来定义按钮的宽和高
3、在java代码中也可以获取到dimens尺寸资源文件的数值
Resources res = getResources();
float btn_h = res.getDimension(R.dimen.btn.height);
float btn_w = res.getDimension(R.dimen.btn.width);
尺寸文件使用建议:
1、在values目录下创建一个默认的 dimens文件
2、尽可能多的创建不同分辨率的dimens文件(这样应用才会适配的完美)
手机适配之values目录基础知识:
values目录用来存放colors.xml,dimens.xml,strings.xml等数值文件,同时也可以根据屏幕分辨率、语言、API 等设置对values目录进行分类,特定的values目录能满足设定的设备进行加载,但values目录命名是有规范的。
3 屏幕适配
由于Android系统的开放性,任何用户、开发商、OEM厂商、运营商都可以对Android进行定制,修改成他们想要的样子,导致碎片化严重。
屏幕尺寸:指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米,常见尺寸: 2.4,2.8,3.5,3.7 ,4.2,5.0,5.5,6.0等
屏幕分辨率:是指在横纵向上的像素点数,单位是px,1px= 1个像素点,一般以 纵向像素 * 横向像素 ,如: 1960 *1080
屏幕像素密度:是指每英寸上的像素点数,单位是dpi,即"dot per inch"的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关。
eg:320*240,2.5inch
在屏幕像素密度为160dpi的情况下,1dp=1px,假如:320dpi→1dp=2px
在尺寸一定的情况下,分辨率越高,屏幕越清晰,屏幕像素密度越大。
1dp= (像素密度/160dpi)*1px
换算公式:pxValue= (像素密度/160dpi)*dpValue
density:(像素密度/160dpi)
像素单位
px:pixel的缩写,像素,1px代表屏幕上一个物理的像素点。
dip、 dp:都是Density Independent Pixels的缩写,即密度无关像素。
sp:scaled pixels,与dp类似,用于设置字体大小。
dp的范围划分
布局适配的方法
1.禁用绝对布局;
2.少用px
3.使用wrap_ content、match_parent、权重layout_weight
4.重建布局文件
1.wrap_content:先按照内容的多少去设定控件大小,然后按照权重的比例来分配剩余控件。
2.match_parent:不受内容长度改变而改变,控件大小=父容器大小+权重比例剩余空间大小。
3.使用0dp:直接按照所设定的比例去分配空间。
图片适配的方法
1.提供不同分辨率的备用位图
2.使用自动拉伸图
4 BaseAdapter抽象类
BaseAdapter简介及使用场景:
BaseAdapter是一个抽象类,常用于和Android中的一些控件如ListView,GridView ,ExpandableListview,Spinner等控件结合来显示数据的一种控件,在Android开发中占有很重要的位置。
使用步骤:
定义一个类来继承BaseAdapter抽象类;
实现里面的方法,书写方法体;
在相应的Activity中使用该适配器。
重写的方法:
public int getCount():数据域大小方法
public object getItem(int arg0):返回每个Item的数据
public long getItemId(int arg0):返回每个Item的ID
View getView(int position, View convertView, ViewGroup parent)
参数介绍:position就是位置从0开始;convertView是Spinner,ListView中每一项要显示的view;parent就是父窗体了,也就是Spinner,ListView,GridView了,通常return的view 也就是convertView。
getView()方法的优化处理
第一种优化方式:
通过缓存convertView。这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能。
第二种优化方式:
通过convertView + ViewHolder来实现,ViewHolder就是一个静态类,使用ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了UI的响应速度。
当我们判断convertView== null的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件( XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView 时从Tag中取出。
如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。
最重要的是:重绘视图,调用次数是由第一个方法确定的,最后将视图返回。
注意:有些控件必须设置成没有获利焦点与点击。
这几个方法写的内容基本不变, 具有参考价值。
重写数据区域使用ArrayList实现List。先封装一个数据类,再将这个数据类装进list集合中,绑定数据区域与视图区域。setlistAdapter(MyAdapter);
注:MyAdapter是自定义的Adapter。