ps:代码都是简洁形式的,比如
public class MainActivity extends Activity {
}
我就是直接写成
Activity {
}
如有问题请多包涵。
一般我们做ListView的核心就是做适配器adapter,而适配器里存放的无非就是资源和样式
直接在Activity{}里写一个自定义的类MyAdapter ,然后继承BaseAdapter,这时候会报错,按alt+回车,OK添加一些方法,即可出现以下一堆东西
Activity {
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
}
}
然后在适配器里写构造函数,当new MyAdapter() 的时候,需要传入当前的上下文,后续用于加载子项布局,按Ctrl键+F键观察mInflater的操作
MyAdapter {
private LayoutInflater mInflater = null;
private MyAdapter (Context context)
{
//根据context上下文加载布局,这里的是Activity本身,即this
this.mInflater = LayoutInflater.from(context);
}
}
然后其他几个函数就这么写
MyAdapter {
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return getItem(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
最复杂的getView后面介绍,前面讲一讲做getView需要哪些准备步骤,首先需要有一个数据集合,比如下文的data,这个是自己做的数据集合,使用了List< Map< String, Object>>,一种看起来非常复杂,但是一旦用过爱不释手的数据存储方式,将每种类型的值存入数组,然后将数组按照key循环存入map,说的比较复杂,直接看代码,然后在草稿纸上画一画可能清楚一点
Activity {
private int[] images;
private String[] names;
private String[] status;
private String[] colors;
private List<Map<String, Object>> data;
private void initData(){
images =new int[]{
R.drawable.clothes_normal_img,
R.drawable.clothes_normal_img,
R.drawable.clothes_off_img,
R.drawable.clothes_off_img};
names=new String[]{"衣服5671","衣服2235","衣服3059","衣服9074"};
status=new String[]{
"连接状态:连接 状态:开 使用时长",
"连接状态:连接 状态:开 使用时长",
"连接状态:未连接 状态:关 使用时长",
"连接状态:未连接 状态:关 使用时长"};
colors=new String[]{"#70b789","#70b789","#888888","#888888"};
data = new ArrayList<Map<String, Object>>();
Map<String, Object> map;
for(int i = 0; i< images.length; i++)
{
map = new HashMap<String, Object>();
map.put("img", images[i]);
map.put("name", names[i]);
map.put("status", status[i]);
map.put("color",colors[i]);
data.add(map);
}
}
}
就是将图片,名称,状态,颜色这些一股脑放入map中,然后将map放入data中,List集合就相当于一个从0开始自增长的泛类型数组,map则是键值对,< String, Object>可以存各种类型的值,非常强大!
定义一个类用来存放需要修改的资源类型,比如我需要修改的有一个图片和两个文字
Activity{
static class ViewHolder
{
public ImageView img;
public TextView title;
public TextView info;
}
}//Activity
适配器的一个重点就是getView,它在每个子项显示的时候调用,我们刚刚定义的ViewHolder类里面有我们需要的所有类型,所以在getView中定义一个该类对象,并让它去匹配布局中的控件,Ctrl键+F键关注convertView的去向
Activity{
MyAdapter{
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
//如果缓存convertView为空,则需要创建View
if(convertView == null)
{
holder = new ViewHolder();
//根据自定义的Item布局加载布局
convertView = mInflater.inflate(R.layout.listview_item_layout, null);
holder.img = (ImageView)convertView.findViewById(R.id.clothes_img);
holder.title = (TextView)convertView.findViewById(R.id.item_title);
holder.info = (TextView)convertView.findViewById(R.id.item_info);
//将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
convertView.setTag(holder);
}else
{
holder = (ViewHolder)convertView.getTag();
}
}//getView
}//MyAdapter
}//Activity
上面有一个listview_item_layout是自定义的子项布局,通过inflate加载这个布局,然后后面的那些控件对象才能找到相应的控件,其实这一步就相当于定义了adapter的样式
其实很多时候麻烦的不是写代码,而是调布局细节,虽然我这没什么东西,但是还是调了很久
为了简洁,就不把每个属性都写出来了,需要的时候慢慢调,百度怎么居中,左右距离之类的
<LinearLayout
android:id="@+id/li2ll">
<LinearLayout
>
<ImageView
android:src="@drawable/clothes_normal_img"
android:id="@+id/clothes_img"/>
</LinearLayout>
<LinearLayout
>
<TextView
android:id="@+id/item_title"/>
<LinearLayout
>
<TextView
android:id="@+id/item_info"
android:text="连接状态:连接 状态:开 使用时长"/>
<ImageView
android:src="@drawable/edit_device_img"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
出来效果就这样
上面的图片也是美工提供的,还有版式,其实我一直觉得美工才是最牛逼的,或者说图形设计,要是让我自己来想样式根本想不到
getView的最后一步就是给每个控件对象设置资源,注意刚刚我们定义了data,我说做adapter无非就是样式和资源,样式已经通过上面定好了,这次把资源都放进去
Activity{
MyAdapter{
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//因为position已经把位置选好,取时直接到data中取即可,第二个get就是取map中的值
holder.img.setImageResource((Integer) data.get(position).get("img"));
holder.title.setText((String)data.get(position).get("name"));
holder.info.setText((String)data.get(position).get("status"));
holder.info.setTextColor(Color.parseColor ((String)data.get(position).get("color")));
return convertView;
}//getView
}//MyAdapter
}//Activity
getView相当于单片机中的底层中断函数,只不过是中断条件为,【某个item显示在屏幕中】
此时getView被执行,立刻进去寻找相关的控件,组织样式,放入资源,然后返回给调用它的函数,显示出来。
好了经过上面一系列操作适配器做好了以后,就把他放到listview里面去
Activity{
private ListView mListView;
private MyAdapter adapter;
onCreate() {
mListView =findViewById(R.id.list_view);
adapter=new MyAdapter(this);
mListView.setAdapter(adapter);
}
}
至于list_view也是非常简单,就一个列表一行字
<LinearLayout
>
<TextView
android:text="设备列表"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#d8d8d8"/>
<ListView
android:id="@+id/list_view"
>
</ListView>
</LinearLayout>
同样只列一些简单的属性方便查看
运行即可显示
其实listview对我来说是比较难的,这次探索也是费了很多劲,记下来希望下次用的时候能快速回忆起来。