在导航抽屉后退按钮不能正常工作?

时间:2016-12-27 08:56:54

标签: android android-fragments navigation-drawer back-button

Fragment Overlap

我有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();
    }
}

6 个答案:

答案 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());
                    }
                }

使用以下代码更改所有replaceFragmentAddFragment方法:

 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方法。