好的,这就是我正在做的......我有两个自定义布局:
HandedLayout extends ViewGroup
和
HandedPathLayout extends HandedLayout
所以在根布局中,我有一个自定义LayoutParameters来接受一个名为handed的布局属性。这是
中的布局参数类 public static class LayoutParams extends ViewGroup.LayoutParams {
public int handed;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray a =
c.obtainStyledAttributes(attrs, R.styleable.HandedLayout_LayoutParams);
handed = a.getInt(R.styleable.HandedLayout_LayoutParams_layout_handed,
HandedLayout.RIGHT_HANDED);
a.recycle();
}
public LayoutParams(int width, int height) {
super(width, height);
}
}
正如我所理解的那样(看起来很糟糕),我还需要覆盖HandedLayout中的3个类。他们在这里:
@Override
public HandedLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new HandedLayout.LayoutParams(getContext(), attrs);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected HandedLayout.LayoutParams generateDefaultLayoutParams() {
return new HandedLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
所以在内部自定义布局(HandedPathLayout)中,我需要大量的布局参数,所以我做的完全一样!这是HandedPathLayout中的LayoutParameters类:
public static class LayoutParams extends HandedLayout.LayoutParams {
public int[] endSides;
public int[] endPositions;
public int[] anchorSides;
public int[] anchorPositions;
public int controlPointDistance;
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
endSides = new int[2];
endPositions = new int[2];
anchorSides = new int[2];
anchorPositions = new int[2];
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HandedPathLayout_LayoutParams);;
try {
//this is the second place that the default handedness is set, watch out!
//handed = a.getInteger(R.styleable.HandedLayout_LayoutParams_layout_handed, HandedLayout.RIGHT_HANDED);
endSides[0] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_from_side, HandedLayout.BOTTOM_SIDE);
endSides[1] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_to_side, HandedLayout.PINKIE_SIDE);
endPositions[0] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_from_position, 0);
endPositions[1] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_to_position, 0);
anchorSides[0] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_up_side, HandedLayout.TOP_SIDE);
anchorSides[1] = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_down_side, HandedLayout.BOTTOM_SIDE);
//todo: should these positions be set relative to handedness? which direction is zero?
anchorPositions[0] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_up_position, 0);
anchorPositions[1] = a.getDimensionPixelSize(R.styleable.HandedPathLayout_LayoutParams_layout_anchor_down_position, 0);
controlPointDistance = a.getInteger(R.styleable.HandedPathLayout_LayoutParams_layout_control_point_position, HandedLayout.BOTTOM_SIDE);
} finally {
a.recycle();
}
}
}
然后再次在HandedPathLayout类中,确保我们获得正确类型的LayoutParams的三个函数:
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof HandedPathLayout.LayoutParams;
}
@Override
public HandedPathLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new HandedPathLayout.LayoutParams(getContext(), attrs);
}
@Override
protected HandedPathLayout.LayoutParams generateDefaultLayoutParams() {
return new HandedPathLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
我在使用和没有完全限定的LayoutParams类名称的情况下尝试了这个。
所以,现在已经全部在那里编译好了,然后在onMeasure的根ViewGroup,HandedLayout,我循环遍历孩子并尝试获取他们的getLayoutParams()所以我可以找出去哪里把它们以及如何测量它们,我得到这个ClassCastException!
05-29 18:16:35.061 9391-9391 / com.codesolutions.onehandkeyboard E / AndroidRuntime:FATAL EXCEPTION:main 处理:com.codesolutions.onehandkeyboard,PID:9391 java.lang.ClassCastException:com.codesolutions.pathlayout.HandedLayout $ LayoutParams无法强制转换为com.codesolutions.pathlayout.HandedPathLayout $ LayoutParams 在com.codesolutions.pathlayout.HandedLayout.onMeasure(HandedLayout.java:90)
这个异常是从这个演员抛出的,看起来它应该是正确的类型,在调试器中我已经确认孩子确实是HandedPathLayout,并且所有迹象都表明LayoutParams是正确的型!
HandedPathLayout.LayoutParams lp =
(HandedPathLayout.LayoutParams)child.getLayoutParams();
我只是不明白为什么LayoutParams的类型不正确!
关于这个我还没有得到的另一件事是关于我想要放入HandedPathLayout的自定义View(扩展TextView)。它需要一个自定义的layout_rows XML属性,所以我需要将它设置为自己的LayoutParams吗?那些只适用于ViewGroups,对吧?但是,它是需要应用该属性的视图,而不是ViewGroup。
更新:
因此,当我运行调试器并在我的演员失败之前停止时,在HandedLayout的onMeasure中...我发现,确实,LayoutParams对象不是我期望的类型!父级的getLayoutParams(HandedLayout)返回一个FrameLayout.LayoutParams(这对我来说毫无意义),而子级(HandedPathLayout)有一个HandedLayout.LayoutParams!为什么?!我在这里不理解什么?
谢谢!