【问题标题】:DrawerLayout getting stuck on swipeDrawerLayout 卡在滑动上
【发布时间】:2013-08-04 11:46:05
【问题描述】:

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

我不确定发生了什么,我完全按照 google sdk 中的代码示例进行操作。有什么想法吗?

这是我的 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)。下面是它的外观:

我已向 Google(here 和后来的 here)报告了这件事,但没有帮助。

我已经在这个线程上尝试了所有现有的解决方案,但没有一个有效。如果有人对此有很好的解决方法(同时仍在使用 DrawerLayout 或扩展它,或类似的东西),请提出一个可行的解决方案。

【问题讨论】:

  • 我认为这是一个错误。我对姜饼有同样的错误。在 Nexus 7 上测试,我无法重现。
  • 您确定这不是功能吗?文档:If the user touches the very left edge of the screen (within 20 dp from the left), have the drawer peek out as soon as the finger makes contact with the display. This promotes accidental discovery and provides richer feedback.
  • 这不是一个功能。我试图解释其中的区别:窥视功能通过单击左侧来工作,并提供反馈说有东西可以拉出 -> 导航抽屉。我遇到的未知是一个错误:它可以窥视,但您无法将其拉出。这不是故意的!
  • 最新支持库版本21.0.1问题依然存在
  • @androiddeveloper 这个问题即使在 Google Play 应用程序中也存在,我认为我们无法修复它

标签: android navigation-drawer androidx


【解决方案1】:

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

android:clickable="true"

例如: 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>

【讨论】:

  • 不幸的是,这对我不起作用。我仍然能够重现卡在从左侧滑动的问题。
  • 这解决了我在 Android 4.4.4、OnePlus One、min API 17、目标 API 21 上的问题
【解决方案2】:

如果您向我们展示了您的布局 xml,我们可以查看您是否将 DrawerLayout 作为 ROOT 元素。以及里面的两个child是否是Main Layout和Navigation Drawer。

根据Create a Drawer Layout

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

【讨论】:

  • Wenza,请查看revisions 以获得答案。我不得不猜测你在说什么,所以如果我错了,请纠正它。但不要使用答案来提问 - 努力获得发布 cmets 的特权。
  • 你好,答案是有抽屉布局作为根和两个元素内。这个问题是额外的。
  • 无需显示任何内容。这个问题甚至存在于一个从一开始就有抽屉的全新项目中,通过 IDE 的向导。
  • 另外,如果你真的愿意,我已经发布了一个示例项目。
【解决方案3】:

我已经通过实现这个 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);
                }
            }
        });

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

【讨论】:

  • 这使行为变得更糟。现在每次抽屉没有完全打开时,它都会关闭。需要一直拖到右边才能打开。
【解决方案4】:

当用户将抽屉拖到20dp而不是打开抽屉时,可以实现20dp Peek功能。 这是对我来说工作正常的代码。

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)
}

}

【讨论】:

  • 抱歉,此代码仍然存在此问题。有点难以复制,但它仍然存在。
  • @androiddeveloper 是的,我已经优化了条件,希望可以解决所有问题。
  • 我不明白你做了什么改变,但问题仍然存在,就像以前一样,所以这仍然不是解决方案/解决方法。
【解决方案5】:

我无法发表评论,但在 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>

【讨论】:

    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    相关资源
    最近更新 更多