【问题标题】:Keep TextView text, size, visibility after rotation旋转后保留 TextView 文本、大小、可见性
【发布时间】:2013-09-08 11:11:59
【问题描述】:

所以我有一个非常基本的布局,在屏幕顶部有一个 EditText 和一个按钮。当有人点击按钮时,EditText 输入被保存到文本视图中,然后 EditText 和按钮一样被隐藏。这是我的代码:

public void setName(View view){
    EditText editText = (EditText) findViewById(R.id.getUserName);
    Button button = (Button) findViewById(R.id.setName);
    TextView textView = (TextView) findViewById(R.id.displayName);
    playerName = editText.getText().toString();
    textView.setText(playerName);
    editText.setVisibility(View.GONE);
    button.setVisibility(View.GONE);
    textView.setTextSize(40);
    textView.setVisibility(View.VISIBLE);
}

那么当屏幕旋转时,再次调用onCreate,如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_score_keeper);
        // Identifies a textView
        TextView textView = (TextView) findViewById(R.id.displayName);
        // Hide that textView until later
        textView.setVisibility(View.GONE);
        // Set player name to default value
        playerName = "Player Name";
        // Set score to default value
        score = 0;

}

这样做的问题是它失去了我隐藏 EditText 和 Button 的事实,并且再次隐藏了 TextView。

我怎样才能使所有这些属性保持不变? (例如保持文本相同、文本大小、视图的可见性等); 可以用 onSaveInstanceState 做吗?

谢谢大家。

OSFTW

【问题讨论】:

    标签: java android android-activity android-lifecycle


    【解决方案1】:

    您绝对可以在 Activity 的 savedInstanceState 上执行此操作,但我也建议(因为这可能是您在多个位置执行的操作)只需编写视图的子类,该子类还将其可见性保存为状态,例如:

    public class VisibiitySaveTextView extends TextView {
        //These are just keys to save and restore values from the state
        private static final String SUPER_STATE = "super_state";
        private static final String VISIBILITY = "visibility";
    
        //Constructors
    
        @Override
        public Parcelable onSaveInstanceState () {
            Bundle state = new Bundle();
    
            //Piggyback off of the View's implementation and store that
            //bundle of saved information in our container bundle
            state.putParcelable(SUPER_STATE, super.onSaveInstanceState());
    
            //Store the current visibility of the View in the saved state
            state.putInt(VISIBILITY, getVisibility());
            return state;
        }
    
        @Override
        public void onRestoreInstanceState (Parcelable state) {
            //state should always be an instance of Bundle since that's what
            //we're saving, but check for safety
            if (state instanceof Bundle) {
                Bundle savedState = (Bundle)state;
    
                //Set the visibility of the View to match the visibility that
                //we retained in onSavedInstanceState(), falling back to the 
                //current visibility as default if no state was saved
                setVisibility(savedState.getInt(VISIBILITY, getVisibility()));
    
                //Pull out the superclass state we saved, and let the superclass
                //handle restoring all of the other state
                Parcelable superState = savedState.getParcelable(SUPER_STATE);
                super.onRestoreInstanceState(superState);
            } else {
                //Nothing special to do here other than pass it up to the super
                super.onRestoreInstanceState(state);
            }
        }
    }
    

    编辑:让 Activity 处理状态的示例:

    private static final String MY_EDIT_TEXT_VISIBILITY = "my_edit_text_visibility";
    private static final String MY_TEXT_VIEW_VISIBILITY - "my_text_view_visibility";
    private static final String MY_BUTTON_VISIBILITY - "my_button_visibility";
    
    @Override
    protected void onSaveInstanceState (Bundle outState) {
        super.onSaveInstanceState(outState);
    
        //Save the state of each of these. It's super important to add null checks here
        //(which is why I prefer to let the View handle it) as in some cases this can
        //get called after the Views have been destroyed.
    
        if (myEditText != null) {
            outState.putInt(MY_EDIT_TEXT_VISIBILITY, myEditText.getVisibility());
        }
    
        if (myTextView != null) {
            outState.putInt(MY_TEXT_VIEW_VISIBILITY, myTextView.getVisibility());
        }
    
        if (myButton != null) {
            outState.putInt(MY_BUTTON_VISIBILITY, myButton.getVisibility());
        }
    }
    
    @Override
    protected void onRestoreInstanceState (Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    
        //Check if we have saved state, and restore the visibility 
        //to all of the Views we care about
        if (savedInstanceState != null) {
            myEditText.setVisibility(savedInstanceState.getInt(MY_EDIT_TEXT_VISIBILITY, myEditText.getVisibility()));
            myTextView.setVisibility(savedInstanceState.getInt(MY_TEXT_VIEW_VISIBILITY, myTextView.getVisibility()));
            myButton.setVisibility(savedInstanceState.getInt(MY_BUTTON_VISIBILITY, myButton.getVisibility()));
        }
    }
    

    【讨论】:

    • 感谢您的回复,非常感谢!我是android编程的新手,全新的。您能否添加一些 cmets 来解释发生了什么,以便我更好地理解它?提前致谢!另外,有没有办法在不创建类的情况下做到这一点?因为,如果可能的话,我想让它更简单。如果我能在活动课上做到这一切(如果可以的话,那就太好了)!
    • 当然,我已经添加了 cmets,以及 Activity 如何处理它的示例。我真的不喜欢这种方法(尽管我肯定会在某些地方使用它——如果你只使用一次或两次,有时它不值得子类化);让 View 处理保存自己的状态似乎更干净。
    • 非常感谢,非常感谢!我明白为什么让 View 处理它会更干净,而且它也更有意义。但就我而言,我认为我应该能够让活动处理它。谢谢!
    【解决方案2】:

    覆盖:

       @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState)
        {
            super.onRestoreInstanceState(savedInstanceState);
    
                if (button not visible)
                     savedInstanceState.putBoolean("Visibility", false);
                savedInstanceState.putString("text", "EditView text");
        }
    

    在创建时:

    if (savedInstanceState != null) {
    
    boolean x = savedInstanceState.getBoolean("visibility");
        String s = savedInstanceState.getString("text");
    // set values
    }
    

    【讨论】:

    • 按钮可见性是视图的一个属性。例如: textView.setVisibility(View.GONE);所以我不知道如何使用它来修改该属性,除非我误解了。
    • if (x) textView.setVisibility(View.visible);
    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    相关资源
    最近更新 更多