瀑布流StaggeredGridView源码详细分析

一,准备知识:

1,View的绘制流程。

该文将从View的绘制流程:onMesure() --> onLayout() -->onDraw()。这一流程分析

扩展阅读:Android中View绘制流程

2,requestLayout()方法。

会导致调用measure()过程 和 layout()过程 。说明:只是对View树重新布局layout过程包括measure()和layout()过程,不会调用draw()过程,但不会重新绘制任何视图包括该调用者本身。

3,invalidate()方法。

请求重绘View树,即draw()过程,假如视图发生大小没有变化就不会调用layout()过程,并且只绘制那些“需要重绘的”视图,即谁(View的话,只绘制该View ;ViewGroup,则绘制整个ViewGroup)请求invalidate()方法,就绘制该视图。

4,AbsListView类。

     ExtendableListView继承自AbsListView,该类重写了draw(),和dispatchDraw()方法,所以ExtendableListView只需重写onMesure()和onLayout()即可。

二,ExtendableListView类

核心类,该类继承自AbsListView。重写了AbsListView类的onMesure()和onLayout()方法,

1,ExtendableListView()构造方法。

[java]  view plain copy
  1. public ExtendableListView(final Context context, final AttributeSet attrs, final int defStyle) {  
  2.         super(context, attrs, defStyle);  
  3.   
  4.         // setting up to be a scrollable view group  
  5.         setWillNotDraw(false);  
  6.         setClipToPadding(false);  
  7.         setFocusableInTouchMode(false);  
  8.   
  9.         final ViewConfiguration viewConfiguration = ViewConfiguration.get(context);  
  10.         mTouchSlop = viewConfiguration.getScaledTouchSlop();  
  11.         mMaximumVelocity = viewConfiguration.getScaledMaximumFlingVelocity();  
  12.         mFlingVelocity = viewConfiguration.getScaledMinimumFlingVelocity();  
  13.   
  14.         mRecycleBin = new RecycleBin();  
  15.         mObserver = new AdapterDataSetObserver();  
  16.   
  17.         mHeaderViewInfos = new ArrayList<FixedViewInfo>();  
  18.         mFooterViewInfos = new ArrayList<FixedViewInfo>();  
  19.   
  20.         // start our layout mode drawing from the top  
  21.         mLayoutMode = LAYOUT_NORMAL;  
  22.     }  

1.1  setWillNotDraw(false)

调用这句话的方法的作用是防止我们重写的onDraw()方法不被调用,可以看官方的注释

If this view doesn't do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup.Typically, if you override {@link #onDraw(android.graphics.Canvas)}you should clear this flag.

中文意思是:如果没有在View上画任何东西,则需要设置这个标示以可以进一步的优化绘画。默认情况下,在View上是不会设置这个标示的,但是可以在View的子类上设置

如ViewGroup。通常情况下,如果你重写了onDraw这个方法,你需要清楚这个标示。

1.2  setClipToChilren(false)

用来定义ViewGroup是否允许在padding中绘制。默认情况下,cliptopadding被设置为ture, 也就是把padding中的值都进行裁切了

扩展阅读:用android:clipChildren来实现边界绘制

1.3 RecycleBin类

item缓存类,这个和AbsListView 中的RecycleBin 一样,只是少了RecyclerListener,

The data set used to store unused views that should be reused during the next layout to avoid creating new ones

大概意思是:这个数据集合是用来存储没有使用的views的,是为了避免重复创建这些新的views,这样在下一次布局的时候这些些views可以被重用。

The RecycleBin facilitates reuse of views across layouts. The RecycleBin has two levels of

storage: ActiveViews and ScrapViews. ActiveViews are those views which were onscreen at the

start of a layout. By construction, they are displaying current information. At the end of

layout, all views in ActiveViews are demoted to ScrapViews. ScrapViews are old views that

could potentially be used by the adapter to avoid allocating views unnecessarily.

大概意思是:这个类是用来帮助在滑动布局时重用View的,这个RecyleBin 有两个级别的存储分别是ActiveViews和ScrapViews,mActiveViews是一个View类型的数组,存储的是那些显示在屏幕上的views。ScrapViews是一个ArrayList<View>类型的数组,存储的是那些已经废弃的不是显示在屏幕上的views,这些views都有可能被adapter使用避免分配失败。在布局结束的时候,mActiveViews存储的views都降级为ScrapViews。

扩展阅读:

Android AdapterView View的复用机制 分析

ListView回收机制相关分析

2,onAttachedToWindow()和onDetachedFromWindow()方法。

<span style="font-size:14px;">@Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (mAdapter != null) {
            // Data may have changed while we were detached. Refresh.
            mDataChanged = true;
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
        }
        mIsAttached = true;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        // Detach any view left in the scrap heap
        mRecycleBin.clear();

        if (mFlingRunnable != null) {
            removeCallbacks(mFlingRunnable);
        }

        mIsAttached = false;
    }</span>
扩展阅读: Android重写view时onAttachedToWindow () 和 onDetachedFromWindow ()
3,setAdapter()方法

@Override
 public void setAdapter(final ListAdapter adapter) {
        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mObserver);
        }

        // use a wrapper list adapter if we have a header or footer
        if (mHeaderViewInfos.size() > 0 || mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        }
        else {
            mAdapter = adapter;
        }

        mDataChanged = true;
        mItemCount = adapter != null ? adapter.getCount() : 0;

        if (adapter != null) {
            adapter.registerDataSetObserver(mObserver);
            mRecycleBin.setViewTypeCount(adapter.getViewTypeCount());
        }

        requestLayout();
  }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值