android 手把手教你打造万能的ListView GridView的适配器

Android 快速开发系列 打造万能的ListView GridView 适配器 在这里小编整理了一份Android大厂常见面试题,和一些Android架构视频解析,都已整理成文档,全部都已打包好了,希望能够对大家有所帮助,在面试中能顺利通过。喜欢本文的话,不妨顺手给我点个小赞、评论区留言或者转发支持一下呗《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!_content"自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。 阅读详情

我们在开发项目中,listview是最常用的控件,也算是android中控件这块属于比较难点的,或容易出现问题的地方,说他难不是说简单的使用,那个相信大家会,比如结合网络访问,异步记载图片,滑动卡以及嵌套等,今天是写一篇关于ListView,GridView通用的adapter,而在adapter中getCount,getItem,getItemId,getView要复写这4个方法,下面看下我们adapter类常写的方式

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >
    <ListView
        android:id="@+id/lv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
         />
</RelativeLayout>


item布局

<?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" >
<TextView 
   android:id="@+id/tvContent"
   android:layout_width="fill_parent"
   android:layout_height="40dp"
   />
</LinearLayout>

MainActivity,class

public class MainActivity extends Activity {
private ListView lv;
private List<String> datas;
private LayoutInflater inflater;
  @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
inflater = LayoutInflater.from(this);
datas = new ArrayList<String>();
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
datas.add("hello world");
MyAdapter adapter = new MyAdapter();
lv.setAdapter(adapter);
}
class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}


@Override
public long getItemId(int position) {
return position;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item, null);
holder.tvContent = (TextView) convertView.findViewById(R.id.tvContent);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.tvContent.setText(datas.get(position));
return convertView;
}
}

static class ViewHolder{
TextView tvContent;
}
}

在adapter中我们发现其实adapter真正每次实现不一样的是getView()方法,我们要对其优化封装,现在想办法封装一个通用的adapter,如何抽取呢?其实无非是java面向对象的几个基本特征:抽象,封装,继承,多态,当我们看见一段代码在每个类中都会出现,那么我们就最好把这些相同的代码封装到一个父类中,而每个类针对不同的业务方法不一样,就让其子类去实现,那么这个时候我们想到了java中的抽象类了,现在就对adapter方法进行简单的封装下:

MyBaseAdapter.java

public abstract class MyBaseAdapter<T> extends BaseAdapter {
private List<T> datas;
private Context context;
public MyBaseAdapter(List<T> datas, Context context) {
super();
this.datas = datas;
this.context = context;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public abstract View getView(int position, View convertView, ViewGroup parent);
}

 我们发现以后只要继承此MyBaseAdapter就可以少写getCount,getItem,getItemId。只要复写getView()方法即可,这比之前优化进了一下步,现在我们看看getView()方法代码怎么写的

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item, null);
holder.tvContent = (TextView) convertView.findViewById(R.id.tvContent);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.tvContent.setText(datas.get(position));
return convertView;
}
}

static class ViewHolder{
TextView tvContent;
}

现在发现getView方法中与ViewHoler类绑定在一起,我们知道ViewHolder是通过converetView.setTag()与其绑定,这样当convertView复用时,就不用findViewById了,因为view的id都封装在ViewHolder中了,所以针对不同的listview,我们肯定要写不同的ViewHolder类了,那么现在想打造一个常用的ViewHolder,继续优化getView方法,

也就是说,实际上们每个convertView会绑定一个ViewHolder对象,这个viewHolder主要用于帮convertView存储布局中的控件,那么ViewHolder类一个是提供setTag方法一个是对外提供一个获取View对象的方法,根据这2点我们写一个ViewHolder类出来,

public class ViewHolder {
private View convertView;
public void setTag(){
convertView.setTag(this);
}

public View getView(){

return convertView;
}
}

这个ViewHolder肯定是不能用的,convertView这个变量是从来的,一是通过set方法从外界设置进来,二是通过构造函数传递进来,但是如果是通过构造函数对convertView进行初始化,那么我们可以随便创建ViewHolder对象了,那么构造函数就不能对外使用了,这个时候我们就把构造函数做成private,所以我们只要对外提供一种方法就是获取到ViewHoler,而ViewHolder是和convertView绑定的,如果做缓存的都知道,先看看缓存有没有,如果没有就去就去new,在方法内部做一个判断即可,说了这么多,把刚才的思路转换成代码实现如下:

ViewHolder:

<span style="font-size:18px;">public class ViewHolder {
	    private View mConvertView;  
	    private ViewHolder(Context context, ViewGroup parent, int layoutId, int position)  
	    {  
	        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);  
	        mConvertView.setTag(this);  
	    }  
	    /** 
	     * 获取一个ViewHolder对象 
	     */  
	    public static ViewHolder get(Context context, View convertView,  
	            ViewGroup parent, int layoutId, int position)  
	    {  
	        if (convertView == null)  
	        {  
	            return new ViewHolder(context, parent, layoutId, position);  
	        }  
	        return (ViewHolder) convertView.getTag();  
	    }  
	    public View getConvertView()  
	    {  
	        return mConvertView;  
	    } 
}</span>

adapter的getView方法如下:

@Override
		public View getView(int position, View convertView, ViewGroup parent) {
		    //实例化一个viewHolder  
	        ViewHolder viewHolder = ViewHolder.get(getApplicationContext(), convertView, parent,  
	                R.layout.item, position);  
	        return viewHolder.getConvertView(); 
		}
此时心中一震窃喜,我很牛逼比,运行跑起来界面空白,我的去啊,赶脚好牛逼,怎么能让view设置数据到界面上呢,这又是一个废闹细胞的时刻到了,心想一个layout那么多view,怎么办啊,神啊,我突然想到了集合的概念,牛比不,抽烟去,等下继续写!集合?List能用么,不可以为什么呢?因为每个item上的view,是通过id去寻找的,这么一说我马上想到了用Map集合,但是我就不用,我使用android一个自带的容器,叫做SparseArray这个类

public class ViewHolder {
	    private View mConvertView;  
	    private final SparseArray<View> mViews;
	    private ViewHolder(Context context, ViewGroup parent, int layoutId, int position)  
	    {  
	    	mViews = new SparseArray<View>();
	        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);  
	        mConvertView.setTag(this);  
	    }  
	    /** 
	     * 获取一个ViewHolder对象 
	     */  
	    public static ViewHolder get(Context context, View convertView,  
	            ViewGroup parent, int layoutId, int position)  
	    {  
	        if (convertView == null)  
	        {  
	            return new ViewHolder(context, parent, layoutId, position);  
	        }  
	        return (ViewHolder) convertView.getTag();  
	    }  
	    public View getConvertView()  
	    {  
	        return mConvertView;  
	    } 
	    /** 
	     * 通过控件的Id获取对于的控件,如果没有则加入views 
	     */  
	    public <T extends View> T $(int viewId)  
	    {  
	          
	        View view = mViews.get(viewId);  
	        if (view == null)  
	        {  
	            view = mConvertView.findViewById(viewId);  
	            mViews.put(viewId, view);  
	        }  
	        return (T) view;  
	    }
}

Adapter中getView方法如下:

class MyAdapter extends MyBaseAdapter<String> {
public MyAdapter(List<String> datas, Context context) {
super(datas, context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
   //实例化一个viewHolder  
       ViewHolder viewHolder = ViewHolder.get(getApplicationContext(), convertView, parent,  
               R.layout.item, position); 
       TextView tvContent = viewHolder.$(R.id.tvContent);
       tvContent.setText(datas.get(position));
       return viewHolder.getConvertView(); 
}
}
}

现在一个adapter中就这几行代码了,是不是之前adapter中的代码要少很多呢,大牛都是写很少的代码实现业务,我们在向大牛的方向前行!


打造万能Adapter(适配器)——适用于ListView、GridListView 整理总结自鸿洋的博客:http://blog.youkuaiyun.com/lmj623565791/article/details/38902805 阅读详情

相关推荐

FoundationPose实战:从零部署到Demo运行全记录

本文详细记录了FoundationPose从零部署到Demo运行的全过程,包括Ubuntu环境配置、项目部署、依赖安装及常见问题解决方案。特别针对复现过程中的关键步骤如CUDA版本选择、Eigen3安装等提供了实用技巧,帮助开发者高效完成FoundationPose的部署与调试。

weixin_27102543的博客 268

Android 打造万能的ListView GridView 适配器

1、概述 相信做Android开发的写得最多的就是ListView,GridView的适配器吧,记得以前开发一同事开发项目,一个项目下来基本就一直在写ListView的Adapter都快吐了~~~对于Adapter一般都继承BaseAdapter复写几个方法,getView里面使用ViewHolder模式,其实大部分的代码基本都是类似的。 本篇博客为快速开发系列的第一篇,将一步一步带您

King的专栏 574

如何使用AutoDl平台跑自己的模型(纯干货,步骤很详细)

记录我使用AutoDL云服务器来跑自己模型的全过程

qq_45073592的博客 3万+

android gridview源代码,android 打造ListView和Gridview万能adapter适配器(附源码)(示例代码)...

android开发中,我们离不开adapter,每个项目都有很多地方需要adapter,那么我们如何让自己少写adapter代码呢?那就是封装adapter,让我们的adapter成为万能的adapter。下面我列出我实现的思路,供给大家学习与参考,当然有更好的方式也可以提供建议哦。一、针对Listview或GridView的万能适配器(源码)1.第一步实现公用的viewholder/*** 优化...

weixin_36382265的博客 309

ERA5数据驱动WRFV4.4实战:单层嵌套配置与关键报错排查指南

本文详细介绍了使用ERA5再分析数据驱动WRFV4.4模式进行单层嵌套模拟的完整实战流程。内容涵盖从数据精准下载、WPS前处理配置、WRF核心参数设置到高频报错的深度排查与解决方案,旨在帮助初学者在有限服务器资源下,高效完成WRF模拟并规避常见陷阱。

q5r6s7的博客 770

java结合Ai

Spring AI 是 AI 工程的应用框架。其目标是将Spring生态系统的设计原则(如可移植性和模块化设计)应用于AI领域,并促进使用POJO作为应用程序的构建块到AI领域。特征跨 AI 提供商的可移植 API 支持,适用于聊天、文本到图像和嵌入模型。支持同步 API 和流 API 选项。还支持下拉以访问特定于模型的功能。聊天模型亚马逊基岩人类学Cohere的命令AI21 Labs的侏罗纪-2Meta 的 LLama亚马逊的泰坦人类学克劳德Azure 开放式 AI。

qq_67832732的博客 2848

Android打造ListView和GridView万能适配器

本篇博客是我学习过慕课网的《Android-打造万能适配器》课程后的学习笔记一、传统方式分析  传统写法下,我们几乎每个ListView都会单独写一个Adapter和一个ViewHolder,分析代码可以发现,传统的Adapter里有很多的重复性代码,比如说getCount()、getItem(int position)、getItemId(int position),传统Adapter写法如下:p

playing_the_fool的博客 990

ArduSub深度调参指南:如何让水下机器人像鱼一样稳定游动

本文深入探讨了ArduSub水下机器人的深度调参策略,旨在解决ROV在水下晃动、响应迟钝等问题。文章系统解析了级联PID控制逻辑,并针对静水与水流环境,提供了具体的深度保持与姿态控制调参方法、实战日志分析技巧以及异常振荡处理方案,帮助用户实现水下机器人稳定、流畅的游动性能。

CAT789的专栏 372

android开发之ListView GridView适配器架构

懒惰,只是为了更好的懒惰!

ZaneLove's blog 929

Matlab实战:用DQN算法让机器人学会自主避障(附完整代码)

本文详细介绍了如何使用Matlab实现DQN(深度Q网络)算法,使机器人在复杂环境中学会自主避障。通过环境建模、网络架构设计、奖励函数优化及实战调试,提供了完整的代码实现和训练策略,帮助开发者快速应用于机器人路径规划项目。

t8u9v0w1x的博客 232

【DeepSeek R1构建本地RAG知识库】数据结构化清洗-知识图谱制作、使用、dify集成

本文探讨了在构建本地RAG(Retrieval-Augmented Generation)系统时,如何通过引入知识图谱来增强系统的知识理解能力。传统的向量数据库和嵌入模型虽然能处理语义匹配,但无法有效捕捉知识间的关联性。知识图谱通过“实体-关系-属性”的结构化表示,能够更好地支持推理、推荐和多跳问答等高级功能。文章详细介绍了知识图谱的基本概念、制作思路,以及如何使用Neo4j图数据库进行知识图谱的构建和查询。通过实例展示了从PDF文件解析到知识图谱入库的全过程,强调了知识图谱在提升RAG系统性能中的重要作用

少说,多做 563

打造一个万能的适配器!!!

最近项目中 经常用listView和GridView ,可以说是项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter 最近抽了时间,自己也打造了一个万能的适配器 看我们之前的一些写法: public class ImageViewAdapter2 extends RecyclerView.Adapter<ImageV...

beibei_programme的博客 181

让 Claude Code 接管 SAP 事务流, 用 Python 和 SAP GUI Scripting 做一个真正能干活的 AI Agent

摘要:SAP系统自动化面临的核心瓶颈在于繁琐的GUI操作而非分析能力不足。通过整合Claude AI、Python和SAP GUI Scripting技术,可构建能直接操作SAP界面的智能代理。该方案利用SAP官方提供的脚本接口,实现事务码执行、界面导航、数据提取等自动化操作,特别适用于DMLT过账引擎等复杂错误分析场景。相比传统SQL导出方案,这种GUI级自动化能处理树控件、ALV表格等复杂界面元素,且无需额外API开发,直接在现有SAP GUI会话上工作,在保持原有权限体系的同时显著提升效率。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 321
上一篇: android 手把手教你10分钟快速接个推推送服务
下一篇: android 线程范围内共享变量以及ThreadLocal的使用
zhoushenxian
博客等级 码龄12年 453粉丝 549原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值