摘要:
在Android开发中,对事件的处理机制有两种方式,一种基于回调机制的事件处理,另一种基于监听接口的事件处理。实际开发中,通过监听接口是否传入了源数据,然后在实现接口的类处理,形象将三者比喻成:源头,接口和终点。想象一下,一根水管如何将水引流到家里的,首先必须有源头,然后水管之间的连接,最后流到家里,供生活使用,体现面向对象的编程思想。
一.深入理解接口使用
RecyclerView没有类似ListView的OnItemClickListener的接口,想要实现点击选项执行跳转,想要点击效果,需要获取点击的对象,定义接口OnItemClickListener,如下:
- publi interface OnItemClickListener{
- void setOnItemClickListener(RecyclerView.ViewHolder vh);
- }
如何获取到RecyclerView.ViewHolder,然后间接获取View对象?查看RecyclerView开发文档后,我们知道RecyclerView提供了OnItemTouchListener接口,有一个onTouchEvent的方法,使用SimpleOnGestureListener处理手势动作,比如:单击,通过单击调用RecyclerView的方法findChildViewUnder()获取到View对象,最后通过接口传递并在实现类中处理。
- mRecyclerView.addItemTouchListener(new ItemTouchListener(){
- ...
- @Override
- public void onTouchEvent(RecyclerView rv, MotionEvent e) {
- mGestureDetector.onTouchEvent(e);
- }
- ...
- });
- mGestureDetector = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener(){
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- View child = findChildViewUnder(e.getX(), e.getY());
- if (child != null) {
- RecyclerView.ViewHolder vh = getChildViewHolder(child);
- mOnItemClickListener.setOnItemClickListener(vh);
- }
- return true;
- }
- });
从这个实例,你是否理解了接口的三个比喻:源头,接口,终点?如果不明白也没有关系,继续往下看详细代码。
源头:重写RecyclerView,命名为MyRecyclerView
- /**
- * Created by TeachCourse.cn on 2016/5/28 11:39.
- */
- public class RecyclerView1 extends RecyclerView {
- private OnItemClickListener onItemClickListener;
- private GestureDetectorCompat mGestureDetector;
- public RecyclerView1(Context context) {
- super(context);
- }
- public RecyclerView1(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
- public RecyclerView1(Context context, @Nullable AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- public void setOnItemClickListener(OnItemClickListener onItemClickListener){
- this.onItemClickListener=onItemClickListener;
- init();
- addOnItemTouchListener(onItemTouchListener);
- }
- /**
- *设置接口:调用setOnItemClickListener()方法传递数据
- */
- private void init(){
- mGestureDetector = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener(){
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- View child = findChildViewUnder(e.getX(), e.getY());
- if (child != null) {
- RecyclerView.ViewHolder vh = getChildViewHolder(child);
- onItemClickListener.setOnItemClickListener(vh);
- }
- return true;
- }
- });
- }
- /**
- * 实现RecyclerView.OnItemTouchListener接口
- */
- private RecyclerView.OnItemTouchListener onItemTouchListener=new RecyclerView.OnItemTouchListener(){
- @Override
- public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
- return false;
- }
- //方法一:在RecyclerView本身或其子视图处理触摸事件之前,该方法静静监视和接管发送到RecyclerView的事件消息,即对RecyclerView进行事件拦截
- @Override
- public void onTouchEvent(RecyclerView rv, MotionEvent e) {
- mGestureDetector.onTouchEvent(e);
- }
- //方法二:在方法一返回true,作为手势事件处理的一部分,即对RecyclerView进行触摸事件处理,获取MotionEvent对象,这一步就可以使用GestureDetectorCompat进行事件分发处理(下面详细说明)
- @Override
- public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
- }
- //方法三:当RecyclerView子视图不想被RecyclerView或其父类事件拦截,回调该方法
- };
- }
接口:完整代码和上面OnItemClickListener接口一样(省略)
终点:在MainActivity中监听,调用setOnItemClickListener方法,最后处理业务逻辑
- myRecyclerView.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {
- @Override
- public void onItemClick(RecyclerView.ViewHolder vh) {
- Intent intent = null;
- String url = list.get(vh.getAdapterPosition()).getUrl();
- String title = list.get(vh.getAdapterPosition()).getTitle();
- if (intent == null) {
- intent = new Intent(getContext(), BaseWebActivity.class);
- }
- intent.putExtra("url", url);
- intent.putExtra("title", title);
- startActivity(intent);
- }
- });
二.思考:如何给ViewGroup的子控件添加点击事件?
毫不犹豫想到了遍历ViewGroup,获取到每个子控件,然后设置onClick()接口,最后调用setOnClickListener方法监听,但这里我们不考虑这样做。现在我们使用手势的onSingleTapUp实现一个类似单击的事件,首先父控件调用getChildCount获取子控件数量,然后调用getChildAt获取指定的子控件,最后设置setOnTouchListener监听器,重写SimpleOnGestureListener的onSingleTapUp()方法,在里面实现类似单击的事件。具体代码如下:
- private void addGesture() {
- int i=0;
- int length=mLinearLayout.getChildCount();
- while(i<length){
- View view=mLinearLayout.getChildAt(i);
- view.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- mOnGesture.onSingleTapUp(event);
- return false;
- }
- });
- i++;
- }
- }
- GestureDetector.OnGestureListener mOnGesture=new GestureDetector.SimpleOnGestureListener(){
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- Toast.makeText(LinearLayoutActivity.this,"哈哈哈哈,成功触摸了屏幕。。。",Toast.LENGTH_LONG).show();
- return true;
- }
- };
你可能感兴趣的文章
转载请注明出处: https://www.teachcourse.cn/2074.html ,谢谢支持!