控件ListView讲解

控件ListView讲解其实当converView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对…

1.listView是如何提高其效率的?

其实当converView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件。

1)复用ConvertView,使用历史的view,提升效率200%,

2)自定义静态类ViewHolder,减少findViewById的次数。提升效率50%

3)异步加载数据,分页加载数据。

4)使用WeakRefrence引用ImageView对象

2.当ListView数据集改变后,如何更新ListView?

使用该ListView的adapter的notifyDataSetChanger()方法。该方法会使ListView重新绘制。

3.ListView如何实现分页加载?

1)设置ListView的滚动监听器:setOnScrollListener(new OnScrollListener{})

在监听器中有两个方法:滚动状态发生变化的方法(onScrollStateChanged)和listView被滚动时调用的方法onScroll

2)在滚动状态发生改变的方法中,有三种状态:手指按下移动的状态:SCROLL_STATE_TOUCH_SCROLL://触摸滑动 惯性滚动(滑翔(flgin)状态):SCROLL_STATEFLING//滑翔状态

静止状态:SCROLL_STATE_IDLE:静止

分批加载数据,只关心静止状态;关心最后一个可见的条目,如果最后一个可见条目就是数据适配器(集合)里的最后一个,此时可加载更多的数据。在每次加载的时候,计算出滚动的数量,当滚动的数量大于等于总数量的时候,可以提示用户无更多数据了。

4.ListView可以显示多种类型的条目吗

这个当天可以的,listView显示的每个条目都是通过baseAdapter的getView(int position,View convertView ,ViewGroup parent)来展示的,理论上我们完全可以让每个条目都是不同类型的view。

比如:从服务器拿回一个标识为id=1,那么当id=1的时候,我们就加载类型一的条目,当id=2的时候,加载类型二的条目,常见布局在资讯类客户端中可以经常看到。

除此之外adapter还提供了getViewTypeCount()和getItemViewType(int position)两个方法。在getView方法中我们可以根据不同viewtype加载不同的布局文件。

5.listView 如何定位到指定位置

可以通过listview提供的lv.setSelection(View.getPosition());方法。

6.如何在ScrollView中如何嵌入ListView

通常情况下我们不会在ScrollView中嵌套ListView,在ScrollView添加一个Listview会导致listview控件显示不全,通常只会显示一条,这是因为两个控件的滚动事件冲突导致。所以需要通过listview中的item数量去计算listview的显示高度,从而使其完整展示,如下提供一个方法供大家参考:

     lv =(ListView)findViewById(R.id.lv);
     adapter =new MyAdapter();
     lv.setAdapter(adapter);
     setListViewHeightBasedOnChildren(lv);
     
     public  void  setListViewHeightBasedOnChildren(ListView listview){
     ListAdapter listAdapter =listView.getAdapter();
     if(listAdapter ==null){
          return;
     }
       int  totalHeight =0;
       for (int i=0;i<listAdapter.getCount();i++){
       View  listItem =listAdapter.getView(i,null,listView);
       listItem.measure(0,0);
       totalHeight+=listItem.getMeasuredHeight();
       
       }
       ViewGroup.LayoutParams params =listView.getLayoutParams();
       params.height =totalHeight+(listView.getDividerHeight())*(listAdapter.getCount()-1);
       params.height+=5;
       
       listView.setLayoutParams(params);
       
       
       }
       
     
     
     }
     

现阶段最好的处理的方式是:自定义ListView,重载onMeasure()方法,设置全部显示。

 package com.meiya.ui;

 import.android.widget.ListView;

 /** *scrollview中嵌套listview的简单实现 * ScrolViewwithListView.java */

public class ScrollViewwithListView extends ListView{
   
   public ScrollViewWithListView(android.content.Context context, 
  android.util.AttributeSet attrs) {
 super(context, attrs);
 }
 
 /** ** Integer.MAX_VALUE>>2.如果不设置,系统默认设置是显示两条 */

  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
  int  expandSpec =MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
  super.onMeasure(widthMeasureSpec,expandSpec);
  
  
  }

 }
 
 

7.ListView 中如何优化图片

图片的优化策略比较多。

1).处理图片的方式:

如果ListView中自定义的Item中有涉及到大量图片的,一定要对图片进行细心的处理,因为图片占的内存是ListView项中最头疼的,处理图片的方法大致有以下几种:

(1.不要直接拿路径就去循环BitmapFactory.decodeFile;使用Options保存图片大小,不要加载图片到内存去。

(2.对图片一定要经过边界压缩尤其是比较大的图片,如果你的图片是后台服务器处理好的那就不需要了

(3.在ListView中取图片时也不要直接拿个路径去取图片,而是以WeakReference(使用WeakReference代替强引用。比如可以使用WeakReference mContextRef),SoftReference,WeakHashMap等的来存储图片信息。

(4.在getView中做图片转换时,产生的中间变量一定及时释放

2.异步加载图片基本思想:

(1.先从内存缓存中获取图片显示(内存缓冲)

(2.获取不到的话从sd卡里获取(sd卡缓冲)

(3.都获取不到的话从网络下载图片并保存到sd卡同时加入内存并显示(视情况看是否要显示)

原理:

优化一:先从内存中加载,没有则开启线程从sd卡或网络中获取,这里注意从sd卡获取图片是放在子线程里执行的,否则快速滑屏的话会不够流畅。

优化二:于此同时,在adapter里有个busy变量,表示listview是否处于滑动状态,如果是滑动状态则仅从内存中获取图片,没有的话无需再开启线程去外存或网络获取图片。

优化三:ImageLoader里的线程使用了线程池,从而避免了过多的线程频繁创建和销毁,如果每次总是new 一个线程去执行这是非常不可取的,好一点的用AsyncTask类,其实内部也是用到了线程池。在从网络获取图片时,先是将其保存到sd卡,然后在加载到内存,这么做的好处是在加载到内存时可以做个压缩处理,以减少图片所占内存。

8listview中图片错位的问题是如何产生的

图片错位问题的本质源于我们的listview使用了缓存convertview,假设一种场景,一个listview一屏显示九个item,那么在拉出第十个item的时候,事实上该item是重复使用了第一个item,也就是说在第一个item从网络中下载图片并最终要在显示的时候,其实该item已经不再当前显示区域内了,此时显示的后果将可能在第十个item上输出图像,这就导致了图片错位的问题。所以解决之道在于可见则显示,不可见则不显示。

9.如何刷新listview中单个item的数据,不刷新整个listview的数据?

修改单个item的数据,然后调用适配器的notifyDataSetChanged()方法

今天的文章控件ListView讲解分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18940.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注