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

作者:张亚波 时间:2021-12-25 16:31:07 

最近交流群里面有人问到一个问题:如何在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直接实现,也可以由其成员变量来实现。

原文链接:http://blog.csdn.net/u011895534/article/details/50439547

标签:Activity,ListView
0
投稿

猜你喜欢

  • MyBatis一二级缓存

    2021-07-03 13:01:59
  • Java查找并高亮PDF文本过程解析

    2022-02-17 07:20:32
  • Java异步调用转同步方法实例详解

    2023-11-01 20:38:25
  • 详解Java中final的用法

    2022-09-22 10:20:32
  • springboot使用自定义注解实现aop切面日志

    2023-11-11 09:14:48
  • Java 基础语法中的逻辑控制

    2022-11-22 16:30:59
  • 怎样使用PowerMockito 测试静态方法

    2022-06-18 08:28:59
  • JAVA实现LRU算法的参考示例

    2022-01-26 21:56:49
  • Quartz与Spring集成的两种方法示例

    2022-05-22 05:15:41
  • Java map存放数组并取出值代码详解

    2023-06-27 23:32:18
  • Java关键字详解之final static this super的用法

    2022-01-19 09:24:39
  • Android ProgressDialog使用总结

    2023-07-10 22:16:33
  • Spring 4.0新功能:@Conditional注解详细介绍

    2022-01-19 06:37:35
  • C#中跨线程访问控件问题解决方案分享

    2021-06-27 18:47:24
  • Java中使用Lambda表达式和函数编程示例

    2022-05-06 03:30:40
  • Javaweb El表达式实例详解

    2021-06-21 22:59:32
  • 短网址的原理与生成方法(Java实现)

    2022-04-14 11:29:19
  • java理论基础Stream管道流状态与并行操作

    2021-08-31 14:24:07
  • Java使用线程同步解决线程安全问题详解

    2022-02-28 02:03:24
  • Java接口DAO模式代码原理及应用详解

    2023-06-21 05:29:04
  • asp之家 软件编程 m.aspxhome.com