Android 在配置更改上保存和恢复片段视图状态

Android 在配置更改上保存和恢复片段视图状态,android,android-fragments,fragment,Android,Android Fragments,Fragment,编辑 我一直在搜索和阅读很多关于这个话题的文章,但我就是找不到解决问题的方法。我不知道我是做错了什么,还是设计错了什么 我的活动中有一个片段,这个片段有三种不同的布局,出现或消失(这取决于用户做了什么或正在做什么)。此外,还将创建一个视图组,动态添加新的文本视图。当屏幕的方向改变时,我想保留片段的所有视图,保持布局不可见,保持所有文本视图不变,等等 我知道当屏幕方向改变时,片段和活动的生命周期是如何工作的,但我不知道如何管理它。如何以及从何处恢复仍在内存中的片段,如何恢复视图并在onCreate

编辑

我一直在搜索和阅读很多关于这个话题的文章,但我就是找不到解决问题的方法。我不知道我是做错了什么,还是设计错了什么

我的活动中有一个片段,这个片段有三种不同的布局,出现或消失(这取决于用户做了什么或正在做什么)。此外,还将创建一个视图组,动态添加新的文本视图。当屏幕的方向改变时,我想保留片段的所有视图,保持布局不可见,保持所有文本视图不变,等等

我知道当屏幕方向改变时,片段和活动的生命周期是如何工作的,但我不知道如何管理它。如何以及从何处恢复仍在内存中的片段,如何恢复视图并在onCreateView中返回它。我对这件事感到困惑

下面是片段的xml文档

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true"
android:weightSum="1">

<RelativeLayout
        android:id="@+id/top_layout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:padding="8dp"
        android:animateLayoutChanges="true"
        android:weightSum="1"
        android:background="#fc033967">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15sp"
            android:fontFamily="sans-serif-condensed"
            android:textColor="#ffffff"
            android:text="@string/scan_new_code_location"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="20dp"
            android:layout_gravity="center_vertical"
            android:id="@+id/location_textView" />

        <LinearLayout
            android:id="@+id/new_location_layout"
            android:layout_width="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageButton
                    android:id="@+id/new_location_image"
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:background="@android:color/transparent"
                    android:layout_marginLeft="20dp"
                    android:src="@drawable/ic_action_new"
                    android:layout_gravity="center_vertical"/>

                <Button
                    android:id="@+id/boton_nuevaLoc"
                    android:text="@string/newLocation"
                    android:fontFamily="sans-serif-condensed"
                    android:textColor="#ffffff"
                    android:textSize="15sp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="20dp"
                    android:background="@android:color/transparent"
                    android:layout_gravity="center_vertical"
                    />

        </LinearLayout>

        <RelativeLayout
            android:id="@+id/cancel_ingress_layout"
            android:layout_gravity="center_vertical"
            android:layout_width="40dp"
            android:layout_height="match_parent"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true">
        </RelativeLayout>

    </RelativeLayout>


<RelativeLayout
    android:id="@+id/location_container"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:padding="8dp"
    android:layout_gravity="center"
    android:animateLayoutChanges="true"
    android:weightSum="1"
    android:background="#fc033967">


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:orientation="horizontal">

        <ImageButton
            android:id="@+id/location_image"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:background="@android:color/transparent"
            android:layout_marginLeft="20dp"
            android:src="@android:drawable/ic_menu_mylocation"
            android:layout_gravity="center_vertical"/>

        <TextView
            android:id="@+id/added_location_textView"
            android:text="@string/newLocation"
            android:fontFamily="sans-serif-condensed"
            android:textColor="#ffffff"
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="20dp"
            android:background="@android:color/transparent"
            android:layout_gravity="center_vertical"
            />

    </LinearLayout>

    <RelativeLayout
        android:id="@+id/close_location_container"
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true">

        <ImageButton
            android:id="@+id/close_location_image"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:background="@android:color/transparent"
            android:layout_marginLeft="20dp"
            android:src="@android:drawable/ic_menu_send"
            android:layout_gravity="center_vertical"/>

    </RelativeLayout>

</RelativeLayout>

<LinearLayout android:id="@+id/container"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@android:color/transparent"
        android:layout_marginTop="15dp"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:animateLayoutChanges="true"
        android:visibility="invisible"/>



<EditText
        android:id="@+id/scan_reader_EditText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="500dp"
        android:inputType="text"/>

</LinearLayout>
***************编辑***********************

嗯。多亏了Endzeit,我才解决了这个问题

我需要这样做: 在片段中,我创建了一个视图变量,将视图引用到片段并保留实例。 然后,如果存在已保存的实例,我将在onCreateView中返回对已保存视图的引用。这样地: 公共类LocationFragment扩展了片段{

    private static final String TAG = "LocationFragment";

    //Graphics elements
    @Bind(R.id.top_layout) RelativeLayout topLayout;
                .
                .
                .
    static ViewGroup panelIngresarItem;
    **View rootView**;


    public LocationFragment() {
        // Required empty public constructor
    }

    public static LocationFragment newInstance() {
        LocationFragment fragment = new LocationFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        **setRetainInstance(true)**;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        **if (savedInstanceState == null)** {
            **rootView = inflater.inflate(R.layout.fragment_location, container, false);**
            ButterKnife.bind(this, rootView);
        }

        **return rootView;**
    }

    public void onViewCreated(View view, Bundle savedInstanceState){

        if(savedInstanceState == null) {
            locationTextView.setVisibility(View.GONE);
            translation = topLayout.getMeasuredWidth() - addLocationLayout.getMeasuredWidth() +
                    newLocationButton.getMeasuredWidth();
            cancelScanLayout.setOnClickListener(new CloseButtonListener());
            cancelScanLayout.setClickable(false);

            // Add item listener, for only create one listener
            addItemListener = new AddItemListener();

            closeImageButton.setOnClickListener(new CloseLocationListener());

            panelIngresarItem = (ViewGroup) LayoutInflater.from(this.getActivity()).inflate(
                    R.layout.new_item_panel, containerLayout, false);
            panelIngresarItem.setOnClickListener(addItemListener);

            scanLocationMode = true;
            closeLayout.setVisibility(View.GONE);
            super.onViewCreated(view, savedInstanceState);
        }
    }
                .
                .
                .

}
然后在活动中,将片段放入FragmentManager中,如果有保存的实例,则再次获取该片段

public class MainActivity extends AppCompatActivity {


    private FragmentManager fm;
    public static final String FRAG_LOCATION = "frag_loc";
    private LocationFragment fragmentLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fm = getSupportFragmentManager();
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            fragmentLocation = new LocationFragment();
        } else {
            fragmentLocation = (LocationFragment) fm
                    .getFragment(savedInstanceState,FRAG_LOCATION);
        }

        fm.beginTransaction()
                .replace(R.id.container_fragment, fragmentLocation)
                .commit();

        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setIcon(R.drawable.ic_launcher_other);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        if(fragmentLocation != null) {
            getSupportFragmentManager().putFragment(outState,FRAG_LOCATION, fragmentLocation);
        }

        super.onSaveInstanceState(outState);
    }
                            .
                            .
                            .

}

例如,我想保存片段和活动的旋转状态

您必须在activities
onSaveInstanceState()
方法上保存片段

要实现这一点,请将代码更改为:

    public static final String TAG_FRAG_LOCATION = "key_frag_loc";  
    private LocationFragment fragmentLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

    ...

    fm = getSupportFragmentManager();

    if(savedInstanceState != null) {
        fragmentLocation = (LocationFragment) fragmentManager
                .findFragmentByTag(savedInstanceState.getString(TAG_FRAG_LOCATION));
    } else {
        fragmentLocation = new LocationFragment(); 
    }

    fm.beginTransaction()
                .replace(R.id.container_fragment, fragmentLocation)
                .commit();

     ...
    }


    @Override
    public void onSaveInstanceState(Bundle outState) {
        if(fragmentLocation != null) {
            outState.putString(TAG_FRAG_EXAMS, fragmentLocation.getTag());
        }

        super.onSaveInstanceState(outState);
    }
public class MainActivity extends AppCompatActivity {


    private FragmentManager fm;
    public static final String FRAG_LOCATION = "frag_loc";
    private LocationFragment fragmentLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fm = getSupportFragmentManager();
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            fragmentLocation = new LocationFragment();
        } else {
            fragmentLocation = (LocationFragment) fm
                    .getFragment(savedInstanceState,FRAG_LOCATION);
        }

        fm.beginTransaction()
                .replace(R.id.container_fragment, fragmentLocation)
                .commit();

        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setIcon(R.drawable.ic_launcher_other);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        if(fragmentLocation != null) {
            getSupportFragmentManager().putFragment(outState,FRAG_LOCATION, fragmentLocation);
        }

        super.onSaveInstanceState(outState);
    }
                            .
                            .
                            .

}
    public static final String TAG_FRAG_LOCATION = "key_frag_loc";  
    private LocationFragment fragmentLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

    ...

    fm = getSupportFragmentManager();

    if(savedInstanceState != null) {
        fragmentLocation = (LocationFragment) fragmentManager
                .findFragmentByTag(savedInstanceState.getString(TAG_FRAG_LOCATION));
    } else {
        fragmentLocation = new LocationFragment(); 
    }

    fm.beginTransaction()
                .replace(R.id.container_fragment, fragmentLocation)
                .commit();

     ...
    }


    @Override
    public void onSaveInstanceState(Bundle outState) {
        if(fragmentLocation != null) {
            outState.putString(TAG_FRAG_EXAMS, fragmentLocation.getTag());
        }

        super.onSaveInstanceState(outState);
    }