GridLayout 动态更改以填充 Gone 视图

问题描述 投票:0回答:3

我正在使用 GridLayout 设计一个基于 2 列的仪表板。所以我只是添加小部件,它直接定义网格。

我遇到的问题是,我有 12 个单元格,但有些单元格将根据信息可用性设置为

View.VISIBLE
View.GONE
。我遇到的问题是,当单元格设置为
View.GONE
时,它没有显示,但空间仍然存在。

我希望当我将一个单元格设置为

View.GONE
时,设置为
View.VISIBLE
的下一个单元格会显示出来,并且不会让屏幕中间出现空单元格。

抱歉,我无法发布屏幕图像,所以我尝试制作一张。以上是我所看到的。我期望当单元格设置为

View.GONE
时,单元格会重新排列自己,并且不会出现空单元格

我使用的xml是:

<GridLayout
                    android:id="@+id/grid"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:columnCount="2"
                    android:orientation="horizontal">

                    <include
                        android:id="@+id/button1"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_columnWeight="1"
                        layout="@layout/button_a"
                        bind:tileModel="@{model.button1}"/>

                    <include
                        android:id="@+id/button2"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_columnWeight="1"
                        layout="@layout/button_b"
                        bind:tileModel="@{model.button2}"/>

                    <include
                        android:id="@+id/button3"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_columnWeight="1"
                        layout="@layout/button_a"
                        bind:tileModel="@{model.button3}"/>

                    <include
                        android:id="@+id/button4"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_columnWeight="1"
                        layout="@layout/button_c"
                        bind:tileModel="@{model.button4}"/>

                    <include
                        android:id="@+id/button5"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_columnWeight="1"
                        layout="@layout/button_b"
                        bind:tileModel="@{model.button5}"/>

                    <include
                        android:id="@+id/button6"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_columnWeight="1"
                        layout="@layout/button_a"
                        bind:tileModel="@{model.button6}"/>


tileModel
接收viewModel并将信息传递给关联的布局。

有什么想法吗?

android kotlin grid grid-layout android-gridlayout
3个回答
0
投票

您应该尝试 View.INVISIBLE 而不是 View.GONE,因为 View.INVISIBLE 仅隐藏视图而不是其空间,而 View.GONE 隐藏视图及其占用的空间。


0
投票
  1. 您将需要使用此自定义 RearrangingGridLayout,因为默认网格布局没有预期的行为。
  2. 在 XML 布局中使用此类。
  3. 您的 Activity 的 onCreate 最初只需使用 saveViews() 方法。

您必须使用的课程:

public class RearrangingGridLayout extends GridLayout { 
private final List views = new ArrayList<>();

public RearrangingGridLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public RearrangingGridLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public RearrangingGridLayout(Context context) {
    this(context, null);
}

private void arrangeElements() {
    removeAllViews();

    for (int i = 0; i < views.size(); i++) {
        if (views.get(i).getVisibility() != GONE)
            addView(views.get(i));
    }
}

public void saveViews() {
    for (int i = 0; i < getChildCount(); i++) {
        views.add(getChildAt(i));
    }
}

public void hideView(View child) {
    for (int i = 0; i < views.size(); i++) {
        if (views.get(i).getId() == child.getId()) {
            views.get(i).setVisibility(GONE);
            arrangeElements();
            break;
        }
    }
}

public void showView(View child) {
    for (int i = 0; i < views.size(); i++) {
        if (views.get(i).getId() == child.getId()) {
            views.get(i).setVisibility(VISIBLE);
            arrangeElements();
        }
    }
}}

创建时:

glRearranging.saveViews();

像这样隐藏视图,

glRearranging.hideView(viewName);

像这样显示视图,

glRearranging.showView(viewName);

0
投票

如果您必须使用

GridLayout
而不是
GridView
,这里有一个简单但肮脏的技巧来绕过重新排列问题
GridLayout
有。

每次将

GridLayout
内的视图设置为
GONE
或返回
VISIBLE
时,请调用此方法:

    private fun realignChildrenOfGridLayoutByVisibility(gridLayout: GridLayout) {
    val goneChildren = gridLayout.children.toList().filter { it.visibility == GONE }
    goneChildren.forEach { gridLayout.removeView(it) }
    goneChildren.forEach { gridLayout.addView(it) }
}

这会按

GridLayout
内的可见性对视图进行排序,并首先显示可见的视图。消失的视图将放回布局中,以便您可以根据需要使它们再次可见。

  • 放在最后时,GONE 视图不会有大小,也不会添加额外不需要的空间。
  • 请注意,如果您切换随机视图的可见性,顺序将不会保留
© www.soinside.com 2019 - 2024. All rights reserved.