我创建了一个全新的项目来展示我的问题。基本上,我的片段有两个RadioButton
。在使用CreateView时,我总是使用RadioButtonFirst.SetChecked(true);
。但是,如果我检查RadioButtonSecond
,然后通过按后退按钮向外导航,下次打开它时,它会自动检查RadioButtonSecond
。那种行为打破了我的逻辑。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private WeirdFragment weirdFragment;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
weirdFragment = new WeirdFragment();
fragmentManager = getSupportFragmentManager();
}
public void openFragment(View v){
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, weirdFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
weirdfragment.java
public class WeirdFragment extends Fragment {
private RadioButton radioButtonFirst;
private RadioButton radioButtonSecond;
private Button buttonReturn;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_weird, container, false);
radioButtonFirst = view.findViewById(R.id.radio_button_first);
radioButtonSecond = view.findViewById(R.id.radio_button_second);
buttonReturn = view.findViewById(R.id.button_return);
radioButtonFirst.setChecked(true);
// I decide to set a listener right here, to see what happened to my radio button. So this listener will be removed in my real project.
radioButtonSecond.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.v("weird", "i got here");
}
});
buttonReturn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getFragmentManager().beginTransaction().remove(WeirdFragment.this).commit();
}
});
return view;
}
}
<Button
android:id="@+id/button_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="openFragment"
android:text="Open"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_open" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<RadioButton
android:id="@+id/radio_button_first"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:checked="true"
android:text="First" />
<RadioButton
android:id="@+id/radio_button_second"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Second" />
</RadioGroup>
<Button
android:id="@+id/button_return"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Return"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
onCheckedChanged:31, WeirdFragment$1 (com.peanut.myweirdradiobutton)
setChecked:154, CompoundButton (android.widget)
toggle:113, CompoundButton (android.widget)
toggle:78, RadioButton (android.widget)
performClick:118, CompoundButton (android.widget)
run:19866, View$PerformClick (android.view)
handleCallback:739, Handler (android.os)
dispatchMessage:95, Handler (android.os)
loop:135, Looper (android.os)
main:5254, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
invoke:372, Method (java.lang.reflect)
run:903, ZygoteInit$MethodAndArgsCaller (com.android.internal.os)
main:698, ZygoteInit (com.android.internal.os)
onCheckedChanged:31, WeirdFragment$1 (com.peanut.myweirdradiobutton)
setChecked:154, CompoundButton (android.widget)
onRestoreInstanceState:522, CompoundButton (android.widget)
dispatchRestoreInstanceState:13740, View (android.view)
dispatchRestoreInstanceState:2893, ViewGroup (android.view)
dispatchRestoreInstanceState:2893, ViewGroup (android.view)
restoreHierarchyState:13718, View (android.view)
restoreViewState:494, Fragment (android.support.v4.app)
moveToState:1486, FragmentManagerImpl (android.support.v4.app)
moveFragmentToExpectedState:1784, FragmentManagerImpl (android.support.v4.app)
moveToState:1852, FragmentManagerImpl (android.support.v4.app)
executeOps:802, BackStackRecord (android.support.v4.app)
executeOps:2625, FragmentManagerImpl (android.support.v4.app)
executeOpsTogether:2411, FragmentManagerImpl (android.support.v4.app)
removeRedundantOperationsAndExecute:2366, FragmentManagerImpl (android.support.v4.app)
execPendingActions:2273, FragmentManagerImpl (android.support.v4.app)
run:733, FragmentManagerImpl$1 (android.support.v4.app)
handleCallback:739, Handler (android.os)
dispatchMessage:95, Handler (android.os)
loop:135, Looper (android.os)
main:5254, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
invoke:372, Method (java.lang.reflect)
run:903, ZygoteInit$MethodAndArgsCaller (com.android.internal.os)
main:698, ZygoteInit (com.android.internal.os)
因此,我可以看到它是onRestoreInstanceState检查我的RadioButtonSecond
。但我不知道如何预防。我正在考虑的事情:
在我真正的项目中,这个片段就像我的应用程序中的一个设置,它有一个取消和一个确定按钮。因此,我希望片段在每次打开时都处于默认状态,因为我认为,例如,用户可能会配置很多东西,但然后按取消,那么看到所有视图都处于默认状态是合理的,而不是配置的状态(也许这种想法导致了我的问题,这是一个好的用户体验吗?)
那么,如何防止我的片段在未经我允许的情况下恢复其状态呢?
如果我理解正确的话,您希望在用户离开片段
之前重置RadioButton
的状态,以便为稍后重新输入片段
做准备。
由于您希望在用户每次离开片段
后重新输入片段
时检查第一个radioButton
,但(我想)不是在用户刚刚离开应用程序半小时,然后返回到他们停止的地方继续时,您应该使用savedInstanceState包
确保radioButton
具有正确的状态,这取决于具体情况:
让我们引入一个字段私有布尔isFirstButtonChecked=true;
。
保持OnCheckedChangeListener
以跟踪RadioButton
的选中状态,使用
isFirstButtonChecked = radioButtonFirst.isChecked();
除此之外,在OnClickListener
中将Boolean
设置为true
buttonReturn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isFirstButtonChecked = true;
getFragmentManager().beginTransaction().remove(WeirdFragment.this).commit();
}
});
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("FIRST_RB_STATE", isFirstButtonChecked);
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
isFirstButtonChecked = savedInstanceState == null
? true
: savedInstanceState.getBoolean("FIRST_RB_STATE");
radioButtonFirst.setChecked(isFirstButtonChecked);
}
我们使用的是片段,我们不需要在重新创建活动时自动恢复它们。但是,Android每次调用->时,都会恢复片段,即使我们对这些片段使用setRetaInstance(false)。 附言。我们知道,在为配置更改重新创建活动的情况下,可以通过在manifest中添加来完成。但是,在自动清理内存的情况下,如何重新创建活动呢?
我试图探索Android框架是如何管理碎片的,通过我的研究,我了解了很多关于碎片的新知识,但我有一次陷入了困境,无法理解这是如何发生的。 请先试着理解我的场景。它是这样的:我有一个活动,一个接一个地添加两个片段。首次加载活动时,使用以下代码将片段A附加到该活动: 片段A的这些回调方法在加载时被调用 FirstDummyFragment:onCreate:savedInstanceState---
我在AWS EC2上运行3个节点集群,我的一个节点崩溃了,重新启动后,我看到2900个未分配的碎片和集群状态为红色。 我将索引配置为有5个碎片和1个副本--我不明白为什么重新启动后碎片不能从副本中恢复。 我尝试使用elasticsearch重新路由API https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-
当我添加fragment并使用以下代码从Fragment1转到Fragment2时: 当我从Fragment2回来时,我无法在Fragment1中检查暂停和毁灭,在Fragment1中检查恢复。我想用添加来做这件事,而不是用替换。请帮帮我。谢啦
我搜索了很多信息,但没有一个明确的。有人能给出一个明确的解决方案和一个例子吗?
我可以使用一个片段作为一个活动吗?我已经创建了一个片段,但我希望它有像活动一样的功能,所以我使用片段扩展碎片活动。然而,我有一个带有碎片的导航抽屉。当我更改为“扩展碎片活动”时,我的代码有问题?请给我指路。