AlexVogel
AlexVogel

Reputation: 10621

Custom View which has subviews with same id

I've implemented a custom view with hosts two subviews which are identified by an id in the xml. When using two of this custom view in the same layout I run into the problem that it is random which custom view is chosen.

How can I write a custom view with different view ids that can be multiply used in the same layout?

Here is the xml of the custom view:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >

<EditText
    android:id="@+id/clearable_edit"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:inputType="textCapWords"
    android:paddingRight="35dip" />

<Button
    android:id="@+id/clearable_button_clear"
    android:layout_width="30dip"
    android:layout_height="30dip"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_marginRight="5dip"
    android:background="@drawable/clear_button" />

</RelativeLayout>

The id (android:id="@+id/clearable_edit") of the EditText is the problem here.

Usage of custom view:

<LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <com.custom.package.ClearableEditText
                android:id="@+id/arr_location"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                 >
            </com.custom.package.ClearableEditText>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <com.custom.package.ClearableEditText
                android:id="@+id/dep_location"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                 >
            </com.custom.package.ClearableEditText>
        </LinearLayout>

In this example the views of type "ClearableEditText" share the same id of their EditText subview.

Here is the code for ClearableEditText:

public class ClearableEditText extends RelativeLayout {

private LayoutInflater inflater = null;
private EditText edit_text;
private Button btn_clear;

public ClearableEditText(Context context, AttributeSet attrs, int defStyle){
    super(context, attrs, defStyle);
    initViews();
}

public ClearableEditText(Context context, AttributeSet attrs){
    super(context, attrs);
    initViews();

}

public ClearableEditText(Context context){
    super(context);
    initViews();
}

private void initViews(){
    inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.clearable_edittext, this, true);
    edit_text = (EditText) view.findViewById(R.id.clearable_edit);
    btn_clear = (Button) findViewById(R.id.clearable_button_clear);
    btn_clear.setVisibility(RelativeLayout.INVISIBLE);
}
}

Upvotes: 8

Views: 3424

Answers (2)

AlexVogel
AlexVogel

Reputation: 10621

I've found a solution.

I've added a method to ClearableEditText where you can set the id of the underlying EditText from outside the object and set it with a new id.

Here is a code sample:

//inside ClearableEditText
public void setEditId(int id){
    edit_text.setId(id);
}

//somewhere else

departureLocation = (ClearableEditText)view.findViewById(R.id.dep_location);
departureLocation.setEditId(R.id.clearable1);
arrivalLocation = (ClearableEditText)view.findViewById(R.id.arr_location);         
arrivalLocation.setEditId(R.id.clearable2);

The Ids are created with a "ids.xml" in the values folder, which causes eclipse/ADT to create a placeholder id for the entered items

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <!-- This file is used to create unique ids for custom views, which will be used more 
   than once in the same layout file. Using unique ids prevents the custom view from         getting 
   the wrong state. -->
        <item name="clearable1" type="id"></item>
        <item name="clearable2" type="id"></item>
</resources>

Upvotes: 2

M-Wajeeh
M-Wajeeh

Reputation: 17284

First fetch parent View like this:

View v1 = findViewById(R.id.arr_location);

and then

EditText ed1 = (EditText)v1.findViewById(R.id.clearable_edit);

Similarly

View v2 = findViewById(R.id.dep_location);
EditText ed2 = (EditText)v2.findViewById(R.id.clearable_edit);

This way you can add as many ClearableEditText as you want having same id for EditText and Button. Just make sure that every ClearableEditText has different id e.g. in this case R.id.arr_location and R.id.dep_location.

Upvotes: 2

Related Questions