View.GONE 留空 space
View.GONE leaves empty space
我使用 Firebase 获得 2 种类型的数据,使用 RadioButton 对显示的数据进行排序。一切似乎都正常,但当其中一种数据类型被隐藏时,仍然有一个空的 space。告诉我如何正确隐藏/显示数据。
适配器:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
switch (viewType) {
case Person.PersonType.TYPE_1:
View userType1 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.driver_row, parent, false);
return new PersonType1ViewHolder(userType1);
case Person.PersonType.TYPE_2:
View userType2 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fare_row, parent, false);
return new PersonType2ViewHolder(userType2);
}
return super.onCreateViewHolder(parent, viewType);
}
@Override
protected void populateViewHolder(RecyclerView.ViewHolder viewHolder,
Person model,
int position) {
if (viewHolder instanceof PersonType1ViewHolder) {
((PersonType1ViewHolder) viewHolder).time.setText("Full time: " +
model.getTime());
if (activate) {
viewHolder.itemView.setVisibility(View.GONE);
} else {
viewHolder.itemView.setVisibility(View.VISIBLE);
}
return;
}
if (viewHolder instanceof PersonType2ViewHolder) {
((PersonType2ViewHolder) viewHolder).time.setText("Full time2: " +
model.getTime());
if (activate2) {
viewHolder.itemView.setVisibility(View.GONE);
} else {
viewHolder.itemView.setVisibility(View.VISIBLE);
}
private class PersonType1ViewHolder extends RecyclerView.ViewHolder {
TextView time;
PersonType1ViewHolder(View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time);
}
}
private class PersonType2ViewHolder extends RecyclerView.ViewHolder {
TextView time;
PersonType2ViewHolder(View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time_two);
}
}
行布局相同 - wrap_content
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
主要活动XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_trip_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/radio_button_group" />
<Button
android:id="@+id/add_trip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:onClick="addTrip"
android:text="add" />
<RadioGroup
android:id="@+id/radio_button_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/add_trip"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="all" />
<RadioButton
android:id="@+id/rb_driver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="driver" />
<RadioButton
android:id="@+id/rb_fare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fare" />
</RadioGroup>
</RelativeLayout>
问题不是很清楚。
但我可以向您保证,使用 View.GONE
,视图在不离开 space 的情况下变得不可见。使用 View.INVISIBLE
时,视图会留下不可见的 space。
如果不起作用,则说明您的布局有问题。
我也遇到过这样的问题,原来是adapter中override方法getItemCount()
的问题。我猜如果你指定了getItemCount()
的个数,RecyclerView即使你隐藏它也会为ViewHolder预留一个位置。这是我如何解决它的代码。
override fun getItemViewType(position: Int): Int {
when {
!importantImages.isNullOrEmpty() && !otherImages.isNullOrEmpty() -> {
return when (position) {
0 -> Important.ordinal
else -> Other.ordinal
}
}
otherImages.isNullOrEmpty() -> {
return Important.ordinal
}
importantImages.isNullOrEmpty() -> {
return Other.ordinal
}
}
return 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (ViewType.values()[viewType]) {
Important -> {
val layoutInflater = LayoutInflater
.from(parent.context)
.inflate(R.layout.layout_important_list, parent, false)
ImportantViewHolder(layoutInflater)
}
Other -> {
val layoutInflater = LayoutInflater
.from(parent.context)
.inflate(R.layout.layout_other_list, parent, false)
OtherViewHolder(layoutInflater)
}
}
}
override fun getItemCount(): Int = when {
!importantImages.isNullOrEmpty() && !otherImages.isNullOrEmpty() -> {
2
}
importantImages.isNullOrEmpty() && otherImages.isNullOrEmpty() -> {
0
}
else -> {
1
}
}
希望对您有所帮助! :)
我不知道这有多正确,但我只是以编程方式设置参数
viewHolder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
我也有这个问题,我发现如果用wrap_content在外面加一个容器就可以了。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/v_root"
android:layout_width="match_parent"
android:layout_height="48dp">
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
在java代码中:
v_root.setVisibility(View.GONE);
v_root 在代码中表示您的旧视图根。
1.Why 会发生吗?
viewHolder.itemView.setVisibility(View.GONE);
这在 RecyclerView 中不起作用。
itemView
是 RecyclerView 中的一个 child 视图。与其他 ViewGroup(FrameLayout 等)不同,RecyclerView 在布局过程中忽略 childen 的可见性。
2.How能解决吗?
选项1使用FrameLayout等常规视图组包裹你的真实布局,隐藏你的真实布局:findViewById(R.id.layout_to_hide).setVisibility(View.GONE)
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:id="@+id/layout_to_hide"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//Put here your views
</LinearLayout>
</FrameLayout>
选项2 把itemView的高度改成0这样我们就看不到了
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
Option3 如果这个项目不应该在列表中,那么就不要让它在适配器数据中,或者删除它。
3.Learn更多
1.为什么其他视图组(例如 FrameLayout)在 children 的可见性下工作正常?
如果 child 消失了,他们不会计算它的布局参数
2。为什么 RecyclerView 没有?
RecyclerView 仍然计算 child 的布局参数,如果它已经消失,所以它仍然占用空间。
我使用 Firebase 获得 2 种类型的数据,使用 RadioButton 对显示的数据进行排序。一切似乎都正常,但当其中一种数据类型被隐藏时,仍然有一个空的 space。告诉我如何正确隐藏/显示数据。
适配器:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
switch (viewType) {
case Person.PersonType.TYPE_1:
View userType1 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.driver_row, parent, false);
return new PersonType1ViewHolder(userType1);
case Person.PersonType.TYPE_2:
View userType2 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fare_row, parent, false);
return new PersonType2ViewHolder(userType2);
}
return super.onCreateViewHolder(parent, viewType);
}
@Override
protected void populateViewHolder(RecyclerView.ViewHolder viewHolder,
Person model,
int position) {
if (viewHolder instanceof PersonType1ViewHolder) {
((PersonType1ViewHolder) viewHolder).time.setText("Full time: " +
model.getTime());
if (activate) {
viewHolder.itemView.setVisibility(View.GONE);
} else {
viewHolder.itemView.setVisibility(View.VISIBLE);
}
return;
}
if (viewHolder instanceof PersonType2ViewHolder) {
((PersonType2ViewHolder) viewHolder).time.setText("Full time2: " +
model.getTime());
if (activate2) {
viewHolder.itemView.setVisibility(View.GONE);
} else {
viewHolder.itemView.setVisibility(View.VISIBLE);
}
private class PersonType1ViewHolder extends RecyclerView.ViewHolder {
TextView time;
PersonType1ViewHolder(View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time);
}
}
private class PersonType2ViewHolder extends RecyclerView.ViewHolder {
TextView time;
PersonType2ViewHolder(View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time_two);
}
}
行布局相同 - wrap_content
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
主要活动XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_trip_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/radio_button_group" />
<Button
android:id="@+id/add_trip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:onClick="addTrip"
android:text="add" />
<RadioGroup
android:id="@+id/radio_button_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/add_trip"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="all" />
<RadioButton
android:id="@+id/rb_driver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="driver" />
<RadioButton
android:id="@+id/rb_fare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fare" />
</RadioGroup>
</RelativeLayout>
问题不是很清楚。
但我可以向您保证,使用 View.GONE
,视图在不离开 space 的情况下变得不可见。使用 View.INVISIBLE
时,视图会留下不可见的 space。
如果不起作用,则说明您的布局有问题。
我也遇到过这样的问题,原来是adapter中override方法getItemCount()
的问题。我猜如果你指定了getItemCount()
的个数,RecyclerView即使你隐藏它也会为ViewHolder预留一个位置。这是我如何解决它的代码。
override fun getItemViewType(position: Int): Int {
when {
!importantImages.isNullOrEmpty() && !otherImages.isNullOrEmpty() -> {
return when (position) {
0 -> Important.ordinal
else -> Other.ordinal
}
}
otherImages.isNullOrEmpty() -> {
return Important.ordinal
}
importantImages.isNullOrEmpty() -> {
return Other.ordinal
}
}
return 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (ViewType.values()[viewType]) {
Important -> {
val layoutInflater = LayoutInflater
.from(parent.context)
.inflate(R.layout.layout_important_list, parent, false)
ImportantViewHolder(layoutInflater)
}
Other -> {
val layoutInflater = LayoutInflater
.from(parent.context)
.inflate(R.layout.layout_other_list, parent, false)
OtherViewHolder(layoutInflater)
}
}
}
override fun getItemCount(): Int = when {
!importantImages.isNullOrEmpty() && !otherImages.isNullOrEmpty() -> {
2
}
importantImages.isNullOrEmpty() && otherImages.isNullOrEmpty() -> {
0
}
else -> {
1
}
}
希望对您有所帮助! :)
我不知道这有多正确,但我只是以编程方式设置参数
viewHolder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
我也有这个问题,我发现如果用wrap_content在外面加一个容器就可以了。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/v_root"
android:layout_width="match_parent"
android:layout_height="48dp">
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
在java代码中:
v_root.setVisibility(View.GONE);
v_root 在代码中表示您的旧视图根。
1.Why 会发生吗?
viewHolder.itemView.setVisibility(View.GONE);
这在 RecyclerView 中不起作用。
itemView
是 RecyclerView 中的一个 child 视图。与其他 ViewGroup(FrameLayout 等)不同,RecyclerView 在布局过程中忽略 childen 的可见性。
2.How能解决吗?
选项1使用FrameLayout等常规视图组包裹你的真实布局,隐藏你的真实布局:findViewById(R.id.layout_to_hide).setVisibility(View.GONE)
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:id="@+id/layout_to_hide"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//Put here your views
</LinearLayout>
</FrameLayout>
选项2 把itemView的高度改成0这样我们就看不到了
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
Option3 如果这个项目不应该在列表中,那么就不要让它在适配器数据中,或者删除它。
3.Learn更多
1.为什么其他视图组(例如 FrameLayout)在 children 的可见性下工作正常?
如果 child 消失了,他们不会计算它的布局参数
2。为什么 RecyclerView 没有?
RecyclerView 仍然计算 child 的布局参数,如果它已经消失,所以它仍然占用空间。