注:本文为阅读郭霖先生的《第一行代码 Android》之后个人臆想,叙述不足之处可前往郭霖大牛的博客学习,此处仅为个人方便长久学习、记忆。
ListView的应用
ListView的使用主要分为分为以下几步
一、确定ListView的子项布局内容
二、为ListView构造适配器
三、实现ListView
接下来是各步骤的个人见解。
一、确定ListView中的子项布局内容
java中的List列表里面的每一个子项可以是一个对象,而一个对象可以包含多个属性;类比可知ListView中的每个子项布局内容其实就相当于List中的一个对象,确定其内容相当于确定一个对象应当具备那些属性,只不过这些布局属性是Button、TextView之类的控件,通过控件来展示你想要表达的信息。
在这一步中,你需要设计一个类来对应一个子项布局,类的每一个属性对应子项布局中的每一个控件,用属性存放控件中要展示的信息。第三步实现ListView时获取一个该类的对象列表,传入适配器,再进一步将对象中的数据加载到ListView内。
二、为ListView构造适配器
java中最原生的适配器类为ArrayAdaper<T>,如果我们的子项布局内容超过一项,我们同就得自己重新设计一个适配器,原生的适配器只能为子项只包含一个控件属性的ListView适配内容。
而构造适配器也是ListView成为难用控件的最主要原因(个人认为)。
我从郭霖大牛的书中学来的构造适配器的过程如下,
- 自定义一个构造器继承自ArrayAdaper<T>(此处的T位第一步中你构造的类)
- 设置一个int属性,用于记录传入的子项布局文件的id,这里记为sub_id
- 编写构造函数,参数有三个,类型分别为Context、int、List<T>(此处T与1中同,以下T皆同),其中Context为程序执行上下文对象,int 为子项布局文件的id,List为第一大步骤中所述的对象列表。构造函数比较简单,只包含两行,第一行是调用super即父类ArrayAdaper中的构造函数,将当前构造函数传入的参数在super中重传一遍即可;第二行代码就是将传入的int值赋给第2步中设置的属性,构造函数就这样完成了
- 重写getView方法,这是初学者使用ListView整个过程中我认为最困难的部分。getView方法返回一个View对象,即一个子项布局。参数同样有三个,类型分别为int position、View convertView、ViewGroup parent,作用如下:int值(position)作为函数getItem方法的实参获取一个T型实例,这个T型实例将作为数据的承载体将数据填入每一个子项布局,然后加载到ListView中;另外两个参数只是个人的一些猜测,这里就不详述。在方法体内获取一个T型实例后,接下来就是将实例内容加载到子项布局中。这里构造一个View型对象view,通过LayoutInflate.from(getConext()).inflate(sub_id,parent,false)方法实例化;接下来的数据加载过程比较简单,只在代码中展示。
三、实现ListView
这一步逻辑相对比较简单,首先构造T型对象列表,然后new一个适配器对象并实例化,最后通过ListView对象的setAdapter方法将适配器作为实参传入即可实现ListView的应用。接下来是ListView的实战使用:
第一步,确定子项布局内容然后是设置对应的类:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/contacter_image" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerInside"/> <TextView android:id="@+id/contact_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:textColor="@color/colorPrimaryDark" android:textSize="15dp"/> </LinearLayout>
第二步:构造适配器public class Contacter { protected String name; protected int image_id; public Contacter(String name, int image_id) { this.name = name; this.image_id = image_id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getImage_id() { return image_id; } public void setImage_id(int image_id) { this.image_id = image_id; }
第三步:实现ListViewpublic class SecondListViewAdapter extends ArrayAdapter<Contacter> { //记录传入的子项布局的id private int sub_listview_id; //自定义的适配器的构造函数 public SecondListViewAdapter(Context context, int listview_item_id, List<Contacter> contacterList){ super(context,listview_item_id,contacterList); sub_listview_id=listview_item_id; } /*重写getView方法,该方法当每个子项被滚动到屏幕内时调用,该方法内通过getItem方法得到当前的 * Contacter实例,然后使用LayoutInflater来为这个子项加在传入的布局。 */ @Override public View getView(int position, View convertView, ViewGroup parent){ //获取T型实例 Contacter contacter=getItem(position); View view= LayoutInflater.from(getContext()).inflate(sub_listview_id,parent,false); //实体化申请的子项控件,以便加载数据 ImageView con_ima=(ImageView)view.findViewById(R.id.contacter_image); TextView con_name=(TextView)view.findViewById(R.id.contact_name); //加载数据 con_ima.setImageResource(contacter.getImage_id()); con_name.setText(contacter.getName()); return view; } }
public class SecondActivity extends AppCompatActivity { private List<Contacter> contacterList=new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.secondlayout); Contacter c; try { /*以下是通过java反射获取本地图片并封装将图片名和图片id封装为Contacter对象最后添加到 *contacterList中 */ R.drawable d = new R.drawable(); for (int i = 1; i <= 10; i++) { String ima_name="christmas_lable_0" + i; Field fieldimgId = d.getClass().getDeclaredField(ima_name); int imgId = (Integer) fieldimgId.get(d);//这个ID就是每个图片资源ID c=new Contacter(ima_name,imgId); //TODO contacterList.add(c); } } catch (Exception e) { e.printStackTrace(); } //创建适配器对象 SecondListViewAdapter adapter=new SecondListViewAdapter(SecondActivity.this,R.layout.sub_listview,contacterList); ListView listView=(ListView)findViewById(R.id.listview_contacts); //为设置适配器listView对象,完成ListView和数据之间的关联 listView.setAdapter(adapter); } }
接下来运行程序应该就可以看到一个列表,里面有图片还有图片的名字。
好了,ListView的使用到此结束,希望我的表述你能看明白。 第一次写这玩意,手都冻僵了,也算给自己留点记忆,希望以后自己再也不用翻书了。觉得不明白的朋友可以前往郭霖大佬(http://blog.csdn.net/sinyu890807/)处搜索更好的解答吧,或者相信我的话可以评论区留言,我会尽力为你解答的。