Android 适配器委托模式

来源:互联网 发布:java反序列化漏洞原理 编辑:程序博客网 时间:2024/05/17 04:00

Github
问题:
通常,在使用适配器,控件的点击事件的处理会写到适配器来处理;
如果需要显示一个电话号码的列表,这个列表的每行有两个不同的点击控件,
一个用于从列表中删除电话号码.一个用于拨打电话,你会把点击处理方法放到什么位置呢?
下面通过委托模式来解决上述问题,该模式会帮助开发者把业务逻辑从适配器中转移到Activitity中.
下面我们创建一个应用,可以向列表中添加电话号码,列表中每一行都有一个删除按钮,用来执行删除点击事件.
思路很简单:
在适配器中实现删除按钮的点击事件监听,但是,点击后删除对象的代码,通过一个委托接口调用Activity中的方法来删除对象.
首先,创建适配器:
NumbersAdapter.java

import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.TextView;public class NumbersAdapter extends ArrayAdapter<Integer> {  public static interface NumbersAdapterDelegate {//定义委托接口    void removeItem(Integer value);  }  private LayoutInflater mInflator;  private NumbersAdapterDelegate mDelegate;  public NumbersAdapter(Context context, List<Integer> objects) {    super(context, 0, objects);    mInflator = LayoutInflater.from(context);  }  @Override  public View getView(int position, View cv, ViewGroup parent) {    if (null == cv) {      cv = mInflator.inflate(R.layout.number_row, parent, false);    }    final Integer value = getItem(position);    TextView tv = (TextView) cv.findViewById(R.id.numbers_row_text);    tv.setText(value.toString());    View button = cv.findViewById(R.id.numbers_row_button);    button.setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        if (null != mDelegate) {          mDelegate.removeItem(value);//删除对象        }      }    });    return cv;  }  public void setDelegate(NumbersAdapterDelegate delegate) {//设置委托对象    mDelegate = delegate;  }}

MainAcitvity.java代码:

import java.util.ArrayList;import com.manning.androidhacks.hack027.NumbersAdapter.NumbersAdapterDelegate;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.EditText;import android.widget.ListView;import android.widget.Toast;public class MainActivity extends Activity implements    NumbersAdapterDelegate {  private static final String TAG = MainActivity.class      .getCanonicalName();  private ListView mListView;  private ArrayList<Integer> mNumbers;  private NumbersAdapter mAdapter;  private EditText mEditText;  @Override  public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    mEditText = (EditText) findViewById(R.id.main_edittext);    mListView = (ListView) findViewById(R.id.main_listview);    mNumbers = new ArrayList<Integer>();    mAdapter = new NumbersAdapter(this, mNumbers);    mListView.setAdapter(mAdapter);  }  @Override  protected void onResume() {    super.onResume();    mAdapter.setDelegate(this);//注册委托对象  }  @Override  protected void onPause() {    super.onPause();    mAdapter.setDelegate(null);//取消委托对象  }  @Override  public void removeItem(Integer value) {//在Activity中执行移除操作,并通知适配器更新数据    mNumbers.remove(value);    Toast        .makeText(this, "Removed object: " + value, Toast.LENGTH_SHORT)        .show();    mAdapter.notifyDataSetChanged();  }  public void addNumber(View v) {    String value = mEditText.getText().toString().trim();    try {      mNumbers.add(Integer.valueOf(value));      mEditText.setText("");      mAdapter.notifyDataSetChanged();    } catch (NumberFormatException e) {      Log.e(TAG, "Couldn't convert to integer the string: " + value);    }  }}
1 0