Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 导航抽屉:在平板电脑上设置为始终打开_Android_Tablet_Navigation Drawer - Fatal编程技术网

Android 导航抽屉:在平板电脑上设置为始终打开

Android 导航抽屉:在平板电脑上设置为始终打开,android,tablet,navigation-drawer,Android,Tablet,Navigation Drawer,我正在使用支持库中的导航抽屉模式: 我试图将其设置为在平板电脑上始终打开(作为一个侧菜单) 在当前的实现中,这是可能的,还是我们必须使用Listview创建一个新的布局和新的结构,而不是重复使用相同的代码?在大屏幕设备上锁定打开的抽屉 正如我在评论中指出的,我不认为DrawerLayout是为您的场景设计的(尽管这不是一个坏主意,IMHO)。可以使用不同的布局来承载相同的列表视图和内容,也可以下载并修改您自己的抽屉布局,在大屏幕设备上,打开内容时将其滑动而不是重叠。根据Commonware的

我正在使用支持库中的导航抽屉模式:

我试图将其设置为在平板电脑上始终打开(作为一个侧菜单)

在当前的实现中,这是可能的,还是我们必须使用Listview创建一个新的布局和新的结构,而不是重复使用相同的代码?

在大屏幕设备上锁定打开的抽屉


正如我在评论中指出的,我不认为
DrawerLayout
是为您的场景设计的(尽管这不是一个坏主意,IMHO)。可以使用不同的布局来承载相同的
列表视图
和内容,也可以下载并修改您自己的
抽屉布局
,在大屏幕设备上,打开内容时将其滑动而不是重叠。

根据Commonware的答案,您可以进行一些调整。第一个是设置以下三行:

drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow));
isDrawerLocked = true;
drawerNoShadow颜色只能是无alpha颜色(如0x00000000)。这会让你有一个没有背景覆盖的开放抽屉

您需要做的第二件事是调整FrameLayout的padding_left值。为此,您可以设置一个维度来控制此操作(默认情况下为0dp)-在本例中为R.dimen.drawerContentPadding。您还需要一个R.dimen.drawerSize值,该值将是抽屉布局的宽度

这允许您检查FrameLayout的paddingLeft值以调用这些行

FrameLayout frameLayout = (FrameLayout)findViewById(R.id.content_frame);
if(frameLayout.getPaddingLeft() == (int)getResources().getDimension(R.dimen.drawerSize) {
    drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
    drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow));
    isDrawerLocked = true;
}
然后,如果(!isDrawerLocked)语句中包含所有不希望启用的功能,则可以将其包装到
语句中。这将包括:

  • drawerLayout.setDrawerListener(抽屉切换)
  • getActionBar().setDisplayHomeAsUpEnabled(true)
最后,您确实需要为具有静态抽屉的视图设置备用布局。例如:

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout

    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- The navigation drawer -->
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="@dimen/drawerSize"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>

</android.support.v4.widget.DrawerLayout>
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="@dimen/drawerContentPadding"/>


基于大型设备可能有不同布局文件的想法,我创建了以下项目

突出显示

由于大型设备的抽屉始终可见,因此不需要有抽屉。相反,具有两个同名元素的线性布局就足够了

<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="horizontal">
     <ListView
             android:id="@+id/listview_drawer"
             android:layout_width="@dimen/drawer_size"
             android:layout_height="match_parent"
             android:layout_gravity="start"
             android:choiceMode="singleChoice"
             android:divider="@android:color/transparent"
             android:dividerHeight="0dp"
             android:background="@color/drawer_background"/>
    <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="@dimen/drawer_content_padding"
            />
</LinearLayout>
下面是将其用作布尔值的示例

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    if (mDrawerLayout != null) {
        mDrawerToggle.syncState();
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (mDrawerLayout != null) {
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
}

前面的答案很好,但是在我的项目中实现它们时我遇到了一些问题,所以我想分享我的解决方案。 首先,我们需要定义一个自定义抽屉:

public class MyDrawerLayout extends DrawerLayout {
    private boolean m_disallowIntercept;

    public MyDrawerLayout (Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(final MotionEvent ev) {
        // as the drawer intercepts all touches when it is opened
        // we need this to let the content beneath the drawer to be touchable
        return !m_disallowIntercept && super.onInterceptTouchEvent(ev);
    }

    @Override
    public void setDrawerLockMode(int lockMode) {
        super.setDrawerLockMode(lockMode);
        // if the drawer is locked, then disallow interception
        m_disallowIntercept = (lockMode == LOCK_MODE_LOCKED_OPEN);
    }
}
然后我们把它放在一个基本的活动布局中(没有前面答案中的任意布局),如下所示:

<MyDrawerLayout 
    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">

    <!--We must define left padding for content-->
    <FrameLayout
        android:id="@+id/content_frame"
        android:paddingStart="@dimen/content_padding"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/menu_nav" />

</MyDrawerLayout>
values land/dimens.xml
-

<dimen name="content_padding">0dp</dimen>
<dimen name="content_padding">300dp</dimen>

只需为平板电脑提供一个备用布局文件。这样,您就可以保存
NavigationView
的所有默认行为


第一步 只需为平板电脑设备创建一个类似于此的备用布局文件,并将其放置在
layout-w600dp-land
资源目录中

<?xml version="1.0" encoding="utf-8"?>
<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">

    <!--
    NavigationView and the content is placed in a horizontal LinearLayout
    rather than as the direct children of DrawerLayout.
    This makes the NavigationView always visible.
    -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <android.support.design.widget.NavigationView
            android:id="@+id/nav"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer"/>
        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

</android.support.v4.widget.DrawerLayout>
这是针对非平板设备的。对于平板电脑设备,创建另一个同名设备,并将其放入
values-w600dp-land

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isDrawerFixed">true</bool>
</resources>
使用下面的另一条
if
语句包装当单击某个项目时关闭抽屉的代码

if (!isDrawerFixed) {
    drawer.closeDrawer(GravityCompat.START);
}



最终结果将有点像这样

if (!isDrawerFixed) {
    drawer.closeDrawer(GravityCompat.START);
}

抽屉打开了,但在我实际布局的前面。@wazau_-Be:哦,对了。我不认为
DrawerLayout
是为您的场景设计的。可以使用不同的布局来承载相同的
列表视图
和内容,也可以下载并修改您自己的
抽屉布局
,在大屏幕设备上,打开时将内容滑动而不是重叠。我接受了您的答案,但如果您将您的评论复制到答案中,则会很有用;-)很好的例子!由于您将其更改为padding_left而不是margin,因此您无法再使用示例检测哪个布局。但是,如果您在每个版面上设置了一个标记,则可以比较该标记以查找正在使用的版面。***不过还有一件事——我发现在抽屉锁定在“out”位置后,当我切换回“Picture”以便打开/关闭时,滑动动作不再打开抽屉。知道为什么吗?我还刚刚意识到,在从打开的抽屉切换回肖像模式后,我的onKeyDown事件停止触发活动!我正在使用兼容性片段,我想知道其中是否有bug…我通过将此代码移到onpostreate()中解决了大部分问题,但是,如果你试图在抽屉被锁定打开的同时将其关闭,我仍然会崩溃。@methodin如果你能将完整的代码添加到你的博客中,我将不胜感激。@eddy如果你知道如何运行代码,如何确定它是平板设备?使用
res/layout-sw600dp-land
是否足够?这是一个古老但有趣的问题。您可能会在这里找到答案:请注意,仅通过创建此文件夹并将布局放置在其中,并不意味着将使用此布局。如果需要,您可以检测它是否为平板电脑,然后通过编程强制它处于横向模式。这样就行了。祝你好运我认为这是目前为止最好的答案,因为没有重复的代码,它利用了NavigationView API为导航图让路。干得好。这是一个很好的答案。比其他提供的要容易和明智得多。非常感谢。我使用了
RelativeLayout
而不是
LinearLayout
,仅使用
LinearLayout
无法显示主/细节片段。再次感谢。提供屏幕截图进行验证并与我的设备进行比较的额外要点。
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isDrawerFixed">true</bool>
</resources>
if (!isDrawerFixed) {
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();
}
if (!isDrawerFixed) {
    drawer.closeDrawer(GravityCompat.START);
}