当我在switchboxes
代码中使用<include>
时,我遇到了非常奇怪的行为。最小的例子:
activity_main.xml中
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment"
android:name="com.fimagena.myapplication.MainActivityFragment"
tools:layout="@layout/fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
fragment_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include android:id="@+id/inc1" layout="@layout/includelayout" />
<include android:id="@+id/inc2" layout="@layout/includelayout" />
<include android:id="@+id/inc3" layout="@layout/includelayout" />
</LinearLayout>
includelayout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Switch"
android:id="@+id/switch1"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MainActivityFragment.java
public class MainActivityFragment extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main, container, false);
((Switch) root.findViewById(R.id.inc1).findViewById(R.id.switch1)).setChecked(false);
((Switch) root.findViewById(R.id.inc2).findViewById(R.id.switch1)).setChecked(false);
((Switch) root.findViewById(R.id.inc3).findViewById(R.id.switch1)).setChecked(false);
return root;
}
}
我期望的是:一个带有3个开关的空片段,它们总是在配置更改时自行重置以取消选中(因为Activity和Fragment会被重建。)
我得到的是:当配置发生变化时(即旋转手机时),3个开关始终将自身重置为第3个开关所处的状态。
这是一个错误还是我错过了什么?鉴于我在所有3个交换机上明确使用setChecked(false)
,它们无论如何都不能将自己设置为on。配置更改正常,重建Activity
和Fragment
,按预期调用onCreateView()
。然而,所有3个开关的状态由最后一个开关确定,而不是由我的setChecked()
电话确定。
我认为它与所有交换机具有相同ID的事实有关,因为它们包含在同一XML中。虽然我们可以正确识别它们,例如,我可以在一台交换机上呼叫setEnabled()
,但只有该交换机受到影响。
答案 0 :(得分:0)
我从未遇到过这个问题,因为我通常在布局中使用不同的ID。我认为问题在于Android通过其ID在内部维护视图状态。
您对所有支票使用相同的ID,因此您需要自己保存/恢复其状态。要小心,您必须恢复onViewStateRestored内的视图状态。这将确保您的视图状态不被系统覆盖。以下代码段应该可以使用。
<强> MainActivityFragment.java 强>
package com.example.testapp;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Switch;
public class MainActivityFragment extends Fragment
implements CompoundButton.OnCheckedChangeListener {
private static final String TAG = "MainActivityFragment";
private Switch mSwitch1;
private Switch mSwitch2;
private Switch mSwitch3;
private boolean mRestoreFlag = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
View root = inflater.inflate(R.layout.fragment_main, container, false);
mSwitch1 = (Switch) root.findViewById(R.id.inc1).findViewById(R.id.switch1);
mSwitch2 = (Switch) root.findViewById(R.id.inc2).findViewById(R.id.switch1);
mSwitch3 = (Switch) root.findViewById(R.id.inc3).findViewById(R.id.switch1);
mSwitch1.setOnCheckedChangeListener(this);
mSwitch2.setOnCheckedChangeListener(this);
mSwitch3.setOnCheckedChangeListener(this);
return root;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onViewCreated");
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!mRestoreFlag) {
return;
}
if (buttonView == mSwitch1) {
Log.d(TAG, "switch1.isChecked()=" + isChecked);
} else if (buttonView == mSwitch2) {
Log.d(TAG, "switch2.isChecked()=" + isChecked);
} else if (buttonView == mSwitch3) {
Log.d(TAG, "switch3.isChecked()=" + isChecked);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "onSaveInstanceState");
outState.putBoolean("switch1", mSwitch1.isChecked());
outState.putBoolean("switch2", mSwitch2.isChecked());
outState.putBoolean("switch3", mSwitch3.isChecked());
}
@Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
Log.d(TAG, "onViewStateRestored");
if (savedInstanceState != null) {
Log.d(TAG, "restore savedInstanceState");
mSwitch1.setChecked(savedInstanceState.getBoolean("switch1", false));
mSwitch2.setChecked(savedInstanceState.getBoolean("switch2", false));
mSwitch3.setChecked(savedInstanceState.getBoolean("switch3", false));
}
mRestoreFlag = true;
}
}