使用LayoutParams.addRule设置动态设置视图到视图的最后位置

时间:2015-06-08 20:47:08

标签: android android-layout android-relativelayout

我正在动态地将视图添加到相对布局并以编程方式定义它们。视图可以在屏幕上移动,因此它们的位置会发生变化。

当我尝试将视图(button2)设置为位于另一个视图(button1)下方时,button2将被放置在button1的旧位置(移动前添加视图的默认位置)。我已经链接了图像,希望能更好地传达这一点。

这是原始布局Original Layout

Button2重新定位后的布局Re-positioned Layout

我有一个后台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时,它将获得旧位置。

有没有办法强制相对布局视图重新定位?

3 个答案:

答案 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

structure

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以下。