在写ViewList的时候要写Adapter的时候,经常大量的代码都是差不多的。

1 ViewHold

2 if(convertView ==null ){}else{}

3 setTag

4 FIndElement 和 Set 等等

所以我想能不能写一个通用的ViewHold的和通用的Adapter呢?

我们来试试吧。

直接上代码,然后再进行分析。

<?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/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20pt"
/>
<TextView
android:id="@+id/context"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15pt"/> </LinearLayout>

Bean数据结构

public class Bean {
String context;
String title; public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getContext() {
return context;
} public void setContext(String context) {
this.context = context;
}
}

通用的ViewHold

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; /**
* Created by sunfan on 15-4-19.
* 通用的ViewHold类
*/
public class CommonViewHold {
private View mView;//当前页面
private SparseArray<View> elements = new SparseArray<View>();//控件元素 /**
* 构造函数,当传入的convertView为null时对mView进行初始化,并设置tag
* @param context
* @param parent
* @param resource
*/
private CommonViewHold(Context context, ViewGroup parent, int resource) {
mView = LayoutInflater.from(context).inflate(resource,parent,false);
mView.setTag(this);
} /**
* 获取 CommonViewHold对象,包含 mView和layout里已经添加elements的容器
* @param context
* @param convertView
* @param parent
* @param resource
* @return
*/
public static CommonViewHold getViewHold(Context context ,View convertView,ViewGroup parent,int resource){
if (convertView==null){
return new CommonViewHold(context,parent,resource);
}else{
CommonViewHold viewHold = (CommonViewHold) convertView.getTag();
return viewHold;
}
} public View getView() {
return mView;
} /**
* 维护一个element的容器,如果容器里存在此控件则直接读取,如果不存在则通过findAndSetElement找到元素后
* 写入容器中
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T getElement(int viewId){
View view = elements.get(viewId);
if(view == null){
view = mView.findViewById(viewId);
elements.put(viewId,view);
}
return (T)view;
}
}

通用的adapter

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter; import java.util.List; /**
* Created by sunfan on 15-4-18.
*/
public abstract class CommonArrayAdapter<T> extends ArrayAdapter{
protected Context mContext;//当前上下文
protected int mResource;//item
protected int mPosition;//当前位置
protected CommonViewHold viewHold;//ViewHold的引用 /**
* 初始化
* @param context
* @param resource
* @param objects
*/
public CommonArrayAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
this.mContext = context;
this.mResource = resource;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
this.mPosition = position;
viewHold = CommonViewHold.getViewHold(mContext,convertView,parent,mResource);
findAndSetElement();
return viewHold.getView();
} /**
* 需要实现控件的获取与赋值过程
* 这里建议调用内部的viewhold对象里的获取控件的方法
* 例如
* TextView title = super.viewHold.getElement(R.id.title);
title.setText(bean.getTitle());
*/
public abstract void findAndSetElement(); }

客户端

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Window;
import android.widget.ListView;
import android.widget.TextView; import java.util.ArrayList;
import java.util.List; public class MainActivity extends Activity { ListView listView;
List<Bean> beans = new ArrayList<Bean>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
init();
listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(new MyAdapter(this, R.layout.list_item, beans)); } /**
* 实现CommonArrayAdapter的findAndSetElement方法
*/
class MyAdapter extends CommonArrayAdapter<Bean> {
public MyAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
} @Override
public void findAndSetElement() {
TextView title = super.viewHold.getElement(R.id.title);
TextView context = super.viewHold.getElement(R.id.context);
Bean bean = beans.get(super.mPosition);
title.setText(bean.getTitle());
context.setText(bean.getContext());
}
} /*
初始化测试数据
*/
private void init() {
Bean b1 = new Bean();
b1.setTitle("title1");
b1.setContext("content1content1content1content1content1content1content1content1content1content1content1content1");
Bean b2 = new Bean();
b2.setTitle("title2");
b2.setContext("content2content2content2content2content2content2content2content2content2");
Bean b3 = new Bean();
b3.setTitle("title3");
b3.setContext("content3content3content3content3content3content3content3content3");
Bean b4 = new Bean();
b4.setTitle("title4");
b4.setContext("content4content4content4content4content4content4content4content4");
Bean b5 = new Bean();
b5.setTitle("title5");
b5.setContext("content5content5content5content5content5content5content5content5content5content5content5");
Bean b6 = new Bean();
b6.setTitle("title6");
b6.setContext("content6content6content6content6content6content6content6content6");
Bean b7 = new Bean();
b7.setTitle("title7");
b7.setContext("content7content7content7content7content7content7content7content7"); beans.add(b1);
beans.add(b2);
beans.add(b3);
beans.add(b4);
beans.add(b5);
beans.add(b6);
beans.add(b7);
}
}

--------------以上为全部代码----------------------

代码分析

整个代码的流程和结构

CommonViewHold 相比传统的Viewhold,他采用容器的方式存储元素,并且封装了客户端用来判断covertview为空的初始化操作

提供了一个存放元素的容器

private SparseArray<View> elements = new SparseArray<View>();//控件元素

当然他提供有获取容器的方法

/**
* 维护一个element的容器,如果容器里存在此控件则直接读取,如果不存在则通过findAndSetElement找到元素后
* 写入容器中
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T getElement(int viewId){
View view = elements.get(viewId);
if(view == null){
view = mView.findViewById(viewId);
elements.put(viewId,view);
}
return (T)view;
}

然后就是做初始化的动作了。

convertView==null的时候的判断,这一段逻辑其实很简单,如果不为空就直接返回,为空就初始化。
private CommonViewHold(Context context, ViewGroup parent, int resource) {
mView = LayoutInflater.from(context).inflate(resource,parent,false);
mView.setTag(this);
} /**
* 获取 CommonViewHold对象,包含 mView和layout里已经添加elements的容器
* @param context
* @param convertView
* @param parent
* @param resource
* @return
*/
public static CommonViewHold getViewHold(Context context ,View convertView,ViewGroup parent,int resource){
if (convertView==null){
return new CommonViewHold(context,parent,resource);
}else{
CommonViewHold viewHold = (CommonViewHold) convertView.getTag();
return viewHold;
}
}

通用的commonAdapter是一个模板类

public abstract class CommonArrayAdapter<T> extends ArrayAdapter

关键属性,当用户实现findAndSet的时候需要使用这个引用来获取控件

  protected  CommonViewHold viewHold;//ViewHold的引用

核心模板方法

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
this.mPosition = position;
viewHold = CommonViewHold.getViewHold(mContext,convertView,parent,mResource);
findAndSetElement();
return viewHold.getView();
}

需要用户去实现的方法

    /**
* 需要实现控件的获取与赋值过程
* 这里建议调用内部的viewhold对象里的获取控件的方法
* 例如
* TextView title = super.viewHold.getElement(R.id.title);
title.setText(bean.getTitle());
*/
public abstract void findAndSetElement();

直接从客户端可以看到,代码是十分便捷的,只需要一个内部类重写commonAdapter的findAndSet方法即可。

 class MyAdapter extends CommonArrayAdapter<Bean> {
public MyAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
} @Override
public void findAndSetElement() {
TextView title = super.viewHold.getElement(R.id.title);
TextView context = super.viewHold.getElement(R.id.context);
Bean bean = beans.get(super.mPosition);
title.setText(bean.getTitle());
context.setText(bean.getContext());
}
}

调用也变得很轻松

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
init();
listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(new MyAdapter(this, R.layout.list_item, beans)); }

android-ViewList的通用ViewHold的更多相关文章

  1. [Cocos2d-x]Android的android.mk文件通用版本

    原文地址: http://blog.ready4go.com/blog/2013/10/12/update-android-dot-mk-with-local-src-files-and-local- ...

  2. iOS,Android,.NET通用AES加密算法

    原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...

  3. Android点滴---ViewHolder通用,优雅写法

    近期在做项目时,又要写 ViewHolder. 突然想到网上看看有没什么好的写法! 不知道你是不是也烦透了写那些没有技术含量的ViewHolder 看看这些.也许会有收获! 然后就找到了以下两篇文章( ...

  4. TitleLayout——一个Android轻松实现通用、标准、支持沉浸式状态栏的标题栏库

    TitleLayout 多功能.通用的.可在布局或者使用Java代码实现标题栏:支持沉浸式状态栏,支持左侧返回按钮(不需要手动实现页面返回),左侧支持图片+文字.图片.文字:右侧支持图片.文字等. 堆 ...

  5. Android开发进阶 -- 通用适配器 CommonAdapter

    在Android开发中,我们经常会用到ListView 这个组件,为了将ListView 的内容展示出来,我们会去实现一个Adapter来适配,将Layout中的布局以列表的形式展现到组件中.     ...

  6. Android 异步请求通用类

    package com.example.demo1; import java.util.EventListener; public interface MyAsyncTaskListener exte ...

  7. Android 文件管理器通用类 FileUtil

    1.整体分析 1.1.源代码如下,可以直接Copy. public class FileUtil { private FileUtil() { } //****系统文件目录************** ...

  8. App与Js交互(三)Android、iOS通用解决方案推荐

    https://www.jianshu.com/p/6224f429ce87 window.navigator.userAgent用来区分设备和浏览器 https://blog.csdn.net/li ...

  9. DateTimeUtil 工具类,android 和 java 通用

    import java.sql.Date;import java.text.SimpleDateFormat; public class DateTimeUtil { public final cla ...

随机推荐

  1. DB2表空间重定向恢复数据库实战

    DB2的备份恢复有点坑,当源系统和目标系统的路径设置不同时,要手动进行重定向恢复,本文是我一次实战操作之后总结的过程,仅供参考. 一.发出重定向恢复命令 DB2 RESTORE DB TO " ...

  2. EasyUI加zTree使用解析 easyui修改操作的表单回显方法 验证框提交表单前验证 datagrid的load方法

    带参提交一次查询,从服务器加载新数据.这是一个神奇的方法 $('#dg').datagrid('load',{ code: '01', name: 'name01' }); easyui修改操作的回显 ...

  3. django-初始配置(纯手写)

    我们通过django-admin startproject zhuyu命令创建好项目后,在pycharm中打开 我们需要在在该项目中,配置一些相关操作. 1.template(存放模板的文件夹) 如果 ...

  4. 常用的标准SQL 语句

    1.创建数据库的语句如下: Create database databaseName 上述语句创建一个名字叫 databaseName 的数据库2.删除数据库的语句如下. Drop database ...

  5. 【TOJ 3369】CD(二分)

    描述 Jack and Jill have decided to sell some of their Compact Discs, while they still have some value. ...

  6. SpringMVC中session使用&&拦截器&&乱码处理&&异常处理

    ### 1. 使用Session 通常,会在Session中存放: 1. 客户端(用户)的身份标识,通常是用户的id:2. 使用频率非常高的数据,例如显示在页面中的用户名.头像等:3. 其它的不便于使 ...

  7. Percona-Tookit工具包之pt-kill

      Preface       Sometimes,we are determined to kill some MySQL connections which are occupying huge ...

  8. 吐血分享:QQ群霸屏技术教程(利润篇)

    QQ群技术,不论日进几百,空隙时间多的可以尝试,日进100问题不大. QQ群技术,如何赚钱,能赚多少钱?不同行业,不同关键词,不同力度,不一样的产出. 群费 群费,这个和付费群是有区别的,群费在手机端 ...

  9. 接口API封装中常见的HTTP状态码

    在进行后端接口API封装的过程中,需要考虑各种错误信息的输出.一般情况下,根据相应问题输出适合的HTTP状态码,可以方便前端快速定位错误,减少沟通成本. HTTP状态码有很多,每个都有对应的含义,下面 ...

  10. ffplay使用笔记

    ffplay播放yuv文件命令: ffplay -f rawvideo -video_size 1920x1080 a.yuv   ffplay播放mp4.h.264.hevc文件命令: ffplay ...