編輯:關於Android編程
博主由於項目中頻繁的使用了V7包中的RecyclerView來代替ListView的列表展示,所以抽空基於ListView的通用適配器的原理,給RecyclerView也寫了一個通用適配器主要支持以下功能:
1.支持item的點擊事件,在多布局的情況下可以指定生效的itemType
2.支持item中的控件的點擊事件(博主覺得具有創新性),在多布局的情況下可以指定生效的itemType
3.支持添加和移除頭部(博主沒有寫添加尾部的方法,其實和添加頭部的方法是類似的,如果你有需要就自己參照著改下吧)
4.支持多布局(其實這個並不是博主寫的功能,而是自帶的,下面會陳述)
以上的功能都是通用適配器完成的,對RecyclerView本身沒有做任何的更改
那麼博主就先帶大家來看看是如何使用的吧,看看他是如果提高我們的開發效率的!
public class MainActivity extends AppCompatActivity {
//展示數據的列表
private RecyclerView rv = null;
//需要展示的數據
private List data = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//展示的數據造假
for(int i = 0; i < 100; i++) {
data.add("item:" + i);
}
//尋找控件
rv = (RecyclerView) findViewById(R.id.rv);
//創建一個線性的布局管理器並設置
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rv.setLayoutManager(layoutManager);
CommonRecyclerViewAdapter adapter = new CommonRecyclerViewAdapter(this, data) {
@Override
public void convert(CommonRecyclerViewHolder h, String entity, int position) {
h.setText(android.R.id.text1, entity);
}
//返回item布局的id
@Override
public int getLayoutViewId(int viewType) {
return android.R.layout.simple_list_item_1;
}
};
//設置適配器
rv.setAdapter(adapter);
}
}
你可以看到適配器是通過內部類new出來的,因為代碼量比較少所以這樣子寫了,你們在項目中最好創建一個類哦
代碼很簡單,就是讓RecyclerView豎直的展示了數據,item的布局暫時使用了系統的

可以看到顯示沒有一點問題,那麼我要實現條目的點擊怎麼辦?
adapter.setOnRecyclerViewItemClickListener(new CommonRecyclerViewAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View v, int position) {
Toast.makeText(MainActivity.this, "你點擊了第" + position + "個item", Toast.LENGTH_SHORT).show();
}
});
是不是和Listview的條目監聽是一樣一樣的?換個方法名稱而已嘛對不對

可以看到,點擊事件生效
由於顯示的需要,我們需要一個實體對象
public class DemoEntity {
//如果有這個說明需要使用tag條目
private String tag;
//如果有這個說明要使用item條目
private String name;
public DemoEntity(String tag, String name) {
this.tag = tag;
this.name = name;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
注釋中可以看出,如果有tag屬性,那麼沒有name屬性
既然是多布局,那麼兩個及以上的布局,這裡以兩個布局為例子
然後我們在適配器中需要多一個方法了,先看代碼
public class MainActivity extends AppCompatActivity {
//展示數據的列表
private RecyclerView rv = null;
//需要展示的數據
private List data = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//展示的數據造假
data.add(new DemoEntity("A", null));
data.add(new DemoEntity(null, "阿大"));
data.add(new DemoEntity(null, "阿姨"));
data.add(new DemoEntity("C", null));
data.add(new DemoEntity(null, "陳旭金"));
//尋找控件
rv = (RecyclerView) findViewById(R.id.rv);
//創建一個線性的布局管理器並設置
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rv.setLayoutManager(layoutManager);
CommonRecyclerViewAdapter adapter = new CommonRecyclerViewAdapter(this, data) {
@Override
public void convert(CommonRecyclerViewHolder h, DemoEntity entity, int position) {
int itemViewType = getItemViewType(position);
if (itemViewType == 1) {
h.setText(R.id.tv_tag, entity.getTag());
} else {
h.setText(R.id.tv_name, entity.getName());
}
}
//返回item布局的id
@Override
public int getLayoutViewId(int viewType) {
if (viewType == 1) {
return R.layout.tag;
} else {
return R.layout.item;
}
}
//默認是返回0,所以你可以定義返回1表示使用tag,2表示使用item,
//這裡返回的值將在getLayoutViewId方法中出現
@Override
public int getItemType(int position) {
//根據實體對象中的屬性來返回view的類型
DemoEntity demoEntity = data.get(position);
if (demoEntity.getTag() != null) { //如果是tag,應該返回1
return 1;
} else {
return 2;
}
}
};
//設置適配器
rv.setAdapter(adapter);
adapter.setOnRecyclerViewItemClickListener(new CommonRecyclerViewAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View v, int position) {
Toast.makeText(MainActivity.this, "你點擊了第" + position + "個item", Toast.LENGTH_SHORT).show();
}
});
}
}
我們看到多了一個getItemType方法,用來返回下標為position的時候的viewItem的標識,這個可以隨你自己定義,上面就是1表示Tag,2表示name
然後我們的getLayoutViewId方法就不再是單純的返回同一個布局啦,就要根據剛剛的標識返回對應的xml的id啦
同理,在convert方法中也得判斷後再進行對item中的控件賦值啦!代碼不難,博主也做了注釋

數據的數量比較少就不能滑動了,你自己數據弄多點就行啦
針對多布局的item點擊事件,有時候我們需要只要名稱的item的點擊作用生效就行了,所以adapter中也提供了相應的方法
public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener, int... itemTypes)
adapter.setOnRecyclerViewItemClickListener(new CommonRecyclerViewAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View v, int position) {
Toast.makeText(MultiLayoutActivity.this, "你點擊了第" + position + "個item", Toast.LENGTH_SHORT).show();
}
}, 2);
細心一點可以看到,設置監聽的最後我跟上了一個2,那麼這個2是什麼用呢?還記得上面的多布局,我們的2表示顯示名稱的item,所以這裡的2就是指點擊事件只對顯示名稱的item起作用,而這個2也是你自己在上面自定義的,所以要學會變通

可以看我我無論如何點擊藍色的字母,這裡都沒有起作用,這個設計博主覺得挺6的,你說呢?
就添加了一個按鈕
然後呢,我們在Activity去監聽這個item中的按鈕!方法為:
public void setOnViewInItemClickListener(OnViewInItemClickListener onViewInItemClickListener, int... viewIdsInItem)viewIdsInItem是一個整形數組,就是你想監聽的item中的控件的id
用法:
//添加item中按鈕控件監聽
adapter.setOnViewInItemClickListener(new CommonRecyclerViewAdapter.OnViewInItemClickListener() {
@Override
public void onViewInItemClick(View v, int position) {
DemoEntity demoEntity = data.get(position);
Toast.makeText(MultiLayoutActivity.this, "你點擊了第" + position + "個item,name = " + demoEntity.getName(), Toast.LENGTH_SHORT).show();
}
}, R.id.bt);
為了可以滑動,數據我造假多一點
data.add(new DemoEntity("A", null));
data.add(new DemoEntity(null, "阿大"));
data.add(new DemoEntity(null, "阿姨1"));
data.add(new DemoEntity(null, "阿姨2"));
data.add(new DemoEntity(null, "阿姨3"));
data.add(new DemoEntity(null, "阿姨4"));
data.add(new DemoEntity("C", null));
data.add(new DemoEntity(null, "陳旭金1"));
data.add(new DemoEntity(null, "陳旭金2"));
data.add(new DemoEntity(null, "陳旭金3"));
data.add(new DemoEntity(null, "陳旭金4"));
可以看到item中的按鈕被成功點擊!並且顯示出對應的名稱和點擊item是有點區別的
然後我們添加一個頭部
adapter.addHeaderView(View.inflate(this, R.layout.header, null));
深入Android 五大布局對象的應用
FrameLayout(幀布局),LinearLayout (線性布局),AbsoluteLayout(絕對布局),RelativeLayout(相對布局),TableL
微信不能發語音怎麼辦
有朋友在問微信無法發送語音怎麼辦,微信無法語音解決方法有哪些呢?我們最常使用的微信功能就是與好友語音,所以遇到微信不能發送語音這樣故障的朋友一定很著急吧,希
Android逆向之旅---Android中的sharedUserId屬性詳解
一、前言今天我們來看一下Android中一個眾人熟悉的一個屬性:shareUserId,關於這個屬性可能大家都很熟悉了,最近在開發項目,用到了這個屬性,雖然知道一點知識,
Android界面編程——導航欄及菜單(六)
2.7導航欄及菜單2.7.1 ActionBarActionBar是Android3.0(API 11)開始增加的新特性,ActionBar出現在活動窗口的頂部,可以顯示