【问题标题】:onSaveInstanceState null in Fragment everytime每次在 Fragment 中的 onSaveInstanceState null
【发布时间】:2018-06-05 02:19:50
【问题描述】:

我到处寻找解决方案,但没有找到,我需要一些帮助。

我有一个应用程序,它有两个活动,活动 A 和活动 B,但 B 有片段,来自 B 的第一个片段有一个重要数据,当用户返回活动时我不想丢失这些数据A.

我的问题是每次我回到活动 A 并转到 B 时,我的数据都会变空,因为 android 清除了它,所以我对代码进行了一些搜索和更改,但仍然没有找到解决方案。现在我的代码:

活动 A

  fbReceive.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                startActivity(new Intent(MainActivity.this, OmniActivity.class));

            }
        });

我从这一行调用 B,当他们转到 B 时,这是代码:

活动 B

public class OmniActivity extends BaseActivity {

private View parent_view;

private TabLayout tab_layout;

FragmentOmni fragmentOmni     = new FragmentOmni();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_omni_om);
    parent_view = findViewById(R.id.container);

    Tools.setSystemBarColor(this, R.color.new_purple_O200);

    openFragment(fragmentOmni);

    initToolbar();
    initComponent();

}

public void openFragment(final Fragment fragment) {

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.replace(R.id.containerView, fragment, fragment.getTag());
    transaction.addToBackStack(null);
    transaction.commit();

}

@Override
public void onBackPressed() {

   Intent intent = new Intent(this, MainActivity.class);
   startActivityForResult(intent, 1);

}

    private void initToolbar() {

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setNavigationIcon(R.drawable.ic_arrow_back_black_24dp);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle("Voltar");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    toolbar.getNavigationIcon().setColorFilter(getResources().getColor(android.R.color.white), PorterDuff.Mode.SRC_ATOP);

    toolbar.setNavigationOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(OmniActivity.this, MainActivity.class);
                startActivityForResult(intent, 1);

            }
    });

}

当应用程序执行 OpenFragment() 时,它们会从 Fragment 转到这段代码:

片段 A

public class FragmentOmni extends Fragment {

RecyclerView recyclerView;
MDOmniturn controller;


List<HashMap<String, String>> listproduct;
private ArrayList<Product> producttypelist;
Product tpobjproduct;
private ActionMode actionMode;
private ActionModeCallback actionModeCallback;


private ListProductAdapter lpAdapter;

private NestedScrollView nested_scroll_view;

private ImageButton bt_toggle_input;
private Button      bt_hide_input;
private View        lyt_expand_input;

EditText edOmni, edMani,edEan ;

LinearLayout layoutNoResult;

Handler time;
TextWatcher textexample;


private ProgressBar progressBarProduct;

LinearLayout linearLayout;


public FragmentOmni() {
}

public static FragmentOmni newInstance() {
    FragmentOmni fragment = new FragmentOmni();
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    if(savedInstanceState != null){

        producttypelist = savedInstanceState.getParcelableArrayList("list");

    }

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View root = inflater.inflate(R.layout.fragment_omni, container, false);

    return root;
}

@Override
public void onSaveInstanceState(Bundle outState) {

    outState.putParcelableArrayList("list", producttypelist);

    super.onSaveInstanceState(outState);

}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {

    if (savedInstanceState != null) {

        producttypelist = savedInstanceState.getParcelableArrayList("list");

    }


    initexpand(view);

    linearLayout = (LinearLayout) view.findViewById(R.id.container);

    edOmni = (EditText) view.findViewById(R.id.edOmni);
    edMani = (EditText) view.findViewById(R.id.edBManifesto);
    edEan  = (EditText) view.findViewById(R.id.edEan);

    progressBarProduct = (ProgressBar) view.findViewById(R.id.progressBarProduct);

    layoutNoResult = (LinearLayout) view.findViewById(R.id.layoutNoResult);
    recyclerView   = (RecyclerView) view.findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.addItemDecoration(new LineItemDecoration(getActivity(), LinearLayout.VERTICAL));
    recyclerView.setHasFixedSize(true);

    controller      = new MDOmniturn(getActivity());
    producttypelist = new ArrayList<>();
    listproduct     = new ArrayList<>();

    addListenerTextChange(edOmni);

    //set data and list adapter
    lpAdapter = new ListProductAdapter(getActivity(), producttypelist);
    recyclerView.setAdapter(lpAdapter);
    lpAdapter.setOnClickListener(new ListProductAdapter.OnClickListener() {
        @Override
        public void onItemClick(View view, Product obj, int pos) {

            if (lpAdapter.getSelectedItemCount() > 0) {

                enableActionMode(pos);

            } else {

                // read the inbox which removes bold from the row
                Product product = lpAdapter.getItem(pos);
                Toast.makeText(getActivity(), "Read: " + product.prd_description, Toast.LENGTH_SHORT).show();

            }

        }

        @Override
        public void onItemLongClick(View view, Product obj, int pos) {
            enableActionMode(pos);
        }
    });

    actionModeCallback = new ActionModeCallback();

}

FRAGMENT A 中的 savedInstanceState 总是为 NULL,我做错了什么?

【问题讨论】:

    标签: android android-fragments android-activity


    【解决方案1】:

    将您的代码替换为以下顺序

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    
        outState.putParcelableArrayList("list", producttypelist);    
    }
    

    您也可能在错误的状态下期待数据。 例如,savedInstanceState 在第一次启动 Activity 时始终是 null,它也指向您的片段,但如果 Activity 在旋转期间被销毁,则可能是 non-null,因为每次活动都会调用 onCreate启动或重新启动。

    这行transaction.addToBackStack(null); 是不必要的。您可以将片段状态保存在其onStop() 和onPause() 并恢复onResume() 和onCreate()。

    您现在可以在活动 B 中删除 onBackPressed()



    或者,您可以使用共享首选项。退出应用程序时,(onBackPressed,onPause ...)保存您想要的项目。例如游戏的高分。

     activity.getSharedPreferences(getString(R.string.app_name), 
                Context.MODE_PRIVATE).edit().putInt("score", highScore).apply();
    

    检索分数是:

    int value = activity.getSharedPreferences(getString(R.string.app_name), 
                Context.MODE_PRIVATE).getInt("score", 0);
    

    【讨论】:

    • 我放了,但什么也没发生,当他通过 Fragment 的 onViewCreated 验证时,总是为 null。
    • 当我按下我的 Activity B 时,该 Activity 没有被破坏,我对其进行了调试,并从 Activity B 登录 onDestroy 函数从未被破坏。我把这个函数 @Override public void onBackPressed() { Intent intent = new Intent(this, MainActivity.class); startActivityForResult(intent, 1); } 为了防止这种情况,你知道吗?当用户转到另一个活动时,我只想保存片段中的数据,当他回到具有片段 A 的活动 A 时,他会看到旧数据。
    • @Wavrik 为答案添加更多内容
    • 嗨 Lucem,感谢您的帮助。我在这个线程中看到从堆栈溢出到持久性数据不是一个好习惯的saveInstanceState。 stackoverflow.com/questions/151777/… 必须按照你说的做,OnPause() 或 OnResume() 但我该怎么做呢?如果转到 OnPause 并且我的变量会丢失?更改活动后我将如何恢复它?另一件事,我不想要共享偏好解决方案。
    • 它实际上是更简单的方法。你想让我用替代方法编辑答案吗? @Wavrik
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    相关资源
    最近更新 更多