我有3个片段A,B,C.我写了一段代码来替换它们并维护后台堆栈:
public void addFragment(Fragment fragmentToAdd, String fragmentTag) {
FragmentManager supportFragmentManager = getSupportFragmentManager();
Fragment activeFragment = getActiveFragment();
FragmentTransaction fragmentTransaction = supportFragmentManager
.beginTransaction();
if (null != activeFragment) {
fragmentTransaction.hide(activeFragment);
}
fragmentTransaction.replace(R.id.layout_child_activity, fragmentToAdd,
fragmentTag);
if (supportFragmentManager.getBackStackEntryCount() > 1) {
supportFragmentManager.popBackStack();
}
fragmentTransaction.addToBackStack(fragmentTag);
fragmentTransaction.commit();
}
这段代码
if (supportFragmentManager.getBackStackEntryCount() > 1) {
supportFragmentManager.popBackStack();
}
如果堆栈长度大于1,我用于弹出最新的片段。现在由于这个,当长度大于1时,它会一次又一次地调用onCreate视图。 喜欢:
为什么我会遇到这种行为?当我删除斜体代码而不是没有发生时。
答案 0 :(得分:5)
正如文档所说,行为是正常的,来自后台交易。 backstack,从不保存Fragments,它只是保存事务
http://developer.android.com/intl/es/guide/components/fragments.html
我做什么,我不确定它是否是最好的方式,但是 当我想清除我做的所有交易时
1)在您的活动中检查后台堆栈中是否有任何交易, 并在你的片段中添加一个标志,在你的情况下是A
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if(backStackCount > 0) {
Transactions.MUST_DETACH_FROM_BACKSTACK = true;
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
2)在你的片段A中,获取标志并删除fragent onCreateView并像这样返回null
public class Transactions extends android.support.v4.app.Fragment{
public static boolean MUST_DETACH_FROM_BACKSTACK = false;
public Transactions() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("FRAGMENT", "onCreateView "+MUST_DETACH_FROM_BACKSTACK);
// Inflate the layout for this fragment
if (MUST_DETACH_FROM_BACKSTACK) {
MUST_DETACH_FROM_BACKSTACK = false;
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
return null;
}
return inflater.inflate(R.layout.fragment_transactions, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i("FRAGMENT", "onViewCreated");
if(view != null){
Log.i("FRAGMENT", "ThreadStarted");
startThread(view);
}
}
但要小心我得到onResume()在
之后调用OnCreateView()
即使使用getActivity()。getSupportFragmentManager()。beginTransaction()。remove(this).commit();
因此,如果你有任何conde onResume方法,你应该正确地处理它
答案 1 :(得分:0)
我通过继承(1)我自定义BaseFragment的所有片段(2)解决了这个问题。 在这个BaseFragment中,我创建了一个变量:public static boolean removeing; (3) 并在调用popBackStackImmediate()之前将其设置为true(4),然后将其重置为false。 (5) 在BaseFragment-childs中,我检查变量。 (6)
示例代码
活动级别
BaseFragment.removing = true; //(4)
//pop all fragments
while(getSupportFragmentManager().getBackStackEntryCount() > 0){
fragmentManager.popBackStackImmediate();
}
BaseFragment.removing = false; //(5)
BaseFragment(2)
public class BaseFragment extends Fragment{
public static boolean removing = false; //(3)
}
Fragment-Child
public class fragment extends BaseFragment{ //(1)
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
if(!removing){ // (6)
//your code
}
}
}
答案 2 :(得分:0)
记住fragment
的生命周期。到我们回到这一点时,它将始终从oncreateView()
开始。但是我们仍然可以保存数据,然后在创建的数据中进行处理以填充视图。为您可以做到:
Main-activity.java
public class MainActivity extends AppCompatActivity implements Fragment2.myListener {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate: ");
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Fragment1 fragment1 = Fragment1.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragmentContainer, fragment1, Fragment1.TAG);
fragmentTransaction.addToBackStack(Fragment1.TAG);
fragmentTransaction.commit();
}
});
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
Log.e(TAG, "onSaveInstanceState");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy");
}
@Override
public void bindCount(int newCount) {
((Fragment1)getSupportFragmentManager().findFragmentByTag(Fragment1.TAG)).setCount(newCount);
}
}
Fragment1.java
public class Fragment1 extends Fragment {
public static final String TAG = "fragment1";
private static final String SAVE_COUNT = "save_count";
private int count;
public Fragment1() {
}
public static Fragment1 newInstance() {
Fragment1 fragment = new Fragment1();
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate: ");
if (savedInstanceState != null) {
count = savedInstanceState.getInt(SAVE_COUNT);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment1, container, false);
Button goToButton = (Button) view.findViewById(R.id.button);
goToButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Fragment2 fragment2 = Fragment2.newInstance();
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragmentContainer, fragment2, Fragment2.TAG);
fragmentTransaction.addToBackStack(Fragment2.TAG);
fragmentTransaction.commit();
}
});
return view;
}
public void setCount(int newCount){
count = newCount;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.e(TAG, "onSaveInstanceState: ");
outState.putInt(SAVE_COUNT, count);
}
}
Fragment2.java
public class Fragment2 extends Fragment {
public static final String TAG = "fragment2";
public Fragment2() {
// Required empty public constructor
}
public static Fragment2 newInstance() {
Fragment2 fragment = new Fragment2();
return fragment;
}
myListener listener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment2, container, false);
//Here I am just modifying a value that wants to send to fragment1
listener.bindCount(45);//newCount
return view;
}
public interface myListener{
void bindCount(int newCount);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//initialice listener
listener = (myListener) getActivity();
}
}
所以...对于fragments
之间的通信,我们需要通过接口来使用您的容器activity
。如我们所见,Fragment2有一个实现其interface
的{{1}},当它执行时,它调用一个方法,在其中我们更改activity
中的计数值,该计数值存储在{{ 1}},因此即使重新执行fragment1
,我们也可以继续进行任何修改。可以用于许多其他数据,例如onSaveInstanceState
等。
对不起,我的“英语” !!!!