android自定义布局参数ClassCastException以及View怎么样?

时间:2016-05-29 22:33:59

标签: android android-layout android-custom-view android-layoutparams

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

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!为什么?!我在这里不理解什么?

谢谢!

0 个答案:

没有答案