web-dev-qa-db-fra.com

La vue setVisibility (GONE) devient invisible mais occupe toujours de l'espace

J'ai une vue qui est effectivement un bouton. Voici sa disposition 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>

Quand j'ai défini sa visibilité sur GONE comme ceci

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

il disparaît mais occupe toujours l'espace. Comme ça: enter image description here

Ce bouton est un en-tête dans le ListView, qui est défini par ce 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> 

Et je ne veux pas qu'il occupe un élément de liste supplémentaire lorsque sa visibilité est définie sur GONE. Comme indiqué dans la documentation.

GONE - Cette vue est invisible et ne prend pas de place à des fins de mise en page.

Avez-vous des idées sur la façon de ne pas occuper d'espace?

Merci, Dennis xx

P.S. Ma liste est à l'intérieur d'un FoldersFragment ListFragmentet voici le xml de mon MainActivity où FoldersFragment est présenté

<?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>
52
Dennis

Il s'agit d'un bug Android à mon avis, nous corrigeons simplement ce problème en procédant comme suit:

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

Juste cacher LinearLayout avec l'ID LAYOUT_TO_HIDE avec Visible.GONE puis FrameLayout racine réduira sa hauteur, vous donnant un en-tête "caché" avec un espace non vide.

44
noni

ensemble layout_width et layout_height à 0 où vous souhaitez masquer l'élément, en procédant ainsi

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

Toutes les réponses dans ce fil suggèrent une nouvelle vue wrapper, qui a un coût. La manière correcte de masquer complètement une vue consiste à définir des marges à 0 tout en définissant la visibilité sur DISPARU . Dans cet exemple de code, cardView est la vue que j'essaie de masquer. Le parent direct de cardView est RecyclerView, c'est pourquoi nous utilisons RecyclerView.LayoutParams - n'oubliez pas de remplacer par les bons paramètres de mise en page.

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

Si cela est toujours nécessaire, il existe un excellent moyen de le gérer:

parentView.removeView(childView);

voici un exemple:

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

C'est ma solution. Créez un nouveau fichier de mise en page avec le nom "special.xml", copiez le code dans le fichier.

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

Utilisez la condition pour gonfler la mise en page vide à l'intérieur de la nouvelle vue. N'utilisez pas 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
}
2
kyorilys

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>

Code Java:

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

utilisez mHeaderView.setVisiable () pour contrôler visiable et non externalView.setVisiable (). ça marche pour moi.

2
wanglugao

Ce que vous pouvez faire est de définir une instruction if, chaque fois que la condition pour définir la visibilité sur "GONE", définissez la vue en tant que contenu enveloppé et votre espace sera libre, je l'ai fait et cela a fonctionné pour une barre de recherche

2
Jayo2k
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);
 }
0
murugan mani