【问题标题】:Navigation drawer fragments overlap even with replace()即使使用 replace(),导航抽屉片段也会重叠
【发布时间】:2016-01-28 11:27:09
【问题描述】:

我在活动中有一个导航抽屉。活动的布局具有片段的相对布局。 relativelayout 的 id 是 mainContent,我在其中加载片段(称为 fragA)到活动的 onCreate() 中。我在导航抽屉中也有这个相同的片段以及其他导航项。它是在活动创建时加载的,也可以从导航抽屉中加载。

在选择导航项时,我将mainContent 中的片段替换为replace(),这是活动中的相对布局。在导航抽屉中,第 0 项是“fragB”(与 fragA 相同,但在导航抽屉中)。其次是另一个片段(fragC)。当我选择 fragB “多次”然后选择 fragA 并按下后退按钮时, fragB 和 fragC 重叠。

而且我还必须一直按返回按钮才能进入初始屏幕,因为每次我从导航抽屉中选择一个项目时,都会创建新的片段 fragBs 和 fragCs。不换。我将它们替换为活动布局中的mainContent(第一个相对布局)。我将FrameLayout 用于片段。

这是我放置片段的活动布局:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.prematixsofs.taxiapp.DateVehiclePicker">
<!-- The main content view -->

<RelativeLayout
    android:id="@+id/mainContent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        layout="@layout/footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal|bottom"></include>
</RelativeLayout>

<!-- The navigation drawer -->
<RelativeLayout
    android:id="@+id/drawerPane"
    android:layout_width="230dp"
    android:layout_height="match_parent"

    android:layout_gravity="start">

    <!-- Profile Box -->

    <RelativeLayout
        android:id="@+id/profileBox"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="#ff02c7c4"
        android:padding="8dp">

        <ImageView
            android:id="@+id/avatar"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginTop="15dp"
            android:src="@drawable/user" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="42dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dp"
            android:layout_toRightOf="@+id/avatar"
            android:orientation="vertical">

            <TextView
                android:id="@+id/userName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:clickable="true"
                android:textColor="#fff"
                android:textSize="16sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/viewProfile"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:layout_marginTop="4dp"
                android:text="View Profile"
                android:textColor="#fff"
                android:textSize="12sp" />
        </LinearLayout>
    </RelativeLayout>

    <!-- List of Actions (pages) -->
    <ListView
        android:id="@+id/navList"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_below="@+id/profileBox"
        android:background="#ffffffff"
        android:choiceMode="singleChoice" />

    <TextView
        android:id="@+id/invisibleTextViewId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone" />
</RelativeLayout>

这是我加载 fragA 的 Activity 代码:

 android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.mainContent, new DateTimePicker(),"tags").commit();

这是导航抽屉 onSelect:

  private void selectItemFromDrawer(int position) {
    Fragment fragment = null;

    switch (position){
        case 0: fragment = new DateTimePicker();
            break;
        case 1: fragment = new PreferencesFragment();
            break;
        case 2:
            mDrawerLayout.closeDrawer(mDrawerPane);
            AlertDialog.Builder alertDialog = new AlertDialog.Builder(DateVehiclePicker.this);

            alertDialog.setTitle("Logout");

            // Setting Dialog Message
            alertDialog.setMessage("Do you want to Logout?");
            alertDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    sessionManager.logoutUser();
                }
            });

            alertDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intent.putExtra("EXIT", true);
                    startActivity(intent);
                    dialog.cancel();
                }
            });

            alertDialog.show();
    }
    if(fragment!=null)
    {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.addToBackStack(null).replace(R.id.mainContent, fragment);
        fragmentTransaction.commit();
        mDrawerLayout.closeDrawer(mDrawerPane);
    }

这是我为导航抽屉设置监听器的地方:

 mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItemFromDrawer(position);

        }
    });

我调用方法selectItemFromDrawer(position);

【问题讨论】:

  • 在情况 2 中你在做什么,你有没有在某个地方调用过这个方法。你有什么错误吗??
  • @VivekMishra 关闭导航抽屉并显示对话框。 case 2: 不适用于片段。我没有收到任何错误。
  • 抽屉关闭代码已经写在最后一行,并告诉你在哪里调用了这个方法
  • 方法在android.support.v4.widget.DrawerLayout类中。我已经删除了关闭代码。我不认为这会导致问题
  • 所以你是说 selectItemFromDrawer 是一个覆盖方法??

标签: android android-layout android-fragments


【解决方案1】:

您必须为此处理 BackStack,您必须在添加或替换为主片段时清除堆栈上的所有片段

 @Override
    public void onBackPressed() {
        Logg.e(TAG, getFragmentManager().getBackStackEntryCount());
        try {
            if (mNavigationDrawerFragment.isDrawerOpen())
            {
                mNavigationDrawerFragment.closeDrawer();
            }

            if (getFragmentManager().getBackStackEntryCount() > 1) {
                getFragmentManager().popBackStack();
            } else
            {   Exit();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

【讨论】:

    【解决方案2】:

    问题是您每次尝试更改片段时都在为片段事务创建新对象。在您的代码中使其成为全局并在任何地方使用相同的实例。 这是带有switch case而不是if else的代码

     private void displayView(int position) {
                Fragment fragment = null;
                String title = getString(R.string.app_name);
                switch (position) {
                    case 0:
                      fragment=new FragmentHome();
                        title="Home";
                        break;
                    case 1:
                       fragment=new FragmentAddress();
                        title="Update Address";
                        break;
                    case 2:
                        fragment=new FragmentHelpList();
                        title="My Helps";
                        break;
                    case 3:
                        fragment=new FragmentCompletedHelps();
                        title="History";
                        break;
                    case 4:
                        fragment=new FragmentSupport();
                        title="Account & Support";
                        break;
                    case 5:
                        fragment=new FragmentAbout();
                        title="About";
                        break;
                    case 6:
                            appSharedPreferences.setSession(false);
                        finish();
                        break;
                    default:
                        break;
                }
    
                if (fragment != null) {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.replace(R.id.container_body, fragment);
                    fragmentTransaction.commit();
                    // set the toolbar title
                    getSupportActionBar().setTitle(title);
                }
    

    使片段变量也全局化

    【讨论】:

    • 我收到commit() already called 错误。你能告诉我怎么做吗?
    • 不要每次都调用commit。我可以给你一个开关盒的例子。你可以相应地关注它
    • 它没有用。我已经编辑了我的问题以显示我做了什么。请看看你说的是不是这个。它仍在创造新的重复片段
    【解决方案3】:

    尝试将 R.id.mainContent 更改为 R.id.container。我有类似的设置,但它与 R.id.container 一起工作正常。

    fragmentManager.beginTransaction().replace(R.id.container,
                    new Registration_fragment()).commit();
    

    并且您必须在加载期间最初也替换 FragA(而不是添加)。

    fragmentTransaction.replace(R.id.mainContent, new DateTimePicker(),"tags").commit();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多