Activity中响应Adapter的点击回调事件

作者: NapleC | 来源:发表于2016-05-30 18:04 被阅读4967次

    假设一个场景,在ListView的Item中,点击"+"按钮加入该item的商品到购物车中.给予的解决方案是: 在Adapter中定义一个回调接口,在Activity中实现该接口,从而实现对点击事件的响应。
    这个比较简单,我先直接上代码,稍后会稍微说下一些注意事项。

    1.首先是Adapter中的代码:
    package com.ivan.adapter;
    
    import java.util.List;
    
    import android.content.Context;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.ivan.listvieweventcallback.R;
    
    public class ContentAdapter extends BaseAdapter implements  OnClickListener {
    
      private static final String TAG = "ContentAdapter";
      private List<String> mContentList;
      private LayoutInflater mInflater;
      private MyClickListener mListener;
    
      //自定义接口,用于回调按钮点击事件到Activity
      public interface MyClickListener{
          public void clickListener(View v);
      }
    
      public ContentAdapter(Context context, List<String> contentList,
              MyClickListener listener) {
          mContentList = contentList;
          mInflater = LayoutInflater.from(context);
          mListener = listener;
      }
    
      @Override
      public int getCount() {
          Log.i(TAG, "getCount");
          return mContentList.size();
      }
    
      @Override
      public Object getItem(int position) {
          Log.i(TAG, "getItem");
          return mContentList.get(position);
      }
    
      @Override
      public long getItemId(int position) {
          Log.i(TAG, "getItemId");
          return position;
      }
    
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          Log.i(TAG, "getView");
          ViewHolder holder = null;
          if (convertView == null) {
              convertView = mInflater.inflate(R.layout.list_item, null);
              holder = new ViewHolder();
              holder.textView = (TextView) convertView
                    .findViewById(R.id.textView1);
              holder.button = (Button) convertView.findViewById(R.id.button1);
              convertView.setTag(holder);
          } else {
              holder = (ViewHolder) convertView.getTag();
          }
          holder.textView.setText(mContentList.get(position));
    
          holder.button.setOnClickListener(this);
          holder.button.setTag(position);
          return convertView;
      }
    
      public class ViewHolder {
          public TextView textView;
          public Button button;
      }
    
      //响应按钮点击事件,调用子定义接口,并传入View
      @Override
       public void onClick(View v) {
          mListener.clickListener(v);
      }
    }
    
    2.然后是Acitvity中的代码:
    package com.naple.listvieweventdemo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ListView;
    import android.widget.Toast;
    
    import com.ivan.adapter.ContentAdapter;
    import com.ivan.adapter.ContentAdapter.MyClickListener;
    import com.ivan.listvieweventcallback.R;
    //MainActivity需要实现自定义接口
    public class MainActivity extends Activity implements MyClickListener {
    
      // 模拟listview中加载的数据
      private static final String[] CONTENTS = { "北京", "上海", "广州", "深圳", "安徽",
            "福州", "黄冈", "长沙", "杭州" };
      private List<String> contentList;
      private ListView mListView;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
      }
    
      private void init() {
          mListView = (ListView) findViewById(R.id.listview);
          contentList = new ArrayList<String>();
          for (int i = 0; i < CONTENTS.length; i++) {
              contentList.add(CONTENTS[i]);
          }
          //
          mListView.setAdapter(new ContentAdapter(this, contentList, this));
      }
    
      /**
       * 接口方法,响应ListView按钮点击事件
       */
      @Override
      public void clickListener(View v) {
          // 点击之后的操作在这里写
          Toast.makeText(
                  MainActivity.this,
                  "listview的内部的按钮被点击了!,位置是-->" + (Integer) v.getTag() + ",内容是-->"
                          + contentList.get((Integer) v.getTag()),
                  Toast.LENGTH_SHORT).show();
      }
    }
    

    实现的步骤(以下代码片段都可以在上面的代码中找到):

    • Adpater中:
    1. 实现(implements) OnClickListener 方法
      public class ContentAdapter extends BaseAdapter implements OnClickListener
    2. 自定义接口(MyClickListener),用于回调按钮点击事件到Activity
      private MyClickListener mListener; //自定义接口,用于回调按钮点击事件到 Activity public interface MyClickListener{ public void click(View v); }
    3. 有参的构造方法
      public ContentAdapter(Context context, List<String> contentList, MyClickListener listener) {
      mContentList = contentList;
      mInflater = LayoutInflater.from(context);
      mListener = listener;
      }
    4. 在实现的 void onClick(View v) 方法 中调用子定义接口,传入View
      public void onClick(View v) { mListener.click(v); }
    5. 最后 控件增加点击事件
      button.setOnClickListener(this);
    6. 记住 一定要setTag不然会报空指针
      button.setTag(position);
    • Activity中
    1. 实现自定义的接口(implements) MyClickListener 方法
      public class MainActivity extends Activity implements MyClickListener
    2. 实例化ContentAdapter类,并传入实现类
      new ContentAdapter(this, contentList, this)
    3. 在实现的自定义接口的 void clickListener(View v) 方法
      public void clickListener(View v) { // 点击控件要实现的操作在这里写 }

    这种方法是使用接口实现的回调。


    还有一种是使用抽象类回调
    该方法需要自己在adapter中写一个用于回调的抽象类

    public static abstract class MyClickListener implements View.OnClickListener {    
         //基类的onClick方法   
         @Override    
         public void onClick(View v) {        
             myOnClick((Integer) v.getTag(), v);    
         }    
         public abstract void myOnClick(int position, View v);
    }
    

    然后
    在activity中实现

    //实现类,响应按钮点击事件
    private MyClickListener mListener = new MyClickListener() {
        @Override
        public void myOnClick(int position, View v) {
        } 
    };
    

    其他的和接口回调一样使用
    Tips:两种方式的区别在于,抽象类在Activity中实现的时候,只能定义一个成员变量来实现,不能由Activity直接实现,因为Java不支持多继承。而接口既可以由Activity直接实现,也可以由其成员变量来实现。

    相关文章

      网友评论

      本文标题:Activity中响应Adapter的点击回调事件

      本文链接:https://www.haomeiwen.com/subject/qnfcdttx.html