关于接口的理解:源头,接口,终点

2016-11-11 22:40 评论 0 条

摘要:

在Android开发中,对事件的处理机制有两种方式,一种基于回调机制的事件处理,另一种基于监听接口的事件处理。实际开发中,通过监听接口是否传入了源数据,然后在实现接口的类处理,形象将三者比喻成:源头,接口和终点。想象一下,一根水管如何将水引流到家里的,首先必须有源头,然后水管之间的连接,最后流到家里,供生活使用,体现面向对象的编程思想。

一.深入理解接口使用

RecyclerView没有类似ListView的OnItemClickListener的接口,想要实现点击选项执行跳转,想要点击效果,需要获取点击的对象,定义接口OnItemClickListener,如下:

  1. publi interface OnItemClickListener{  
  2.      void setOnItemClickListener(RecyclerView.ViewHolder vh);  
  3. }  

如何获取到RecyclerView.ViewHolder,然后间接获取View对象?查看RecyclerView开发文档后,我们知道RecyclerView提供了OnItemTouchListener接口,有一个onTouchEvent的方法,使用SimpleOnGestureListener处理手势动作,比如:单击,通过单击调用RecyclerView的方法findChildViewUnder()获取到View对象,最后通过接口传递并在实现类中处理。

  1. mRecyclerView.addItemTouchListener(new ItemTouchListener(){  
  2.   
  3.         ...     
  4.      
  5.        @Override  
  6.         public void onTouchEvent(RecyclerView rv, MotionEvent e) {  
  7.             mGestureDetector.onTouchEvent(e);  
  8.         }  
  9.   
  10.        ...  
  11.   
  12. });  
  1. mGestureDetector = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener(){  
  2.             @Override  
  3.             public boolean onSingleTapUp(MotionEvent e) {  
  4.                 View child = findChildViewUnder(e.getX(), e.getY());  
  5.                 if (child != null) {  
  6.                     RecyclerView.ViewHolder vh = getChildViewHolder(child);  
  7.                     mOnItemClickListener.setOnItemClickListener(vh);  
  8.                 }  
  9.                 return true;  
  10.             }  
  11. });  

从这个实例,你是否理解了接口的三个比喻:源头,接口,终点?如果不明白也没有关系,继续往下看详细代码。

源头:重写RecyclerView,命名为MyRecyclerView

  1. /** 
  2.  * Created by TeachCourse.cn on 2016/5/28 11:39. 
  3.  */  
  4. public class RecyclerView1 extends RecyclerView {  
  5.     private OnItemClickListener onItemClickListener;  
  6.     private GestureDetectorCompat mGestureDetector;  
  7.   
  8.     public RecyclerView1(Context context) {  
  9.         super(context);  
  10.     }  
  11.   
  12.     public RecyclerView1(Context context, @Nullable AttributeSet attrs) {  
  13.         super(context, attrs);  
  14.     }  
  15.   
  16.     public RecyclerView1(Context context, @Nullable AttributeSet attrs, int defStyle) {  
  17.         super(context, attrs, defStyle);  
  18.     }  
  19.   
  20.     public void setOnItemClickListener(OnItemClickListener onItemClickListener){  
  21.         this.onItemClickListener=onItemClickListener;  
  22.         init();  
  23.         addOnItemTouchListener(onItemTouchListener);  
  24.     }  
  25.   
  26.     /** 
  27.      *设置接口:调用setOnItemClickListener()方法传递数据 
  28.      */  
  29.     private void init(){  
  30.         mGestureDetector = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener(){  
  31.             @Override  
  32.             public boolean onSingleTapUp(MotionEvent e) {  
  33.                 View child = findChildViewUnder(e.getX(), e.getY());  
  34.                 if (child != null) {  
  35.                     RecyclerView.ViewHolder vh = getChildViewHolder(child);  
  36.                     onItemClickListener.setOnItemClickListener(vh);  
  37.                 }  
  38.                 return true;  
  39.             }  
  40.         });  
  41.     }  
  42.   
  43.     /** 
  44.      * 实现RecyclerView.OnItemTouchListener接口 
  45.      */  
  46.     private RecyclerView.OnItemTouchListener onItemTouchListener=new RecyclerView.OnItemTouchListener(){  
  47.         @Override  
  48.         public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {             
  49.             return false;  
  50.         }  
  51.         //方法一:在RecyclerView本身或其子视图处理触摸事件之前,该方法静静监视和接管发送到RecyclerView的事件消息,即对RecyclerView进行事件拦截  
  52.   
  53.         @Override  
  54.         public void onTouchEvent(RecyclerView rv, MotionEvent e) {  
  55.             mGestureDetector.onTouchEvent(e);  
  56.         }  
  57.         //方法二:在方法一返回true,作为手势事件处理的一部分,即对RecyclerView进行触摸事件处理,获取MotionEvent对象,这一步就可以使用GestureDetectorCompat进行事件分发处理(下面详细说明)  
  58.         @Override  
  59.         public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {  
  60.   
  61.         }  
  62.         //方法三:当RecyclerView子视图不想被RecyclerView或其父类事件拦截,回调该方法  
  63.     };     
  64. }  

接口:完整代码和上面OnItemClickListener接口一样(省略)

终点:在MainActivity中监听,调用setOnItemClickListener方法,最后处理业务逻辑

  1. myRecyclerView.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {  
  2.     @Override  
  3.     public void onItemClick(RecyclerView.ViewHolder vh) {  
  4.         Intent intent = null;  
  5.         String url = list.get(vh.getAdapterPosition()).getUrl();  
  6.         String title = list.get(vh.getAdapterPosition()).getTitle();  
  7.         if (intent == null) {  
  8.         intent = new Intent(getContext(), BaseWebActivity.class);  
  9.         }  
  10.         intent.putExtra("url", url);  
  11.         intent.putExtra("title", title);  
  12.         startActivity(intent);  
  13.     }  
  14. });  

二.思考:如何给ViewGroup的子控件添加点击事件?

毫不犹豫想到了遍历ViewGroup,获取到每个子控件,然后设置onClick()接口,最后调用setOnClickListener方法监听,但这里我们不考虑这样做。现在我们使用手势的onSingleTapUp实现一个类似单击的事件,首先父控件调用getChildCount获取子控件数量,然后调用getChildAt获取指定的子控件,最后设置setOnTouchListener监听器,重写SimpleOnGestureListener的onSingleTapUp()方法,在里面实现类似单击的事件。具体代码如下:

  1. private void addGesture() {  
  2.         int i=0;  
  3.         int length=mLinearLayout.getChildCount();  
  4.         while(i<length){  
  5.             View view=mLinearLayout.getChildAt(i);  
  6.             view.setOnTouchListener(new View.OnTouchListener() {  
  7.                 @Override  
  8.                 public boolean onTouch(View v, MotionEvent event) {  
  9.   
  10.                     mOnGesture.onSingleTapUp(event);  
  11.   
  12.                     return false;  
  13.                 }  
  14.             });  
  15.             i++;  
  16.         }  
  17.   
  18.     }  
  19. GestureDetector.OnGestureListener mOnGesture=new GestureDetector.SimpleOnGestureListener(){  
  20.         @Override  
  21.         public boolean onSingleTapUp(MotionEvent e) {  
  22.             Toast.makeText(LinearLayoutActivity.this,"哈哈哈哈,成功触摸了屏幕。。。",Toast.LENGTH_LONG).show();  
  23.             return true;  
  24.         }  
  25.     };  

当前文章价值4.95元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

你可能感兴趣的文章

来源:每日教程每日一例,深入学习实用技术教程,关注公众号TeachCourse
转载请注明出处: https://www.teachcourse.cn/2074.html ,谢谢支持!

资源分享

harmony学习Button组件 harmony学习Button组件
php封装MySQL调用的详细例子 php封装MySQL调用的详细例子
Python实现提取文章关键字 Python实现提取文章关键字
浅谈无序广播和有序广播 浅谈无序广播和有序广播

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情