【问题标题】:How to move main content with Drawer Layout left side如何使用抽屉布局左侧移动主要内容
【发布时间】:2018-02-20 19:46:29
【问题描述】:

刚刚检查了如何使用 DrawerLayout here 制作菜单。但是左侧菜单在主要内容的前面移动。如何将其设置为菜单和主要内容并排移动(菜单将内容推送到右侧)?

【问题讨论】:

  • 您链接中的示例是可以的。覆盖而不是推送底层内容的关键是 FrameLayout。你能提供你写的布局吗?
  • 你知道它应该这样做吗?这就是系统应用程序所做的事情,这是在 Android 上实现 Drawer 时建议的最佳实践。是否有充分的理由需要它来将内容推送到右侧?

标签: android android-ui


【解决方案1】:

如果您不想使用第三方库,您可以自己实现它,只需覆盖 ActionBarDrawerToggle 中的 onDrawerSlide。在那里,您可以根据抽屉的打开百分比来翻译框架布局视图。

代码示例:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <FrameLayout android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>    

    <ListView android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"/>

</android.support.v4.widget.DrawerLayout>

在这里,覆盖 onDrawerSlide:

public class ConfigurerActivity extends ActionBarActivity 
{
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    private FrameLayout frame;
    private float lastTranslate = 0.0f;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);
        frame = (FrameLayout) findViewById(R.id.content_frame);

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.acc_drawer_open, R.string.acc_drawer_close) 
        {            
            @SuppressLint("NewApi")
            public void onDrawerSlide(View drawerView, float slideOffset)
            {
                super.onDrawerSlide(drawerView, slideOffset);
                float moveFactor = (mDrawerList.getWidth() * slideOffset);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
                {
                    frame.setTranslationX(moveFactor);
                }
                else
                {
                    TranslateAnimation anim = new TranslateAnimation(lastTranslate, moveFactor, 0.0f, 0.0f);
                    anim.setDuration(0);
                    anim.setFillAfter(true);
                    frame.startAnimation(anim);

                    lastTranslate = moveFactor;
                }
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

        // ... more of your code
    }
}

由于 setTranslationX 在 pre-honeycomb android 版本中不可用,我使用 TranslateAnimation 来管理低版本设备。

希望对你有帮助!

【讨论】:

  • 这对我很有帮助。因为我从两边都有导航抽屉,所以我只需要放 -- if (drawerView.getId() == R.id.right_drawer) slideOffset *= -1; -- 在 onDrawerSlide 方法之上
  • 在这个区域,主布局将进一步向右移动并且不可见。如果你们只想移动它的一半,你可以将它除以二。 float moveFactor = (mDrawerList.getWidth() * slideOffset) / 2
  • 只需添加对 super.onDrawerSlide 的调用,它将再次与动画一起移动:D
  • 它移到了另一边?我补充说 - 它现在移动到正确的一侧,但不仅仅是 slideOffset ?!
  • 非常感谢......它为我工作......我从昨天开始搜索。但每个人都说使用幻灯片菜单库。但我不想添加它。谢谢你从我这边+100
【解决方案2】:

您可能想使用我写的Drawer Toggles 这个库。

我相信你会发现ContentDisplaceDrawerToggle很方便:

ContentDisplaceDrawerToggle mContentDisplaceToggle = new ContentDisplaceDrawerToggle(this, mDrawerLayout, R.id.content_frame);    
mDrawerLayout.setDrawerListener(mContentDisplaceToggle);

ContentDisplaceDrawerToggle 完全按照您所说的进行。当您滑入/滑出DrawerLayout 时,它会移动内容视图。

如果您想组合不同的切换开关,您可以使用ActionBarToggleWrapperDrawerToggleWrapper

自述文件中提供了使用选项。

【讨论】:

  • 抽屉打开时会不会移动ActionBar?
  • @cmcromance 不是本机 ActionBar,但您可以将抽屉与自定义操作栏(模拟操作栏的视图)一起使用,并在抽屉打开时将其作为视图移动
  • @Nikola 它说“导入库项目并将其设置为您的项目。”。你是怎么做到的?
  • 我可以在Activity而不是ActionBarActivity中使用它吗?
  • @V.Kalyuzhnyu 为什么需要本地代码来进行简单的翻译?如果它不符合您的需求,请随意编写或继续搜索。
【解决方案3】:

答案很简单: 首先创建一个 NavigationDrawer Activity。

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

然后打开 app_bar_main.layout 并为父布局分配一个 id。

假设你给了 android:id="@+id/appBarMain"

只需在 MainActivity.class 中用各自的 id 声明父视图组:

并在抽屉布局中添加一个抽屉监听器,如下所示:

drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                float moveFactor = 0;
                moveFactor = (drawerView.getWidth() * slideOffset);

                appBarMain.setTranslationX(moveFactor);
            }

            @Override
            public void onDrawerOpened(View drawerView) {

            }

            @Override
            public void onDrawerClosed(View drawerView) {

            }

            @Override
            public void onDrawerStateChanged(int newState) {

            }
        });

在上面的 OnDrawerSlide() 方法中添加翻译代码,就是这样。

【讨论】:

    【解决方案4】:

    这是工作代码...

    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
     @Override
     public void onDrawerSlide(View drawerView, float slideOffset) {
        super.onDrawerSlide(drawerView, slideOffset);
        mContainerFrame.setTranslationX(slideOffset * drawerView.getWidth());
        mDrawerLayout.bringChildToFront(drawerView);
        mDrawerLayout.requestLayout();
        //below line used to remove shadow of drawer
        mDrawerLayout.setScrimColor(Color.TRANSPARENT);
      }//this method helps you to aside menu drawer
     };
    

    【讨论】:

    • 这工作正常,但推送的视图会离开屏幕并且似乎无法调整大小以适应新空间。
    【解决方案5】:

    OP 得到了答案。但是对于想要这种效果的其他人,可以使用SlidingPaneLayout。它是为此目的而设计的。

    在 XML 文件中:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.SlidingPaneLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@id/mainFrame"
        style="@style/MP.mainFrame" >
    
    
        <!--****************************Right Pane ****************************-->
        <LinearLayout style="@style/searchLayout">
            <android.support.v4.widget.NestedScrollView style="@style/MP">
                <LinearLayout style="@style/MP.verticalLinearLayout">
    
    
                </LinearLayout>
            </android.support.v4.widget.NestedScrollView>
        </LinearLayout>
        <!--****************************Right Pane ****************************-->
    
        <!--****************************Left Pane ****************************-->
    <FrameLayout style="@style/MP.mainLayout">
        <LinearLayout android:id="@id/fragmentContainer" style="@style/MP.fragmentContainer"/>
    
        <android.support.v7.widget.Toolbar style="@style/toolbar">
            <ir.tooskar.excomponents.ExtendedTextView android:id="@id/appTitle" style="@style/WC.appTitle"/>
            <ir.tooskar.excomponents.ExtendedTextView android:id="@id/appBarSearchIcon" style="@style/WC.appBarSearchIcon"/>
        </android.support.v7.widget.Toolbar>
    </FrameLayout>        <!--****************************Left Pane ****************************-->
    

    有两个窗格,左右,粘在一起,因此一起移动。对我来说,左侧窗格是主窗格,右侧隐藏了一个切换图标来显示它。 (ID appBarSearchIcon 的视图)。

    请记住,有一个名为 SlidingPaneLayoutviewgroup 只有两个孩子,LeftRight >.

    活动中的重要部分:

            slidingPaneLayout = (SlidingPaneLayout) findViewById(R.id.mainFrame);
    //        Sets a color for covering left pane(Main Pane)
            slidingPaneLayout.setSliderFadeColor(ContextCompat.getColor(context, R.color.searchPaneFadeColor));
    
    //        The listener for Opening the Right pane(Hidden pane)
            findViewById(R.id.appBarSearchIcon).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view){
                    slidingPaneLayout.openPane();
                }
            });
    

    关闭右窗格由 API 完成,就像 Navigation Drawer 一样。

    【讨论】:

      【解决方案6】:

      在第二个布局集中

      android:layout_gravity="start"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多