Android-RecyclerView-Item點擊事件設置


在上一篇博客Android-RecylerView初識中提到,RecyclerView不再負責Item視圖的布局及顯示,所以RecyclerView也沒有為Item開放OnItemClick等點擊事件,這就需要開發者自己實現。博客最下面有Demo程序運行動畫。

奉上Demo的Github鏈接

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

思路是:因為ViewHolder我們可以拿到每個Item的根布局,所以如果我們為根布局設置單獨的OnClick監聽並將其開放給Adapter,那不就可以在組裝RecyclerView時就能夠設置ItemClickListener,只不過這個Listener不是設置到RecyclerView上而是設置到Adapter。

我們首先看ViewHolder的代碼:

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:

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

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

上面提到過,listener是設定到Adapter上的,所以Adapter就需要對外開放相關方法:

@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。

最后就是組裝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的運行動畫。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM