Android-RecyclerView-Item點擊事件設置

在上一篇博客Android-RecylerView初識中提到,RecyclerView再也不負責Item視圖的佈局及顯示,因此RecyclerView也沒有爲Item開放OnItemClick等點擊事件,這就須要開發者本身實現。博客最下面有Demo程序運行動畫。git

奉上Demo的Github連接github

在調研過程當中,發現有同窗修改RecyclerView源碼來實現Item的點擊監聽,但認爲這不是一個優雅的解決方案,最終決定在RecyclerView.ViewHolder上作文章。ide

思路是:由於ViewHolder咱們能夠拿到每一個Item的根佈局,因此若是咱們爲根佈局設置單獨的OnClick監聽並將其開放給Adapter,那不就能夠在組裝RecyclerView時就可以設置ItemClickListener,只不過這個Listener不是設置到RecyclerView上而是設置到Adapter。佈局

咱們首先看ViewHolder的代碼:post

public class MyViewHolder extends ViewHolder implements OnClickListener,OnLongClickListener{

    public ImageView iv;
    public TextView tv;
    private MyItemClickListener mListener;
    private MyItemLongClickListener mLongClickListener;
    
    public MyViewHolder(View rootView,MyItemClickListener listener,MyItemLongClickListener longClickListener) {
        super(rootView);
        iv = (ImageView)rootView.findViewById(R.id.item_iv);
        tv = (TextView)rootView.findViewById(R.id.item_tv);
        this.mListener = listener;
        this.mLongClickListener = longClickListener;
        rootView.setOnClickListener(this);
        rootView.setOnLongClickListener(this);
    }

    /**
     * 點擊監聽
     */
    @Override
    public void onClick(View v) {
        if(mListener != null){
            mListener.onItemClick(v,getPosition());
        }
    }

    /**
     * 長按監聽
     */
    @Override
    public boolean onLongClick(View arg0) {
        if(mLongClickListener != null){
            mLongClickListener.onItemLongClick(arg0, getPosition());
        }
        return true;
    }

}

由於在構造ViewHolder時,rootView將做爲一個必傳參數傳遞進來,因此咱們只須要拿到rootView並給其綁定點擊監聽事件便可。動畫

下面要考慮的就是怎樣把listener傳遞進來。Demo中設定了監聽點擊事件的Interface:MyItemClickListener:this

public interface MyItemClickListener {
    public void onItemClick(View view,int postion);
}

MyItemClickListener模仿ListView的OnItemClickListener,開放了view和position兩個參數,這對習慣使用ListView的開發者們使用起來更駕輕就熟。從ViewHolder的代碼中能夠看到,執行onClick方法時會調用getPosition()將當前Item的位置回調給listener。getPosition()是ViewHolder的內置方法,可直接使用。spa

上面提到過,listener是設定到Adapter上的,因此Adapter就須要對外開放相關方法:.net

@Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent,false);
        MyViewHolder vh = new MyViewHolder(itemView,mItemClickListener,mItemLongClickListener);
        return vh;
    }

    /**
     * 設置Item點擊監聽
     * @param listener
     */
    public void setOnItemClickListener(MyItemClickListener listener){
        this.mItemClickListener = listener;
    }
    
    public void setOnItemLongClickListener(MyItemLongClickListener listener){
        this.mItemLongClickListener = listener;
    }

上篇博客(Android-RecylerView初識)提到過,Adapter的onCreateViewHolder是負責實例化每一個Item的視圖,因此我在實例化視圖時就將listener傳遞給ViewHolder。code

最後就是組裝RecyclerView時根據需求設定點擊監聽了:

/**
     * 初始化RecylerView
     */
    private void initView(){
        mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
        MyLayoutManager manager = new MyLayoutManager(this);
        manager.setOrientation(LinearLayout.HORIZONTAL);//默認是LinearLayout.VERTICAL
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    }
    
    private void initData(){
        this.mData = new ArrayList<MyItemBean>();
        for(int i=0;i<20;i++){
            MyItemBean bean = new MyItemBean();
            bean.tv = "Xmy"+i;
            mData.add(bean);
        }
        this.mAdapter = new MyAdapter(mData);
        this.mRecyclerView.setAdapter(mAdapter);
        RecyclerView.ItemDecoration decoration = new MyDecoration(this);
        this.mRecyclerView.addItemDecoration(decoration);
        this.mAdapter.setOnItemClickListener(this);
        this.mAdapter.setOnItemLongClickListener(this);
    }

Demo爲ViewHolder設置了OnClick和OnLongClickListener,在Activity中咱們實現了接口方法並在裏面打印Toast提示:

@Override
    public void onItemClick(View view, int postion) {
        MyItemBean bean = mData.get(postion);
        if(bean != null){
            Toast.makeText(this, bean.tv, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onItemLongClick(View view, int postion) {
        MyItemBean bean = mData.get(postion);
        if(bean != null){
            Toast.makeText(this, "LongClick "+bean.tv, Toast.LENGTH_SHORT).show();
        }
    }

下面是Demo的運行動畫。

 

相關文章
相關標籤/搜索