之AbsListView

Posted zhangjiaofa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了之AbsListView相关的知识,希望对你有一定的参考价值。

android Widget源码分析系列文章之AbsListView

AbsListView的源码剖析

这是一个基本的类,可以被用来实现虚拟化的列表。一个列表没有一个空间的定义在这里。例如,这个类的子类展示了列表的内容以九宫格、旋转木马或者是堆栈。

继承的类

AdapterView

实现的接口

  1. TextWatcher ,监听字符的变化
  2. ViewTreeObserver.OnGlobalLayoutListener,OnGlobalLayoutListener 是ViewTreeObserver的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver监听到,这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知。ViewTreeObserver不能直接实例化,而是通过getViewTreeObserver()获得。
  3. Filter.FilterListener,用一个过滤的模式,约束输入的字符的内容,内部的函数是通知过滤操作的结束。
  4. ViewTreeObserver.OnTouchModeChangeListener,注册一个观察者来监听视图树,当视图树的布局、视图树的焦点、视图树将要绘制、视图树滚动等发生改变时,ViewTreeObserver都会收到通知,ViewTreeObserver不能被实例化,可以调用View.getViewTreeObserver()来获得。
  5. RemoteViewAdapter.RemoteAdapterConnectionCallback,一个接口针对RemoteAdapter 去通知其他的类当这个Adapters被真正的连接到他们真实的服务,或者是真实的解除连接。

相关的成员变量

逐一的对这个类中的定义的成员变量进行定义,基本意思以及功能作用。

  1. TRANSCRIPT_MODE_DISABLED, 这是一个public类型修饰的常量。表面的意思是禁止文字记录的模式,实际上的意思是不允许自动滚动到用户指定的位置。
  2. TRANSCRIPT_MODE_NORMAL,这是public类型修饰的常量。这个列表将会自动滚动到底部,当一个数据集合改变的通知被收到,并且只有这个最后一个条目在屏幕上是真实可见的时候。
  3. TRANSCRIPT_MODE_ALWAYS_SCROLL,这是public类型修饰的常量。这个列表将会自动滚动到底部,不论当前屏幕上可见的条目是什么。
  4. TOUCH_MODE_REST,预测我们并不是处于手指触摸的中间。
  5. TOUCH_MODE_DONE_WAITING,预测我们已经等待每一件我们能够等待的事情。但是这个用户的手指始终是出于按下的状态。
  6. TOUCH_MODE_SCROLL,预测用户的手指是处于滚动的状态。
  7. TOUCH_MODE_FLING,预测当前的视图是处于被翻动的状态。
  8. TOUCH_MODE_OVERSCROLL,预测这个手势是过度的滚动,是一种滚动超过了开始或者是结束。
  9. TOUCH_MODE_OVERFLING,达到了边缘,并且绘制回弹的效果。
  10. LAYOUT_NORMAL,普通的布局,经常一个来自于视图系统的没有请求的布局。
  11. LAYOUT_FORCE_TOP,显示第一个条目。
  12. LAYOUT_SET_SELECTION ,强制选中的条目到屏幕指定的位置。
  13. LAYOUT_FORCE_BOTTOM,显示最后一个条目。
  14. LAYOUT_SPECIFIC,创建一个选中的条目,呈现在一个指定的位置,并且构建这个视图的剩余的部分从这里开始。这个顶部是被特殊的指定。
  15. LAYOUT_SYNC,布局与数据的改变同步发生了变化,恢复同步的位置,去让他的顶部在他指定的位置。
  16. LAYOUT_MOVE_SELECTION,布局作为使用航海的钥匙的结果。
  17. CHOICE_MODE_NONE,普通的列表,没有预测的选择。
  18. CHOICE_MODE_SINGLE,列表支持一个选择。
  19. CHOICE_MODE_MULTIPLE,列表支持多个选择。
  20. CHOICE_MODE_MULTIPLE_MODAL,这个列表支持多个选择在一个模态的选择模式。
  21. mOwnerThread,对应的是视图被创建的线程。
  22. mChoiceMode,控制是否/怎样这个用户也许选择/检测在列表中的条目。
  23. mCheckedItemCount,当前有多少列表的条目被选中。
  24. mDrawSelectorOnTop,预测是否这个列表的选择器应该绘制在子节点顶部还是底部。
  25. mSelector,图片用来绘制选择器。
  26. mSelectorPosition,当前被选中的条目在列表中的位置。
  27. mRecycler,这个数据集合用来存储没有被使用的视图,这些视图在接下来的布局中可能被用到,避免创建新的视图的对象。
  28. mVelocityTracker,决定了滚动的速度。
  29. mScrollingCacheEnabled,当设置位true, 这个列表将会自动丢弃子视图的缓存,当滚动的时候。
  30. mSmoothScrollbarEnabled,判断是基于像素的滚动,还是基于条目的滚动。
  31. mFastScroll,帮助类的对象绘制和控制快速滚动的滑块。

内部定义的接口

OnScrollListener

  1. SCROLL_STATE_IDLE,视图当前处于静止的状态。
  2. SCROLL_STATE_TOUCH_SCROLL,用户通过触摸滚动视图,并且用户当前的手指还是处于屏幕上。
  3. SCROLL_STATE_FLING,用户之前已经通过触摸,操作了一次滑动,当前处于滑动状态,即将停止。
  4. onScrollStateChanged,回调方法将会被触发,当列表视图或者是九宫格的视图被滚动。这个方法将会被调用当滚动的视图的下一个数据帧将会被绘制。
  5. onScroll,当滚动行为结束后被调用。

SelectionBoundsAdjuster

  1. adjustListItemSelectionBounds,允许列表的条目去调整他被选中的矩形的边界。

构造函数

  1. initAbsListView, 初始化列表的相关的组件。
  2. mOwnerThread = Thread.currentThread(),创建当前UI操作所在的线程。
  3. setVerticalScrollBarEnabled(true),设置允许显示垂直的滚动条。
  4. initializeScrollbarsInternal,初始化垂直的滚动条的内部的业务逻辑。

成员函数

initAbsListView

  1. 代码片段
        // Setting focusable in touch mode will set the focusable property to true
        setClickable(true);
        setFocusableInTouchMode(true);
        setWillNotDraw(false);
        setAlwaysDrawnWithCacheEnabled(false);
        setScrollingCacheEnabled(true);

        final ViewConfiguration configuration = ViewConfiguration.get(mContext);
        mTouchSlop = configuration.getScaledTouchSlop();
        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        mOverscrollDistance = configuration.getScaledOverscrollDistance();
        mOverflingDistance = configuration.getScaledOverflingDistance();

        mDensityScale = getContext().getResources().getDisplayMetrics().density;
  1. setClickable(true),设置当前的UI是可以被点击的
  2. setFocusableInTouchMode(true),设置当前的UI在触摸的模式下是可以获取焦点的。
  3. setWillNotDraw,如果这个View控件在他自己的内部没有做任何的绘制,设置这个标志位允许以后的优化。
  4. setAlwaysDrawnWithCacheEnabled,预测是否这个ViewGroup是否将会总是尝试绘制它的子节点使用它们自己的缓存。这个属性可以被设置位true,当这个缓存的渲染略微不同于子节点的正常的渲染。渲染是可以不同的,比如,当这个缓存的品质被设置为低。当设置属性是被禁用,这个ViewGroup将会使用它的子节点的绘制的缓存,仅仅当被询问的时候。这个是它的子类的任务去告诉ViewGroup什么时候开始使用这个绘制的缓存,以及什么时候停止使用。
  5. 剩下的几个属性的初始化,包括触摸的阈值、最小以及最大的速度、滑动的最大的区间以及分辨率的初始化。

setOverScrollMode

在这个函数中,判断是否允许用户滑动超过边界,这也就决定了mEdgeGlowTop以及mEdgeGlowBottom是否进行初始化。

performItemClick

contentFits

返回true,如果列表的内容当前完全是在视图的边界内。

setFastScrollAlwaysVisible

设置是否这个快速的缓动应该被展示,而不是标准的滑动块。这将决定了是否允许使用快速滑动。

if (isOwnerThread()) 
                setFastScrollerAlwaysVisibleUiThread(alwaysShow);
             else 
                post(new Runnable() 
                    @Override
                    public void run() 
                        setFastScrollerAlwaysVisibleUiThread(alwaysShow);
                    
                );
            

逻辑上的线程切换,值得代码的借鉴。

pointToPosition

将一个坐标点转换位一个列表的条目的索引。

public int pointToPosition(int x, int y) 
        Rect frame = mTouchFrame;
        if (frame == null) 
            mTouchFrame = new Rect();
            frame = mTouchFrame;
        

        final int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) 
            final View child = getChildAt(i);
            if (child.getVisibility() == View.VISIBLE) 
                child.getHitRect(frame);
                if (frame.contains(x, y)) 
                    return mFirstPosition + i;
                
            
        
        return INVALID_POSITION;
    

以上是关于之AbsListView的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView之isTracking delaysContentTouches canCancelContentTouches

javaScript事件事件类型之触摸与手势事件

停止 ListView 滚动动画

AbsListView unregisterIRListener() 被调用

详细讲解Android中的AbsListView的源码

setAdapter“调用需要 API 级别 11(当前最低为 8):android.widget.AbsListView#setAdapter”?