我在使應用程序持續存在困難。當我旋轉手機時,屏幕上的數據不會改變。但是當我點擊一個按鈕來檢索一個新的片段後,我得到一個錯誤,說「在onSaveInstanceState之後不能執行這個動作」。我搜索了一下,發現了類似的問題,但我仍然不知道如何解決這個問題。如何在手機方向上保存我的數據?
我有一個活動類,一個控制器類和兩個片段類。 活動類有一個帶有2個按鈕的瀏覽查看器,可以觸發片段交易。也就是說,在每個按鈕上單擊它將用當前按鈕偵聽器中設置的片段替換當前片段。我的控制器類創建系統,碎片就是UI。
我的活動類:
public class LoggedInActivity extends AppCompatActivity {
private final String TAG = "LoggedInActivity: ";
private Controller controller;
private TextView navName;
private NavigationView navigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logged_in);
if(savedInstanceState == null) {
Log.v(TAG, "savedInstanceState == null");
initComponents();
setNavName();
initListener();
initializeSystem();
} else {
Log.v(TAG, "savedInstanceState != null");
initComponents();
setNavName();
initListener();
this.controller = (Controller)savedInstanceState.getSerializable("controller");
}
}
private void initComponents() {
navigationView = (NavigationView) findViewById(R.id.navigation_view);
View headerView = navigationView.getHeaderView(0);
navName = (TextView) headerView.findViewById(R.id.tv_name_surname);
}
private void initListener() {
navigationView.setNavigationItemSelectedListener(new MyNavigationItemListener());
}
private void initializeSystem() {
Log.v(TAG, "new controller");
controller = new Controller(this, null);
}
public void setFragment(Fragment fragment) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container_logged_in, fragment).commit();
}
private class MyNavigationItemListener implements NavigationView.OnNavigationItemSelectedListener {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()) {
case R.id.drawer_summary:
controller.setFragmentSummary();
break;
case R.id.drawer_income:
controller.setFragmentIncome();
break;
}
return false;
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("controller", controller);
super.onSaveInstanceState(outState);
Log.v(TAG, "onSaveInstanceState, saving the controller");
}
}
我的控制器類:
public class Controller implements Serializable {
private final String TAG = "Controller: ";
/********************** Fragments ***********************/
private Fragment_Income fragment_income;
private Fragment_Summary fragment_summary;
/********************************************************/
/********************** Activities **********************/
private LoggedInActivity logged_in_activity;
/********************************************************/
public Controller(LoggedInActivity logged_in_activity) {
this.logged_in_activity = logged_in_activity;
initLoggedInFragments();
setFragmentSummary();
}
}
/* Initializes fragments that are connected to LoggedInActivity */
private void initLoggedInFragments() {
fragment_income = new Fragment_Income();
fragment_income.setController(this);
fragment_summary = new Fragment_Summary();
fragment_summary.setController(this);
}
/* use to replace current fragment with the given one */
private void replaceFragmentWith(Fragment fragment) {
logged_in_activity.setFragment(fragment);
}
/***********************************************************
* METHODS REGARDING FRAGMENT INCOME *
**********************************************************/
public void setFragmentIncome() {
replaceFragmentWith(fragment_income);
}
/* Summary fragment is started at first */
public void setFragmentSummary() {
replaceFragmentWith(fragment_summary);
}
}
Fragment_Income:
public class Fragment_Income extends Fragment implements Serializable{
private final String TAG = "Fragment_Income: ";
private Controller controller;
private FloatingActionButton fab_income;
private ListView lv_income;
private ArrayList<LvData> incomeData;
private LvAdapterIncome lvAdapterIncome;
public Fragment_Income() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.v(TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_income, container, false); // Inflate the layout for this fragment
if(savedInstanceState != null) {
this.controller = (Controller) savedInstanceState.getSerializable("controller");
}
initComponents(view);
initListener();
setupListView();
return view;
}
private void initComponents(View view) {
fab_income = (FloatingActionButton) view.findViewById(R.id.fab_income);
lv_income = (ListView) view.findViewById(R.id.lv_income);
}
private void initListener() {
ButtonListener buttonListener = new ButtonListener();
fab_income.setOnClickListener(buttonListener);
}
private void setupListView() {
if (incomeData == null) { // checks if incomeData have been initalized before, if so do not change array to defualt
incomeData = new ArrayList<>();
lvAdapterIncome = new LvAdapterIncome(getContext(), incomeData);
}
lv_income.setAdapter(lvAdapterIncome);
}
public void setController(Controller controller) {
this.controller = controller;
}
@Override
public void onSaveInstanceState(Bundle outState) {
Log.v(TAG, "onSaveInstanceState, saving the controller");
outState.putSerializable("controller", this.controller);
super.onSaveInstanceState(outState);
}
}
Fragment_Summary:
public class Fragment_Summary extends Fragment implements Serializable {
private static final String TAG = "Fragment_Summary: ";
private Controller controller;
private TextView tv_user;
private TextView tv_total_revenue;
private TextView tv_total_expenditure;
private TextView tv_balance;
private float totalRevenue;
private float totalExpenditure;
private float balance;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_summary, container, false);// Inflate the layout for this fragment
initComponents(view);
setUserName();
if(savedInstanceState == null) {
//DO SOMETHING
}
return view;
}
private void addData() {
totalRevenue = controller.getTotalRevenue();
totalExpenditure = controller.getTotalExpenditure();
balance = totalRevenue - totalExpenditure;
tv_total_revenue.setText(String.valueOf(totalRevenue));
tv_total_expenditure.setText(String.valueOf(totalExpenditure));
tv_balance.setText(String.valueOf(balance));
}
private void initComponents(View view) {
tv_user = (TextView)view.findViewById(R.id.tv_user);
tv_total_revenue = (TextView)view.findViewById(R.id.tv_revenue);
tv_total_expenditure = (TextView)view.findViewById(R.id.tv_sum_exp);
tv_balance = (TextView)view.findViewById(R.id.tv_balance);
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("revenue", String.valueOf(balance));
outState.putString("totalExpenditure", String.valueOf(balance));
outState.putString("balance", String.valueOf(balance));
super.onSaveInstanceState(outState);
}
public void setController(Controller controller) {
this.controller = controller;
}
}
我從我的課監守我因子評分,他們不適合此問題,取消了所有的頭文件和一些方法。
以下是錯誤日誌:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1434)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1452)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:708)
at android.app.BackStackRecord.commit(BackStackRecord.java:672)
at com.example.user.my_app.LoggedInActivity.setFragment(LoggedInActivity.java:85)
at com.example.user.my_app.Controller.replaceFragmentWith(Controller.java:89)
at com.example.user.my_app.Controller.setFragmentIncome(Controller.java:99)
at com.example.user.my_app.LoggedInActivity$MyNavigationItemListener.onNavigationItemSelected(LoggedInActivity.java:127)
at android.support.design.widget.NavigationView$1.onMenuItemSelected(NavigationView.java:156)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:156)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:969)
at android.support.design.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:342)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
嘗試使用'getSupportFragmentManager()'而不是'getFragmentManager()'因爲您使用'AppCompatActivity' – ono
沒有幫助,謝謝你的答案。我發現奇怪的是,當我將commit()更改爲commitAllowingStateLoss()時,代碼給了我以下錯誤「IllegalStateException:Activity已被銷燬」。但是,如果它已經在onCreate方法中創建,它怎麼會被銷燬呢? – Pakash