У меня есть класс CustomButton
(расширяет LinearLayout
), где я раздуваю макет, содержащий ToggleButton
(на самом деле это сложнее, но я упростил здесь проблему).
public class CustomButton extends LinearLayout {
private ToggleButton toggleOnOffButton;
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.custom_button_layout, this);
}
@Override
protected void onFinishInflate() {
toggleOnOffButton = (ToggleButton) findViewById(R.id.toggle_on_off_button);
super.onFinishInflate();
}
public ToggleButton getToggleOnOffButton() {
return toggleOnOffButton;
}
}
custom_button_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ToggleButton android:id="@+id/toggle_on_off_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="Off"
android:textOn="On"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
У меня есть активность, где я раздуваю макет с помощью 2 CustomButton
-s. Состояние включения/выключения первого toggleButton сохраняется в общих настройках, и я загружаю значение оттуда в методе onCreate
.
public class FirstActivity extends Activity
{
private CustomButton customButton;
private ToggleButton toggleBut;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
customButton = (CustomButton)findViewById(R.id.toggleButton);
toggleBut = customButton.getToggleOnOffButton();
boolean saved = loadPreferences("toggleBut");
toggleBut.setChecked(saved);
toggleBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean checked = toggleBut.isChecked();
savePreferences("toggleBut", checked);
}
});
}
private void savePreferences(String key, boolean value){
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(key, value);
editor.commit();
}
private boolean loadPreferences(String key){
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
return sharedPreferences.getBoolean(key, true);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.example.example.cs.ssd.custom.CustomButton
android:id="@+id/toggleButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<com.example.example.cs.ssd.custom.CustomButton
android:id="@+id/toggleButton2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Когда я запускаю приложение, первый переключатель toggleButton включен. Когда я меняю ориентацию экрана, автоматически первый переключатель toggleButton становится Off, даже saved
значение true
и вызывается toggleBut.setChecked(saved);
и я думаю, что это связано с CutomButton
который я создал, потому что если макет main.xml
содержит только 1 CustomButton
эта проблема не воспроизводится. Я не уверен, что я делаю неправильно... Вот архив с вышеуказанным кодом (как проект): архив
Если вы хотите, чтобы ваш CustomButton сохранил свое текущее состояние после изменения ориентации, просто переопределите onSaveInstanceState() и onRestoreInstanceState().
Решение
Я пробежал ваш код и заметил, что состояние toggleBut
было изменено после onActivityCreated(), но до onStart(). Чтобы избежать использования каких-либо из этих методов для переопределения настроек переключения, я просто переместил эти строки из onViewCreated():
boolean saved = loadPreferences("toggleBut");
toggleBut.setChecked(saved);
и поместите их в onResume(). Надеюсь, это поможет!
Лучшее решение
Настройки ToggleButton перезаписываются, когда система пытается восстановить значение по умолчанию saveInstanceState
, возможно, в Fragment.onActivityCreated().
В CustomButton переопределите эти функции следующим образом:
@Override
protected Parcelable onSaveInstanceState() {
Bundle state = new Bundle();
state.putParcelable("default", super.onSaveInstanceState());
state.putParcelable("toggle", toggleOnOffButton.onSaveInstanceState());
return state;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
super.onRestoreInstanceState(bundle.getParcelable("default"));
toggleOnOffButton.onRestoreInstanceState(bundle.getParcelable("toggle"));
};
Поймите, что система все равно изменит состояния ToggleButton, без чего-то еще. Но позвольте мне попытаться объяснить, что происходит:
onActivityCreated(Bundle savedInstanceState)
передает его savedInstanceState
в каждый элемент макета, вызывая 'onRestoreInstanceState (Bundle savedInstanceState)'.Итак, наконец, мы исключим ToggleButtons из этого поведения по умолчанию, добавив следующую строку в CustomButton.onFinishInflate():
toggleOnOffButton.setSaveEnabled(false);
Voila, ваши пользовательские кнопки автоматически сохраняют свое состояние.
A
иB
оба имеют значение true, когда вы возвращаете только CustomButtonA
изменяется его состояние на false?