在Activity中响应ListView内部按钮的点击事件的两种方法

来源:互联网 发布:面向连接的网络协议 编辑:程序博客网 时间:2024/06/08 05:45

http://blog.csdn.net/u011895534/article/details/50439547

最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在Adapter中响应?

对于这个问题,我最初给他的解答是,在Adapter中定义一个回调接口,在Activity中实现该接口,从而实现对点击事件的响应。

下班后思考了一下,觉得有两种方式都能比较好的实现:使用接口回调和使用抽象类回调

正好可以复习一下接口和抽象类的区别,于是写了两个Demo:

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 Callback mCallback;                /**          * 自定义接口,用于回调按钮点击事件到Activity          * @author Ivan Xu          * 2014-11-26          */          public interface Callback {              public void click(View v);          }                public ContentAdapter(Context context, List<String> contentList,                  Callback callback) {              mContentList = contentList;              mInflater = LayoutInflater.from(context);              mCallback = callback;          }                @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) {              mCallback.click(v);          }      }  
Activity类:


    package com.ivan.listvieweventdemo;            import java.util.ArrayList;      import java.util.List;            import android.app.Activity;      import android.os.Bundle;      import android.view.Menu;      import android.view.View;      import android.widget.AdapterView;      import android.widget.AdapterView.OnItemClickListener;      import android.widget.ListView;      import android.widget.Toast;            import com.ivan.adapter.ContentAdapter;      import com.ivan.adapter.ContentAdapter.Callback;      import com.ivan.listvieweventcallback.R;      //MainActivity需要实现自定义接口      public class MainActivity extends Activity implements OnItemClickListener,              Callback {                // 模拟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));              mListView.setOnItemClickListener(this);          }                @Override          public boolean onCreateOptionsMenu(Menu menu) {              getMenuInflater().inflate(R.menu.main, menu);              return true;          }                /**          * 响应ListView中item的点击事件          */          @Override          public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {              Toast.makeText(this, "listview的item被点击了!,点击的位置是-->" + position,                      Toast.LENGTH_SHORT).show();          }                /**          * 接口方法,响应ListView按钮点击事件          */          @Override          public void click(View v) {              Toast.makeText(                      MainActivity.this,                      "listview的内部的按钮被点击了!,位置是-->" + (Integer) v.getTag() + ",内容是-->"                              + contentList.get((Integer) v.getTag()),                      Toast.LENGTH_SHORT).show();          }      }  

2.使用抽象类回调

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.listvieweventabstract.R;    public class ContentAdapter extends BaseAdapter {        private static final String TAG = "ContentAdapter";      private List<String> mContentList;      private LayoutInflater mInflater;      private MyClickListener mListener;        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(mListener);          holder.button.setTag(position);          return convertView;      }        public class ViewHolder {          public TextView textView;          public Button button;      }        /**      * 用于回调的抽象类      * @author Ivan Xu      * 2014-11-26      */      public static abstract class MyClickListener implements OnClickListener {          /**          * 基类的onClick方法          */          @Override          public void onClick(View v) {              myOnClick((Integer) v.getTag(), v);          }          public abstract void myOnClick(int position, View v);      }  

Activity类:

    package com.ivan.listvieweventdemo;            import java.util.ArrayList;      import java.util.List;            import android.app.Activity;      import android.os.Bundle;      import android.view.Menu;      import android.view.View;      import android.widget.AdapterView;      import android.widget.AdapterView.OnItemClickListener;      import android.widget.ListView;      import android.widget.Toast;            import com.ivan.adapter.ContentAdapter;      import com.ivan.adapter.ContentAdapter.MyClickListener;      import com.ivan.listvieweventabstract.R;            public class MainActivity extends Activity implements OnItemClickListener {                // 模拟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]);              }              //实例化ContentAdapter类,并传入实现类              mListView.setAdapter(new ContentAdapter(this, contentList, mListener));                            mListView.setOnItemClickListener(this);          }                @Override          public boolean onCreateOptionsMenu(Menu menu) {              getMenuInflater().inflate(R.menu.main, menu);              return true;          }                //响应item点击事件          @Override          public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {              Toast.makeText(this, "listview的item被点击了!,点击的位置是-->" + position,                      Toast.LENGTH_SHORT).show();          }                /**          * 实现类,响应按钮点击事件          */          private MyClickListener mListener = new MyClickListener() {              @Override              public void myOnClick(int position, View v) {                  Toast.makeText(                          MainActivity.this,                          "listview的内部的按钮被点击了!,位置是-->" + position + ",内容是-->"                                  + contentList.get(position), Toast.LENGTH_SHORT)                          .show();              }          };      }  

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

0 0