Android setVisibility(GONE) 视图变得不可见但仍然占用空间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12302172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:22:21  来源:igfitidea点击:

setVisibility(GONE) view becomes invisible but still occupies space

androidandroid-listviewandroid-view

提问by Dennis

I've got a view that is effectively is a button. Here is its XML layout (add_new.xml)

我有一个实际上是一个按钮的视图。这是它的 XML 布局 (add_new.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <Button
        android:id="@+id/buttonNew"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/bText" 
        android:onClick="addNew"/>
</LinearLayout>

When I set its visibility to GONE like this

当我像这样将其可见性设置为 GONE 时

v = getActivity().getLayoutInflater().inflate(R.layout.add_new, null);
v.setVisibility(View.GONE);

it disappears but still occupies space. Like this: enter image description here

它消失了,但仍然占据着空间。像这样:在此处输入图片说明

This button is a header in the ListView, which is defined by this xml:

这个按钮是 中的一个标题,ListView由这个 xml 定义:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/porno" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="30dp"
        android:layout_height="40dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="4dp"
        android:src="@drawable/ic_launcher">
    </ImageView>

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@+id/label"
        android:textSize="20dp" >
    </TextView>

</LinearLayout> 

And I dont want it to occupy an additional list item when its visibility is set to GONE. As it is stated in the documentation.

当它的可见性设置为 GONE 时,我不希望它占用额外的列表项。正如文档中所述。

GONE - This view is invisible, and it doesn't take any space for layout purposes.

GONE - 此视图是不可见的,并且不占用任何布局空间。

Any ideas on how to make it NOT occupy space?

关于如何使它不占用空间的任何想法?

Thanks, Dennis xx

谢谢,丹尼斯 xx

P.S. My listview is inside of a FoldersFragment ListFragmentand here is the xml of my MainActivity where FoldersFragment is presented

PS 我的列表视图位于 FoldersFragment 内ListFragment,这里是我的 MainActivity 的 xml,其中显示了 FoldersFragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <fragment
        android:id="@+id/foldersFragment"
        android:layout_width="200dip"
        android:layout_height="match_parent"
        class="com.example.fragments.FoldersFragment" >
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.example.fragments.DetailFragment" >
    </fragment>

</LinearLayout>

采纳答案by noni

This is an Android bug in my opinion, we just fix this issue doing this:

在我看来,这是一个 Android 错误,我们只是通过以下方式解决此问题:

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

Just hide LinearLayout with id LAYOUT_TO_HIDEwith Visible.GONEand then root FrameLayout will collapse its height giving you a "hidden" with non-blank-space header.

只是隐藏的LinearLayout id为LAYOUT_TO_HIDEVisible.GONE再根的FrameLayout会崩溃的高度给你一个“隐藏的”非空白空间标题。

回答by Jaguar

All replies in this thread are suggesting a new wrapper view, which comes at a cost. The correct way of hiding a view completely is to set margins to 0 while setting visibility to GONE. In this code sample, cardViewis the view I am trying to hide. The direct parent of cardViewis RecyclerView, that's why we are using RecyclerView.LayoutParams - remember to replace with the right layout params.

此线程中的所有回复都建议使用新的包装器视图,这是有代价的。完全隐藏视图的正确方法是将边距设置为 0,同时将可见性设置为GONE。在此代码示例中,cardView是我试图隐藏的视图。cardView的直接父是 RecyclerView,这就是我们使用 RecyclerView.LayoutParams 的原因——记得用正确的布局参数替换。

if (cardView.getVisibility() != GONE) {
    cardView.setVisibility(GONE);
    RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) cardView.getLayoutParams();
    layoutParams.setMargins(0, 0, 0, 0);
    cardView.setLayoutParams(layoutParams);
}

回答by Asad

set layout_widthand layout_heightto 0where you want to hide item, by doing this

设置layout_width并设置layout_height0您想要隐藏项目的位置,通过执行此操作

//if item's parent layout is LinearLayout, change according to your item xml
holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(0,0));

回答by Jayo2k

If this is stil needed, there is a great way to deal with it:

如果这仍然需要,有一个很好的方法来处理它:

parentView.removeView(childView);

here an example:

这里有一个例子:

final WhatEverLayout parentView, childView;
parentView = (WhatEverLayout)findViewById(R.id.parentView_xml);
childView =(WhatEverLayout)findViewById(R.id.childView_xml);
parentView.removeView(childView);

回答by kyorilys

This is my solution. Create a new layout file with name "special.xml", copy the code to the file.

这是我的解决方案。创建一个名为“special.xml”的新布局文件,将代码复制到文件中。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
    android:visibility="gone">

</LinearLayout>

Use condition to inflate the empty layoutinside the newview. Don't Use the view.setVisibility(View.GONE);.

使用条件来膨胀新视图内的空布局。不要使用view.setVisibility(View.GONE); .

if(true){
  view=mInflater.inflate ( R.layout.special,parent, false );
}else{
  view=mInflater.inflate(R.layout.normal,parent,false);
  // The view that you want to be visible
}

回答by wanglugao

header_layout.xml:

header_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:id="@+id/mHeaderView"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/mNoHelpLayout"
                android:layout_width="match_parent"
                android:layout_height="176dip"
                android:background="#ffffffff"
                android:gravity="center"
             />
       </LinearLayout>
   </LinearLayout>

java code:

代码:

LayoutInflater mInflater =(LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View outerView =  mInflater.inflate(R.layout.header_layout, null);
mHeaderView = (LinearLayout) outerView.findViewById(R.id.mHeaderView);

use mHeaderView.setVisiable() to control visiable not the outerView.setVisiable(). it works for me.

使用 mHeaderView.setVisiable() 来控制可见而不是 outerView.setVisiable()。这个对我有用。

回答by Jayo2k

What you can do is set an if statement, whenever the condition to set the visibility to "GONE", set the view as wrap content and your space will be free, I did it and it worked for a seekbar

您可以做的是设置一个 if 语句,每当将可见性设置为“GONE”的条件时,将视图设置为换行内容,您的空间将是免费的,我做到了,它适用于搜索栏

回答by murugan mani

If you want to show itemView 

if (ItemBean.isShow()) 
{
   holder.itemView.setVisibility(View.VISIBLE);
   holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
 } else
 {
     holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(0, 0));
     holder.itemView.setVisibility(View.GONE);
 }

回答by Mudit Khandelwal

You can use : viewToHide?.postDelayed({ viewToHide?.visibility = View.GONE }, durationInMillis)

您可以使用 : viewToHide?.postDelayed({ viewToHide?.visibility = View.GONE }, durationInMillis)

回答by Prajwal W

A generic and easy solution is to avoid all thuse heck of code:

一个通用且简单的解决方案是避免所有这些代码:

You need to add a Container Layout or a Parent Layoutover your set of views that you want to hide. It can be anything like CardView or FrameLayout or etc.

您需要在要隐藏的视图集上添加容器布局或父布局。它可以是 CardView 或 FrameLayout 等任何东西。

Just it has to be a parent for that view that you want to hide. And you wont get all those white spaces. Coz it will consider the entire container to hide instead of considering individual views to HIDE thus, avoiding the white spaces.

只是它必须是您想要隐藏的视图的父级。你不会得到所有这些空白。因为它会考虑隐藏整个容器,而不是考虑隐藏单个视图,从而避免空白。