在事务之间维护片段实例状态

时间:2015-01-23 08:55:30

标签: android android-fragments android-support-library instancestate

我在SO上找到的所有搜索都说明你应该在@Override public void onSaveInstanceState(Bundle outState)

中保存你的实例状态

然而,这与活动生活方式紧密相连。

如何将listview的状态保存在与另一个片段交换的片段中。 我有一个主要活动,所有碎片都被加载到其中。

到目前为止我已尝试过这个:

    @Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //Save adapter data so that when the fragment is returned to it can be resused.
    ArrayList<CategoryMobileDto> categories = new ArrayList<CategoryMobileDto>();
    for(int i=0; i < adapter.getCount();i++)
    {
        categories.add(adapter.getItem(i));
    }
    String persistData = new Gson().toJson(categories);
    outState.putString("Categories", persistData);        
}

然后在我的OnCreate();

   if(savedInstanceState!=null)
    {
        String data =savedInstanceState.getString("Categories");
        Type collectionType = new TypeToken<ArrayList<CategoryMobileDto>>() {
        }.getType();
        adapter.addAll(gson.<Collection<CategoryMobileDto>>fromJson(data, collectionType));
        adapter.notifyDataSetChanged();
    }else{
       // Make request to server
    }

savedInstanceState始终为空。但这是有道理的,因为我的活动没有被破坏和重建。

这是我从一个片段转换到另一个片段的方式:

    fragment.setArguments(args);
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container, fragment, "ProductListFragment");
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

有什么方法可以在删除片段时保存listview的状态,然后在从后栈中弹出片段时再次恢复它?

2 个答案:

答案 0 :(得分:0)

将此代码从onCreate()移动到Fragment的onActivityCreated()

if(savedInstanceState!=null)
    {
        String data =savedInstanceState.getString("Categories");
        Type collectionType = new TypeToken<ArrayList<CategoryMobileDto>>() {
        }.getType();
        adapter.addAll(gson.<Collection<CategoryMobileDto>>fromJson(data, collectionType));
        adapter.notifyDataSetChanged();
    }else{
       // Make request to server
    }

如果您有任何疑问,请告诉我。

答案 1 :(得分:0)

您可以将参数与片段一起使用(只有在片段加载之前有片段显示的数据意味着附加)。你可以将setArguments设置为一个片段,当你通过片段事务转到另一个片段时它将被保留,当你回来时,从getArguments函数加载片段。

public void setArguments(Bundle args)

在API级别11中添加 提供此片段的构造参数。这只能在片段附加到其活动之前调用;也就是说,你应该在构造片段后立即调用它。这里提供的参数将在片段销毁和创建中保留。

public final Bundle getArguments()

在API级别11中添加 返回片段实例化时提供的参数,如果有的话。

请查看以下示例代码,以便在片段之间传递数据:

main.xml中

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >

</FrameLayout>

MainActivity.java

public class MainActivity extends Activity implements IFragContainer {

private static final String FRAG_TAG = "FragTag";
private FragBase mFrag;
private String dataToBePassedBack;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    changeFragment(FragA.class, "Data to Frag A");
}

@Override
public void changeFragment(Class<? extends FragBase> fragClass, String data) {
    try {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        mFrag = fragClass.newInstance();
        Bundle args = new Bundle();
        args.putString("DATA", data);
        mFrag.setArguments(args);
        ft.replace(R.id.flContainer, mFrag, FRAG_TAG);
        ft.addToBackStack(mFrag.toString());
        ft.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void onBackPressed() {
    dataToBePassedBack = mFrag.getDataToPassBack();
    FragmentManager mgr = getFragmentManager();
    mgr.executePendingTransactions();

    boolean doCheckAndExit = true;

    for (int i = mgr.getBackStackEntryCount() - 1; i > 0; i--) {
        BackStackEntry entry = mgr.getBackStackEntryAt(i);

        if (!TextUtils.isEmpty(entry.getName())) {
            mgr.popBackStackImmediate(entry.getId(),
                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
            doCheckAndExit = false;
            break;
        }
    }

    if (doCheckAndExit) {
        finish();
    } else {
        mFrag = (FragBase) mgr.findFragmentByTag(FRAG_TAG);
    }
}

@Override
public String getDataToBePassedBack() {
    return dataToBePassedBack;
}

}

IFragContainer.java

public interface IFragContainer {
void changeFragment(Class<? extends FragBase> fragClass, String data);

String getDataToBePassedBack();
}

FragBase.java

public abstract class FragBase extends Fragment {

public String getDataToPassBack(){
    return null;
}

}

FragA.java

public class FragA extends FragBase {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Button btn = new Button(getActivity());
    final IFragContainer fragContainer = (IFragContainer) getActivity();
    if (TextUtils.isEmpty(fragContainer.getDataToBePassedBack())) {
        btn.setText(getArguments().getString("DATA"));
    } else {
        btn.setText(fragContainer.getDataToBePassedBack());
    }
    btn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT));
    btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            fragContainer.changeFragment(FragB.class, "Data to Frag B");
        }
    });
    return btn;
}

}

FragB.java

public class FragB extends FragBase {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Button btn = new Button(getActivity());
    btn.setText(getArguments().getString("DATA"));
    btn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT));
    btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            getActivity().onBackPressed();
        }
    });
    return btn;
}

@Override
public String getDataToPassBack() {
    return "Data from Frag B to A";
}
}