问题描述:
我有一个自定义的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类似乎相同吗?我没有看到必要性。
答案 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();
}
}