Restore fragment with two views having the same id

对着背影说爱祢 提交于 2019-12-07 02:59:25

问题


I have a complex layout to implement. It has 19 sections that can be displayed or not based on plenty of parameters previously entered by the user. In order to simplify the code and to not display unused sections, the layout is created dynamically.

Everything is inside a fragment. The fragment has a LinearLayout used as a container and, when the fragment is created, I generate all the necessary sections.

Each section is managed by its own local adapter which is in charge to inflate the layout of this section and to add it into the container.

Everything works perfectly fine. The issue is that 2 sections have the exact same structure so they share the same xml layout. Because of that the internal views of both sections have the same id. This is not an issue as the section is managed locally in its adapter. The problem appears when I go to the next fragment and then go back to this one. The system tries to recover the previous state of the view and, because these 2 sections have the same ids, when the second section is restored, its values are set to the first one too.

Is there any solution to manage that or to tell the fragment to not restore its state (as everything is manually reloaded anyway).

Here is an light example of the current structure:

fragment xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

section xml

<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/section_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

fragment code

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_layout, container, false);

    if (<condition>)
       createSection1(getContext(),view);

    if (<condition>)        
       createSection2(getContext(),view);

    return view;
}


private void createSection1(Context context, ViewGroup root){
    Section1Adapter adapter = new Section1Adapter(context, root);
    // ...
}

private void createSection2(Context context, ViewGroup root){
    Section2Adapter adapter = new Section2Adapter(context, root);
    // ...
}

adapter code (same idea for both)

public Section2Adapter(LayoutInflater inflater, ViewGroup root) {

    View view = LayoutInflater.from(context).inflate(R.layout.section_layout, root, false);

    initView(view);

    root.addView(view);
}

回答1:


Your issue, as you correctly said, is that basically, you are in this state:

What you need to do, is to tell Android yourself at what key in the SparseArray to save the state of which EditText. Basically, you need to get to this:

The mechanism through which you achieve this is very well explained in this amazing article, by Pasha Dudka. (credits to him for the nice images, also)

Just search for "View IDs should be unique" in the article, and you'll have your answer.

The gist of the solution for your particular situation is one the following:

  • you can subclass LinearLayout s.t. your CustomLinearLayout will know the Section a child belongs to, when its state. This way, you can save all child states within a section to a SparseArray dedicated just for that section, and add the dedicated SparseArray to the global SparseArray (just like in the image)
  • you can subclass EditText, s.t. your CustomEditText know in which section it belongs to, and will save its state at a custom key in the SparseArray - e.g. section_text_Section1 for the first section, and section_text_Section2 for the second one

Personally, I prefer the first version, since it will work even if you later add more views to your Sections. The second will not work with more views, since in the second it's not parent that does the smart state saving, but the view itself.

Hope this helps.



来源:https://stackoverflow.com/questions/45818015/restore-fragment-with-two-views-having-the-same-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!