4-VI--☆ListView的封装支持多种条目
零、前言
[1.]封装了一晚,总算把多条目的ListView封装了一下
一、使用
1.初始化数据
ArrayList<Message> messages = new ArrayList<>();
messages.add(new Message("你瞅啥?!", "巫缨:", 0));
messages.add(new Message("瞅你怎滴!!", "捷特:", 1));
messages.add(new Message("2018-8-13", "9:30", 2));
messages.add(new Message("你再瞅试试!", "巫缨:", 0));
for (int i = 0; i < 100; i++) {
if (i % 3 == 0) {
messages.add(new Message("我试了怎滴!!--1", "捷特:", 1));
} else if (i % 3 == 1) {
messages.add(new Message("2018-8-13", "9:30", 2));
} else {
messages.add(new Message("你再瞅试试!--0", "巫缨:", 0));
}
}
2.使用:
//类型和布局id放在HashMap中
HashMap<Integer, Integer> typeMap = new HashMap<>();
typeMap.put(0, R.layout.list_item_left);
typeMap.put(1, R.layout.list_item_right);
typeMap.put(2, R.layout.list_item_center);
mLv.setAdapter(new MyLVsAdapter<Message>(this, messages, typeMap) {
@Override
public void setData(MyLVsHolder holder, Message data, int position, int type) {
switch (type) {
case 0:
holder.setText(R.id.id_tv_right, data.getValue());
holder.setText(R.id.id_tv_name, data.getName());
break;
case 1:
holder.setText(R.id.id_tv_left, data.getValue());
holder.setText(R.id.id_tv_name, data.getName());
break;
case 2:
holder.setText(R.id.id_tv_center, data.getValue());
holder.setText(R.id.id_tv_name, data.getName());
break;
}
}
});
3.必须有个实体类,且继承ItemBean类:保证实体类有type属性
/**
* 作者:张风捷特烈<br/>
* 时间:2018/8/27 0027:18:37<br/>
* 邮箱:1981462002@qq.com<br/>
* 说明:信息实体类
*/
public class Message extends ItemBean {
public Message(String value, String name, int type) {
super(type);
this.value = value;
this.name = name;
}
private String value;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
二、具体封装类
1.Item类:保证实体类有type属性
/**
* 作者:张风捷特烈<br/>
* 时间:2018/8/27 0027:19:30<br/>
* 邮箱:1981462002@qq.com<br/>
* 说明:多类型ListView实体类父类
*/
public class ItemBean {
private int type;
public ItemBean(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
2.适配器类
public abstract class MyLVsAdapter<T> extends BaseAdapter {
/**
* 数据
*/
protected List<T> mDatas;
/**
* 布局映射
*/
protected Map<Integer, Integer> mTypeMap;
/**
* 上下文
*/
protected Context mCtx;
public MyLVsAdapter(Context ctx, List<T> datas, Map<Integer, Integer> typeMap) {
mCtx = ctx;
mDatas = datas;
mTypeMap = typeMap;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public T getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//创建 MyLVHolder 对象
T t = mDatas.get(position);
int type = ((ItemBean) t).getType();
MyLVsHolder holder = new MyLVsHolder(mCtx, convertView, mTypeMap, position, type);
setData(holder, getItem(position), position, type);
return holder.getConvertView(type);
}
/**
* 设置数据抽象方法
*
* @param holder MyLVHolder
* @param data 数据
* @param position 位置
* @param type
*/
public abstract void setData(MyLVsHolder holder, T data, int position, int type);
/**
* 根据数据源的position返回需要显示的的layout的type
*
* @param position 位置
* @return
*/
@Override
public int getItemViewType(int position) {
T t = mDatas.get(position);
((ItemBean) t).getType();
return ((ItemBean) t).getType();
}
@Override
public int getViewTypeCount() {
return mTypeMap.size();
}
}
3.Holder类
public class MyLVsHolder<T> {
/**
* 条目内部控件的view集合
*/
private SparseArray<View> mViews;
/**
* 位置
*/
private int mPosition;
private int mType;
/**
* 条目视图
*/
private View mItemView;
private SparseArray<View> mItemViews;
private List<Integer> mPos;
/**
* @param ctx 上下文
* @param typeMap 布局ID
* @param position 位置
* @param type 类型
*/
public MyLVsHolder(Context ctx, View convertView, Map<Integer, Integer> typeMap, int position, int type) {
mPosition = position;
mType = type;
mViews = new SparseArray<>();
mItemViews = new SparseArray<>();
//生成条目的View
for (int i = 0; i < typeMap.size(); i++) {
if (type == i) {
if (convertView == null) {
mItemView = LayoutInflater.from(ctx).inflate(typeMap.get(i), null);
} else {
mItemView = convertView;
//用MyLVHolder为条目View设置标签
mItemView.setTag(this);
}
mItemViews.put(i, mItemView);
return;
}
}
}
public List<Integer> handleCheckBox(int checkBoxId) {
mPos = new ArrayList<>();
final CheckBox cb = this.getView(checkBoxId);
cb.setChecked(false);
if (mPos.contains(this.getPosition())) {
cb.setChecked(true);
}
cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cb.isChecked()) {
mPos.add(getPosition());
} else {
mPos.remove((Integer) getPosition());
}
}
});
return mPos;//返回选中的CheckBox位置集合
}
/**
* 通过viewId获取控件
*
* @param viewId 条目内部控件的id
* @param <T> 数据泛型
* @return view
*/
public <T extends View> T getView(int viewId) {
//通过viewId为键获取View值
View view = mViews.get(viewId);
//如果view为空
if (view == null) {
//条目findViewById获取View
view = mItemViews.get(mType).findViewById(viewId);
//以id为键,View为值存入mViews集合
mViews.put(viewId, view);
}
return (T) view;
}
public View getConvertView(int type) {
L.d(type + L.l());
return mItemView;
}
public int getPosition() {
return mPosition;
}
/**
* 设置TextView文本方法
*
* @param viewId 条目内部控件的id
* @param text 文本
* @return MyLVHolder对象
*/
public MyLVsHolder setText(int viewId, String text) {
TextView view = getView(viewId);
if (view != null) {
view.setText(text);
}
return this;
}
/**
* 通过id设置图片
*
* @param viewId 条目内部控件的id
* @param resId 资源id
* @return MyLVHolder对象
*/
public MyLVsHolder setImageViewRes(int viewId, int resId) {
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
}
/**
* 通过id设置图片
*
* @param viewId 条目内部控件的id
* @param bitmap 图片
* @return MyLVHolder对象
*/
public MyLVsHolder setImageViewBitmap(int viewId, Bitmap bitmap) {
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
}
附录、布局
1.layout/list_item_center.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="176dp"
android:padding="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@mipmap/head_center"/>
<TextView
android:id="@+id/id_tv_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
android:textColor="@android:color/holo_orange_light"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="@+id/id_tv_name"
app:layout_constraintEnd_toStartOf="@+id/iv_icon"
app:layout_constraintTop_toTopOf="@+id/id_tv_name"
app:layout_constraintVertical_bias="1.0"/>
<TextView
android:id="@+id/id_tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
android:textColor="?android:attr/colorActivatedHighlight"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="@+id/iv_icon"
app:layout_constraintStart_toEndOf="@+id/iv_icon"
app:layout_constraintTop_toTopOf="@+id/iv_icon"/>
</android.support.constraint.ConstraintLayout>
2.layout/list_item_left.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/id_tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
android:textColor="?attr/colorControlActivated"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/iv_icon"
app:layout_constraintStart_toEndOf="@+id/iv_icon"
app:layout_constraintTop_toTopOf="@+id/iv_icon"
app:layout_constraintVertical_bias="0.555"/>
<ImageView
android:id="@+id/iv_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@mipmap/head_left"
tools:layout_editor_absoluteX="26dp"/>
<TextView
android:id="@+id/id_tv_right"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginBottom="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/iv_icon"
app:layout_constraintStart_toEndOf="@+id/id_tv_name"
app:layout_constraintTop_toTopOf="@+id/iv_icon"/>
</android.support.constraint.ConstraintLayout>
3.layout/list_item_right.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="16dp"
android:padding="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@mipmap/test"/>
<TextView
android:id="@+id/id_tv_left"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginEnd="12dp"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/id_tv_name"
app:layout_constraintEnd_toStartOf="@+id/id_tv_name"
app:layout_constraintTop_toTopOf="@+id/id_tv_name"
app:layout_constraintVertical_bias="1.0"/>
<TextView
android:id="@+id/id_tv_name"
android:layout_width="wrap_content"
android:layout_height="21dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
android:textColor="#283be8"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/iv_icon"
app:layout_constraintEnd_toStartOf="@+id/iv_icon"
app:layout_constraintTop_toTopOf="@+id/iv_icon"/>
</android.support.constraint.ConstraintLayout>
4.layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fastScrollEnabled="true">
</ListView>
</LinearLayout>
后记、
1.声明:
[1]本文由张风捷特烈原创,转载请注明
[2]欢迎广大编程爱好者共同交流
[3]个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
[4]你的喜欢与支持将是我最大的动力
2.连接传送门:
更多安卓技术欢迎访问:安卓技术栈
我的github地址:欢迎star
简书首发,腾讯云+社区同步更新
张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com
3.联系我
QQ:1981462002
邮箱:1981462002@qq.com
微信:zdl1994328
4.欢迎关注我的微信公众号,最新精彩文章,及时送达:

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
小程序踩坑第二谈
小程序学习总结 首先贴上官方文档的链接地址 小程序开发文档 1. 触发 upper 和 lower 事件的条件。如何在 scroll-view 中触发该条件 首先 upper 事件和 lower 事件是在 scroll-view 中使用,可以用在上拉自动加载和下拉刷新;或者单独的下拉刷新也可以,即 onPullDownRefresh,不过需要在全局变量中开启才行。 *在滚动 scroll-view 时会阻止页面回弹,所以在 scroll-view 中滚动,是无法触发 onPullDownRefresh 注意 scroll-view 和 onPullDownRefresh 是不能够同时使用的,这个在开发文档中也有提示。 虽然都有文档但还是需要我们自己去踩坑才能更好的学习了解,下面是 demo upper-threshold 是表示距顶部/左边多远时(单位px),触发 scrolltoupper 事件; lower-threshold 是表示距底部/右边多远时(单位px),触发 scrolltolower 事件,定义好之后在 .js 文件中定义函数即可。 2 . 跳转带有底部菜单的时候...
-
下一篇
老司机带你快速上手调试Flutter项目
对于开发项目来说,调试控制工具是不可少的,开发者是一定要掌握调试工具的使用,一来是为了查看log日志,一来是为了排查错误,再一个原因是可以查看内存占用情况,以便后续性能优化。 Flutter的调试主要有3个需要去关注的,一个是Flutter Outline,一个是Flutter Inspector,还有一个是log控制台。前者主要是用于视图预览,后者是用于性能调试,log控制台用于查看log信息以及定位错误等。 下面就详细的讲解一下如何使用Flutter的调试工具。 一、基础配置和设置 在讲解调试工具之前,先来看看有关的设置选项,点击菜单栏File-->Settings-->Languages & Frameworks --> Flutter,打开之后设置如图2.6.1所示,重点字段我都翻译成了中文,帮助大家理解,如果不是很熟悉这个设置,推荐大家按照我这样去配置。 【提示】如果Flutter Outline和Flutter Inspector没有出现在侧边栏(默认是在右边侧边栏),建议重启Android Studio,如果还没有出现,建议卸载Flutter插件...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- MySQL数据库在高并发下的优化方案
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)