Hide row from ListView without taking up space
Asked Answered
S

6

10

I have a ListView with an associated ArrayAdapter that displays its contents in several activities. Unfortunately it got necessary now, that my ListView in one of the settings does not display all its elements, but just the ones where "property" is not set to true. I would like to avoid to use two ArrayAdapters with different content, since then I somehow need to keep them in sync. I tried it like this (this method now just assumes that getView is called in the setting where we want to hide certain elements):

public View getView(int position, View convertView, Context context) {
....

    if(!arrayitems[position].isProperty()) { //arrayitems is the underlying array
        convertView.setVisibility(View.VISIBLE); 
    } 
    else {
        convertView.setVisibility(View.GONE); 
    }
    return convertView;
}

This works, however I get a white row if the element has isProperty == true. I would like to make the row invisible in the sense, that it does not take up any space anymore. Is that possible?

The used xml file for convertView looks like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/text_item_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="4dp"
            android:maxLines="1"
            android:ellipsize="none"
            android:textSize="12sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/text_item_status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:textStyle="bold" />

    </LinearLayout>

     <TextView android:id="@+id/text_item_text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:textSize="12sp"
         android:maxLines="3"
         android:ellipsize="none" />

     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="2dp"
         android:orientation="horizontal" >

         <TextView
             android:id="@+id/text_item_rating"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginRight="4dp"
             android:textSize="10sp" />

         <TextView
             android:id="@+id/text_item_voted"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textSize="10sp" />

     </LinearLayout>

</LinearLayout>

I tried to replay all android:layout_height="wrap_content" with "fill_parent" but it did not change anything...

Thanks!

Semang answered 30/11, 2012 at 13:23 Comment(3)
I don't get it, the boolean property is the same for all elements as it's an attribute to the adapter. How could it know what row to hide?Catchy
sorry, isProperty() of course is a method of items in the arraySemang
if still have problem please check my answer it will work for sure.Boorman
F
9

Set the Visibility of all the contents of the list view to GONE and then set the visibility of the View to Gone.... this will hide the row without occupying space..... it worked for me even i have been searching for this but after a research i found this....

EDIT 1 : Setting the visibility of the View to GONE is enough. No need to set the child element's visibility.

Fifteen answered 22/6, 2013 at 18:35 Comment(0)
B
7

I'm having same problem as you've

I've figured it out by inflating another layout layout with no height and width

Adapter.java

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if (YOUR_CONDITION) {
            return inflater.inflate(R.layout.blank_layout, parent,
                    false);
    } else {
            View vi = inflater.inflate(R.layout.list_item, parent, false);
            return vi;
    }

}

And blank layout will be like this,

blank_layout.xml

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


</LinearLayout>
Boorman answered 10/7, 2014 at 10:9 Comment(1)
Nice solution just pass the "blank_layout" according to condition.Jacobo
L
4

So what Romain meant was to add an id to your LinearLayout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:orientation="vertical"
    android:id="@+id/linear_layout">

Then in your Java you would do

    public View getView(int position, View convertView, Context context) {
    ....
    holder.lLayout = (LinearLayout) convertView.findViewById(R.id.linear_layout);
    ....
    if(!arrayitems[position].isProperty()) { //arrayitems is the underlying array
        holder.lLayout.setVisibility(View.VISIBLE); 
    } 
    else {
        holder.lLayout.setVisibility(View.GONE); 
    }
    return convertView;
    }

You may need to change it a bit if your inflating your views differently. I've done this myself and it works really well.

Latoya answered 23/1, 2013 at 23:27 Comment(3)
Eventhough I used View.GONE I had a bunch of empty space at the end of the listview that the user could scroll through. To fix it, I updated getCount() to exclude the hidden rows from the total count. A much cleaner implementation would have been to keep two arraylists: one for the original data, and another for the adapter that excludes the data of the hidden rows.Godart
I've done that before and what I don't like about that is that your then baby sitting extra data.Latoya
yeah I agree - that's why I didn't go that route for this particular instance :-) I forgot to mention in my comment above: once getCount() returns a value that excludes the data rows you want to hide, you should locate the hidden data rows to the end of the array that's used by your adapter.Godart
S
3

You can use the getview layout of android:layout_height="wrap_content" and do use Visibility gone to hide your layout

Selima answered 30/11, 2012 at 13:50 Comment(1)
Sorry, I don't get what you are saying. Could you clarify your solution?Semang
C
1

Another user had the same problem and he solved it this way: https://mcmap.net/q/1176747/-android-set-view-gone-does-not-quot-release-quot-space-in-listview .

I hope this could help you.

Greets

Ceuta answered 30/11, 2012 at 13:43 Comment(1)
Thank you, however I could not transfer his solution. I added my used xml file for convertView above.Semang
L
-2

By modifying getCount() and also the position in getView() with your logic you can make it work for sample Check http://www.sherif.mobi/2012/01/listview-with-ability-to-hide-rows.html by @sherif-elkhatib

Landslide answered 22/10, 2015 at 9:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.