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

来源:互联网 发布:ip2780清零软件 编辑:程序博客网 时间:2024/06/05 19:34

总是看书上写着回调回调,以为就是函数调用换了个名字,尤其是看了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之间。

写的不对的地方请告诉我谢谢!

0 0
原创粉丝点击