Android RecyclerView單擊、長按事件標準實現:基於OnItemTouchListener + GestureDetector

來源:互聯網
上載者:User

標籤:textview   intercept   zhang   中介   androi   進一步   測試的   one   pat   

??

Android RecyclerView單擊、長按事件:基於OnItemTouchListener + GestureDetector標準實現

Android RecyclerView雖然擁有ListView絕大多數的功能,但Android RecyclerView卻沒有實現像ListView那樣的點擊事件、長按事件的標準實現方式,我在附錄文章1中介紹的方式,實現了典型的RecyclerView的item點擊事件,大致的思路是通過為RecyclerView的ViewHolder添加View.OnClickListener事件達到點擊事件的監聽,這種實現方式可以正常工作,但不太標準。現在給出一種較為規範的Android官方實現。
翻了Android RecyclerView的官方文檔,這文檔中確實沒有提供像ListView的OnItem點擊事件,但是注意到有一個addOnItemTouchListener,根據官方文檔的描述,addOnItemTouchListener是Android官方文檔中留下的點擊事件的線索入口,文檔中也暗示開發人員應該從這個事件監聽介面中實現所需的邏輯代碼。但是直接new一個對象傳遞過去,則需要自己解析Android Touch Event複雜的處理,所幸Android官方給出了RecyclerView.SimpleOnItemTouchListener,顧名思義,就是一個簡化的OnItemTouchListener。雖然有了SimpleOnItemTouchListener,到此還沒完,因為SimpleOnItemTouchListener只是事件攔截處理的入口,真正要做事情的主角是:GestureDetector。通過GestureDetector裡面的攔截到的所託管的單擊、長按事件,才最終實現了RecyclerView的單擊、長按事件。

完整代碼:

package zhangphil.app;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    private RecyclerView mRecyclerView;    private GestureDetector mGestureDetector;    //長按事件    private OnItemLongClickListener mOnItemLongClickListener = new OnItemLongClickListener() {        @Override        public void onItemLongClick(int position, View childView) {            Toast.makeText(getApplication(), "長按:" + position, Toast.LENGTH_SHORT).show();        }    };    //單擊事件    private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {        @Override        public void onItemClick(int position, View childView) {            Toast.makeText(getApplication(), "單擊:" + position, Toast.LENGTH_SHORT).show();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //建立一個簡單的用以測試的RecyclerView        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);        LinearLayoutManager layoutManager = new LinearLayoutManager(this);        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);        mRecyclerView.setLayoutManager(layoutManager);        mRecyclerView.setAdapter(new ItemAdapter());        //以下是添加點擊、長按事件的關鍵代碼        mRecyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {            @Override            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {                if (mGestureDetector.onTouchEvent(e)) {                    return true;                }                return false;            }        });        mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {            //長按事件            @Override            public void onLongPress(MotionEvent e) {                super.onLongPress(e);                if (mOnItemLongClickListener != null) {                    View childView = mRecyclerView.findChildViewUnder(e.getX(), e.getY());                    if (childView != null) {                        int position = mRecyclerView.getChildLayoutPosition(childView);                        mOnItemLongClickListener.onItemLongClick(position, childView);                    }                }            }            //單擊事件            @Override            public boolean onSingleTapUp(MotionEvent e) {                if (mOnItemClickListener != null) {                    View childView = mRecyclerView.findChildViewUnder(e.getX(), e.getY());                    if (childView != null) {                        int position = mRecyclerView.getChildLayoutPosition(childView);                        mOnItemClickListener.onItemClick(position, childView);                        return true;                    }                }                return super.onSingleTapUp(e);            }        });    }    //長按事件介面    public interface OnItemLongClickListener {        public void onItemLongClick(int position, View childView);    }    //單擊事件介面    public interface OnItemClickListener {        public void onItemClick(int position, View childView);    }    private class ItemViewHolder extends RecyclerView.ViewHolder {        public TextView text;        public ItemViewHolder(View itemView) {            super(itemView);            text = (TextView) itemView.findViewById(android.R.id.text1);        }    }    private class ItemAdapter extends RecyclerView.Adapter<ItemViewHolder> {        @Override        public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {            View view = View.inflate(parent.getContext(), android.R.layout.simple_list_item_1, null);            ItemViewHolder holder = new ItemViewHolder(view);            return holder;        }        @Override        public void onBindViewHolder(ItemViewHolder holder, int position) {            holder.text.setText(String.valueOf(position));        }        @Override        public int getItemCount() {            return 99;        }    }}


因為我是在onInterceptTouchEvent裡面攔截了RecyclerView的觸摸事件,並通過GestureDetector
託管處理,由此可以延伸、進一步封裝出更多更複雜的事件處理介面。


附錄:
1,《RecyclerView點擊事件》連結:http://blog.csdn.net/zhangphil/article/details/46771865



Android RecyclerView單擊、長按事件標準實現:基於OnItemTouchListener + GestureDetector

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.