個(gè)人主頁為 The_D的博客
很多人使用 Listview 時(shí),總是用 ViewHolder 的模式來創(chuàng)建,而根據(jù) Customizing Android ListView Rows by Subclassing 中說的,ViewHolder 是一種愚笨的方式永高。在這篇文章中恨豁,作者提出了一個(gè)新的思路,也就是通過自定義的 Layout 來代替 ViewHolder迁匠。
ViewHolder的缺點(diǎn)
- Adapter 的 getView() 函數(shù)承擔(dān)了很多責(zé)任
- ViewHolder 類中通常是一些無意義的代碼
- view 的 tag 需要轉(zhuǎn)換到正確的 holder 類型
- 違反了封裝性,因?yàn)?adapter/holder 必須知道 item 內(nèi)部有什么 view
demo:
![動(dòng)圖](http://7xozv0.com1.z0.glb.clouddn.com/2016/1/26/customRelativeLayoutdemo.gif)
動(dòng)圖
下面來說說如何實(shí)現(xiàn):
首先驹溃,創(chuàng)建item_relative_layout.xml
:
item由頭像ImageView
城丧,名字TextView
和描述TextView
構(gòu)成
<?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="200dp">
<ImageView
android:id="@+id/iv"
android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="fitCenter"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iv"
android:layout_marginLeft="20dp"
android:layout_marginTop="60dp"
android:textSize="16sp"
/>
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iv"
android:layout_below="@id/tv_title"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:textSize="14sp"
/>
</RelativeLayout>
然后,創(chuàng)建CustomRelativeLayout.java
:
public class CustomRelativeLayout extends RelativeLayout {
//使用ButterKnife注解的方式豌鹤,簡(jiǎn)化了findViewById
@Bind(R.id.iv)
ImageView mIv;
@Bind(R.id.tv_title)
TextView mTvTitle;
@Bind(R.id.description)
TextView mDescription;
public CustomRelativeLayout(Context context) {
super(context);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.item_relative_layout, this);
ButterKnife.bind(this);
//因?yàn)槊恳粋€(gè)item的listener都相同亡哄,所以將clickListener寫在這個(gè)類中,如果不同布疙,可寫在adapter的getView()中根據(jù)position設(shè)置不同listener
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), mTvTitle.getText().toString() + " " + mDescription.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
}
public void setData(int iv, String title, String description){
mIv.setImageResource(iv);
mTvTitle.setText(title);
mDescription.setText(description);
}
}
ListAdapter.java
:
public class ListAdapter extends BaseAdapter {
Context mContext;
int[] images;
String[] titles;
String[] descriptions;
public ListAdapter(Context context) {
mContext = context;
}
public void setData(int[] images, String[] titles, String[] descriptions) {
this.images = images;
this.titles = titles;
this.descriptions = descriptions;
}
@Override
public int getCount() {
return images.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
//相對(duì)于ViewHolder簡(jiǎn)化了getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
CustomRelativeLayout customRelativeLayout = null;
if (convertView != null && convertView instanceof CustomRelativeLayout) {
customRelativeLayout = (CustomRelativeLayout) convertView;
} else {
customRelativeLayout = new CustomRelativeLayout(mContext);
}
customRelativeLayout.setData(images[position], titles[position], descriptions[position]);
return customRelativeLayout;
}
}
UsingCustomLayoutActivity.java
:
public class UsingCustomLayoutActivity extends AppCompatActivity {
@Bind(R.id.lv)
ListView mLv;
ListAdapter mListAdapter;
int[] images = {R.drawable.p1, R.drawable.p2, R.drawable.p3};
String[] titles = {"The_D", "閆一彪", "Android技術(shù)小鋪"};
String[] descriptions = {"Android開發(fā)", "Java后端開發(fā)", "我的微信公眾號(hào)蚊惯,專注于Android技術(shù)分享愿卸,歡迎關(guān)注"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_using_custom_layout);
ButterKnife.bind(this);
mListAdapter = new ListAdapter(this);
mListAdapter.setData(images, titles, descriptions);
mLv.setAdapter(mListAdapter);
}
}
activity_using_custom_layout.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.zhangkaiyue.jkdemo.UsingCustomLayoutActivity">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
這種做法的優(yōu)勢(shì):
這樣寫可以使item復(fù)用,并且針對(duì)復(fù)雜的Adapter截型,大大的簡(jiǎn)化了書寫趴荸。對(duì)于一些跟View相關(guān)的邏輯,可以直接寫在CustomRelativeLayout中菠劝,消除了Adapter的冗余赊舶。
![我的微信公眾號(hào)](http://7xozv0.com1.z0.glb.clouddn.com/code.jpg)
我的微信公眾號(hào)