这一周,也就是第二周,的重点在于ListView这下视图。
我把创建一个ListView的Activity的过程当看成一个布置一个教室的过程。
ListView本身是一个容器,也就可以把它看成是婚空的教室,里面什么也没有。同样,在这个教室会利用xml负责外观布置,由Java负责教室里面的学生(也就是数据)的进进出出的活动流程安排。
通常一个空教室是要装修一下,放进桌子椅子才能让学生和老师正常使用的,所以在这个时候校长就决定把装修和布置的工作交给专门的人负责,也就由Adapter来完成。
关于ListView本身的代码并不是很多,首先是在包含有ListView布局的layout中加入一个ListView控件:
<ListView
android:background="@color/colorDarker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fake_wechat_about"
/>
以上是我在作业中所用到设置ListView控件的代码,其实和普通的Button控件并没有什么太大的区别,第一行设置一下ListView的背景色,接下来是高度与宽度,最后再加入一个id,方便后续的使用。
在Java文件夹下的Activity的文件中,也是通过类似于Button一样的使用方法,通过id将ListView找到:
//在函数外声明一个全局的ListView对象mListView
private ListView mListView;
//在函数内部通过findView函数将xml中定义的ListView布局
//与mListView对象连接起来,并划分内存空间给此对象
mListView = (ListView) findView(R.id.name_listview_about);
到此,一个空的教室就被分配出来了,接下来就是要做教室内部布置的工作。
之前提到过的Adapter是负责装饰教室的总工程师。他需要在Java文件夹中另外定义,并且他是继承了家族事业,所以还需要继承他的父类BaseAdapter。在Java文件夹下新建一个AboutAdapter类:
public class AboutAdapter extends BaseAdapter{
...
}
刚创建好的Adapter类是会看到AS报错的,其原因是因为Adapter继承了父类的接口,也就像是继承了家族事业的规矩,装修时必须完成的几个要点,所以我们可以在AS的Code一栏中有一个Generate,快捷键是ctrl+n或者command+n,然后选择Implement Methods…这一项来看看父辈们到底要求下一代完成什么样的动作。
public class AboutAdapter extends BaseAdapter{
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
以上四个方法就是Adapter要做的最为基本的四个动作,也可以说是必须完成的四件事情。
getCount() 顾名思义就是要计数,计算一个教室中需要多少排桌椅。
getItem(int position) 是要确定某一个位置后,读取这个这一个位置上的数据,这个过程可以想像成,Adapter知道以后某一个位置上会坐哪一个学生,所以他通过位置,就能得知学生的信息或者了解他的情况。(可能有点牵强)
getItemId(int position)的作用博主还是不太理解,只知道返回一个position,有待进一步学习。
getView(int position, View convertView, ViewGroup parent)则是这个类的重点,其中包括要请一个叫Inflater的木匠师傅来根据图纸(另一个xml文件)来制作桌椅的过程。
以下就是在作业中写到的代码:
public class AboutAdapter extends BaseAdapter {
//声名类内的私有成员变量
private List<String> mListItem;
private Context mContext;
private LayoutInflater mLayoutInflater;
//重写构造器(构造函数)
//目的是为了在外部使用的时候要传入一个上下文,以及一个列表对象
public AboutAdapter(Context context, List<String> stringArrayList) {
mContext = context;
mListItem = stringArrayList;
//以下是请出木匠
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mListItem.size();
}
@Override
public Object getItem(int position) {
return mListItem.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//下面的list_view_item_mid是在layout文件夹中的一个新的布局文件
//它是对ListView中Item的样式进行设计,然后通过Inflater类的功能
//将其转化成一整套控件组
//就像一个木匠用自己的手艺按图纸打造桌椅
if(convertView == null){
convertView = mLayoutInflater.inflate(R.layout.list_view_item_mid,null);
}
//下面出现的list_item_text是上面提到的“图纸”xml文件中一个文字控件
//在此是外部传过来的列表文件中的数据一一利用文字控件显示出来
TextView textViewItem = (TextView) convertView.findViewById(R.id.list_item_text);
textViewItem.setText(mListItem.get(position));
return convertView;
}
}
以上就是Adapter的基本功能和实现,现在所有的装修工作已经规划好了,校长同意以后就可以把它实施起来。首先校长理出一份学生的名单(ArrayList),然后找到这个装修公司(new 一个AboutAdapter(…)),并委派他们完成这间教室(ListVeiw的对象)的装修任务(setAdapter(…))。
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private List<String> mItemString;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建一个学生的名单
mItemString = new ArrayList<>();
mItemString.add("小明");
mItemString.add("小张");
mItemString.add("小刘");
mItemString.add("小虎");
mItemString.add("小文");
mItemString.add("小米");
//下面出现的name_listview_about是layout文件夹中的activity布局中的ListView控件的id
mListView = (ListView) findViewById(R.id.name_listview_about);
AboutAdapter aboutAdapter = new AboutAdapter(MainActivity.this, mItemString);
//记住最后一定要set这个Adapter
mListView.setAdapter(aboutAdapter);
}
}