AWT
AWT

Reputation: 3707

Is it possible to reuse the outer elements of an Android layout?

I have two very similar Android layouts:

default_spinner.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="@dimen/settings_line_min_height"
    android:orientation="horizontal"
    android:paddingLeft="@dimen/common_padding"
    android:paddingRight="@dimen/common_padding">

    <TextView
        android:id="@id/label"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" />

    <ImageButton
        android:id="@+id/down_spinner_btn"
        style="@style/SpinnerDownButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

    <EditText
        android:id="@+id/edit_box"
        style="@style/EditableSpinnerText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:inputType="number"
        android:imeOptions="actionDone"
        android:longClickable="false" />

    <ImageButton
        android:id="@+id/up_spinner_btn"
        style="@style/SpinnerUpButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

</LinearLayout>

and

custom_spinner.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingLeft="@dimen/common_padding"
    android:paddingRight="@dimen/common_padding">

    <TextView
        android:id="@id/label"
        style="@style/Subhead.Translucent"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" />

    <ImageButton
        android:id="@+id/down_spinner_btn"
        style="@style/SpinnerDownButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

    <com.company.CustomEditText
        android:id="@+id/edit_box"
        style="@style/EditableSpinnerText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:inputType="text" />

    <ImageButton
        android:id="@+id/up_spinner_btn"
        style="@style/SpinnerUpButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

</LinearLayout>

As you can see, the only difference between the two is that the second one has a custom implementation of the EditText class.

In some classes, I load the default spinner:

View view = inflater.inflate(R.layout.default_spinner, parent, false);

And in other classes, I load the custom spinner:

View view = inflater.inflate(R.layout.custom_spinner, parent, false);

This all works fine, but the inefficiency bothers me.

I know it's possible to reuse layout elements in Android using the <import /> command... however, I'm not sure if that would be applicable here. Since a majority of both of these layouts is the same, I'd like to consolidate the identical code and just have it use either the CustomEditText or EditText class, depending on the situation.

Does anyone have an idea of how I could reuse the outer elements of these layouts and eliminate all of that duplication?

Upvotes: 3

Views: 427

Answers (2)

Fl&#225;vio Faria
Fl&#225;vio Faria

Reputation: 6605

Yes, there is. In this case, you can have a single layout file with a ViewStub in place of EditText/CustomEditText. Like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingLeft="@dimen/common_padding"
    android:paddingRight="@dimen/common_padding">

    <TextView
        android:id="@id/label"
        style="@style/Subhead.Translucent"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" />

    <ImageButton
        android:id="@+id/down_spinner_btn"
        style="@style/SpinnerDownButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

    <ViewStub
        android:id="@+id/view_stub"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <ImageButton
        android:id="@+id/up_spinner_btn"
        style="@style/SpinnerUpButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

</LinearLayout>

Then, in your Java code, you will lazily inject the EditText of your choice:

ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);
viewStub.setLayoutResource(someCondition ? R.layout.custom_edit_text : R.layout.regular_edit_text);
viewStub.inflate();

As you can see, you'll have two more layout files for each EditText:

custom_edit_text.xml

<com.company.CustomEditText
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/edit_box"
        style="@style/EditableSpinnerText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:inputType="text" />

regular_edit_text.xml

<EditText
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/edit_box"
        style="@style/EditableSpinnerText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:inputType="text" />

Upvotes: 6

Anton Malyshev
Anton Malyshev

Reputation: 8851

I think, the best way is to use single layout adding different views programmatically. That's how it would be easier to support in future.

Upvotes: 1

Related Questions