Android 面试题总结之Android 基础(五)

Android 面试题总结之Android 基础(ListView)(五)

前几篇面试总结中,主要讲了Android 的四大组件的相关知识点,希望在大家日常工作中有所帮助,那么在本节中主要是Android 必不可少的ListView 的相关知识点。Listview 类似的控件 ,不管是在.Net 中 ,还是在Java 中 都是使用非常广泛。正因为他的重要性,内容比较多,所以单独章节的介绍。前两篇文章传送门:
Android 面试题总结之Android 基础(一)
Android 面试题总结之Android 基础(二)

Listview 基础问题

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

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

  2. ListView 如何实现分页加载

    1. 设 置 ListView 的 滚 动 监 听 器 : setOnScrollListener(new OnScrollListener{….})
      在监听器中有两个方法: 滚动状态发生变化的方法 (onScrollStateChanged)和 listView 被滚动时调用的方法(onScroll)
    2. 在滚动状态发生改变的方法中,有三种状态:
      手指按下移动的状态: SCROLL_STATE_TOUCH_SCROLL: // 触摸滑动
      惯性滚动(滑翔(flgin)状态): SCROLL_STATE_FLING: // 滑翔 静止状态:
      SCROLL_STATE_IDLE: // 静止

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

  3. ListView 如何显示多种类型的Item

    ListView 显示的每个条目都是通过 baseAdapter 的 getView(int position, View convertView, ViewGroup parent)来展示的,理 论上我们完全可以让每个条目都是不同类型的 view。
    比如:从服务器拿回一个标识为 id=1,那么当 id=1 的时候,我们就加载类 型一的条目,当 id=2 的时候,加载类型二的条目。常见布局在资讯类客户端中 可以经常看到。
    除此之外 adapter 还提供了 getViewTypeCount()getItemViewType(int position)两个方法。在 getView 方法中我们可以根据不 同的 viewtype 加载不同的布局文件。

  4. ListView 如何定位到指定位置?
    可以通过 ListView 提供的 lv.setSelection(listView.getPosition());方法。

  5. 在ListView中设置Selector为null会报空指针?
    mListView.setSelector(null);//空指针
    试试下面这个:
    mListView.setSelector(new ColorDrawable(Color.TRANSPARENT));

  6. ListView中主要有2种监听器:
    OnItemClickListener: 处理视图中单个条目的点击事件。 (OnItemSelectedListener,参数与其一致,只是监听用户手指行为不同)
    OnScrollListener:监听滚动变化,可以用于视图滚动中加载数据。

  7. ListView中图片错位问题
    每次getView能给对象一个标识,在异步加载完成时比较标识与当前行item的标识是否一致,一致则显示,否则不做处理即可

    
    // 给 ImageView 设置一个 tag
    holder.img.setTag(imgUrl);
    // 预设一个图片
    holder.img.setImageResource(R.drawable.ic_launcher);
    
    // 通过 tag 来防止图片错位
    if (imageView.getTag() != null &&imageView.getTag().equals(imageUrl)) {
    imageView.setImageBitmap(result);
    }
    
  8. ListView中多线程更新问题
    使用Handler负责统一刷新,
    ListView带有进度条的每个Item,多个子线程刷新各自的进度,如果子线程很多那么刷新就会变得很频繁,我们可以由一个Handler负责统一刷新,这样我们就要以增加一些额外条件限制刷新的次数和条件

Android 面试题总结之Android 基础(五)_第1张图片

Listview 优化问题

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

  1. 复用 ConvertView,使用历史的 view,提升效率 200%
  2. 自定义静态类 ViewHolder,减少 findViewById 的次数。提 升效率 50%
  3. 异步加载数据,分页加载数据。
  4. 使用 WeakRefrence 引用 ImageView 对象

    1. 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 卡,然后再加载到内存,这么做的好处是在加载到内存时可以做 个压缩处理,以减少图片所占内存。

    1. ListView实现Item局部刷新?
private void updateView(int itemIndex) {
          //得到第一个可显示控件的位置,
          int visiblePosition = mListView.getFirstVisiblePosition();
          //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新
          if (itemIndex - visiblePosition >= 0) {
              //得到要更新的item的view
            View view = mListView.getChildAt(itemIndex - visiblePosition);
              //调用adapter更新界面
             mAdapter.updateView(view, itemIndex);
        }
     }

具体传送地址:http://www.cnblogs.com/liuling/p/2015-10-20-01.html

Listview 的替代方案

RecyclerView

RecyclerView是一个比ListView更灵活的一个控件,以后可以直接抛弃ListView了,也可以替代Gridview。
RecyclerView改善了ListView的编程接口,他其实是一个ViewGroup ,能配合任何基于adapter的view实现多种布局

更好的实现局部刷新 ,调用notifyItemChanged(position)即可

Listview 原理

首先要理解Listview 三个重要的成员,用MVC思路来理解:
* ListVeiw: 用来展示列表的View (V)
* Adapter : 用来把数据映射到ListView上,(C)
* 数据:item显示的数据(M)

ListView 针对每个item,要求 adapter “返回一个视图” (getView),也就是说ListView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到ListView的长度,然后根据这个长度,调用getView()一行一行的绘制ListView的每一项。如果你的getCount()返回值是0的话,列表一行都不会显示,如果返回1,就只显示一行.如果我们有几千几万甚至更多的item要显示怎么办?为每个Item创建一个新的View?不可能!!!实际上Android早已经缓存了这些视图.

可以通过下图来理解

Android 面试题总结之Android 基础(五)_第2张图片

当要显示一个View就调用一次这个方法。这个方法是ListView性能好坏的关键。方法中有个convertView,这个是Android在 为我们而做的缓存机制。
ListView中每个item都是通过getView返回并显示的,假如item有很多个,那么重复创建这么多对象来显示显然是不合理。因此,Android提供了Recycler,将没有正在显示的item放进RecycleBin,然后在显示新视图时从RecycleBin中复用这个 View。

Recycler可以理解为一个回收池,存放着不同ViewType的convertView。
Recycler的工作原理大致如下

假设屏幕最多能看到11个item,那么当第1个item滚出屏幕,这个item的View进入RecycleBin中,第12个要出现前,通过 getView从回收站(RecycleBin)中重用这个View,然后设置数据,而不必重新创建一个View。

有哪些开源的ListView控件?

这里主要列出几个比较常见的:

  • android-pulltorefresh
    一个强大的拉动刷新开源项目,支持各种控件下拉刷新,ListView、ViewPager、WebView、ExpandableListView、GridView、ScrollView、Horizontal ScrollView、Fragment 上下左右拉动刷新,比下面 johannilsson 那个只支持 ListView 的强大的多。并且它实现的下拉刷新 ListView 在 item 不足一屏情况下也不会显示刷新提示,体验更好。
    Github:https://github.com/chrisbanes/Android-PullToRefresh

  • Android-PullToRefreshRecyclerView
    支持下拉刷新的RecyclerView,同时支持滑动到底部自动加载数据、给RecyclerView添加Header。并且不更改原有RecyclerView的逻辑。
    Github:https://github.com/HomHomLin/Android-PullToRefreshRecyclerView

  • android-pulltorefresh-listview
    下拉刷新 ListView,这个被很多人使用的项目实际有不少 bug
    Github:https://github.com/johannilsson/android-pulltorefresh

  • SwipeListView
    支持定义 ListView 左右滑动事件,支持左右滑动位移,支持定义动画时间
    Github:https://github.com/47deg/android-swipelistview

  • pinned-section-listview
    GroupName 滑动到顶端时会固定不动直到另外一个 GroupName 到达顶端的 ExpandListView
    Github:https://github.com/beworker/pinned-section-listview

等等,比较多,了解几个就行了,看看实现。。。。

到目前为止Listview 相关知识点,就先总结到这。基本可以满足面试要求了。

更多Android 面试题总结,请点击下方图片哦。

水平有限,若有错漏,欢迎指正,批评,如需转载,请注明出处–http://blog.csdn.net/vfush,谢谢!

Android 面试题总结之Android 基础(五)_第3张图片

你可能感兴趣的:(Android,Android,之美)