代码之家  ›  专栏  ›  技术社区  ›  TychoTheTaco

getSavedInstanceState()和onViewStateRestored()捆绑包存在问题

  •  0
  • TychoTheTaco  · 技术社区  · 10 年前

    我在活动中有一个片段,当设备旋转时,会调用onSaveInstanceState()和onViewStateRestored()。

    onSaveInstanceState():

    @Override
    public void onSaveInstanceState(Bundle outState){
        Log.e("Fragment", "Called onSaveInstanceState");
    
        outState = getSavedInstanceState();
    
        super.onSaveInstanceState(outState);
    }
    

    这是在onSaveInstanceState()中设置outState包的原因:

    public static Bundle getSavedInstanceState(){
        Bundle saveState = new Bundle();
    
        //Save view states
        saveState.putBoolean("startButtonVisible", buttonStart.getVisibility() == View.VISIBLE);
        saveState.putBoolean("stopButtonVisible", buttonStop.getVisibility() == View.VISIBLE);
        saveState.putBoolean("resetButtonVisible", buttonReset.getVisibility() == View.VISIBLE);
        saveState.putBoolean("saveButtonVisible", buttonSave.getVisibility() == View.VISIBLE);
        saveState.putBoolean("openLatestFileButtonVisible", buttonOpenLatestFile.getVisibility() == View.VISIBLE);
    
        saveState.putBoolean("editTextStartValueVisible", editTextStartValue.isEnabled());
        saveState.putBoolean("buttonStartValueDownVisible", buttonStartValueDown.isEnabled());
        saveState.putBoolean("buttonStartValueUpVisible", buttonStartValueUp.isEnabled());
        saveState.putBoolean("editTextEndValueVisible", editTextEndValue.isEnabled());
        saveState.putBoolean("buttonEndValueDownVisible", buttonEndValueDown.isEnabled());
        saveState.putBoolean("buttonEndValueUpVisible", buttonEndValueUp.isEnabled());
    
        return saveState;
    }
    

    这将正确保存数据,但当调用onViewStateRestored()时,数据不正确。

    @Override
    public void onViewStateRestored(Bundle savedInstanceState){
        Log.e("Fragment", "Called onViewStateRestored");
    
        super.onViewStateRestored(savedInstanceState);
    
        //Restore view states
        if (savedInstanceState != null){
    
            restoreInstanceState(savedInstanceState);
    
            if (buttonReset.getVisibility() == View.VISIBLE){
                updateUi();
            }
        }
    }
    

    当调用onViewStateRestored()时,它还调用restoreInstanceState(),这是恢复每个视图状态的方法。

    public static void restoreInstanceState(Bundle savedInstanceState){
        buttonStart.setVisibility(savedInstanceState.getBoolean("startButtonVisible") ? View.VISIBLE : View.INVISIBLE);
        buttonStop.setVisibility(savedInstanceState.getBoolean("stopButtonVisible") ? View.VISIBLE : View.INVISIBLE);
        buttonReset.setVisibility(savedInstanceState.getBoolean("resetButtonVisible") ? View.VISIBLE : View.INVISIBLE);
        buttonSave.setVisibility(savedInstanceState.getBoolean("saveButtonVisible") ? View.VISIBLE : View.INVISIBLE);
        buttonOpenLatestFile.setVisibility(savedInstanceState.getBoolean("openLatestFileButtonVisible") ? View.VISIBLE : View.INVISIBLE);
    
        editTextStartValue.setEnabled(savedInstanceState.getBoolean("editTextStartValueVisible"));
        buttonStartValueDown.setEnabled(savedInstanceState.getBoolean("buttonStartValueDownVisible"));
        buttonStartValueDown.setImageResource(buttonStartValueDown.isEnabled() ? R.drawable.ic_arrow_down : R.drawable.ic_arrow_down_gray);
        buttonStartValueUp.setEnabled(savedInstanceState.getBoolean("buttonStartValueUpVisible"));
        buttonStartValueUp.setImageResource(buttonStartValueUp.isEnabled() ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_up_gray);
        editTextEndValue.setEnabled(savedInstanceState.getBoolean("editTextEndValueVisible"));
        buttonEndValueDown.setEnabled(savedInstanceState.getBoolean("buttonEndValueDownVisible"));
        buttonEndValueDown.setImageResource(buttonEndValueDown.isEnabled() ? R.drawable.ic_arrow_down : R.drawable.ic_arrow_down_gray);
        buttonEndValueUp.setEnabled(savedInstanceState.getBoolean("buttonEndValueUpVisible"));
        buttonEndValueUp.setImageResource(buttonEndValueUp.isEnabled() ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_up_gray);
    
        Log.e("Fragment", "Restored view visibility");
    }
    

    为什么调用onViewStateRestored()时数据不正确?所有的视图都变得不可见,不管它们以前是什么。保存和恢复状态时捆绑包是否不同?

    然而,当调用 fragmentManager.beginTransaction().replace(R.id.content_frame, CustomFragmentManager.savedFilesFragment).commit(); 然后手动调用ViewStateRestored()。

    编辑: 更改了字段名称。

    解决方案: 我已更换 outState = new Bundle(getSavedInstanceState()); 具有 outState.putAll(getSavedInstanceState()); 它现在正在工作。使命感 setRetainInstance(true); 没有必要。

    2 回复  |  直到 10 年前
        1
  •  2
  •   Trịnh Quân    10 年前

    您不应该使用在onSaveInstanceState()方法中传递的outState对象手动创建状态包,并在onCreate()中恢复。另外,您应该在片段的onCreate()中调用setRetainInstance(true)。

        2
  •  0
  •   AutonomousApps    10 年前

    我怀疑这与你的方法签名有关。为什么要使用 static ? 静态方法无法访问实例成员。这:

    public static Bundle getSavedInstanceState()
    public static void restoreInstanceState(Bundle savedInstanceState)
    

    应该是:

    public Bundle getSavedInstanceState()
    public void restoreInstanceState(Bundle savedInstanceState)
    

    其次,您的字段名非常不象Java。这:

    BTN_startValueDown
    

    应为(例如):

    btnStartValueDown
    

    第一次编辑

    应该早点想到这一点。由于您只是试图保留片段的状态,所以只需调用 setRetainInstance(true) 在你的片段中 onCreate() 看见 here .

    第二次编辑

    另一个答案是正确的:你不应该为out状态创建另一个Bundle。如果您真的想在单独的方法中创建Bundle,请使用以下方法:

    outState.putAll(getSavedInstanceState());