我有5个片段。按下后退按钮我想移动到主片段,无论打开多少片段。
如果我离开
[1] - > [2]并按回[1]显示的主片段
[1] - > [3]并按回[1]显示的主片段
[1] - > [4]并按回[1]显示的主片段
[1] - > [5]并按回[1]显示的主片段
因为我没有问题。
但问题是
[1] - > [2] - > [3]并在[3]
上按回主片段重叠[1] - > [2] - > [4]并在[4]
上按回主片段重叠[1] - > [2] - > [5]并在[5]
上按回主片段重叠我只在homeStack中添加了主页片段,并使用了替换片段方法。
为什么会发生这种情况?
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.all_activity_layout); setToolbar(); addFragment(AttractionsFragment.newInstance()); setNavigationDrawer(); } @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.nav_attractions: if (mCurrentNavigationDrawerItem != 0) { mCurrentNavigationDrawerItem = 0; replaceFragment(AttractionsFragment.newInstance()); } break; case R.id.nav_packages: if (mCurrentNavigationDrawerItem != 1) { mCurrentNavigationDrawerItem = 1; replaceFragment(PackagesFragment.newInstance()); } break; case R.id.nav_passes: if (mCurrentNavigationDrawerItem != 2) { mCurrentNavigationDrawerItem = 2; replaceFragment(PassesFragment.newInstance()); } break; case R.id.nav_coupons: if (mCurrentNavigationDrawerItem != 3) { mCurrentNavigationDrawerItem = 3; replaceFragment(CouponsFragment.newInstance()); } break; case R.id.nav_more: if (mCurrentNavigationDrawerItem != 4) { mCurrentNavigationDrawerItem = 4; replaceFragment(MoreFragment.newInstance()); } break; } mNavigationView.getMenu().getItem(mCurrentNavigationDrawerItem).setChecked(true); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } public void replaceFragment(Fragment fragment) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Get Current Visible fragment Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container); // Add to back stack only if it is AttractionsFragment if (f instanceof AttractionsFragment) { transaction.addToBackStack(fragment.getClass().getName()); } transaction.replace(R.id.fragment_container, fragment); transaction.commit(); Log.d("Navigation", "BackStack Count:" + getSupportFragmentManager().getBackStackEntryCount()); } public void addFragment(Fragment fragment) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.fragment_container, fragment, "AttractionsFragment"); transaction.commit(); } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } }
答案 0 :(得分:1)
在导航到第3个片段之前,您需要弹出第2个片段。
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
// Add to back stack only if it is AttractionsFragment
if (f instanceof AttractionsFragment) {
transaction.addToBackStack(fragment.getClass().getName());
} else {
activity.getSupportFragmentManager().popBackStackImmediate();
}
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
答案 1 :(得分:0)
删除它将正常工作的transaction.addToBackStack(fragment.getClass().getName());
行。请检查以下代码
public void replaceFragment(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Get Current Visible fragment
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
// Add to back stack only if it is AttractionsFragment
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
Log.d("Navigation", "BackStack Count:" + getSupportFragmentManager().getBackStackEntryCount());
}
答案 2 :(得分:0)
用第一个片段替换容器视图:
#pragma once
#include <math.h>
#include <assert.h>
struct Class2
{
union
{
float Element[2];
struct { float X, Y; };
struct { float U, V; };
};
Class2() {}
Class2(float p_fValue)
: X(p_fValue), Y(p_fValue) {}
Class2(float p_x, float p_y)
: X(p_x), Y(p_y) {}
Class2(const Class2 &p_vector)
: X(p_vector.X), Y(p_vector.Y) {}
float operator[](int p_nIndex) const { return Element[p_nIndex]; }
float& operator[](int p_nIndex) { return Element[p_nIndex]; }
inline void Set(float p_x, float p_y) {
X = p_x; Y = p_y;
}
inline bool Equals(const Class2 &p_vector, const float p_epsilon = 1e-5f) const
{
if (fabs(X - p_vector.X) > p_epsilon) return false;
if (fabs(Y - p_vector.Y) > p_epsilon) return false;
return true;
}
Class2& operator=(const Class2 &p_vector)
{
X = p_vector.X;
Y = p_vector.Y;
return *this;
}
inline bool operator==(const Class2 &p_vector) const {
return Equals(p_vector);
}
inline bool operator!=(const Class2& p_vector) const {
return !(*this == p_vector);
}
inline Class2 operator*(float p_fValue) const {
return Class2(p_fValue * X, p_fValue * Y);
}
inline Class2 operator/(float p_fValue) const
{
assert(p_fValue != 0.f);
return Class2(*this * (1.0f / p_fValue));
}
inline Class2 operator*(const Class2 &p_vector) const {
return Class2(p_vector.X * X, p_vector.Y * Y);
}
inline Class2 operator+(const Class2 &p_vector) const {
return Class2(X + p_vector.X, Y + p_vector.Y);
}
inline Class2 operator-(const Class2 &p_vector) const {
return Class2(X - p_vector.X, Y - p_vector.Y);
}
inline Class2 operator-(void) const {
return Class2(-X, -Y);
}
inline Class2& operator*=(float p_fValue) {
return *this = *this * p_fValue;
}
inline Class2& operator*=(const Class2 &p_vector) {
return *this = *this * p_vector;
}
inline Class2& operator/=(float p_fValue) {
return *this = *this / p_fValue;
}
inline Class2& operator+=(const Class2 &p_vector) {
return *this = *this + p_vector;
}
inline Class2& operator-=(const Class2 &p_vector) {
return *this = *this - p_vector;
}
inline float MaxComponent() const {
return std::max(X, Y);
}
inline float MinComponent() const {
return std::min(X, Y);
}
inline float MaxAbsComponent() const {
return std::max(fabs(X), fabs(Y));
}
inline float MinAbsComponent() const
{
return std::min(fabs(X), fabs(Y));
}
static Class2 Max(const Class2 &p_vector1, const Class2 &p_vector2)
{
return Class2(std::max(p_vector1.X, p_vector2.X),
std::max(p_vector1.Y, p_vector2.Y));
}
static Class2 Min(const Class2 &p_vector1, const Class2 &p_vector2)
{
return Class2(std::min(p_vector1.X, p_vector2.X),
std::min(p_vector1.Y, p_vector2.Y));
}
inline float Length(void) const {
return sqrt(X * X + Y * Y);
}
inline float LengthSquared(void) const {
return X * X + Y * Y;
}
inline void Normalize(void) {
*this = Class2::Normalize(*this);
}
inline float Dot(const Class2 &p_vector) const {
return Class2::Dot(*this, p_vector);
}
inline float AbsDot(const Class2 &p_vector) const {
return Class2::AbsDot(*this, p_vector);
}
static float Dot(const Class2 &p_vector1, const Class2 &p_vector2) {
return p_vector1.X * p_vector2.X + p_vector1.Y * p_vector2.Y;
}
static float AbsDot(const Class2 &p_vector1, const Class2 &p_vector2) {
return fabs(p_vector1.X * p_vector2.X +
p_vector1.Y * p_vector2.Y);
}
static Class2 Normalize(const Class2 &p_vector) {
return p_vector / sqrt(p_vector.Length());
}
static float DistanceSquared(const Class2 &p_point1, const Class2 &p_point2) {
return (p_point2 - p_point1).LengthSquared();
}
static float Distance(const Class2 &p_point1, const Class2 &p_point2) {
return (p_point2 - p_point1).Length();
}
};
inline Class2 operator*(float p_fValue, const Class2 &p_vector) {
return Class2(p_fValue * p_vector.X, p_fValue * p_vector.Y);
}
答案 3 :(得分:0)
如果要在同一个活动中添加/启动所有三个片段,而不是FragmentTransaction的add()方法来显示Fragment3,请使用FragmentTransaction的replace()方法(将Fragment2替换为Fragment3)。在添加新片段之前,replace方法从backstack中删除当前片段。如果您从其他活动启动Fragment3,因此您无法使用replace(),请在开始新活动(添加fragment3)之前从backstack中删除Fragment2:
// in Fragment2, before adding Fragment3:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.remove(this) // "this" refers to current instance of Fragment2
.commit();
fragmentManager.popBackStack();
// now go ahead and launch (add) fragment3
// if fragment3 is launched from a different activity,
// start that activity instead
fragmentManager.beginTransaction()
.add(R.id.a_container_view_in_activity, new Fragment3(),
Fargment3.FRAGMENT3_ID)
.commit();
这将解决您的问题。试试这个..
答案 4 :(得分:0)
试试这个:
在onBackPressed
:
@Override
public void onBackPressed(){
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
Log.i("MainActivity", "popping backstack");
fm.popBackStack();
} else {
Log.i("MainActivity", "nothing on backstack, calling super");
super.onBackPressed();
}
}
也在您的替换片段中 - 解决重叠问题尝试
transaction.replace(((ViewGroup)(getView().getParent())).getId(), fragment);
或
getSupportFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();
尝试在替换片段中更改代码:
public void replaceFragment(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Get Current Visible fragment
//Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
AttractionsFragment myFragment = (AttractionsFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment != null && myFragment.isVisible()) {
// Add to back stack only if it is AttractionsFragment
transaction.addToBackStack(null);
}
transaction.replace(R.id.fragment_container, fragment, "MY_FRAGMENT");
transaction.commit();
Log.d("Navigation", "BackStack Count:" + getSupportFragmentManager().getBackStackEntryCount());
}
答案 5 :(得分:0)
在OnBackpress
中添加以下代码:
@Override
public void onBackPressed() {
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
if (getFragmentManager().findFragmentById(R.id.activity_container) instanceof HomeFragment) {
super.onBackPressed();
} else {
replaceFragment(this, new HomeFragment());
}
}
使用以下代码更改所有replaceFragment
和AddFragment
方法:
public void addFragment(final Activity mActivity, final Fragment newFragment, final Fragment hideFragment) {
final FragmentManager fragmentManager = mActivity.getFragmentManager();
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.hide(hideFragment);
fragmentTransaction.add(R.id.activity_container, newFragment, newFragment.getClass().getSimpleName());
fragmentTransaction.addToBackStack(hideFragment.getClass().getSimpleName());
fragmentTransaction.commitAllowingStateLoss();
}
public void replaceFragment(final Activity mActivity, final Fragment newFragment) {
final FragmentManager fragmentManager = mActivity.getFragmentManager();
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.activity_container, newFragment, newFragment.getClass().getSimpleName());
fragmentTransaction.commit();
}
activity_container
是活动的xml文件中的FrameLayout
ID。
在onCreate
您的活动中调用replaceFragment
方法,而不是addFragment
。在所有导航项目点击事件中,请调用replaceFragment
方法。