我正在使用 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并将信息传递给关联的布局。
有什么想法吗?
您应该尝试 View.INVISIBLE 而不是 View.GONE,因为 View.INVISIBLE 仅隐藏视图而不是其空间,而 View.GONE 隐藏视图及其占用的空间。
您必须使用的课程:
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);
如果您必须使用
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
内的可见性对视图进行排序,并首先显示可见的视图。消失的视图将放回布局中,以便您可以根据需要使它们再次可见。