Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 对ViewPager中测量实现的理解_Android_Android Viewpager_Viewgroup_Onmeasure - Fatal编程技术网

Android 对ViewPager中测量实现的理解

Android 对ViewPager中测量实现的理解,android,android-viewpager,viewgroup,onmeasure,Android,Android Viewpager,Viewgroup,Onmeasure,出于一些不相关的原因,我正在浏览ViewPager的代码,我看到它覆盖了ViewGroup的onMeasure。我一直在努力学习如何正确地实现onMeasure,所以我决定仔细看看。这是供参考的方法- @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // For simple implementation, our internal size is always 0.

出于一些不相关的原因,我正在浏览ViewPager的代码,我看到它覆盖了ViewGroup的onMeasure。我一直在努力学习如何正确地实现onMeasure,所以我决定仔细看看。这是供参考的方法-

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // For simple implementation, our internal size is always 0.
    // We depend on the container to specify the layout size of
    // our view.  We can't really know what it is since we will be
    // adding and removing different arbitrary views and do not
    // want the layout to change as this happens.
    setMeasuredDimension(getDefaultSize(0, widthMeasureSpec),
            getDefaultSize(0, heightMeasureSpec));

    final int measuredWidth = getMeasuredWidth();
    final int maxGutterSize = measuredWidth / 10;
    mGutterSize = Math.min(maxGutterSize, mDefaultGutterSize);

    // Children are just made to fill our space.
    int childWidthSize = measuredWidth - getPaddingLeft() - getPaddingRight();
    int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();

    /*
     * Make sure all children have been properly measured. Decor views first.
     * Right now we cheat and make this less complicated by assuming decor
     * views won't intersect. We will pin to edges based on gravity.
     */
    int size = getChildCount();
    for (int i = 0; i < size; ++i) {
        final View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp != null && lp.isDecor) {
                final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
                final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK;
                int widthMode = MeasureSpec.AT_MOST;
                int heightMode = MeasureSpec.AT_MOST;
                boolean consumeVertical = vgrav == Gravity.TOP || vgrav == Gravity.BOTTOM;
                boolean consumeHorizontal = hgrav == Gravity.LEFT || hgrav == Gravity.RIGHT;

                if (consumeVertical) {
                    widthMode = MeasureSpec.EXACTLY;
                } else if (consumeHorizontal) {
                    heightMode = MeasureSpec.EXACTLY;
                }

                int widthSize = childWidthSize;
                int heightSize = childHeightSize;
                if (lp.width != LayoutParams.WRAP_CONTENT) {
                    widthMode = MeasureSpec.EXACTLY;
                    if (lp.width != LayoutParams.MATCH_PARENT) {
                        widthSize = lp.width;
                    }
                }
                if (lp.height != LayoutParams.WRAP_CONTENT) {
                    heightMode = MeasureSpec.EXACTLY;
                    if (lp.height != LayoutParams.MATCH_PARENT) {
                        heightSize = lp.height;
                    }
                }
                final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
                final int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
                child.measure(widthSpec, heightSpec);

                if (consumeVertical) {
                    childHeightSize -= child.getMeasuredHeight();
                } else if (consumeHorizontal) {
                    childWidthSize -= child.getMeasuredWidth();
                }
            }
        }
    }

    mChildWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY);
    mChildHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightSize, MeasureSpec.EXACTLY);

    // Make sure we have created all fragments that we need to have shown.
    mInLayout = true;
    populate();
    mInLayout = false;

    // Page views next.
    size = getChildCount();
    for (int i = 0; i < size; ++i) {
        final View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            if (DEBUG) {
                Log.v(TAG, "Measuring #" + i + " " + child + ": " + mChildWidthMeasureSpec);
            }

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp == null || !lp.isDecor) {
                final int widthSpec = MeasureSpec.makeMeasureSpec(
                        (int) (childWidthSize * lp.widthFactor), MeasureSpec.EXACTLY);
                child.measure(widthSpec, mChildHeightMeasureSpec);
            }
        }
    }
}
@覆盖
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
//对于简单的实现,我们的内部大小始终为0。
//我们依赖容器来指定
//我们的观点。我们不能真正知道它是什么,因为我们将
//添加和删除不同的任意视图,而不
//希望在发生这种情况时更改布局。
setMeasuredDimension(getDefaultSize(0,widthMeasureSpec),
getDefaultSize(0,heightMeasureSpec));
最终int measuredWidth=getMeasuredWidth();
最终整数maxGutterSize=测量宽度/10;
MGuttSize=Math.min(maxGutterSize,mDefaultGutterSize);
//孩子只是为了填满我们的空间。
int childWidthSize=measuredWidth-getPaddingLeft()-getPaddingRight();
int childHeightSize=getMeasuredHeight()-getPaddingTop()-getPaddingBottom();
/*
*确保所有的孩子都被正确地测量过。首先是装饰视图。
*现在我们作弊,通过装潢使事情变得不那么复杂
*视图不会相交。我们将基于重力固定到边上。
*/
int size=getChildCount();
对于(int i=0;i
我无法理解处理装饰视图的重要性背后的逻辑。据我所知,如果有两个子视图-一个是重力左上角,另一个是右上角,代码将从childHeightSize中减去两个子视图的高度。对我来说,这似乎是错误的,因为逻辑应该只减去具有最大高度的子视图的高度

为什么要这样实施