whao189 发表于 2013-2-3 11:17:15

重写listview(或者定义listview)

之前工作当中虽然做android开发但是细想起来UI 部分还真是接触的少了一些,所以接下来的一段时间决定好好补习UI,这不是今天我在看自定义的 listview(以前也有看过但是没有仔细看)。

那么今天呢,我打算比葫芦画瓢 然后添加我自己的理解 看看大家觉得怎么样?是不是也和我有同样的理解呢?

先来简单的看看关于listview的东西。。。。第一:那就是listview了。。这个东西不用说的

第二:很重要的就是这个东西了。。Adapter 适配器。。。是的,那么到底要怎么用呢?

Adapter下面有三个子类 SimpleAdapter SimpleCursorAdapter ArrayAdapter(SimpleCursorAdapter的父类 CursorAdapter 才是直接继承BaseAdapter的)

那么我们这里提到的自定义Listview用的就是第一个,因为他可扩展性好,你可能会想“难道后面两个就不行了么?” 答案是 肯定的。。。从SimpleCursorAdapter字面上可以看出 “游标适配器” 它主要是用来 包装从数据库查询出来的,而ArrayAdapter则是包装数据 类型的数据的。
稍后你会看到具体的例子。

好吧我们接下来看看具体的例子:
ArrayAdapter

import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.database.Cursor;import android.os.Bundle;import android.provider.Contacts.People;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.SimpleCursorAdapter;public class MainActivity extends Activity {private ListView listView;private ArrayAdapter arrayAdapter;private List<String> list;private Cursor    cursor;private SimpleCursorAdapter cursorAdapter;    @Override    public void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.main);      /****这个东西 是 演示arrayAdapter***/      listView= new ListView(this);      list      = new ArrayList<String>();      list.add("123");      list.add("123");      list.add("123");      arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,list);      listView.setAdapter(arrayAdapter);    }
SimpleCursorAdapter

import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.database.Cursor;import android.os.Bundle;import android.provider.Contacts.People;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.SimpleCursorAdapter;public class MainActivity extends Activity {private ListView listView;private ArrayAdapter arrayAdapter;private List<String> list;private Cursor    cursor;private SimpleCursorAdapter cursorAdapter;    @Override    public void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.main);      listView=new ListView(this);      cursor    = getContentResolver().query(People.CONTENT_URI, null, null, null, null);      //activity开始管理 cursor省去了我们手动管理 cursor         startManagingCursor(cursor);      cursorAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_expandable_list_item_2,cursor,new String[]{People.NAME},new int[]{android.R.id.text1});      listView.setAdapter(cursorAdapter);      }}


这里对于ArrayAdapter 和SimpleCursorAdapter 不做过多的解释。


SimpleAdapter 是我们的重点,因为大多数情况下 我们的需求以上两个Adapter是满足不了的
这个时候我们就需要重新 自定义自己的 ListView了。。

那自定义自己的ListView最主要的就是重写Adapter。我们先看看SimpleAdapter的应用
之后在重写自己的。


import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.ListActivity;import android.os.Bundle;import android.widget.SimpleAdapter;public class MainListActivity extends ListActivity{private SimpleAdapter simpleAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();Map<String,Object> map = new HashMap<String,Object>();map.put("title", "G1");                map.put("info", "google 1");                map.put("img", R.drawable.icon);                list.add(map);simpleAdapter = new SimpleAdapter(this, list, R.layout.main_list_view, new String[]{"title","info","image"}, new int[]{R.id.title,R.id.info,R.id.img});setListAdapter(simpleAdapter);}

可以看到它是按照行来显示的,但是通常我们可能在每一个Item中要做单选radio 或者 复选check等等而且还要为这些按钮添加相应的事件,那么这个时候该怎么办呢?

解决的方法就是自定义Adapter了。。。

下面来看看整个过程:

第一步:我们要创建Acitivyt继承 ListActivity

第二步:创建之后我们要定义自己的数据结构(因为这个地方我们传给SimpleAdapter)这个地方的数据结构格式是这样的List<? extends Map<String,?>> 所以呢这个地方我们一点过要首先产生自己的数据!

第三步:就是要继承BaseAdapter重写Adapter了



import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.AlertDialog;import android.app.ListActivity;import android.content.Context;import android.content.DialogInterface;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;//第一步public class MainListActivtiy2 extends ListActivity{private List<Map<String,Object>> list;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//第二步list = new ArrayList<Map<String,Object>>();Map<String,Object> map = new HashMap<String,Object>();map.put("titile", "标题");map.put("info",   "信息");map.put("image","图片");list.add(map);MyAdapteradapter = new MyAdapter(this);setListAdapter(adapter);}@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {Log.v("MyListView4-click", (String)list.get(position).get("title"));}public void showDialog(){ new AlertDialog.Builder(this)         .setTitle("我的listview")         .setMessage("介绍...")         .setPositiveButton("确定", new DialogInterface.OnClickListener() {             @Override             public void onClick(DialogInterface dialog, int which) {}         })         .show();}//第三步private class MyAdapter extends BaseAdapter{private LayoutInflater layouInflater;public MyAdapter(Context context){layouInflater = LayoutInflater.from(context);}//这个地方时最关键的 你返回的数字是 几 那么listview中就会出现多少个数据(ITEM)@Overridepublic int getCount() {return list.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}//这个地方时最关键的@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if(convertView == null){holder = new ViewHolder();convertView = layouInflater.inflate(R.layout.main_list_view2, null);holder.img= (ImageView)convertView.findViewById(R.id.img);holder.info = (TextView) convertView.findViewById(R.id.info);holder.title= (TextView) convertView.findViewById(R.id.title);holder.btn= (Button) convertView.findViewById(R.id.view_btn);convertView.setTag(holder);}else{holder= (ViewHolder)convertView.getTag();}holder.img.setBackgroundResource((Integer)list.get(position).get("image"));holder.title.setText((String)list.get(position).get("title"));holder.info.setText((String)list.get(position).get("info"));holder.btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showDialog();}});return convertView;}public final class ViewHolder{public ImageView img;          public TextView title;          public TextView info;          public Button   btn;} }

这里我说说自己的理解啊。

为什么要这么做
这个地方时最关键的 你返回的数字是 几 那么listview中就会出现多少个数据(ITEM)@Overridepublic int getCount() {return list.size();}
因为在Adapter中实例化 convertView之后会先调用getcount 方法 因为Adapter 想要知道 你

要返回多少数据在ListView 中显示如果你返回的是0 那么结果可想而知 listview中没有显示,你返回的是2 那就显示出两个(其实仔细想想你会发现 如果你做分页的话不知道能不能从这个地方入手 或者 做 动态地加载也就是 你滚动到listview底部的时候才继续加载)。。。

我觉得应该可以从这个地方入手的。。。

然后我们说说getView 这个方法,这里面的view 都是通过LayoutInflater 动态实例化的

而且是每实例化一次就要调用一次getView 方法(view 里面的数据就是ViewHolder对象)。

好了看到这里估计你也应该明白自定义 ListView 的 过程了。
页: [1]
查看完整版本: 重写listview(或者定义listview)