재사용 가능한 사용자 정의 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를 일반으로 설정하면 수정된 코드는 다음과 같습니다.
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) 관련 매개변수 및 구성 방법:
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 결합
위 내용을 바탕으로 또 다른 바인딩 방법을 추가합니다
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
반품 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. 업그레이드 후 이를 경험하기 위한 코드를 작성합니다.
우리가 달성하려는 렌더링:
두 가지가 있습니다. 위의 목록은 레이아웃이 다르지만 위의 효과를 얻기 위해 BaseAdapter 클래스를 하나만 사용합니다!
키 코드는 다음과 같습니다.
MainActivity.java:
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神) 기다려주셔서 감사합니다~ありがとуございまс~