MainActivity
package example.antonio.activitydemo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.support.v4.app.*;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final FragmentManager fragmentManager = getSupportFragmentManager();
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FirstFragment fragment = new FirstFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, fragment);
fragmentTransaction.commit();
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SecondFragment fragment = new SecondFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
}
});
}
}
FirstFragment
package example.antonio.activitydemo;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
public class FirstFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) {
return inflater.inflate(R.layout.first_fragment, container, false);
}
}
SecondFragment
package example.antonio.activitydemo;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
public class SecondFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) {
return inflater.inflate(R.layout.second_fragment, container, false);
}
}
他们的XML文件:
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start1"
android:id="@+id/button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start2"
android:id="@+id/button2"/>
</LinearLayout>
first_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First!"
android:textColor="#ffffff"/>
</FrameLayout>
second_fragment.xml 就像上一篇文章一样,只有android:text="Second!"
这是奇怪的事情,当我点击Start1
按钮4次然后我得到First!
这个词的4倍,直到这里一切正常。如果我单击Start2
按钮,我会期望删除前面的4个片段并添加一个新片段,其外观为Second!
。这是我从文档中理解的:
替换添加到容器的现有片段。这与使用相同的containerViewId添加的所有当前添加的片段调用remove(Fragment),然后使用此处给出的相同参数添加(int,Fragment,String)基本相同。
但这是我得到的:
我试着阅读源代码,也许我发现了“问题”在哪里,我想知道你的想法,如果是我,我在某个地方犯了错误。
以下是来自 BackStackRecord.java ,run()
方法的代码段:
case OP_REPLACE: {
Fragment f = op.fragment;
int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
}
if (old.mContainerId == containerId) {
if (old == f) {
op.fragment = f = null;
} else {
if (op.removed == null) {
op.removed = new ArrayList<Fragment>();
}
op.removed.add(old);
old.mNextAnim = op.exitAnim;
if (mAddToBackStack) {
old.mBackStackNesting += 1;
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Bump nesting of "
+ old + " to " + old.mBackStackNesting);
}
}
mManager.removeFragment(old, mTransition, mTransitionStyle);
}
}
}
}
以下是 FragmentManager.java :
的摘录public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
final boolean inactive = !fragment.isInBackStack();
if (!fragment.mDetached || inactive) {
if (false) {
// Would be nice to catch a bad remove here, but we need
// time to test this to make sure we aren't crashes cases
// where it is not a problem.
if (!mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment not added: " + fragment);
}
}
**if (mAdded != null) {
mAdded.remove(fragment);
}**
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
fragment.mAdded = false;
fragment.mRemoving = true;
moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
transition, transitionStyle, false);
}
}
正如您所看到的,removeFragment
方法从mAdded
中删除了一个框架,但在run()
方法之后,i
索引未被修改,它从在它离开的地方,它会失去一些元素......
答案 0 :(得分:0)
使用linearlayout作为容器无法实现此方案。
如果您尝试将此片段用作linearlayout中的容器,则可以实现此目的。请参阅此链接以获得进一步说明
Android - fragment .replace() doesn't replace content - puts it on top
否则,请使用以下代码进行按钮点击操作
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FirstFragment fragment = new FirstFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, fragment).addToBackStack(null);
fragmentTransaction.commit();
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SecondFragment fragment = new SecondFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
for(int i=0; i < getSupportFragmentManager().getBackStackEntryCount(); i++)
getSupportFragmentManager().popBackStack();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
}
});
希望这会对你有所帮助..谢谢