android-ViewList的通用ViewHold
在写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的更多相关文章
- [Cocos2d-x]Android的android.mk文件通用版本
原文地址: http://blog.ready4go.com/blog/2013/10/12/update-android-dot-mk-with-local-src-files-and-local- ...
- iOS,Android,.NET通用AES加密算法
原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...
- Android点滴---ViewHolder通用,优雅写法
近期在做项目时,又要写 ViewHolder. 突然想到网上看看有没什么好的写法! 不知道你是不是也烦透了写那些没有技术含量的ViewHolder 看看这些.也许会有收获! 然后就找到了以下两篇文章( ...
- TitleLayout——一个Android轻松实现通用、标准、支持沉浸式状态栏的标题栏库
TitleLayout 多功能.通用的.可在布局或者使用Java代码实现标题栏:支持沉浸式状态栏,支持左侧返回按钮(不需要手动实现页面返回),左侧支持图片+文字.图片.文字:右侧支持图片.文字等. 堆 ...
- Android开发进阶 -- 通用适配器 CommonAdapter
在Android开发中,我们经常会用到ListView 这个组件,为了将ListView 的内容展示出来,我们会去实现一个Adapter来适配,将Layout中的布局以列表的形式展现到组件中. ...
- Android 异步请求通用类
package com.example.demo1; import java.util.EventListener; public interface MyAsyncTaskListener exte ...
- Android 文件管理器通用类 FileUtil
1.整体分析 1.1.源代码如下,可以直接Copy. public class FileUtil { private FileUtil() { } //****系统文件目录************** ...
- App与Js交互(三)Android、iOS通用解决方案推荐
https://www.jianshu.com/p/6224f429ce87 window.navigator.userAgent用来区分设备和浏览器 https://blog.csdn.net/li ...
- DateTimeUtil 工具类,android 和 java 通用
import java.sql.Date;import java.text.SimpleDateFormat; public class DateTimeUtil { public final cla ...
随机推荐
- 手把手教你玩转 CSS3 3D 技术
css3的3d起步 要玩转css3的3d,就必须了解几个词汇,便是透视(perspective).旋转(rotate)和移动(translate).透视即是以现实的视角来看屏幕上的2D事物,从而展现3 ...
- SpringMVC 导入导出Excel文件
/** * 下载Excel模板 创建一个新的文件用于下载,创建的文件放在缓存中 * * @param request * @param response */ /* * @Request ...
- java中泛型的简单使用
泛型是在jdk1.5之后引入的,我们可以在类的声明处增加泛型列表,如:<T,E,V>.此处,字符可以是任何标识符,一般采用这3个字母. 1.泛型类声明 class MyCollection ...
- fastRPC的数据库服务
根据整理的RPC模型,在此上,根据最近的项目,发布了DB服务,操作数据库.以RPC模型,发布数据库的操作服务,主要发送SQL语句,在服务端执行:同时引入了流行的数据库连接池:服务端还发布了文件接收服务 ...
- Angularjs基础(四)
AngularJS过滤器 过滤器可以使用一个管道符(|)添加到表达式和指令中. AngularJS过滤器可用于转换数据: currency 格式化数字为货币格式 filter 从数组中选着应子集. l ...
- 【前行&赛时总结】◇第4站&赛时9◇ CF Round 513 Div1+Div2
◇第4站&赛时9◇ CF Round 513 Div1+Div2 第一次在CF里涨Rating QWQ 深感不易……作blog以记之 ( ̄▽ ̄)" +Codeforces 的门为你打 ...
- (搬运以学习)flask 上下文的实现
引言 本文主要梳理了flask的current_app, request, session, g的实现原理 源码说明 本文使用flask 0.5 版本 application context 和req ...
- TCP回话劫持原理和利用
由于 TCP 协议并没有对 TCP 的传输包进行身份验证,所以在我们知道一个 TCP 连接中的 seq 和 ack 的信息后就可以很容易的伪造传输包,假装任意一方与另一方进行通信,我们将这一过程称为 ...
- ECSHOP和SHOPEX快递单号查询德邦插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- Learning Experience of Big Data: Connect CentOs to Xshell and set Java environment on CentOS
1.set up connections between vitural machine and Xshell: After we connect the virtural machine to ne ...