Android Galaxy S2、S3和S4上的自定义布局重画问题
我有一个自定义布局(扩展Android Galaxy S2、S3和S4上的自定义布局重画问题,android,android-layout,android-view,samsung-mobile,Android,Android Layout,Android View,Samsung Mobile,我有一个自定义布局(扩展FrameLayout),其中包含一些项目。每个项目都是一个自定义的视图,可以加载相应的对象(比如用户的配置文件、显示图片等)。这些视图包含在一些LinearLayouts(行)中,因此我可以在行中正确地排列它们,而不会出现问题。行是固定的(例如,项目0、1和2始终位于第一行并始终存在,3和4位于第二行,依此类推)。我使用FrameLayout,因为这些行需要重叠一点。。。想想交错的六边形 加载布局时,所有的行都被放置在彼此的顶部,因为我还不知道它们的大小 protect
FrameLayout
),其中包含一些项目。每个项目都是一个自定义的视图
,可以加载相应的对象(比如用户的配置文件、显示图片等)。这些视图包含在一些LinearLayout
s(行)中,因此我可以在行中正确地排列它们,而不会出现问题。行是固定的(例如,项目0、1和2始终位于第一行并始终存在,3和4位于第二行,依此类推)。我使用FrameLayout
,因为这些行需要重叠一点。。。想想交错的六边形
加载布局时,所有的行都被放置在彼此的顶部,因为我还不知道它们的大小
protected void onMeasure (final int widthMeasureSpec, final int heightMeasureSpec)
在onMeasure
方法中,我使用提供的宽度和高度MeasureSpec
s来计算我有多少空间。然后在此基础上,我计算每个项目可以拥有的最大宽度和高度,并将其存储在3个变量(宽度、高度和半径)中。我还计算了给定项目之间的填充和间距,布局本身需要的宽度和高度。现在,我获取这些值,并创建新的measurept
s,模式设置为measurept
super.onMeasure (MeasureSpec.makeMeasureSpec (width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec (height, MeasureSpec.EXACTLY));
注意:最初我使用setMeasuredDimension(width,height)
强制调整布局的大小,但它遇到了我将要描述的问题。更改为MeasureSpec。确切地说
方法修复了它
protected void onLayout (final boolean changed, final int l, final int t, final int r, final int b)
在OnLayout
方法中,我使用在onMeasure
中计算的值来布局项目。如果changed
为false,我将退出,因为没有任何更改。否则,我将遍历行并设置它们的顶部边距:
final int rowTop = rowTop(i); // i = index of row
final LayoutParams layoutParams = (LayoutParams) row.getLayoutParams ();
layoutParams.topMargin = rowTop;
layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
row.setLayoutParams (layoutParams);
这允许行重叠一点(数量根据大小、填充等计算)。设置完所有行后,我将遍历项目并设置它们的高度和宽度(如测量中的计算):
这在许多设备上都可以正常工作。当我旋转设备时,它会重新计算所有这些值(将它们打印到日志中以便我确认),并重新绘制所有内容。这包括Nexus 4
,Cyanogenmod-7
,Cyanogenmod-11
,LG G3库存ROM
,以及Galaxy S5
。我可以加载其他片段并返回到包含此布局的片段,所有内容都按预期工作
然而由于某些原因,S2、S3或S4上的情况并不顺利。不幸的是,我不能包括截图(公司IP),但我希望描述症状可能会有所帮助
在下面,我说我已经验证了这一点,我的意思是我用纸和铅笔按比例画了这些项目,看起来很正确
旋转
在有问题的设备上,当我旋转时,onMeasure
值计算正确。我已经通过日志、纸和铅笔证实了这一点。onLayout
值也已正确计算(验证)。然而,我在屏幕上看到的并不是计算值告诉我的。这些值似乎落后于一个旋转。当设备变成横向时,我看到的是与纵向相同的图形(除非设备是正方形,否则不应该出现这种情况)。当我旋转回“纵向”时,现在可以看到使用横向尺寸绘制的项目
重新加载
当我加载另一个片段(想想导航抽屉)并用这个自定义布局重新加载片段时,这些行永远不会扩展到多行(它们保持最初的完全重叠)
我在onconfiguration changed
、onMeasure
、onSizeChanged
和onLayout
的开头有日志输出,它们都在应该的时候打印,并打印出我希望计算的值:
08-28 18:14:41.498 19593-19593/<REDACTED>: config
08-28 18:14:41.518 19593-19593/<REDACTED>: measure
08-28 18:14:41.518 19593-19593/<REDACTED>: Forcing size to 1903x2374
08-28 18:14:41.518 19593-19593/<REDACTED>: measure
08-28 18:14:41.518 19593-19593/<REDACTED>: Forcing size to 1903x2374
08-28 18:14:41.538 19593-19593/<REDACTED>: size
08-28 18:14:41.538 19593-19593/<REDACTED>: layout
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 0: 0
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 1: 524
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 2: 1062
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 3: 1601
08-2818:14:41.49819593-19593/:config
08-28 18:14:41.518 19593-19593/:测量
08-28 18:14:41.518 19593-19593/:强制大小为1903x2374
08-28 18:14:41.518 19593-19593/:测量
08-28 18:14:41.518 19593-19593/:强制大小为1903x2374
08-28 18:14:41.538 19593-19593/:尺寸
08-28 18:14:41.538 19593-19593/:布局图
08-28 18:14:41.548 19593-19593/:行顶0:0
08-28 18:14:41.548 19593-19593/:第1行顶部:524
08-28 18:14:41.548 19593-19593/:第2行顶部:1062
08-28 18:14:41.548 19593-19593/:第3行顶部:1601
有人在这些设备上遇到绘图问题吗?
我的绘画问题让你想起了你必须处理的事情吗?
如果是这样的话,你是如何解决的?
- 在
onLayout()过程中,应在每个子级上使用View.layout()
在布局过程中,您确实希望定位您的孩子,因此您可以计算他们的相对坐标并对他们调用layout()
,以便他们可以继续设置各自的mLeft
,mRight
,等等,并在屏幕上有一个位置。它们的高度和宽度刚刚在测量过程中计算出来
在布局过程中设置LayoutParams
看起来有点像黑客,是一种臭味。你在这里级别较低,你不应该那样做
您的案例:以设置行边距为例。我的想法是,在“没有问题”的设备上,布局过程运行两次。您可能会在这里调用super.onLayout()
。第一次未正确定位子项,但正确计算(忽略的)边距时。您看不到这一点,因为在绘制之前,再次触发布局过程(它是否在RelativeLayout
?)并因此
FrameLayout.onLayout()
根据第一次布局过程中计算的边距设置正确的子位置。在某些设备上,布局过程只运行一次,一切都会中断
如果要为视图组实施布局过程,请选择y
08-28 18:14:41.498 19593-19593/<REDACTED>: config
08-28 18:14:41.518 19593-19593/<REDACTED>: measure
08-28 18:14:41.518 19593-19593/<REDACTED>: Forcing size to 1903x2374
08-28 18:14:41.518 19593-19593/<REDACTED>: measure
08-28 18:14:41.518 19593-19593/<REDACTED>: Forcing size to 1903x2374
08-28 18:14:41.538 19593-19593/<REDACTED>: size
08-28 18:14:41.538 19593-19593/<REDACTED>: layout
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 0: 0
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 1: 524
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 2: 1062
08-28 18:14:41.548 19593-19593/<REDACTED>: Top of row 3: 1601