Android中RelativeLayout.BELOW/ABOVE规则失效,如何修复布局对齐?
修复RelativeLayout中ABOVE/BELOW对齐失效问题
问题根源是noteOut的ID在调用getId()时还未被系统分配有效值——默认情况下,View在被添加到父布局前,ID是-1,这会导致RelativeLayout的ABOVE/BELOW规则无法识别目标View,所以tuneOut和freqOut只能按默认规则显示在屏幕顶部。
修复方案
有两种简单的解决方法:
方法1:手动设置唯一ID
在创建noteOut后,手动给它分配一个全局不冲突的整数ID:
//Add the frequency display noteOut = new TextView(this); // 手动设置唯一ID,确保和其他View的ID不重复 noteOut.setId(1001); freqOut = new TextView(this); tuneOut = new TextView(this); noteOut.setText("test"); freqOut.setText("test_below"); tuneOut.setText("test_above"); RelativeLayout.LayoutParams noteOutDetails = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ); noteOutDetails.addRule(RelativeLayout.CENTER_HORIZONTAL); noteOutDetails.addRule(RelativeLayout.CENTER_VERTICAL); gameLayout.addView(noteOut, noteOutDetails); RelativeLayout.LayoutParams tuneOutDetails = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ); tuneOutDetails.addRule(RelativeLayout.CENTER_HORIZONTAL); tuneOutDetails.addRule(RelativeLayout.ABOVE, noteOut.getId()); gameLayout.addView(tuneOut, tuneOutDetails); RelativeLayout.LayoutParams freqOutDetails = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ); freqOutDetails.addRule(RelativeLayout.CENTER_HORIZONTAL); freqOutDetails.addRule(RelativeLayout.BELOW, noteOut.getId()); gameLayout.addView(freqOut, freqOutDetails);
方法2:使用系统生成的唯一ID(API 17及以上)
如果你的App最低兼容API 17或更高,推荐用系统API生成唯一ID,避免手动设置的ID冲突:
noteOut = new TextView(this); // 系统自动生成全局唯一的View ID noteOut.setId(View.generateViewId());
原理说明
给noteOut设置有效ID后,RelativeLayout就能正确识别这个目标View,ABOVE/BELOW规则会生效,test_above会显示在test的正上方,test_below会显示在test的正下方,且三者都保持水平居中。
内容的提问来源于stack exchange,提问作者Mich
相关产品推荐
相关产品推荐

