关于Android Adapter(适配器),参考Devin Zhang’s blog。简单的说,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
|
public class MainActivity extends Activity{
private List<fruit> myFruits = new ArrayList<fruit>();//将数据定义为实例
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initialFruits(); setContentView(R.layout.activity_main);//与R.layout.activity_main布局绑定 ListView lv = (ListView) findViewById(R.id.lv); fruitAdapter adapter = new fruitAdapter(MainActivity.this,R.layout.list_item,myFruits);//fruitAdpter的三个参数依次为,上下文context,ListView单项布局文件,集合类型的数据 lv.setAdapter(adapter);//用adapter做适配器(就理解为ListView看得懂并且存放有数据的容器) } //初始化实例变量myFruits private void initialFruits(){ fruit orange = new fruit("orange",R.drawable.pa); myFruits.add(orange); fruit grape = new fruit("grape",R.drawable.pb); myFruits.add(grape); fruit milk = new fruit("milk",R.drawable.pc); myFruits.add(milk); fruit bean = new fruit("bean",R.drawable.pd); myFruits.add(bean); fruit kid = new fruit("kid",R.drawable.pe); myFruits.add(kid); fruit banana = new fruit("banana",R.drawable.pf); myFruits.add(banana); fruit lamp = new fruit("lamp",R.drawable.pg); myFruits.add(lamp); fruit hack = new fruit("hack",R.drawable.ph); myFruits.add(hack); fruit keyboard = new fruit("keyboard",R.drawable.pi); myFruits.add(keyboard); fruit water = new fruit("water",R.drawable.pj); myFruits.add(water); fruit mouse = new fruit("mouse",R.drawable.pk); myFruits.add(mouse); fruit ear = new fruit("ear",R.drawable.pl); myFruits.add(ear); } }
|
关于fruitAdapter
类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public class fruitAdapter extends ArrayAdapter<fruit>{
private int resourceId; //textViewResourceId即为传入的ListView的单项布局文件id public fruitAdapter(Context context,int textViewResourceId, List<fruit> objects) { super(context, textViewResourceId, objects); //adapter对象的resourceId实例变量保存ListView的单项布局文件id,以供getView()使用 resourceId = textViewResourceId; }
//在每个子项被滚动到屏幕内的时候调用getView() @Override public View getView(int position, View convertView, ViewGroup parent) { fruit newFruit = getItem(position); View view = LayoutInflater.from(getContext()).inflate(resourceId,null); ImageView imageView = (ImageView) view.findViewById(R.id.fruit_image); TextView textView = (TextView) view.findViewById(R.id.fruit_name); imageView.setImageResource(newFruit.getId()); textView.setText(newFruit.getName()); return view; } }
|
对于getView(),《第一行代码》中给出的解释是“在每个子项被滚动到屏幕内的时候会被调用”。这句话的另一层意思是:凡是ListView中可见的子项,均调用了getView()
方法。事实上也只能如此,因为在构造函数中并未告诉ListView如何呈现样式。也因此呢,整个ListView的过程是:创建Adapter(需调用构造函数)->特定的ListView指定该Adapter->在屏幕需要显示子项时调用getView()
接着附上fruit
类的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public class fruit { private String name; private int pic_id;
public fruit(String fname,int id){ this.name = fname; this.pic_id = id; }
public String getName(){ return name; }
public int getId(){ return pic_id; } }
|
最后就出现了这样的ListView
界面
界面
这样看来图片的大小得事先选好,图片越大,速度越慢
滑动的时候确实会卡顿,优化如下:
getView()的convertView用于缓存加载好的布局,不至于每次有子项滑入屏幕内都要加载一次布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//在每个子项被滚动到屏幕内的时候调用getView() @Override public View getView(int position, View convertView, ViewGroup parent) { View view; ViewHolder viewHolder; fruit myFruit = getItem(position); if(convertView == null){ viewHolder = new ViewHolder(); view = LayoutInflater.from(getContext()).inflate(resourceId,null); viewHolder.imageView = (ImageView) view.findViewById(R.id.fruit_image); viewHolder.textView = (TextView) view.findViewById(R.id.fruit_name); view.setTag(viewHolder); } else{ view = convertView; viewHolder = (ViewHolder) view.getTag(); } viewHolder.imageView.setImageResource(myFruit.getId()); viewHolder.textView.setText(myFruit.getName()); return view; }
|
从优化ListView过程中,看出至始至终都是使用第一次加载好的view,索性在view里面再加上存有控件实例的viewHolder
写子项->适配器->item->mainActivity(传数据)