android listView

第一次写博客,希望大家喜欢

先来简单的创建撒~然后再慢慢优化,发出来供大家交流经验,嘿嘿


先说说listview的原理撒

其实listview 可以看做一个框架子,他有一个整体的框框,还有一个一个的行,

就像这样(图是我自己画的。。。不知道这样理解够不够完善,但是写代码的时候就是这个思路了)


1、首先创建项目咯~


2、在activity_main.xml中拖入ListView的组件(组件在composite中)

刚加进去的代码是这样的

1
2
3
4
5
6
7
<ListView
android:id= "@+id/listView1"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_alignParentLeft= "true"
android:layout_alignParentTop= "true"  >
</ListView>

一定要注意将layout_height的值改为match_parent,否则在运行时会出现跳行的情况(具体原因是:在activity加载ListView的时候,如果ListView的高度为适应内容,那么每次加载行的时候都会重新运算一遍,所以如果打日志的话 会发现 原本只有6行的显示,却打了好多行日志)


3、在layout里面新建个行布局(布局就随便了,我一般用RelativeLayout,如果是只需要一个文本的话,只用一个TextView 也是可以的)

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version= "1.0"  encoding= "utf-8" ?>
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width= "match_parent"
android:layout_height= "match_parent"  >
<TextView
android:id= "@+id/textView1"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentLeft= "true"
android:layout_alignParentTop= "true"
android:text= "Large Text"
android:textAppearance= "?android:attr/textAppearanceLarge"  />
</RelativeLayout>

也可以直接这样的

1
2
3
4
5
6
7
8
9
<TextView
android:id= "@+id/textView1"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentLeft= "true"
android:layout_alignParentTop= "true"
android:text= "Large Text"
android:textAppearance= "?android:attr/textAppearanceLarge"  >
</TextView>


ok  UI(布局文件) 这样就可以了 简单的来么


现在来看代码

在MainActivity.java中的onCreate方法中加入先读取layout中的listview

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
42
43
44
45
@Override
protected  void  onCreate(Bundle savedInstanceState)
{
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView1); //读取listView的
BaseAdapter adapter =  new  BaseAdapter() //创建一个适配器,这是一个内部类了
{
@Override
public  View getView( int  position, View convertView, ViewGroup parent)
{
/*
* getView 加载每一行的时候系统会自动调用这个方法,所以要在这个方法中创建当前行样式
* 主要参数:1、position:当前行的id
*   2、convertView:当listview滑动式缓存消失的行布局
*   3、parent:The parent that this view will eventually be attached to
* (额这是官方解释了。。。sorry~ 没用过具体怎么样我也不太清楚)
*/
//开始创建行,
LayoutInflater inflater = getLayoutInflater();
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.list_item,  null );
//以上两行代码 获取每行的布局
//有了layout就可以获取当前行的组件了,组件拿到了,也就可以设置该组件的值了
TextView textView = (TextView) layout.findViewById(R.id.textView1);
textView.setText( "title" +position); //前面有说过position是代表当前行的id 从零开始计数
return  layout; //一定要记得将创建好的行布局 返回给 系统,不然 你讲神马都看不到了
}
@Override
public  long getItemId( int  position) //这个方法还有getItem()方法 我都没有用过,具体什么效果                                       //大家可以试试撒
{
return  0 ;
}
@Override
public  Object  getItem( int  position)
{
return  null ;
}
@Override
public  int  getCount() //设置要创建多少行
{
return  10 ; //表示要创建10行
}
};
listView.setAdapter(adapter); //将创建的适配器(adapter)放到listview中
}

这样就ok了 一个简单的listview 就搞好了,可以在模拟器上运行下试试撒~


但是这样的代码还是有很多问题的,你可以在getView中打印下日志,输出创建的layout,你就会发现竟然每一行的layout都是新的,这样的话很消耗系统资源,(10行可能太少了,多搞点,在拖动的时候 就会发现了,写多少行,就给你高多少个layout)


所以android官方 推荐用convertView+ViewHolder的方式来提高性能,这样系统只会创建当前页显示数量+1个layout,就可以是layout复用,其他的行都只用创建好的layout就可以了

优化代码如下:


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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class  ViewHolder{ //ViewHolder自己创建就好了,这是内部类,因为当前类只要MainActivity使用就好了,所以不需要新建一个class文件了
TextView mTextView; //官方的源代码中,成员变量就是这样写的
//(前面加个m这样只要看到他就知道这个变量是成员变量了,后面名字随便)
}
@Override
protected  void  onCreate(Bundle savedInstanceState)
{
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView1); //读取listView的
BaseAdapter adapter =  new  BaseAdapter() //创建一个适配器,这是一个内部类了
{
@Override
public  View getView( int  position, View convertView, ViewGroup parent)
{
/*
* getView 加载每一行的时候系统会自动调用这个方法,所以要在这个方法中创建当前行样式
* 主要参数:1、position:当前行的id
*   2、convertView:是一个缓存,存取listview滑动时缓存最先消失的那个行布局,
* 后面显示的行就可以复用这个convertView了,这样就可以达到复用的效果,节省资源
*
*   3、parent:The parent that this view will eventually be attached to
* (额这是官方解释了。。。sorry~ 没用过具体怎么样我也不知道)
*/
//开始创建行,
RelativeLayout layout =  null ;
ViewHolder holder =  null ;
if (convertView ==  null ){ //当缓存为空是 创建layout
LayoutInflater inflater = getLayoutInflater();
layout = (RelativeLayout) inflater.inflate(R.layout.list_item,  null );
//以上两行代码 获取每行的布局
holder =  new  ViewHolder(); //创建holder;
holder.mTextView = (TextView) layout.findViewById(R.id.textView1); //讲获取到的行组件放入holder中
/*这里存在一个问题 layout是两个东西怎样将 layout和holder联系在一起呢?
*不用担心,View类提供了一个方法,setTag(Object obj);
*这个方法可以将holder像一个物品一样放入一个叫Tag 的袋子里
*这样就可以 复用 行布局和布局中的组件了
**/
layout.setTag(holder);
} else { //有缓存时 就直接将缓存中的convertView给layout就好了
layout = (RelativeLayout) convertView;
holder = (ViewHolder) layout.getTag();
}
//更新组件内容
holder.mTextView.setText( "title" +position); //前面有说过position是代表当前行的id 从零开始计数
return  layout; //一定要记得将创建好的行布局 返回给 系统,不然 你讲神马都看不到了
}
@Override
public  long getItemId( int  position)
{
return  0 ;
}
@Override
public  Object  getItem( int  position)
{
return  null ;
}
@Override
public  int  getCount() //设置要创建多少行
{
return  10 ; //表示要创建10行
}
};
listView.setAdapter(adapter); //将创建的适配器(adapter)放到listview中
}

呵呵 优化好啦,这时候可以试试在打日志看看,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windy_yzh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值