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

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

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

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

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

1.使用接口回调:

Adapter类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

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类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

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类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

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类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

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

猜你喜欢

转载自blog.csdn.net/weixin_42602900/article/details/125144198