public class MainActivity extends AppCompatActivity {
private List<Animal> mData = null;
private Context mContext;
private AnimalAdapter mAdapter = null;
private ListView list_animal;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
list_animal = (ListView) findViewById(R.id.list_animal);
mData = new LinkedList<Animal>();
mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog));
mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow));
mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck));
mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish));
mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse));
mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext);
list_animal.setAdapter(mAdapter);
自定义BaseAdapter以及完成数据绑定就是这么简单~
我们从代码 中可以看出比较重要的两个方法:getCount()和getView(),界面上有多少列就会调用多少次getView, 这个时候可能看出一些端倪,每次都是新inflate一个View,都要进行这个XML的解析,这样会 很浪费资源,当然,几十列或者几百列的列表并不能体现什么问题,但假如更多或者布局更加复杂? 所以学习ListView的优化很重要,而本节针对的是BaseAdapter的优化,优化的两点有,复用convertView 以及使用ViewHolder重用组件,不用每次都findViewById。
上面也说了,界面上有多少个Item,那么getView方法就会被调用多少次! 我们来看看上一节我们写的getView()部分的代码:
<span style="font-size:14px;">@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
img_icon.setBackgroundResource(mData.get(position).getaIcon());
txt_aName.setText(mData.get(position).getaName());
txt_aSpeak.setText(mData.get(position).getaSpeak());
return convertView;
}</span>
是吧,inflate()每次都要加载一次xml,其实这个convertView是系统提供给我们的可供服用的View 的缓存对象,那就坐下判断咯,修改下,优化后的代码:
<span style="font-size:14px;">@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
img_icon.setBackgroundResource(mData.get(position).getaIcon());
txt_aName.setText(mData.get(position).getaName());
txt_aSpeak.setText(mData.get(position).getaSpeak());
return convertView;
}</span>
2.ViewHolder重用组件
嘿嘿,getView()会被调用多次,那么findViewById不一样得调用多次,而我们的ListView的Item 一般都是一样的布局,我们可以对这里在优化下,我们可以自己定义一个ViewHolder类来对这一部分 进行性能优化!修改后的代码如下:
<span style="font-size:14px;">@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
holder = new ViewHolder();
holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
holder.txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
holder.txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
convertView.setTag(holder); //将Holder存储到convertView中
}else{
holder = (ViewHolder) convertView.getTag();
holder.img_icon.setBackgroundResource(mData.get(position).getaIcon());
holder.txt_aName.setText(mData.get(position).getaName());
holder.txt_aSpeak.setText(mData.get(position).getaSpeak());
return convertView;
static class ViewHolder{
ImageView img_icon;
TextView txt_aName;
TextView txt_aSpeak;
}</span>
3.分批加载,滑动的时候不加载图片
上面的两个例子中ListView都是显示的本地的List集合中的内容,List的长度也只有100个,我们可以毫不费力一次性加载完这100个数据;但是实际应用中,我们往往会需要使用Listview来显示网络上的内容,比如说我们拿使用ListView显示新闻为例:
其一:假如网络情况很好,我们使用的手机也许能够一下子加载完所有新闻数据,然后显示在ListView中,用户可能感觉还好,假如说在网络不太顺畅的情况下,用户加载完所有网络的数据,可能这个list是1000条新闻,那么用户可能需要面对一个空白的Activity好几分钟,这个显然是不合适的
其二:我们知道Android虚拟机给每个应用分配的运行时内存是一定的,一般性能不太好的机器只有16M,好一点的可能也就是64M的样子,假如说我们现在要浏览的新闻总数为一万条,即便是网络很好的情况下,我们可以很快的加载完毕,但是多数情况下也会出现内存溢出从而导致应用崩溃的情况。
那么为了解决上面的两个问题,我们需要进行分批加载,比如说1000条新闻的List集合,我们一次加载20条,等到用户翻页到底部的时候,我们再添加下面的20条到List中,再使用Adapter刷新ListView,这样用户一次只需要等待20条数据的传输时间,不需要一次等待好几分钟把数据都加载完再在ListView上显示。其次这样也可以缓解很多条新闻一次加载进行产生OOM应用崩溃的情况。
实际上,分批加载也不能完全解决问题,因为虽然我们在分批中一次只增加20条数据到List集合中,然后再刷新到ListView中去,假如有10万条数据,如果我们顺利读到最后这个List集合中还是会累积海量条数的数据,还是可能会造成OOM的情况,这时候我们就需要用到分页,比如说我们将这10万条数据分为1000页,每一页100条数据,每一页加载时都覆盖掉上一页中List集合中的内容,然后每一页内再使用分批加载,这样用户的体验就会相对好一些。
一、Adapter首先我们来看看他的继承结构图:上面就是Adapter以及继承结构图了,接着我们介绍一下实际开发中还用到的几个Adapter吧!BaseAdapter:抽象类,实际开发中我们会继承这个类并且重写相关方法,用得最多的一个Adapter!ArrayAdapter:支持泛型操作,最简单的一个Adapter,只能展现一行文字~SimpleAdapter:
ArrayAdapter<T> 适合非常简单的数据显示,很方便,很简单。
SimpleAdapter 可以自定义Item布局,用于显示交简单的布局及控件,但布局内的控件如按钮等无法获取到焦点,当然也就无法获取到他们的点击事件。
SimpleCursorAdapter 与SimpleAdapter相似,只是他的数据源是Cursor类型而已。
BaseAdpter子类 最常用的ListView数据适配器,通过继承BaseAdpter可以较灵活的实现数据的绑定,同时通过使用View
Android的ListView(列表视图)和Adapter(是配器)实例
Android中有些控件或者View需要用Adapter(适配器)来显示到具体的activity;Adapter是用来帮助填充数据的中间桥梁,另外Adapter需要结合ListView,GridView来使用。这里我们以ListView作为示范。
Adapter作为所有适配器类的父类,下面我就找两个我比较常用的Adapter子类介绍一下吧。
1、 ArrayAdapter 这是最简单的一种Adapter,支持泛型操作,只能展现一行文
android ListView组件使用实在是太频繁了,因此特意制作了Android ListView的详细使用教程,还有和listview配套使用的BaseAdapter以及ArrayAdapter都会在文章后面有讲到,非常的实用。
为了便于理解下面listview的使用方法,我想先让你看下本人的android项目的目录结构是很有必要的,如图。
案例一:首先我们用ListView
ListView的Adapter优化在安卓开发中ListView的使用频率可谓非常之高,差不多所有的数组,集合类的数据展示都会使用到ListView,对于现在的大数据时代,展示的数据很庞大,所以对Adapter的优化显得尤为重要简介有这么一句话,“世上本没有所谓的优化,只有时空变化”
时间换空间
时间换时间
空间换时间
控件换空间
在我们的算法中就经常遇见这种情况,如果降低算法的时间复杂度,那势必会
PS:listview中有一些简单使用的适配器,如:SimpleAdapter:构造方法SimpleAdapter(Context context,List data,reString [] from,int [] to),但这种适配器过于单调,往往不能达到用户想要的效果,想要随心所欲,就用到了BaseAdapter,自定义适配器。
1、首先写布局文件
activity_layout.xml
<?xml version=1.0 encoding=utf-8?>
<LinearLayout xmlns:android=http://sch
v = getIntVolatile(o, offset);
} while (!compareAndSwapInt(o, offset, v, v + delta));
return v;
[/code]
从上面的源码可以看到,在执行 CAS 之前先获取 offset 位置的值
多线程死锁的产生以及如何避免死锁
Jaf932074323:
Java中CAS详解
qq_34251598: