Adapter的继承

BaseAdapter、SimpleAdapter、ArrayAdapter、SimpleCursorAdapte四大Adapter分析
首先解释一下:
适配器采用MVC模式:所谓的MVC,就是M:model;V:View; C:Controller
MVC模式的使用实现了数据与前端的分离,数据源与试图互不干扰
创建视图适配器的一般步骤:
1、创建承载数据的视图容器
2、创建数据源
3、创建适配器并把数据绑定在适配器
4、将适配器绑定在视图容器`

ArrayAdapter


public class MainActivity extends AppCompatActivity {
    private ListView mlv;
    private ArrayList<String> list;
    private ArrayAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mlv = (ListView) findViewById(R.id.mlv);
        //构造数据源
        list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            list.add("数据源" + i);
        }
        //为适配器添加数据源
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
//为listView的容器添加适配器
        mlv.setAdapter(adapter);
        //设置点击事件mlv
        mlv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this, "你点击的是" + position, Toast.LENGTH_SHORT).show();
            }
        });
//实现长按监听
        mlv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            /*
            * 点击事件的参数
            * 1、parent指定的是适配器AdqpterView绑定的视图容器,也就是Listview;
            * 2、View:Item的适配器对象的view
            * 3、position:Item在数据数组的对应下标所以
            * id:Item所在的行号
            * */
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                list.remove(position);
                //监听数据源的改变
                adapter.notifyDataSetChanged();
                return true;
            }
        });

    }
}`

BaseAdapter

近期很多Android开发者来函表示对ArrayAdapter和BaseAdapter的区别不是很清楚,这里Android123简单说下他们的关系和用处,ArrayAdapter是从BaseAdapter派生出来的,具备BaseAdapter的所有功能,但ArrayAdapter更为强大,它实例化时可以直接使用泛型构造,我们在Android SDK中可以看到android.widget.ArrayAdapter的字样,当然也可以使用ArrayAdapter(Context context, int textViewResourceId) 第二个参数直接绑定一个layout,下文的例子我们使用Java泛型实例化。

  通过Adapter我们构造一个支持icon的item,下面我们在getView中使用的是imageView显示图片,当然android123提示大家其实TextView也可以直接绑定一个drawable对象显示的,void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) 或void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) 和void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) 即可,其中第二种的int类型指定的资源id,方位则是textview什么位置显示drawable对象
  

publicclass MyListViewBase extends Activity {  

    private ListView lv;  
    //定义一个动态数组      
    ArrayList<HashMap<String, Object>>listItem;/** Called when the activity is first created. */  

    @Override  
    publicvoid onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  

        lv = (ListView) findViewById(R.id.lv);  
        MyAdapter mAdapter = new MyAdapter(this);//得到一个MyAdapter对象  
        lv.setAdapter(mAdapter);//为ListView绑定Adapter  
        /**为ListView添加点击事件*/  
        lv.setOnItemClickListener(new OnItemClickListener() {  
            @Override  
            publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {  
                Log.v("MyListViewBase", "你点击了ListView条目" + arg2);//在LogCat中输出信息                  
            }  
        });  
    }  
    /**添加一个得到数据的方法,方便使用*/  
    private ArrayList<HashMap<String, Object>> getDate(){  
        ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String,Object>>();  
        /**为动态数组添加数据*/      
        for(int i=0;i<30;i++)   
         {   
             HashMap<String, Object> map = new HashMap<String, Object>();   
             map.put("ItemTitle", "第"+i+"行");   
             map.put("ItemText", "这是第"+i+"行");   
             listItem.add(map);   
         }  
        return listItem;  
    } 


    /** 新建一个类继承BaseAdapter,实现视图与数据的绑定 
     */  
    privateclass MyAdapter extends BaseAdapter {  
        private LayoutInflater mInflater;//得到一个LayoutInfalter对象用来导入布局   

        /**构造函数*/  
        public MyAdapter(Context context) {  
            this.mInflater = LayoutInflater.from(context);  
        }  

        @Override  
        publicint getCount() {  
            return getDate().size();//返回数组的长度          
        }  

        @Override  
        public Object getItem(int position) {  
            returnnull;  
        }  

        @Override  
        publiclong getItemId(int position) {  
            return 0;  
        }  

        /**书中详细解释该方法*/          
        @Override  
        public View getView(finalint position, View convertView, ViewGroup parent) {  
             ViewHolder holder;  
            //观察convertView随ListView滚动情况              
             Log.v("MyListViewBase", "getView " + position + " " + convertView);  
            if (convertView == null) {  
                     convertView = mInflater.inflate(R.layout.item,null);  
                     holder = new ViewHolder();  
                    /**得到各个控件的对象*/                      
                    holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);  
                    holder.text = (TextView) convertView.findViewById(R.id.ItemText);  
                    holder.bt = (Button) convertView.findViewById(R.id.ItemButton);  
                    convertView.setTag(holder);//绑定ViewHolder对象                     
            }  
            else{  
                    holder = (ViewHolder)convertView.getTag();//取出ViewHolder对象                    
            }  
            /**设置TextView显示的内容,即我们存放在动态数组中的数据*/              
            holder.title.setText(getDate().get(position).get("ItemTitle").toString());  
            holder.text.setText(getDate().get(position).get("ItemText").toString());  

            /**为Button添加点击事件*/               
            holder.bt.setOnClickListener(new OnClickListener() {  
                @Override  
                publicvoid onClick(View v) {  
                    Log.v("MyListViewBase", "你点击了按钮" + position);//打印Button的点击信息                      
                }  
            });  

            return convertView;  
        }  

    }  

    /**存放控件*/  
    publicfinalclass ViewHolder{  
        public TextView title;  
        public TextView text;  
        public Button   bt;  
    }  
}  

扩展该对象需要重写如下4个方法。
getCount() :该方法的返回值控制该 Adapter 将会包含多少个列表项。

    getItem(int position) :该方法的返回值决定第 position 处的列表项的内容。

    getItemId(int position) :该方法的返回值决定第 position 处的列表项的 ID。

    getView(int position, View convertView, ViewGroup parent) :该方法的返回值决定第 position 处的列表项组件。

SimpleAdapter

并不简单、功能强大的 Adapter ,可用于将 List 集合的多个对象包装成多个列表项。可以显示图片和文字,但是不能在 Java 代码中对列表进行后期加工,单纯负责显示。


public class MainActivity extends Activity {
    private String[] names = new String[]{"liuwan", "csdn", "github"};
    private String[] descs = new String[]{"博主", "博客" , "git"};
    private int[] imageIds = new int[]{R.drawable.a, R.drawable.b, R.drawable.c};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 创建一个List集合,List集合的元素是Map
        List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < names.length; i++) {
            Map<String, Object> listItem = new HashMap<String, Object>();
            listItem.put("header", imageIds[i]);
            listItem.put("personName", names[i]);
            listItem.put("desc", descs[i]);
            listItems.add(listItem);
        }
        // 创建一个SimpleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.simple_item,
                new String[]{"personName", "header", "desc"}, new int[]{R.id.name, R.id.header, R.id.desc});
        ListView list = (ListView) findViewById(R.id.list);
        // 为ListView设置Adapter
        list.setAdapter(simpleAdapter);

        // 为ListView的列表项的单击事件绑定事件监听器
        list.setOnItemClickListener(new OnItemClickListener() {
            // 第position项被单击时激发该方法
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            }
        });
        // 为ListView的列表项的选中事件绑定事件监听器
        list.setOnItemSelectedListener(new OnItemSelectedListener() {
            // 第position项被选中时激发该方法
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

    }
}

SimpleCursorAdapter

类SimpleCursorAdapter的继承路线是:
SimpleCursorAdapter->ResourceCursorAdapter->CursorAdapter->BaseAdapter

CursorAdapter代码较多,ResourceCursorAdapter代码较少,SimpleCursorAdapter新增的代码主要是实现数据与View的绑定,涉及到内部类ViewBinder和bindView方法。

packagecom.example.simplecursoradapter;

 2

 3     import android.app.Activity;

 4     import android.content.Intent;

 5     import android.database.Cursor;

 6     import android.database.CursorWrapper;

 7     import android.graphics.Color;

 8     import android.net.Uri;

 9     import android.os.Bundle;

10    importandroid.provider.Contacts.People;

11    importandroid.telephony.PhoneNumberUtils;

12    import android.util.Log;

13    import android.view.View;

14    importandroid.widget.AdapterView;

15    import android.widget.LinearLayout;

16    importandroid.widget.ListAdapter;

17    importandroid.widget.ListView;

18    importandroid.widget.SimpleCursorAdapter;

19

20

21   publicclassMainActivity extendsActivity {

22   privatestatic final StringTAG = "MainActivity";

23   ListViewlistView;

24   ListAdapteradapter;

25

26     @Override

27     publicvoid onCreate(BundlesavedInstanceState) {

28         super.onCreate(savedInstanceState);

29

30         LinearLayout linearLayout =new LinearLayout(this);

31         linearLayout.setOrientation(LinearLayout.VERTICAL);

32

33         LinearLayout.LayoutParams param =newLinearLayout.LayoutParams(

34                 LinearLayout.LayoutParams.FILL_PARENT,

35                 LinearLayout.LayoutParams.WRAP_CONTENT);

36

37         listView = newListView(this);

38         linearLayout.addView(listView, param);

39         this.setContentView(linearLayout);

40

41         // 从数据库获取联系人姓名和电话号码

42         Cursor cur = this.getContentResolver().query(People.CONTENT_URI,null,

43                 null,null, null);

44         adapter = newSimpleCursorAdapter(this,

45                android.R.layout.simple_list_item_2, cur,new String[] {

46                         People.NAME,People.NUMBER },new int[] {

47                         android.R.id.text1,android.R.id.text2 });

48         this.startManagingCursor(cur);

49         listView.setAdapter(adapter);

50

51         listView.setOnItemClickListener(newAdapterView.OnItemClickListener() {

52

53             publicvoid onItemClick(AdapterView<?> arg0, View arg1,

54                     intposition, long arg3){

55

56                 // names=((CursorWrapper)listView.getItemAtPosition(position)).getColumnNames();
57                 // 从指针的封装类中获得选中项的电话号码并拨号

58                 CursorWrapper wrapper = (CursorWrapper) listView

59                         .getItemAtPosition(position);

60                 intcolumnIndex = wrapper.getColumnIndex(People.NUMBER);

61                 if(!wrapper.isNull(columnIndex)) {

62                     String number = wrapper.getString(columnIndex);

63                     Log.d(TAG,"number=" + number);

64                     //判断电话号码的有效性

65                     if (PhoneNumberUtils.isGlobalPhoneNumber(number)) {

66                         Intent intent =new Intent(Intent.ACTION_DIAL,Uri

67                                .parse("tel://" + number));

68                         startActivity(intent);

69                     }

70                 }

71             }

72         });

73     }

74 }

猜你喜欢

转载自blog.csdn.net/qq_41434746/article/details/82533671