Brad
Brad

Reputation: 5532

Inflating Android list subviews -> duplicate IDs

I have some content in an Android app which is shown in a list. Each list entry has similar fields - let's say a picture, some text, and a text box. However, some list entries are different than others. The order of the content is based on the result of a server call.

The list itself needs to be fairly dynamic, and I'm currently using a linearlayout rather than a listview for a few reasons. My code looks something like this:

LinearLayout list = findViewById(android.R.id.list);

while (more content to add) {
    switch (content type) {
        case A:
            View v = layoutInflater.inflate(R.layout.list_item_type_a, list, false);
            EditText editText = (EditText)v.findViewById(android.R.id.edit);
            // Do stuff with editText
            list.addView(v);
            break;
        case B:
            View v = layoutInflater.inflate(R.layout.list_item_type_b, list, false);
            ....
    }
}

This works great. Except - when I put this in a fragment, and rotate the screen, now my app crashes because I have multiple fields with the same android.R.id.edit identifier.

I had thought this was a fairly elegant solution and the Android gods seem to disagree. Do I need to rip out the ID for all of my xml sublayouts? If I go this route, how should I grab references to the content?

Upvotes: 0

Views: 335

Answers (4)

Vishal Chauhan
Vishal Chauhan

Reputation: 917

I think this problem occur due to device screen rotation

When the phone rotates and the screen changes orientation, Android usually destroys your application’s existing Activities and Fragments and recreates them. Android does this so that your application can reload resources based on the new configuration.

The most important aspect of handling orientation changes is saving state. In most cases this involves implementing the onSaveInstanceState method (this could be in your Activity, Fragment or both) and placing the values you need to save in the Bundle argument that gets passed to the method.

For more details and code examples... Please read this article

Upvotes: 1

Ishita Sinha
Ishita Sinha

Reputation: 2294

I would suggest using a ListView instead of the LinearLayout and creating a custom adapter to fill the ListView. You could still have the list_item layouts that you have and then add them to the list in the newView method of your adapter. Pass your content type through a method, say getItemViewType(). Something like this:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    // Choose the layout type
    int contentType = getItemViewType();
    int layoutId = -1;
    switch (contentType) {
        case A: {
        View v = layoutInflater.inflate(R.layout.list_item_type_a, list, false);
        EditText editText = (EditText)v.findViewById(android.R.id.edit);
        // Do stuff with editText
        list.addView(v);
        break;
        }
        case B: {
            View v = layoutInflater.inflate(R.layout.list_item_type_b, list, false);
        ....
        }
    }

Upvotes: 1

Kevin Coppock
Kevin Coppock

Reputation: 134664

So obviously, ListView or RecyclerView would be preferable to use here, but since you've stated you have reasons not to, I'd suggest that you disable automatic state saving for each of the views.

You can just call editText.setSaveEnabled(false), which will fix the issue, but have the side effect of not automatically retaining the view's state (e.g. input data will be lost). If you're maintaining this data yourself and restoring it on configuration changes or state restoration, this should be a totally workable solution.

I believe you could also just call setSaveFromParentEnabled(false) on the containing LinearLayout (although I haven't used that flag myself), which should disable state saving for any view in the sub-hierarchy. Same caveat applies.

Upvotes: 1

Scott Kennedy
Scott Kennedy

Reputation: 1346

If you have a dynamic list, you should be using a ListView or RecyclerView.

Upvotes: 0

Related Questions