【发布时间】:2019-02-27 03:43:34
【问题描述】:
所以我有一个 RecycleView 的布局文件,它具有可展开/可折叠的视图。
点击标题会展开/折叠额外的数据。在编辑器中一切看起来都很好。但是,它会有一个类似于layout_marginBottom 的幽灵空间。
首次加载的外观
扩展
正确折叠
所以编辑器只会显示ViewHolder,如图 2 和图 3 所示。
但是在设备上运行时,它首先会显示图 1,然后单击它展开后会显示图 2。再次折叠它会显示图 3 而不是图 1。它将继续显示正确的数字(2 和 3)。
图 2 中的额外内容具有共同的父项,其标头为 ConstraintLayout。
无论GONE 说明符如何,都会发生这种情况:以编程方式或 XML
使用activity.runOnUIThread 无济于事。使用new Handler().onPostDelayed 只会像图 1 那样更糟,但会出现更多不需要的空间,与图 2 一样多,只是没有额外的信息。
这是 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
app:cardCornerRadius="10dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/validity"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<ImageButton
android:id="@+id/expand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
app:srcCompat="@drawable/ic_right" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/textDark" />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:background="@color/colorSecondaryDark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/header" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="@+id/size"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider" />
<TextView
android:id="@+id/size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider" />
<TextView
android:id="@+id/amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="@+id/validity"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/date" />
<LinearLayout
android:id="@+id/validity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/size">
<ImageView
android:id="@+id/help"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:contentDescription="@string/backup_layout_help_desc"
app:srcCompat="@drawable/ic_help" />
<TextView
android:id="@+id/invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/backup_layout_invalid"
android:textAllCaps="true"
android:textColor="@color/red" />
</LinearLayout>
<TextView
android:id="@+id/passwords"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/amount" />
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:background="@android:color/transparent"
android:text="@string/backup_layout_delete"
android:textColor="@color/red"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/importshare"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/passwords"
app:layout_constraintVertical_bias="1.0" />
<LinearLayout
android:id="@+id/importshare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/validity"
app:layout_constraintVertical_bias="1.0">
<Button
android:id="@+id/commit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/transparent"
android:text="Import"
android:textColor="@color/yellow" />
<ImageButton
android:id="@+id/share"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/transparent"
android:contentDescription="Share"
android:padding="10dp"
app:srcCompat="@drawable/ic_share" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
以及 ViewHolder(剪切以显示相关部分):
public ViewHolder(View itemView, Context context) {
super(itemView);
Amount = itemView.findViewById(R.id.amount);
Date = itemView.findViewById(R.id.date);
Delete = itemView.findViewById(R.id.delete);
Divider = itemView.findViewById(R.id.divider);
ExpandCollapse = itemView.findViewById(R.id.expand);
Import = itemView.findViewById(R.id.commit);
ImportShare = itemView.findViewById(R.id.importshare);
Header = itemView.findViewById(R.id.header);
Help = itemView.findViewById(R.id.help);
Passwords = itemView.findViewById(R.id.passwords);
Share = itemView.findViewById(R.id.share);
Size = itemView.findViewById(R.id.size);
Title = itemView.findViewById(R.id.title);
Validity = itemView.findViewById(R.id.validity);
Title.setTypeface(Typeface.createFromAsset(context.getAssets(), "cera.otf"));
Header.setOnClickListener(this);
onClick(Header);
}
@Override
public void onClick(View v) {
if (expanded) collapse();
else expand();
}
public void expand() {
ExpandCollapse.animate().rotation(90).start();
Date.setVisibility(View.VISIBLE);
Size.setVisibility(View.VISIBLE);
Amount.setVisibility(View.VISIBLE);
Passwords.setVisibility(View.VISIBLE);
Divider.setVisibility(View.VISIBLE);
Validity.setVisibility(valid ? View.INVISIBLE : View.VISIBLE);
Delete.setVisibility(View.VISIBLE);
ImportShare.setVisibility(View.VISIBLE);
expanded = true;
}
public void collapse() {
ExpandCollapse.animate().rotation(0).start();
Date.setVisibility(View.GONE);
Size.setVisibility(View.GONE);
Amount.setVisibility(View.GONE);
Passwords.setVisibility(View.GONE);
Divider.setVisibility(View.GONE);
Validity.setVisibility(View.GONE);
Delete.setVisibility(View.GONE);
ImportShare.setVisibility(View.GONE);
expanded = false;
}
【问题讨论】:
-
如果 ConstraintLayout 的目的是消除嵌套,为什么还要嵌套 LinearLayouts?
-
标题需要 LinearLayouts 但其他的,现在你说它是不必要的。我只是不知道如何在 ConstraintLayouts 中水平居中。
-
使用约束和链。
-
我无法通过阅读代码来判断,但我敢打赌,如果您为所有视图临时设置不同的背景颜色(不是白色),您会看到哪个视图占用了该空间。
-
原来有两个视图显示为不可见,尽管它被指定为
GONE。不知道为什么,但是在修改适配器以从不将它们设置为INVISIBLE和GONE之后,一切都变得很好。顺便说一句,这两个视图是TextView和ImageView。
标签: java android android-layout android-constraintlayout android-viewholder