0

好的,这就是我正在做的......我有两个自定义布局:

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 类名。

所以,现在一切都在那里并且编译好了,然后在根 ViewGroup 的 onMeasure 中,HandedLayout,我循环遍历孩子并尝试获取他们的 getLayoutParams(),这样我就可以弄清楚将它们放在哪里以及如何测量它们,我得到了这个 ClassCastException!

05-29 18:16:35.061 9391-9391/com.codesolutions.onehandkeyboard E/AndroidRuntime:致命异常:主进程:com.codesolutions.onehandkeyboard,PID:9391 java.lang.ClassCastException:com.codesolutions.pathlayout.HandedLayout$ LayoutParams 无法在 com.codesolutions.pathlayout.HandedLayout.onMeasure(HandedLayout.java:90) 处转换​​为 com.codesolutions.pathlayout.HandedPathLayout$LayoutParams

这个演员抛出了这个异常,看起来它应该得到正确的类型,在调试器中我已经确认孩子确实是一个 HandedPathLayout,并且所有迹象都表明 LayoutParams 是正确的类型!

                HandedPathLayout.LayoutParams lp =
                    (HandedPathLayout.LayoutParams)child.getLayoutParams();

我只是不明白为什么 LayoutParams 的类型不正确!

我不明白的另一件事是关于我想放入我的 HandedPathLayout 的自定义视图(扩展 TextView)。它需要一个自定义的 layout_rows XML 属性,所以我需要让它成为自己的 LayoutParams 吗?这些仅适用于 ViewGroup,对吗?但是,需要应用该属性的是视图,而不是 ViewGroup。

更新:

因此,当我运行调试器并在我的演员失败之前停止时,在 HandedLayout 的 onMeasure 中......我发现,事实上,LayoutParams 对象都不是我期望的类型!父级(HandedLayout)的 g​​etLayoutParams 返回一个 FrameLayout.LayoutParams(这对我来说根本没有意义),而子级(它是一个 HandedPathLayout)有一个 HandedLayout.LayoutParams!为什么?!我在这里不明白什么?

谢谢!

4

0 回答 0