我有 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);
}
}
}