Encapsulate reusable custom adapters and pay tribute to Xiang Ge, Adapter

Source: Internet
Author: User

Encapsulate reusable custom adapters and pay tribute to Xiang Ge, Adapter

After reading Xiang GE's custom omnipotent adapter, I made my own notes and analyzed the thinking style of the experts, so that we can enter the inner world of abnormal programmers together.

Before analyzing the omnipotent adapter, let's first analyze the common adapter

public class ReportSpinnerAdapter extends BaseAdapter {    private Context context;    private List<String> str;    public ReportSpinnerAdapter(Context context, List<String> str, int textWidth) {        this.context = context;        this.str = str;        this.textWidth = textWidth;    }    @Override    public int getCount() {        return str.size();    }    @Override    public Object getItem(int position) {        return str.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        Viewholder hold;        if (convertView==null){            convertView = LayoutInflater.from(context).inflate(R.layout.spinner_layout,parent,false);            hold = new ViewHold();            hold.textView = (TextView) convertView.findViewById(R.id.textView);            convertView.setTag(hold);        }else{            hold = (ViewHold) convertView.getTag();        }        hold.textView.setText(str.get(position));        return convertView;    }    static class ViewHolder{        TextView textView;    }

A normal adapter is roughly divided into two points: getView and ViewHolder. A class solves the problem and involves the reuse of controls. ViewHolder is used. The main logic is still in getView ,, if you do not understand this, you can first Baidu ViewHolder. The logic in getView is that if convertView is used for the first time, the binding layout is initialized and the tag is set. Otherwise, viewHolder is retrieved from convertView, if you want to change the parameters of the control in the layout, retrieve the control setting parameters from viewHolder. Because the control is initialized together during convertView initialization, you can set the parameters directly. This is a standard programmer's usual practice. However, if we need to use adapter frequently in our program and each Listview or GridView needs to get an adapter, it will waste a lot of time, as a perverted programmer, how can Xiang Ge endure it? So I have made such a blog, Xiang Ge blog, so that we can make profits from it. I have gained new technologies and new ways of thinking.

 

To sum up the custom omnipotent adapter, or reusable adapter, we can split it into three points:

1. encapsulate a special ViewHolder. You can pass in the parameter to get the viewHolder directly. In this step, kill the following:

if (convertView==null){            convertView = LayoutInflater.from(context).inflate(R.layout.spinner_layout,parent,false);            hold = new ViewHold();            hold.textView = (TextView) convertView.findViewById(R.id.textView);            convertView.setTag(hold);        }else{            hold = (ViewHold) convertView.getTag(); }

To get rid of this step, you must think of the parameters passed in to get viewHolder directly. layoutInflater. from (context) 2. r. layout. spinner_layout 3. parent 4. convertView

You can simply write

Public class ViewHolder {private SparseArray <View> views; private View convertView; public ViewHolder (ViewGroup parent, LayoutInflater inflater, int layoutId) {this. views = new SparseArray <View> (); this. convertView = inflater. inflate (layoutId, parent, false); this. convertView. setTag (this );} /*** get viewHolder * @ param parent * @ param convertView * @ param inflater * @ param layoutId * @ return */public static ViewHolder getViewHolder (ViewGroup parent, View convertView, layoutInflater inflater, int layoutId) {if (convertView = null) {return new ViewHolder (parent, inflater, layoutId);} return (ViewHolder) convertView. getTag ();}

This SparseArray <View> views is actually a key-value pair used to save the control of each row or column in listview or gridview, which is more efficient than hashmap. usage is

/*** Get view by Id * @ param viewId * @ param <T> * @ return */public <T extends View> T getView (int viewId) {View view = views. get (viewId); if (view = null) {view = convertView. findViewById (viewId); views. put (viewId, view);} return (T) view ;}

In this way, a ViewHolder is ready.

 

2. writing a universal adapter is basically impossible. What should I do? To make a semi-universal adapter, since it is generally the same as a semi-universal adapter, there are a few differences, it is best to inherit from abstract classes.

public abstract class CommonAdapter<T> extends BaseAdapter {    private List<T> list;    private LayoutInflater inflater;    private int layoutId;    public CommonAdapter(List<T> list, Context context,int layoutId) {        this.list = list;        this.inflater = LayoutInflater.from(context);        this.layoutId = layoutId;    }    @Override    public int getCount() {        return list.size();    }    @Override    public Object getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder viewHolder = ViewHolder.getViewHolder(parent,convertView,inflater,layoutId);        convert(viewHolder,list.get(position));        return viewHolder.getConvertView();    }    public abstract void convert(ViewHolder viewHolder,T t);}

First, when we bind the adapter, we don't know the data source. We need to use a generic class and a generic set, and then pass in the layout id and context, set the place where values need to be assigned to the control as an abstract method and inherit from the subclass. After the encapsulation is completed, there are few things we need to do, you only need to override the convert method and constructor method.

Public class MyAdapter extends CommonAdapter <Bean> {public MyAdapter (List <Bean> list, Context context, int layoutId) {super (list, context, layoutId );} @ Override public void convert (ViewHolder viewHolder, Bean bean) {(TextView) viewHolder. getView (R. id. text )). setText ("this is test data 1"); (TextView) viewHolder. getView (R. id. text )). setText ("this is test data 1 ");}}

In this way, you only need to bind the MyAdapter in activity or fragment, and pass in the data and layout id and content. Only (viewHolder. getView (R. id. text )). setText is a tough way to write code. If you write strong code, you have to cut the cursor back. I am not used to it anyway. What should I do, now that we have a viewholder object, we will transform the viewHolder object to make the public code a little more, and we will write a little less in the future. Add the following method to ViewHolder:

/*** Get TextView by id * @ return */public TextView getTextView (int viewId) {return getView (viewId );} /*** obtain ImageView by id * @ return */public ImageView getImageView (int viewId) {return getView (viewId );} /*** get the Button * @ return */public Button getButton (int viewId) {return getView (viewId);} Based on the id );} /*** obtain RadioButton by id * @ return */public RadioButton getRadioButton (int viewId) {return getView (viewId );} /*** get CheckBox * @ return */public CheckBox getCheckBox (int viewId) {return getView (viewId );} /*** get ImageButton * @ return */public ImageButton getImageButton (int viewId) {return getView (viewId) according to the id );} /*** get ImageButton * @ return */public EditText getEditText (int viewId) {return getView (viewId) according to the id );}

The convert method in Myadapter can be written in this way.

@ Override public void convert (ViewHolder viewHolder, Bean bean) {viewHolder. getTextView (R. id. text ). setText ("this is test data 1"); viewHolder. getTextView (R. id. text ). setText ("this is test data 2 ");}

In this way, the writing will be smoother, better than hand. This is basically the main content of Xiang GE's omnipotent custom adapter. The core idea is illustrated below.







Finally, source code: Click to open the link


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.