Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> RecyclerView的通用適配器的高級使用

RecyclerView的通用適配器的高級使用

編輯:關於Android編程

前言

博主由於項目中頻繁的使用了V7包中的RecyclerView來代替ListView的列表展示,所以抽空基於ListView的通用適配器的原理,給RecyclerView也寫了一個通用適配器主要支持以下功能:

1.支持item的點擊事件,在多布局的情況下可以指定生效的itemType

2.支持item中的控件的點擊事件(博主覺得具有創新性),在多布局的情況下可以指定生效的itemType

3.支持添加和移除頭部(博主沒有寫添加尾部的方法,其實和添加頭部的方法是類似的,如果你有需要就自己參照著改下吧)

4.支持多布局(其實這個並不是博主寫的功能,而是自帶的,下面會陳述)

以上的功能都是通用適配器完成的,對RecyclerView本身沒有做任何的更改

那麼博主就先帶大家來看看是如何使用的吧,看看他是如果提高我們的開發效率的!

 

Xml布局

 




    
    

 

Number One(一個豎直的簡單的列表,顯示人名)

 

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的布局暫時使用了系統的

效果

\

可以看到顯示沒有一點問題,那麼我要實現條目的點擊怎麼辦?

實現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的條目監聽是一樣一樣的?換個方法名稱而已嘛對不對

 

點擊item效果

\

可以看到,點擊事件生效

多布局demo

由於顯示的需要,我們需要一個實體對象

entity

 

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屬性

既然是多布局,那麼兩個及以上的布局,這裡以兩個布局為例子

xml(TagItem)

 




    

 

xml(NameItem)

 

 




    

 

然後我們在適配器中需要多一個方法了,先看代碼

修改後的Activity代碼

 

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的,你說呢?

演示監聽item內部控件的點擊事件

首先我們在顯示名稱的item中添加一個按鈕



    

    

就添加了一個按鈕

然後呢,我們在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是有點區別的

演示添加頭部試圖

頭部xml





    

        

    


然後我們添加一個頭部

 

 

adapter.addHeaderView(View.inflate(this, R.layout.header, null));

 

效果

\

demo和通用適配器源碼下載

https://github.com/xiaojinzi123/android-demos/tree/master/RecyclerViewDemo
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved