如何在布局自定义的所有子项中获取属性自定义?

时间:2017-08-19 07:00:09

标签: android attributes children custom-view

我有 TagLayout 扩展 viewGroup 和自定义属性isNeedShowLoading。

在下面的布局中,我可以通过id fullContentLy获取属性isNeedShowLoading LinearLayout,但是无法在titleTv中获取此属性。 如何在子布局的所有子项中获取属性isNeedShowLoading?

<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:TagLayout="http://schemas.android.com/apk/res-auto"
        xmlns:app="http://schemas.android.com/apk/res-auto">

        <android.support.v7.widget.CardView
                 android:id="@+id/card"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content">

        <com.example.TagLayout
                 android:layout_width="match_parent"
                 android:layout_height="match_parent">

                 <LinearLayout
                        android:id="@+id/fullContentLy"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:baselineAligned="false"
                        android:orientation="vertical"
                        android:tag="LinearLayoutMain"
                        TagLayout:isNeedShowLoading="false" />

                        <!--Photo-->
                      <RelativeLayout
                                 android:layout_width="wrap_content"
                                 android:layout_height="wrap_content"
                             android:tag="RelativeLayoutMainPhotoTotal"
                             TagLayout:isNeedShowLoading="false">

                      <android.support.v7.widget.AppCompatImageView
                              android:id="@+id/photoACImaV"
                              android:layout_width="match_parent"
                              android:layout_height="wrap_content"
                              TagLayout:isNeedShowLoading="false"
                              app:srcCompat="@drawable/test_photo" />

                     <TextView
                            android:id="@+id/titleTv"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_alignParentBottom="true"
                            android:layout_alignParentEnd="true"
                            android:text="title"
                            TagLayout:isNeedShowLoading="true" />

                    </RelativeLayout>

            </com.example.TagLayout>

       </android.support.v7.widget.CardView>

</layout>

公共类TagLayoutTest扩展了ViewGroup {

int deviceWidth;

public TagLayoutTest(Context context) {
    this(context, null, 0);
}

public TagLayoutTest(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public TagLayoutTest(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context);
}

private void init(Context context) {

    final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    Point deviceDisplay = new Point();
    display.getSize(deviceDisplay);
    deviceWidth = deviceDisplay.x;

}

@Override
protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    Paint paint = null;
    Path rectanglePath = new Path();

    // Rectangle
    RectF rectangleRect = new RectF(0, 0, 100, 100);
    rectanglePath.addRoundRect(rectangleRect, 100f, 100f, Path.Direction.CW);
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.RED);


    canvas.drawPath(rectanglePath, paint);

}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = getChildCount();
    int curWidth, curHeight, curLeft, curTop, maxHeight;

    //get the available size of child view
    final int childLeft = this.getPaddingLeft();
    final int childTop = this.getPaddingTop();
    final int childRight = this.getMeasuredWidth() - this.getPaddingRight();
    final int childBottom = this.getMeasuredHeight() - this.getPaddingBottom();
    final int childWidth = childRight - childLeft;
    final int childHeight = childBottom - childTop;

    maxHeight = 0;
    curLeft = childLeft;
    curTop = childTop;

    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);

        if (child.getVisibility() == GONE)
            return;

        //Get the maximum size of the child
        child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
        curWidth = child.getMeasuredWidth();
        curHeight = child.getMeasuredHeight();
        //wrap is reach to the end
        if (curLeft + curWidth >= childRight) {
            curLeft = childLeft;
            curTop += maxHeight;
            maxHeight = 0;
        }
        //do the layout
        child.layout(curLeft, curTop, curLeft + curWidth, curTop + curHeight);
        //store the max height
        if (maxHeight < curHeight)
            maxHeight = curHeight;
        curLeft += curWidth;


    }

}


private ArrayList<View> getAllChildren(View v) {

    if (!(v instanceof ViewGroup)) {
        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        return viewArrayList;
    }

    ArrayList<View> result = new ArrayList<View>();

    ViewGroup viewGroup = (ViewGroup) v;
    for (int i = 0; i < viewGroup.getChildCount(); i++) {

        View child = viewGroup.getChildAt(i);

        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        viewArrayList.addAll(getAllChildren(child));

        result.addAll(viewArrayList);
    }
    return result;
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int count = getChildCount();
    // Measurement will ultimately be computing these values.
    int maxHeight = 0;
    int maxWidth = 0;
    int childState = 0;
    int mLeftWidth = 0;
    int rowCount = 0;

    // Iterate through all children, measuring them and computing our dimensions
    // from their size.
    for (int i = 0; i < count; i++) {
        final View child = getChildAt(i);

        if (child.getVisibility() == GONE)
            continue;

        // Measure the child.
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
        maxWidth += Math.max(maxWidth, child.getMeasuredWidth());
        mLeftWidth += child.getMeasuredWidth();

        if ((mLeftWidth / deviceWidth) > rowCount) {
            maxHeight += child.getMeasuredHeight();
            rowCount++;
        } else {
            maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
        }
        childState = combineMeasuredStates(childState, child.getMeasuredState());
    }

    // Check against our minimum height and width
    maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
    maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

    // Report our final dimensions.
    setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
            resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}


/* LayoutParams */
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new TagLayoutTest.LayoutParams(getContext(), attrs);
}

@Override
protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}

@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
    return new LayoutParams(lp);
}

@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams lp) {
    return lp instanceof LayoutParams;
}

public static class LayoutParams extends MarginLayoutParams {


    public boolean isNeedShowLoading = false;


    public LayoutParams(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (attrs != null) {
            String packageName = "http://schemas.android.com/apk/res-auto";
            isNeedShowLoading = attrs.getAttributeBooleanValue(packageName, "isNeedShowLoading", false);

        }
    }

    public LayoutParams(int width, int height) {
        super(width, height);
    }

    public LayoutParams(ViewGroup.LayoutParams source) {
        super(source);
    }
}

}

0 个答案:

没有答案