详解Android中回调机制与RecyclerView的Item点击事件实现

总是看书上写着回调回调,以为就是函数调用换了个名字,尤其是看了Button的点击事件实现后,觉得不就是触发机制。
A事件发生->后台处理逻辑->告诉前台怎么做->结束。

Android常见button点击事件:


  loginBtn = (Button) findViewById(R.id.login_button);
  loginBtn.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        Toast.makeText(TestButtonActivity.this, "login", Toast.LENGTH_SHORT).show();


      }
    });
但其实回调不是这样的,完全不是!
这里由于使用了匿名内部类,机制是不很清晰,下面我们换成Activity实现接口的方式。
public class MainActivity extends Activity implements OnClickListener {

    private Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(this);
    }
  
  
  //用Activity实现OnClickListener接口
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        Log.i("用Activity实现OnClickListener接口", "点击事件");
        }

}
Button类继承自View类,View类处理点击事件。但是它并不具体指定如何处理,而是给出了接口OnClickListener规范
首先,Acticity这个类中持有Button类实例bt的引用,调用他的setOnClickListener()方法(实际还是View类的),传入了参数this,也就是这个Activity本身,希望View类处理点击事件。
然后,View类接受了请求,并利用传入的Activity类的引用,使用Avtivity类的 onClick()方法处理点击事件

这就是回调
就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法

这里D就是:
 public void onClick(View v) {
        // TODO Auto-generated method stub
        Log.i("用Activity实现OnClickListener接口", "点击事件");
        }
/** 
 * 这个View就相当于B类 
 * 
 */  
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {  
 /** 
     * Call this view's OnClickListener, if it is defined. 
     * 
     * @return True there was an assigned OnClickListener that was called, false 
     *         otherwise is returned. 
     */  
    public boolean performClick() {  
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);  

        if (mOnClickListener != null) {  
            playSoundEffect(SoundEffectConstants.CLICK);  

            //B类(View类)调用A类Activity中click方法  
            mOnClickListener.onClick(this);  
            return true;  
        }  

        return false;  
    }  
}  
打印:Log.i(“用Activity实现OnClickListener接口”, “点击事件”);
也附上一个讲的很好的回调机制博客:回调机制

—————————————————————————————————————————————————————-

下面结合RecyclerView的点击事件实现实例,回顾一下。
RecyclerView是ListView的替代方案,十分的灵活,相比于ListView.难过的是它并没有像ListView一样提供setOnItemClickListener方法。他的点击事件都是由其中的viewholder中的view控件单独注册的,这样的好处是,如果再想实现某个列表项中的某个图标就十分简洁,不像以前ListView中那样麻烦。比如下面中的小三角播放按钮点击事件

列表

但是这时候问题来了,我们想实现原来那样的整个列表项的点击事件怎么办?如:

这里写图片描述

要知道,现在点击事件都是在Adapter中由View自己注册的。如:
 @Override
    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
      View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.category_item,parent,false);
       final ViewHolder holder=new ViewHolder(view);
        holder.cateImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position=holder.getAdapterPosition();
             CateGory   categoryItem=mCateGoryList.get(position);
                Toast.makeText(view.getContext(),"you click view"+categoryItem.getName(),Toast.LENGTH_SHORT).show();//工厂方法


            }
        });


        return holder;
    }
我们的思路是,每个列表项整个的点击事件就是ViewHolder被点击,所以让他自己注册自己的点击事件就好了。
首先,让ViewHolder实现View类的接口,能够处理自己的点击事件。
class ViewHolder extends  RecyclerView.ViewHolder implements View.OnClickListener {
        ImageView cateImage;
        TextView cateText;


        public ViewHolder(View view){
            super(view);
            cateImage= (ImageView) view.findViewById(R.id.cate_image);
            cateText= (TextView) view.findViewById(R.id.cate_name);
            view.setOnClickListener(this);

        }
        @Override
        public void onClick(View v) {
            if (clickListener != null) {
                clickListener.onClick(getAdapterPosition());

            }
        }
    }
注意这已经是一层回调了。在ViewHolder和View之间的回调,clickListener是下面这个接口的实例,因为我们还需要一层回调。
在RecyclerView中定义好接口规范:
 public static interface OnItemClickListener {
        void onClick(int position);
    }
再然后,我们希望在Activity中定义具体的处理逻辑,所以要把cliListener让外部实现,用方法暴露出去。
 private OnItemClickListener clickListener;

    public void setClickListener(OnItemClickListener clickListener) {
        this.clickListener = clickListener;
    }
在Activity的onCreate中实现:
 adapter.setClickListener(new CateGoryAdapter.OnItemClickListener() {

            @Override
            public void onClick( int position) {
                Toast.makeText(MainActivity.this,position+"",Toast.LENGTH_SHORT).show();
            }
        });
这里又是一层回调。在Activity和adapter之间。
写的不对的地方请告诉我谢谢!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值