DrawerLayout卡在滑动上

时间:2013-08-03 06:03:06

标签: android navigation-drawer androidx

我正在玩DrawerLayout,我遇到了一个问题。基本上有时当我从屏幕边缘滑动时,DrawerLayout会卡住,直到我将手指从屏幕上移开(参见下面的截图)

我不确定是什么,我完全按照谷歌sdk的代码示例。有什么想法吗?

Screenshot bug

这是我在FragmentActivity中唯一拥有的东西:

@Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final String[] names =
                getResources().getStringArray(R.array.nav_names);
        ArrayAdapter<String> adapter =
                new ArrayAdapter<String>(
                        getActionBar().getThemedContext(),
                        android.R.layout.simple_list_item_1, names);

        final DrawerLayout drawer =
                (DrawerLayout)findViewById(R.id.drawer_layout);
        final ListView navList =
                (ListView) findViewById(R.id.drawer);
        navList.setAdapter(adapter);
        navList.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {

            @Override
            public void onItemClick(AdapterView<?> parent,
                                    View view, final int pos, long id)
            {
                drawer.setDrawerListener(
                        new DrawerLayout.SimpleDrawerListener()
                        {
                            @Override
                            public void onDrawerClosed(View drawerView)
                            {
                                super.onDrawerClosed(drawerView);

                            }
                        });
                drawer.closeDrawer(navList);
            }
        });

    }

编辑:我正在为此添加赏金,因为这是一个非常古老的问题,即使在今天也存在最新的Android-X(样本可用here)。这是它的外观:

enter image description here

我已经向Google(here以及之后的here)报告了这一情况,但它没有帮助。

我在这个帖子上尝试了所有现有的解决方案,但都没有。如果有人有一个很好的解决方法(虽然仍然使用DrawerLayout或扩展它,或类似的东西),请提出一个有效的解决方案。

6 个答案:

答案 0 :(得分:15)

请注意,您可以通过在DrawerLayout中的FrameLayout上将clickable属性设置为true来绕过此20dp peek功能。

  

机器人:可点击= “真”

例如: http://developer.android.com/training/implementing-navigation/nav-drawer.html

<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">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />
    <!-- The navigation drawer -->
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111"
        android:choiceMode="singleChoice"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="1dp" />
</android.support.v4.widget.DrawerLayout>

答案 1 :(得分:0)

如果您向我们展示了布局xml,我们可以看到您是否将DrawerLayout作为ROOT元素。内部两个孩子是否是主布局和导航抽屉。

根据Create a Drawer Layout

  

要添加导航抽屉,请使用DrawerLayout对象声明用户界面作为布局的根视图。在DrawerLayout内,添加一个包含屏幕主要内容的视图(隐藏抽屉时的主要布局)和另一个包含导航抽屉内容的视图。

答案 2 :(得分:0)

我设法通过实现这个DrawerListener来解决这个问题:

drawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
            @Override
            public void onDrawerStateChanged(int newState) {
                super.onDrawerStateChanged(newState);
                if (drawerLayout.isDrawerVisible(Gravity.LEFT) && !drawerLayout.isDrawerOpen(Gravity.LEFT)) {
                    drawerLayout.closeDrawer(Gravity.LEFT);
                }
            }
        });

每当状态发生变化时,如果抽屉可见但未打开,则表示它正在偷看,所以我将其关闭。

答案 3 :(得分:0)

当用户将抽屉拖动到20dp Peek而不是打开抽屉时,可以实现此20dp功能。  这是适合我的代码。

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {


lateinit var mToggle: ActionBarDrawerToggle
lateinit var mDrawerLayout: DrawerLayout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val toolbar: Toolbar = findViewById(R.id.toolbar)
    setSupportActionBar(toolbar)

    val fab: FloatingActionButton = findViewById(R.id.fab)
    fab.setOnClickListener { view ->
        Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
            .setAction("Action", null).show()
    }

    mDrawerLayout = findViewById(R.id.drawer_layout)
    val navView: NavigationView = findViewById(R.id.nav_view)

    mToggle = ActionBarDrawerToggle(
        this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
    )
    mDrawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
        override fun onDrawerStateChanged(newState: Int) {
            Log.d("onDrawerStateChanged", "$newState")
            mToggle.onDrawerStateChanged(newState)
        }

        override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
            if ((slideOffset >= (dpToPx(19.9f)/drawerView.width)) && (slideOffset <= (dpToPx(20.1f)/drawerView.width))){
                Log.d("onDrawerSlide", "true")
                mDrawerLayout.openDrawer(GravityCompat.START)
            }
            Log.d("onDrawerSlide", "$slideOffset")
            mToggle.onDrawerSlide(drawerView,slideOffset)
        }

        override fun onDrawerClosed(drawerView: View) {
            mToggle.onDrawerClosed(drawerView)
        }

        override fun onDrawerOpened(drawerView: View) {
            mToggle.onDrawerOpened(drawerView)
        }

    })

    mToggle.syncState()

    navView.setNavigationItemSelectedListener(this)
}

override fun onBackPressed() {
    val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
        drawerLayout.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    return when (item.itemId) {
        R.id.action_settings -> true
        else -> super.onOptionsItemSelected(item)
    }
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    // Handle navigation view item clicks here.
    when (item.itemId) {
        R.id.nav_home -> {
            // Handle the camera action
        }
        R.id.nav_gallery -> {

        }
        R.id.nav_slideshow -> {

        }
        R.id.nav_tools -> {

        }
        R.id.nav_share -> {

        }
        R.id.nav_send -> {

        }
    }
    val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}

fun dpToPx(dps : Float) : Float{
    return (dps * Resources.getSystem().displayMetrics.density)
}

}

答案 4 :(得分:0)

我无法发表评论,但是在Android 11上获得最高投票的答案对我有效。我这样做是这样的:

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

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:focusable="true" >
        <include
            layout="@layout/main_activity"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/side_nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/side_nav_menu"/>

</androidx.drawerlayout.widget.DrawerLayout>

答案 5 :(得分:-1)

更新

该资源托管在github上。

要使用它,只需将其导入graddle中即可。 (之前没用过,我想是因为jitpack可能需要一些时间)

dependencies {
   implementation 'com.github.mayank1513:SP_DrawerLayout:master-SNAPSHOT'

确保您还在项目级毕业文件中添加了maven {url'https://jitpack.io'}。

最后一步,您可以添加抽屉了

添加自定义xmlns。您可以通过将此行添加到根视图中来做到这一点

xmlns:custom="http://schemas.android.com/apk/res-auto"

现在创建您的抽屉-您完全可以控制要放入的抽屉

<com.mayank.drawerlayout.Drawer 
  android:id="@+id/drawer"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/colorPrimary"

  custom:drawerBackground="@color/colorAccent"
  custom:drawerWidth="250dp"
  custom:onRightEdge="false">
  <!--Create what you want to put inside your drawer here-->
</com.mayank.drawerlayout.Drawer> 

注意:

  • 轻触即可打开的评论中引起的关注得到解决。
  • 减小了用于关闭抽屉的阻力。

原始答案

您可以使用Custom DrawerLayout类。请找到源代码和详细信息here

该类同时具有左侧和右侧DrawerLayout的功能,并且如果使用和自定义都非常简单,而无需对Java代码进行重大更改。

我在我的应用thisthisthis中使用了此功能。万一您想在使用前尝试一下。

最良好的祝愿。

修改 我将代码以应用和模块格式放在此处-https://github.com/mayank1513/SP_DrawerLayout

现在,“自定义”属性用于设置左边缘或右边缘,背景和抽屉宽度。您可以将其简单地添加到XML布局中。您可以在专用框架布局中创建抽屉并将初始alpha设置为0,也可以添加一行以添加阴影背景-您可以在演示应用中找到它。

您可以在抽屉式布局内创建列表,scrollView等。