Search code examples
androidandroid-layoutandroid-linearlayoutandroid-custom-view

Android - how to control visibility of nested views within a custom view?


I'm trying to create a custom view in android that I can use in the same way as a LinearLayout. The custom view should add two TextView on top of whatever I add inside the layout. How can I control the visibility of the contents of my custom view? I have to be able to add contents at design time and at run time visibility of that nested contents should be toggled, but not those two TextViews. My question is somewhat similar to this one which didn't really get a satisfactory answer.

I've created a custom view that extends LinearLayout:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:orientation="horizontal"
    >
<TextView
    android:id="@+id/txt_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="My title"
    android:layout_marginLeft="10dp"
    />
<TextView
    android:id="@+id/txt_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0"
    android:layout_marginRight="10dp"
    android:text="My button"
    android:onClick="txtButton_onClick"
    android:clickable="true"
    />
</LinearLayout>
<LinearLayout
    android:id="@+id/all_contents"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="visible"
    android:layout_marginTop="10dp"
    />
    <!-- This is where I _want_ to add all nested contents to make it easy to toggle its visibility -->
</merge>

All nested content I want to be contained in the LinearLayout at the bottom, so that when I click txt_button I can set visibility on all_contents to gone and make that disappear. I still want txt_title and txt_button to continue being visible, so I can toggle showing the content or not.

The custom view is supposed to be called like this:

<org.my.app.view.SlidingLayoutView
    android:id="@+id/slv_date_time"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    custom:titleString="Date and time"
    custom:buttonString="Change">
    <!-- This is where all nested contents should go -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Example nested content"
        />
</org.my.app.view.SlidingLayoutView>

What I don't get is how to decide that nested contents goes into the all_content LinearLayout. Or am I thinking about this all wrong? Does nested content end up at the very bottom of the custom view, and if so how do I toggle its visibility and not my two TextView?


Solution

  • By on top of do you mean above in the linear layout? I think that your xml should work if you take out the all_contents LinearLayout, things will be added to the LinearLayout. Make your xml like this.

        <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal"
        >
        <TextView
            android:id="@+id/txt_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="My title"
            android:layout_marginLeft="10dp"
            />
        <TextView
            android:id="@+id/txt_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:layout_marginRight="10dp"
            android:text="My button"
            android:onClick="txtButton_onClick"
            android:clickable="true"
            />
    </LinearLayout>
    <!-- This is where I _want_ to add all nested contents to make it easy to toggle its visibility -->
    </merge>
    

    I would add two methods in the class like this which you can use to toggle the visibility of your contents or the textViews at the top:

    public void setTopTextViewVisibility(int visibility){
        for(int i = 0; i < getChildCount(); i ++){
            View view = getChildAt(i);
            if(view.getId() == R.id.txt_title || view.getId() == R.id.txt_button){
                view.setVisibility(visibility);
            }
        }
    }
    
    public void setContentVisibility(int visibility){
        for(int i = 0; i < getChildCount(); i ++){
            View view = getChildAt(i);
            if(!(view.getId() == R.id.txt_title || view.getId() == R.id.txt_button)){
                view.setVisibility(visibility);
            }
        }
    }