재사용 가능한 사용자 정의 BaseAdapter 빌드


이 섹션 소개:

제목에서 알 수 있듯이 이 섹션에서는 재사용 가능한 사용자 정의 BaseAdapter를 구축하는 경우가 많습니다. GridView 및 기타 Adapter 컨트롤을 사용하려면 또 다른 BaseAdapter 클래스를 직접 작성해야 하는데 이는 매우 번거로운 작업입니다. 또 다른 예로, 하나의 인터페이스에 두 개의 ListView를 표시하려면 두 개의 BaseAdapter도 필요합니다. 프로그래머는 모두 게으른 것을 좋아합니다. 이 섹션에서는 재사용 가능한 사용자 정의 BaseAdapter 클래스를 작성하겠습니다~


1. 조금씩 변경해 보겠습니다.

먼저 이전 섹션에서 작성한 BaseAdapter를 사용자 정의해 보겠습니다. , 나중에 업그레이드하겠습니다

/**
 * 2015년 9월 21일 0021년 Jay가 작성함.
 */
public class MyAdapter 확장 BaseAdapter {

    private Context mContext;
    private LinkedList<Data> mData;

    public MyAdapter() {
    }

    public MyAdapter(LinkedList<Data> mData, Context mContext) {
        this.mData = mData;
        this.mContext = mContext;
    }

    @Override
    public int getCount () {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        반환 위치;
}

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout .item_list, parent, false);
            holder = new ViewHolder();
            holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
           holder.txt_content = (텍스트 보기) convertView.findViewById(R.id .txt_content);
convertView.setTag (holder);
} else {

holder = (viewHolder) convertView.getTag ();
}
holder.img_icon.setimageresource (mdata.get (position) .getimgid ());HOLDER.TXT_CONTENTENT.SETEXT (mdata.get (posity) .getContent ());
Return ConvertView;
}

요소 추가
Public Void ADD (DATA DATA) {
IF (mdata == null) { mData = new LinkedList<>();
                              mData.add(data);                                                                   . 위치,데이터 데이터){
if (mData == null) {
mData = new LinkedList<>();
}
mData.add(position , data);
informDataSetChanged();
}

public void delete(Data data) {
if(mData != null) {
            mData.remove(data);                                 > ㅋㅋㅋ informDataSet
                                                          ' s ' s ' s ' ' s ' ' ' ' ' s ' s ' 통과 ' s ' 통과 ' s 통과 ‐​​​​​​​​​​​​​​​ ​ ​ ​ ​ ​ ​ ​ ​

업그레이드 1: 엔터티를 일반으로 설정

좋아요, 결국 우리가 전달하는 엔터티 엔터티 클래스는 Person, Book, Wether 등과 같이 온갖 종류의 이상할 수 있으므로 Entity를 일반으로 설정하면 수정된 코드는 다음과 같습니다.

<pre>
public class MyAdapter<T> BaseAdapter 확장 {

    private Context mContext;
    private LinkedList<T> mData;

    public MyAdapter() {
    }

    public MyAdapter(LinkedList<T> mData, Context mContext) {
        this.mData = mData;
        this.mContext = mContext;
    }

    @Override
    public int getCount () {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        반환 위치;
}

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout .item_list, parent, false);
            holder = new ViewHolder();
            holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
           holder.txt_content = (텍스트 보기) convertView.findViewById(R.id .txt_content);
convertView.setTag (holder);
} else {

holder = (viewHolder) convertView.getTag ();
}
holder.img_icon.setimageresource (mdata.get (position) .getimgid ());HOLDER.TXT_CONTENTENT.SETEXT (mdata.get (posity) .getContent ());
Return ConvertView;
}

// 요소 추가
Public Void ADD (T DATA) {
if (mdata == Null) {) mData = new LinkedList<>();
                           mData.add(data);                                                                                mData 위치,T 데이터){
if (mData == null) {
mData = new LinkedList<>();
}
mData. add(position, data);
informDataSetChanged();
}

public void delete(T data) {
if(mData != null) {
            mData.remove(data);                                |
;          }
                                                                                      > 를 통해 통해 통해 ‐ ​​​​​​​​​​​​​​​ ​ ​ ​ ​ ​ ​ ​ ​

좋아요, 위에서 한 일은 데이터 유형을 일반 T!로 바꾸는 것입니다.


업그레이드 2: ViewHolder 클래스 업그레이드:

먼저 ViewHolder가 이전에 수행한 작업을 살펴보겠습니다. 답변: findViewById, 제어 상태를 설정합니다. 다음으로, 이 작업을 완료한 것을 바탕으로 getView() 메서드의 로직 대부분을 ViewHolder 클래스에 작성하려고 합니다. 이 ViewHolder가 수행하는 작업:

  • 컨트롤을 찾는 메서드를 정의합니다. 우리의 아이디어는 공용 메서드를 노출하고 메서드를 호출할 때 전달하는 것입니다. ID를 제어하고 TextView 설정 텍스트와 같은 콘텐츠를 설정합니다. public ViewHolder setText(int id, CharSequence text){text settings}
  • convertView 재사용 부분을 여기로 이동한 다음 컨텍스트 객체를 전달해야 합니다. 모든 부분은 생성자에 기록됩니다!
  • 텍스트 크기, 색상, 그림 배경 설정 등 다양한 설정 방법(공개)을 작성하세요!

자, ViewHolder 클래스를 단계별로 변환해 보겠습니다


1) 관련 매개변수 및 구성 방법:

public static class ViewHolder {

private SparseArray<View> //Storage View
in ListView item; private View item; //저장소 ConvertView
private int position; //Cursor
private Context context; //Context context

//관련 초기화 완료를 위한 생성 메소드
private ViewHolder(Context context, ViewGroup parent, intlayoutRes) mViews = new SparseArray<>();
this.context = context;
보기 ConvertView = LayoutInflater.from(context).inflate(layoutRes, parent,false)
    convertView.setTag(this ;

2) ViewHolder와 Item 결합

위 내용을 바탕으로 또 다른 바인딩 방법을 추가합니다

//ViewHolder와 item 결합
public static ViewHolderbind(Context context, View ConvertView, ViewGroup parent,
intlayoutRes, int position ) {
ViewHolder 홀더;
if(convertView == null) {
holder = new ViewHolder(context, parent,layoutRes);
} else {
holder = (ViewHolder) Convert View.getTag();
holder.item = ConvertView;
}
holder.position = position;
returnholder;
}

3) id

public <T extends View> T getView(int id ) { +                                    
반품 t;
}

4) 接着我们再定义一堆暴露 Out来적 방법

/**
* 현재 항목 가져오기
*/
public View getItemView() {
    return item;
}

/**
* 진입 위치 확인
*/
public int getItemPosition() {
    return position;
}

/**
* 텍스트 설정
*/
public ViewHolder setText(int id, CharSequence text) {
    View view = getView(id);
    if(view instanceof TextView) {
((TextView) 보기).setText(text);
    }
    return this;
}

/**
*사진 설정
*/
public ViewHolder setImageResource(int id, int drawableRes) {
    보기 보기 = getView(id) ;
    if(view instanceof ImageView) {
        ((ImageView) view).setImageResource(drawableRes);
    } else {
        view.setBackgroundResource(drawableRes);
    }
    return this;
}


/**
*클릭 모니터링 설정
*/
public ViewHolder setOnClickListener(int id, View.OnClickListener listener) {
    getView(id).setOnClickListener(listener);
    return this;
}

/**
* 설정이 표시됩니다
*/
public ViewHolder setVisibility(int id, int visible) {
    getView(id).setVisibility(visible);
    return this;
}

/**
* 라벨 설정
*/
public ViewHolder setTag(int id, Object obj) {
    getView(id) .setTag(obj);
    return this;
}

//其他方法可自行扩展

자, ViewHolder 변환 및 업그레이드가 완료되었습니다~


업그레이드 3: ViewHolder와 데이터 데이터세트의 바인딩을 완료하기 위한 추상 메소드를 정의하세요

public abstract void bindView(ViewHolder holder, T obj);

새 BaseAdapter를 생성할 때 추가로 이 메소드를 구현하세요. 우리를 맞춤 설정하는 것을 잊지 마세요 BaseAdapter가 추상화로 변경되었습니다!


업그레이드 4: getView() 부분의 내용 수정

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, mLayoutRes
            , position);
    bindView(holder,getItem(position));
    return holder.getItemView();
}

2. 업그레이드 후 이를 경험하기 위한 코드를 작성합니다.

우리가 달성하려는 렌더링:

1.png

두 가지가 있습니다. 위의 목록은 레이아웃이 다르지만 위의 효과를 얻기 위해 BaseAdapter 클래스를 하나만 사용합니다!

키 코드는 다음과 같습니다.

MainActivity.java:

public 클래스 MainActivity는 AppCompatActivity를 확장합니다.{

    private Context mContext;
    private ListView list_book;
    private ListView list_app;

    private MyAdapter<App> myAdapter1 = null;
    private MyAdapter<Book> myAdapter2 = null;
    비공개 목록<App> mData1 = null;
    비공개 목록<도서> mData2 = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = Ma inActivity.this;
        init();

    }

    private void init() {

        list_book = (ListView) findViewById(R.id.list_book);
       list_app = (ListView) findViewById(R.id.list_app);

        //数据初始化
        mData1 = new ArrayList< ;App>();
        mData1.add(new App(R.mipmap.iv_icon_baidu,"百島"));
        mData1.add(new App(R.mipmap.iv_icon_douban,"豆瓣"));
        mData1.add (new App(R.mipmap.iv_icon_zhifubao,"支付宝"));

        mData2 = new ArrayList<Book>();
       mData2.add(new Book(" 《第一行代码Android》","郭霖" ));
        mData2.add(new Book(" 《Android群英传》","徐宜生"));
        mData2.add(new Book(" 《Android开发艺术探索》","任玉刚"));
ㅋㅋㅋ            public void bindView(ViewHolder holder, App obj) {
               holder.setImageResource(R.id.img_icon,obj.getaIcon());
              holder.setText(R.id.txt_aname,obj.getaName());
            }
};
        myAdapter2 = new MyAdapter<Book>((ArrayList)mData2,R.layout.item_two) {
           @Override
           public void bindView(ViewHolder holder, Book obj) {
                holder.setText(R.id.txt_bname,obj .getbName());
               holder.setText(R.id.txt_bauthor,obj.getbAuthor());
           }
        };

        //ListView设置下Adapter:
        list_book.setAdapter(myAdapter2);
        list_app.setAdapter (myAdapter1);

    }


}

우리가 작성한 재사용 가능한 BaseAdapter는 위에서 설명한 대로 사용됩니다~


3. 코드 샘플 다운로드:

ListViewDemo4.zip

필요에 따라 확장할 수 있는 마지막으로 작성된 MyAdapter 클래스 게시:

MyAdapter. 자바 :

/**
 * 2015년 9월 22일 0022에 Jay가 작성함.
 */
공개 추상 클래스 MyAdapter<T> BaseAdapter 확장 {

    비공개 ArrayList<T> mData;
    private int mLayoutRes;           //布局id


    public MyAdapter() {
    }

    public MyAdapter(ArrayList<T>mData, int mLayoutRes) {
        this.mData = mData;
        이. mLayoutRes = mLayoutRes;
    }

    @Override
public int getCount() {
        mData 반환 != null ? mData.size() : 0;
    }

    @Override
    public T getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int 위치) {
        복귀 위치 ;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, mLayoutRes
                , 위치);
        bindView(홀더 , getItem(position));
        return holder.getItemView();
    }

    public abst ract void bindView(ViewHolder holder, T obj);

    //添加一个元素
    public void add(T 데이터) {
        만약 ( mData == null) {
            mData = new ArrayList<>();
        }
        mData.add(data);
        notifyDataSetChanged();
    }

    //往特定位置,添加一个元素
    public void add(int position, T data) {
        if (mData == null) {
           mData = new ArrayList& lt;>();
        }
        mData.add (위치, 데이터);
        notifyDataSetChanged();
    }

    public void remove(T data) {
        if (mData != null) {
           mData.remove(data);
        }
        notifyDataSetChanged();
    }
ㅋㅋㅋ
    public void clear() {
        if (mData != null ) {
           mData.clear();
        }
        notifyDataSetChanged();
    }


    공용 정적 클래스 ViewHolder {

        private SparseArray <보기> mView;   //存储ListView 的 item中的View
        private View item;                  //存放convertView
        private int position;               //游标
        개인 컨텍스트 컨텍스트;            //Context上下文

        //构造方法,完成了关初始化
        private ViewHolder(Context context, ViewGroup parent, int layoutRes) {
           mViews = new SparseArray<>();
           this.context = context;
            View convertView = LayoutInflater.from (컨텍스트).inflate(layoutRes, 상위, false) // 컨텍스트 컨텍스트, 보기 변환 보기, ViewGroup 상위,
                                  int layoutRes, int position) {
            ViewHolder 홀더;
            if (convertView == null) {
               holder = new ViewHolder(context, parent, layoutRes);
          } else {
               holder = (ViewHolder) convertView.getTag();
                holder.item = convertView;
            }
홀더.위치 = 위치;
           반환 홀더;
        }

        @SuppressWarnings("unchecked")
        공개 <T 확장 보기> T getView(int id) {
            T t = (T) mViews.get(id);
            if (t == null) {
               t = (T) item.findViewById(id);
               mViews.put(id, t);
           }
           return t;
        }


        /**
                                                               */
        public View getItemView() {
            반품 항목;
        }

        /**ㅋㅋㅋ*/
        public int getItemPosition() {
            위치 반환;
        }

        /**
                                                             */
        공개 ViewHolder setText (int id, CharSequence text) {
           보기 보기 = getView(id);
            if (TextView 인스턴스 보기) {
               ((TextView) view).setText(text);
            }
            이것을 반환하세요.
        }

        /* *ㅋㅋㅋ*/
        public ViewHolder setImageResource(int id, int drawableRes) {
            보기 보기 = getView(id);
            if (ImageView 인스턴스 보기) {
               ((ImageView) view).setImageResource(drawableRes);
            } else {
             view.setBackgroundResource(drawableRes);
            }
            이것을 반환하세요;
        }


        /**
                                                               * /
        public ViewHolder setOnClickListener(int id, View.OnClickListener listener) {
            getView(id).setOnClickListener(listener);
            return this;
        }
        /**
        * 설정이 표시됩니다
           */
        공개 ViewHolder setVisibility(int id, int visible) {
           getView(id).setVisibility(visible);
            return this;
        }

        /**ㅋㅋㅋ*/
        /**&#&*/
        public ViewHolder setTag(int id , 객체 obj) {
            getView(id).setTag (obj);
            return this;
        }

        //其他方法可自行扩 Exhibition

    }

}


이 섹션 요약:

이 섹션에서는 재사용 가능한 BaseAdapter를 구현하는 방법을 소개합니다. 물론 이를 기반으로 사용할 수 있습니다. 네트워크 이미지를 비동기식으로 설정하는 등 필요에 따라 수정합니다. 수정된 코드는 Hong Yang의 동영상을 참조하여 작성되었습니다. 영상 링크: Android - 범용 어댑터 만들기 그리고 실제 작성 중에 몇 가지 문제가 발생했습니다. Berial(B神) 기다려주셔서 감사합니다~2.jpgありがとуございまс~