我应该使用什么样的LayoutParams?

时间:2014-04-20 21:53:50

标签: android android-layout

问题描述:

我有一个自定义的ImageView:

public class TestImageView extends ImageView {
...
    public void onImageLoaded(Bitmap bitmap) {
        int width = DeviceInfo.getScreenWidth();
        int height = width * (float) bitmap.getHeight() / (float) bitmap.getWidth();
        ViewGroup.MarginLayoutParams layoutParams =
                new ViewGroup.MarginLayoutParams(width, height);
        this.setLayoutParams(layoutParams);
    }
}

然后我收到了这个错误:

java.lang.ClassCastException: android.view.ViewGroup$MarginLayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams

在我的项目中,我确实将一个TestImageView实例作为FrameLayout的子项。因此,如果我将ViewGroup.MarginLayoutParams更改为FrameLayout.LayoutParams,它将起作用。但是这个定制的ImageView可能在其他类型的布局中,如LinearLayout。我不认为我应该将它限制在FrameLayout.layoutParams这里。

那我该怎么办?更一般地说,为什么Android制作不同的LayoutParams? LayoutParams类似乎相同吗?我没有看到必要性。

2 个答案:

答案 0 :(得分:2)

ViewGroup的每个子类都有自己的LayoutParams(从ViewGroup.MarginLayoutParams下降,它是ViewGroup.LayoutParams的后代(每个子类都没有MarginLayoutParams,因为边距设置功能可通过继承获得)),因为它们支持不同素质。例如,LinearLayout.LayoutParams支持使用重力。因此,根据您的ImageView所处的任何类型的ViewGroup,您的LayoutParams必须是相同的类型,或至少转换为相同的类型。你有几个选择。一种是在ImageView的子类中假设您将始终使用某种类型的布局,然后将ViewGroup.MarginLayoutParams替换为(您的布局类型).LayoutParams。但如果你改变它,它将停止工作,所以你可以通过使用泛型来避免所有这些:

public class TestImageView<I extends ViewGroup.LayoutParams> extends ImageView {
    public void onImageLoaded(Bitmap bitmap) {
        int width = DeviceInfo.getScreenWidth();
        int height = width * (float) bitmap.getHeight() / (float) bitmap.getWidth();
        I layoutParams = (I)
                new ViewGroup.LayoutParams(width, height);
        this.setLayoutParams(layoutParams);
    }
}

及其用途:

// using a RelativeLayout
TestImageView<RelativeLayout.LayoutParams> iv = new TestImageView<>();

我希望这会帮助你! (我目前没有测试设备,所以如果不能正常工作,请发表评论)

答案 1 :(得分:1)

我在Android框架中浏览了一些源代码。我想我做得不对:

Layouting应该是View父母的工作!!

所以我不应该把代码放在TestImageView中。相反,它应该放在视图的父级中:

public class ParentOfTestImageView extends LinearLayout {
...
...
...
    public void whateverFunction() {
        TestImageView imageView = new TestImageView(context);
        // Note here
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(whateverWidth, whateverHeight);
        imageView.setLayoutParams(params);
        imageView.requestLayout();
    }
}