Android 万能适配器

来源:互联网 发布:opennms 网络拓扑 编辑:程序博客网 时间:2024/04/30 06:44

传统方式编写适配器的方法 相关代码:

bean::::::::::::::::::::::::::::::::::::::

package com.adapter.bean;public class Bean {private String title;private String desc;private String time;private String phone;public Bean() {}public Bean(String title, String desc, String time, String phone) {    super();    this.title = title;    this.desc = desc;    this.time = time;    this.phone = phone;}public String getTitle() {    return title;}public void setTitle(String title) {    this.title = title;}public String getDesc() {    return desc;}public void setDesc(String desc) {    this.desc = desc;}public String getTime() {    return time;}public void setTime(String time) {    this.time = time;}public String getPhone() {    return phone;}public void setPhone(String phone) {    this.phone = phone;}}

MainActivity::::::::::::::::::::::::::::::::::::package com.adapter;

import java.util.ArrayList;import java.util.List;import com.adapter.bean.Bean;import com.example.adapter.R;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;public class MainActivity extends Activity {    private ListView lv_list;    private List<Bean> mDatas;    private MyAdapter mAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initDatas();    initView();}private void initView() {    lv_list =(ListView) findViewById(R.id.lv_adapter);    lv_list.setAdapter(mAdapter);}private void initDatas() {    mDatas = new ArrayList<Bean>();    Bean bean = new Bean("Android新技能", "android打造万能的adapter适配器", "2014-12-13", "10086");    mDatas.add(bean);     bean = new Bean("Android新技能1", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     bean = new Bean("Android新技能2", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     bean = new Bean("Android新技能3", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     bean = new Bean("Android新技能4", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     mAdapter = new MyAdapter(this, mDatas);}}

MyAdapter:::::::::::::::::::::::::::::::::::

package com.adapter;import java.util.List;import com.adapter.bean.Bean;import com.example.adapter.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView.FindListener;import android.widget.BaseAdapter;import android.widget.TextView;public class MyAdapter extends BaseAdapter {    private LayoutInflater mInflater;    private List<Bean> mDatas;    public MyAdapter(Context context, List<Bean>datas){        mInflater = LayoutInflater.from(context);        mDatas = datas;    }    @Override    public int getCount() {        return mDatas.size();    }    @Override    public Object 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) {        ViewHolder holder = null;        if (convertView == null) {            convertView = mInflater.inflate(R.layout.activity_item, parent,false);            holder = new ViewHolder();            holder.mTitle = (TextView) convertView.findViewById(R.id.tv_title);            holder.mDesc = (TextView) convertView.findViewById(R.id.tv_desc);            holder.mTime = (TextView) convertView.findViewById(R.id.tv_time);            holder.mphone = (TextView) convertView.findViewById(R.id.tv_phone);            convertView.setTag(holder);        }else{            holder = (ViewHolder) convertView.getTag();        }        Bean bean = mDatas.get(position);        holder.mTitle.setText(bean.getTitle());//如果这里有int型的值 强转为String        holder.mDesc.setText(bean.getDesc());        holder.mTime.setText(bean.getTime());        holder.mphone.setText(bean.getPhone());        return convertView;    }private  class ViewHolder{    TextView mTitle;    TextView mDesc;    TextView mTime;    TextView mphone;}}

布局文件::::::::::::::::::::::

activity_main::::::::::::::::::::::::::::

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"     >    <ListView        android:id="@+id/lv_adapter"        android:layout_width="match_parent"        android:layout_height="match_parent"        ></ListView></RelativeLayout>Activity_item::::::::::::::::::::::<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:padding="10dp"    >    <TextView        android:id="@+id/tv_title"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:singleLine="true"        android:text="Android新技能"        android:textColor="#444"        android:textSize="16sp"        />    <TextView        android:id="@+id/tv_desc"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/tv_title"        android:layout_marginTop="10dp"        android:minLines="1"        android:maxLines="2"        android:text="android打造万能的adapter适配器"        android:textColor="#898989"        android:textSize="16sp"        />    <TextView        android:id="@+id/tv_time"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/tv_desc"        android:layout_marginTop="20dp"        android:minLines="1"        android:maxLines="2"        android:text="2014-12-13"        android:textColor="#898989"        android:textSize="12sp"        />    <TextView        android:id="@+id/tv_phone"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/tv_desc"        android:layout_marginTop="10dp"        android:minLines="1"        android:maxLines="2"        android:text="10086"        android:drawableLeft="@drawable/ic_launcher"        android:drawablePadding="5dp"        android:padding="3dp"        android:background="#2ed667"        android:layout_alignParentRight="true"        android:textColor="#fff"        android:textSize="12sp"        /></RelativeLayout>

以上是传统写法涉及到的类和布局;

下面我们要考虑的是怎样抽取我们的ViewHolder

通常的ViewHolder类:

convertView.setTag(holder);

ViewHolder:Item中各种控件的引用

每个listView或Item里面有很多的控件,我们可以考虑用一个

Map

package com.adapter.util;import android.content.Context;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;public class ViewHolder {    private SparseArray<View> mView;    private int mPosition;    private View mConvertView;    public ViewHolder(Context context, ViewGroup parent, int layoutId,            int position) {        this.mPosition = position;        this.mView = new SparseArray<View>();        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,                false);        mConvertView.setTag(this);    }    public static ViewHolder get(Context context, View convertView,            ViewGroup parent, int layoutId, int position) {        if (convertView == null) {            return new ViewHolder(context, parent, layoutId, position);        } else {            ViewHolder holder = (ViewHolder) convertView.getTag();            holder.mPosition = position;//即使viewHolder是复用的,但是在listView中position 是变化的            return holder;        }    }    /**     * 通过、viewId获取控件     * @param viewId     * @return     */    public <T extends View> T getView(int viewId){        View view = mView.get(viewId);        if (view == null) {            view = mConvertView.findViewById(viewId);            mView.put(viewId, view);        }        return (T)view;    }    public View getmConvertView() {        return mConvertView;    }}

以下是 做了相应改动的adapter::::::::::::::::::::::::::

package com.adapter;import java.util.List;import com.adapter.bean.Bean;import com.adapter.util.ViewHolder;import com.example.adapter.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView.FindListener;import android.widget.BaseAdapter;import android.widget.TextView;public class MyAdapterWtihCommonViewHolder extends BaseAdapter {    private LayoutInflater mInflater;    private List<Bean> mDatas;    private Context mContext;    public MyAdapterWtihCommonViewHolder(Context context, List<Bean>datas){        mInflater = LayoutInflater.from(context);        mDatas = datas;        mContext = context;    }    @Override    public int getCount() {        return mDatas.size();    }    @Override    public Object 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) {        /*        ViewHolder holder = null;        if (convertView == null) {            convertView = mInflater.inflate(R.layout.activity_item, parent,false);            holder = new ViewHolder();            holder.mTitle = (TextView) convertView.findViewById(R.id.tv_title);            holder.mDesc = (TextView) convertView.findViewById(R.id.tv_desc);            holder.mTime = (TextView) convertView.findViewById(R.id.tv_time);            holder.mphone = (TextView) convertView.findViewById(R.id.tv_phone);            convertView.setTag(holder);        }else{            holder = (ViewHolder) convertView.getTag();        }        */        //一句代码替换上面的代码        ViewHolder holder = ViewHolder.get(mContext, convertView, parent, R.layout.activity_item, position);        Bean bean = mDatas.get(position);        /*        holder.mTitle.setText(bean.getTitle());//如果这里有int型的值 强转为String        holder.mDesc.setText(bean.getDesc());        holder.mTime.setText(bean.getTime());        holder.mphone.setText(bean.getPhone());        */        //将上面的代码做相应的更改        TextView title = holder.getView(R.id.tv_title);        title.setText(bean.getTitle());        TextView desc = holder.getView(R.id.tv_desc);        title.setText(bean.getDesc());        TextView time = holder.getView(R.id.tv_time);        title.setText(bean.getTime());        TextView phone = holder.getView(R.id.tv_phone);        title.setText(bean.getPhone());        //return convertView;          //返回的值也相应的改变        return holder.getmConvertView();    }    /*private  class ViewHolder{    TextView mTitle;    TextView mDesc;    TextView mTime;    TextView mphone;}*/

}以下是 使用通用ViewHolder做了相应改动的MainActivity::::::::::::::::::::

package com.adapter;import java.util.ArrayList;import java.util.List;import com.adapter.bean.Bean;import com.example.adapter.R;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;public class MainActivity extends Activity {    private ListView lv_list;    private List<Bean> mDatas;    private MyAdapter mAdapter;    //万能适配器进行测试    private MyAdapterWtihCommonViewHolder mMyAdapterWtihCommonViewHolder;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initDatas();    initView();}private void initView() {    lv_list =(ListView) findViewById(R.id.lv_adapter);    lv_list.setAdapter(mMyAdapterWtihCommonViewHolder);}private void initDatas() {    mDatas = new ArrayList<Bean>();    Bean bean = new Bean("Android新技能", "android打造万能的adapter适配器", "2014-12-13", "10086");    mDatas.add(bean);     bean = new Bean("Android新技能1", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     bean = new Bean("Android新技能2", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     bean = new Bean("Android新技能3", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);     bean = new Bean("Android新技能4", "android打造万能的adapter适配器", "2014-12-13", "10086");     mDatas.add(bean);    // mAdapter = new MyAdapter(this, mDatas);    mMyAdapterWtihCommonViewHolder = new MyAdapterWtihCommonViewHolder(this, mDatas);}}

至此完成通用ViewHolder的功能。。。

下面要封装Adapter代码:

写一个CommonAdapter类:::::::::::::::::::::::::::

package com.adapter.util;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public abstract class CommonAdapter<T> extends BaseAdapter {    protected Context mContext;    protected List<T> mDatas;    protected LayoutInflater mInflater;public CommonAdapter(Context context,List<T> datas){    this.mContext = context;    this.mDatas = datas;    mInflater = LayoutInflater.from(context);}    @Override    public int getCount() {        return mDatas.size();    }    @Override    public Object getItem(int position) {        return mDatas.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public abstract View getView(int position, View convertView, ViewGroup parent);}

使MyAdapterWtihCommonViewHolder类继承 CommonAdapter 并做相应改变::::::::::::::

package com.adapter;import java.util.List;import com.adapter.bean.Bean;import com.adapter.util.CommonAdapter;import com.adapter.util.ViewHolder;import com.example.adapter.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView.FindListener;import android.widget.BaseAdapter;import android.widget.TextView;public class MyAdapterWtihCommonViewHolder extends CommonAdapter<Bean> {    public MyAdapterWtihCommonViewHolder(Context context, List<Bean>datas){        super(context, datas);    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = ViewHolder.get(mContext, convertView, parent, R.layout.activity_item, position);        Bean bean = mDatas.get(position);        TextView title = holder.getView(R.id.tv_title);        title.setText(bean.getTitle());        TextView desc = holder.getView(R.id.tv_desc);        title.setText(bean.getDesc());        TextView time = holder.getView(R.id.tv_time);        title.setText(bean.getTime());        TextView phone = holder.getView(R.id.tv_phone);        title.setText(bean.getPhone());        return holder.getmConvertView();    }}

以上就是简单的抽取出了 Adapter中 有些重复的代码 ,然后进行简化

其实到了这里还是不够简化 我们还可以进一步对适配器进行简化

以下是进行简化的CommonAdapter类::::::::::::::::::

package com.adapter.util;import java.util.List;import com.adapter.bean.Bean;import com.example.adapter.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;public abstract class CommonAdapter<T> extends BaseAdapter {    protected Context mContext;    protected List<T> mDatas;    protected LayoutInflater mInflater;    public CommonAdapter(Context context, List<T> datas) {        this.mContext = context;        this.mDatas = datas;        mInflater = LayoutInflater.from(context);    }    @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) {        ViewHolder holder = ViewHolder.get(mContext, convertView, parent,                R.layout.activity_item, position);        convert(holder,getItem(position));        return holder.getmConvertView();    }    public abstract void convert(ViewHolder holder,T t);}

以下是简化后的MyAdapterWtihCommonViewHolder类::::::

package com.adapter;import java.util.List;import com.adapter.bean.Bean;import com.adapter.util.CommonAdapter;import com.adapter.util.ViewHolder;import com.example.adapter.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView.FindListener;import android.widget.BaseAdapter;import android.widget.TextView;public class MyAdapterWtihCommonViewHolder extends CommonAdapter<Bean> {    public MyAdapterWtihCommonViewHolder(Context context, List<Bean> datas) {        super(context, datas);    }    @Override    public void convert(ViewHolder holder, Bean bean) {        TextView title = holder.getView(R.id.tv_title);        title.setText(bean.getTitle());        TextView desc = holder.getView(R.id.tv_desc);        title.setText(bean.getDesc());        TextView time = holder.getView(R.id.tv_time);        title.setText(bean.getTime());        TextView phone = holder.getView(R.id.tv_phone);        title.setText(bean.getPhone());    }}

这样开发人员 就只需要 面向ViewHolder 以及Bean 编程 大大的简化了代码

其实, 到这里了还没有完,还可以在ViewHolder类里面 将具体的item里面的控件的 设置值的方法进行 封装 这里用TextView举例:

以下是改进后的ViewHolderHolder:::::::::::::

package com.adapter.util;import android.content.Context;import android.graphics.Bitmap;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;public class ViewHolder {    private SparseArray<View> mView;    private int mPosition;    private View mConvertView;    public ViewHolder(Context context, ViewGroup parent, int layoutId,            int position) {        this.mPosition = position;        this.mView = new SparseArray<View>();        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,                false);        mConvertView.setTag(this);    }    public static ViewHolder get(Context context, View convertView,            ViewGroup parent, int layoutId, int position) {        if (convertView == null) {            return new ViewHolder(context, parent, layoutId, position);        } else {            ViewHolder holder = (ViewHolder) convertView.getTag();            holder.mPosition = position;//即使viewHolder是复用的,但是在listView中position 是变化的            return holder;        }    }    /**     * 通过、viewId获取控件     * @param viewId     * @return     */    public <T extends View> T getView(int viewId){        View view = mView.get(viewId);        if (view == null) {            view = mConvertView.findViewById(viewId);            mView.put(viewId, view);        }        return (T)view;    }    public View getmConvertView() {        return mConvertView;    }    //后来加的方法    /**     * 设置textView的值     * @param viewId     * @param text     * @return     */    public ViewHolder setText(int viewId,String text){        TextView tv = getView(viewId);        tv.setText(text);        return this;    }    /**     * 设置ImageView的值     * @param viewId     * @param resId     * @return     */    public ViewHolder setImageResource(int viewId, int resId){        ImageView iv = getView(viewId);        iv.setImageResource(resId);        return this;    }public ViewHolder setImageBitmap(int viewId, Bitmap bitmap){        ImageView iv = getView(viewId);        iv.setImageBitmap(bitmap);        return this;    }}

设置哪种控件 就要在以上的代码中做相应的添加,然后就会更加的完善
以下是改进后的MyAdapterWtihCommonViewHolder类:::::::::::::::::

package com.adapter;import java.util.List;import com.adapter.bean.Bean;import com.adapter.util.CommonAdapter;import com.adapter.util.ViewHolder;import com.example.adapter.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView.FindListener;import android.widget.BaseAdapter;import android.widget.TextView;public class MyAdapterWtihCommonViewHolder extends CommonAdapter<Bean> {    public MyAdapterWtihCommonViewHolder(Context context, List<Bean> datas) {        super(context, datas);    }    @Override    public void convert(ViewHolder holder, Bean bean) {        /*         * TextView title = holder.getView(R.id.tv_title);         * title.setText(bean.getTitle()); TextView desc =         * holder.getView(R.id.tv_desc); title.setText(bean.getDesc());         * TextView         * time = holder.getView(R.id.tv_time); title.setText(bean.getTime());         * TextView phone = holder.getView(R.id.tv_phone);         * title.setText(bean.getPhone());         */        // 改进        holder.setText(R.id.tv_title, bean.getTitle())                .setText(R.id.tv_desc, bean.getDesc())                .setText(R.id.tv_time, bean.getTime())                .setText(R.id.tv_phone, bean.getPhone());    }}

关于Item中控件不可点击,有抢占焦点的问题存在时 视频后段有交代,以后再更新。

关于listView 内容复用显示混乱的问题 同样有交代。

0 0
原创粉丝点击