我正在动态地将视图添加到相对布局并以编程方式定义它们。视图可以在屏幕上移动,因此它们的位置会发生变化。
当我尝试将视图(button2)设置为位于另一个视图(button1)下方时,button2将被放置在button1的旧位置(移动前添加视图的默认位置)。我已经链接了图像,希望能更好地传达这一点。
这是原始布局
Button2重新定位后的布局
我有一个后台LinkedList,可以跟踪布局的所有视图更改和视图属性,如果这会有所不同。
以下是代码函数:
我如何重新定位Button1:
Buttons b = (Buttons) viewIndex;
positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams());
positioningLayout.addRule(RelativeLayout.CENTER_VERTICAL);
b.setLayoutParams(positioningLayout);
baseLayout.addView(b);
在另一个视图下方重新定位视图代码片段:
Buttons b = (Buttons) viewIndex;
positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams());
positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue());
b.setLayoutParams(positioningLayout);
b.invalidate();
我如何将视图添加到布局中。
uiList.addView(new Buttons(this), "BUTTON");
setDialogView(uiList.getLast());
showDialog(SET_ID);
reloadUI();
setDialogView只是将视图传递给Dialog SET_ID,以便我可以手动为视图分配ID(用于测试)。 reloadUI()只是找到添加到后台LinkedList的最后一个视图,并使用.addView将它添加到relativeLayout;
如果您需要更多代码,请告诉我们。在更改relativeLayout子视图后,我是否错过了更新视图布局的调用?似乎视图在视觉上重新定位,但实际的LayoutParams没有更新,因此当您将Button2设置为Button1时,它将获得旧位置。
有没有办法强制相对布局视图重新定位?
答案 0 :(得分:2)
我认为您应该尝试简单的解决方案 - 将b.invalidate()
替换为b.requestLayout()
。有关更多背景调查this link。我没有测试它,但我希望它能工作。因此代码应如下所示:
Buttons b = (Buttons) viewIndex;
positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams());
positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue());
b.setLayoutParams(positioningLayout);
b.requestLayout();
或许您可以将其简化为:
Buttons b = (Buttons) viewIndex;
((RelativeLayout.LayoutParams) b.getLayoutParams()).addRule(RelativeLayout.BELOW, viewIdFromList.intValue());
b.requestLayout();
答案 1 :(得分:1)
你似乎走在正确的轨道上,但是犯了一个小错误。没有更多的代码,提供实际的解决方案是非常困难的。但我会试着指出错误。
请参阅以 RelativeLayout 以编程方式相对定位项目,您必须为每个项目分配唯一ID 。
喜欢,
Button b = new Button(this);
b.setId(1);
Button c = new Button(this);
c.setId(2);
每个元素都应该有唯一的ID。
现在,如果您想将Button b垂直放在中间,
layout.addRule(RelativeLayout.CENTER_VERTICAL);
b.setLayoutParams(layout);
现在,如果你想把Button c放在它下面,
layout.addRule(RelativeLayout.BELOW, b.getId());
layout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
b.setLayoutparams(layout);
这肯定会将按钮c放在按钮b下方。正如您所说,您可以使用您选择的任何数据结构来跟踪每个元素的ID。
答案 2 :(得分:1)
这只是关于如何正确移动按钮的详细示例。首先,为View
创建一个唯一ID,即在res/values/
中创建一个新的XML资源文件,并将其命名为ids.xml
:
ids.xml
的内容是:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="button_1" type="id"/>
<item name="button_2" type="id"/>
</resources>
我们必须为您的主要布局设置ID:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/layout_main"> <!-- the id -->
<!-- content of this layout -->
</RelativeLayout>
然后,让我们创建Button
s:
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_main);
final Button button1 = new Button(this);
button1.setId(R.id.button_1);
button1.setText("BUTTON 1");
button1.setTextColor(Color.BLACK);
final Button button2 = new Button(this);
button2.setId(R.id.button_2);
button2.setText("BUTTON 2");
button2.setTextColor(Color.BLACK);
relativeLayout.addView(button1, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
relativeLayout.addView(button2, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) button1.getLayoutParams();
params1.addRule(RelativeLayout.CENTER_IN_PARENT); // set to the center of screen
button1.setLayoutParams(params1);
final RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) button2.getLayoutParams();
params2.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
button2.setLayoutParams(params2);
button2.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
/* We need to remove the existing rules and update it!
* For API 16 and earlier, set the rule to 0, e.g. --> layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
* For API 17 and higher, call layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_LEFT);
*/
int api = android.os.Build.VERSION.SDK_INT;
if (api >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // API level 17
params2.removeRule(RelativeLayout.ALIGN_PARENT_TOP);
params2.removeRule(RelativeLayout.ALIGN_PARENT_LEFT);
}else if (api < Build.VERSION_CODES.JELLY_BEAN_MR1) {
params2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
}
params2.addRule(RelativeLayout.CENTER_IN_PARENT);
params2.addRule(RelativeLayout.BELOW, R.id.button_1); // place below button1
button2.setLayoutParams(params2);
}
});
因此,点击button2
后,它会移至button1
以下。