Héctor
Héctor

Reputation: 26054

Inflate activity layout in custom view constructor

I have a custom button with a custom XML string property watch_enable that is the name of a EditText. In the constructor of the button, I want read this property, and obtain the EditText with this name.

I use my custom button like:

<EditText
    android:id="@+id/edit_login_password"
    android:inputType="textPassword"
    android:text=""/>

<my.project.widgets.WatchingButton
    android:text="Enter"
    app:watch_enable="edit_login_password"/>

And this is my button's class:

public WatchingButton(Context context, AttributeSet attrs) {

    super(context, attrs);
    TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.WatchingButton);
    for (int i = 0; i < attributes.getIndexCount(); i++) {

        int attribute = attributes.getIndex(i);
        if (attribute == R.styleable.WatchingButton_watch_enable) {

            String value = attributes.getString(attribute); //<-- OK, value is edit_text_username
            int idEdittext = context.getResources().getIdentifier(value, "id", context.getPackageName()); //<-- OK, I obtain the resource ID
            Activity activity = (Activity) context;
            EditText et = (EditText)((Activity)context).findViewById(idEditText); //<-- Error. et is null.
            //DO STUFF
        }
    }
}

I guess the activity is not inflated yet and I can't obtain views from it. What can I do?

Thanks.

Upvotes: 0

Views: 786

Answers (3)

H&#233;ctor
H&#233;ctor

Reputation: 26054

Solved!! First of all, thanks to all for answering.

First, I have done what Ankit Bansal said, reference view by @id instead of by name.

  <com.grupogimeno.android.hoteles.widgets.WatchingButton
            android:text="Enter"
            app:watch_enable="@id/edit_login_password"/>

Like I though, I couldn't obtain parent layout's views in the constructor beacuse this layout is not completely inflated yet. So I store the value of watch_enable property in a variable.

public WatchingButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.WatchingButton);
        this.id = attributes.getResourceId(R.styleable.WatchingButton_watch_enable, 0);
}

Then, when layout is completely inflated onAttachedToWindow method is called in all its views, so I obtain the EditText here:

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
           EditText et = (EditText)((Activity)getContext()).findViewById(this.id);//<-- OK 
         //DO STUFF
        }
    }

Upvotes: 1

ρяσѕρєя K
ρяσѕρєя K

Reputation: 132982

Try it as by get parent view of WatchingButton view:

ViewGroup parentView = (ViewGroup)WatchingButton.this.getParent(); 
EditText et = (EditText)parentView.findViewById(idEditText);

Upvotes: 1

Ankit Bansal
Ankit Bansal

Reputation: 1811

In place of using a String for making id app:watch_enable="edit_login_password" use Reference and pass app:watch_enable="@id/edit_login_password" which will give you integer value of id that is referenced.

Upvotes: 1

Related Questions