Установить маркер для Android-навигации

Я использую новый Навигационный ящик в своем приложении. Это здорово, за исключением того, что я не нашел простой способ установить, как ящик открыт. Поведение по умолчанию - перетаскивание от левого края экрана, чтобы открыть. Это нормально, если только на телефоне / столе не установлен чехол и к краю телефона нельзя прикоснуться. Я хотел бы разрешить пользователю прикасаться к краю экрана влево и перетаскивать его. Это легко установить с помощью других библиотек навигационного ящика (Sliding lib). К сожалению, я ничего не видел с библиотекой Google.

Существует метод onTouchEvent() для NavigationLayout, который можно использовать. Конечно, вы могли прослушивать все сенсорные события и запускать openDrawer, но надеялись на легкий путь с меньшим количеством кода. Есть идеи?

2 ответа

Решение

Здесь я нашел решение с помощью размышлений

DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
Field mDragger = mDrawerLayout.getClass().getDeclaredField(
        "mLeftDragger");//mRightDragger for right obviously
mDragger.setAccessible(true);
ViewDragHelper draggerObj = (ViewDragHelper) mDragger
        .get(mDrawerLayout);

Field mEdgeSize = draggerObj.getClass().getDeclaredField(
        "mEdgeSize");
mEdgeSize.setAccessible(true);
int edge = mEdgeSize.getInt(draggerObj);

mEdgeSize.setInt(draggerObj, edge * 5); //optimal value as for me, you may set any constant in dp

Это действительно старый вопрос, но сегодня я столкнулся с этой проблемой, попробовал оригинальное решение, но оно мне не помогло.

После нескольких часов попыток я обнаружил, что проблема не в решении. Это с изменением версии библиотеки.

Принятый ответ работал для android.drawerlayout:drawerlayout:1.0.0

но для меня я использовал com.google.android.material:material:1.5.0, что зависит от более высокой версии drawerlayout:drawerlayout

Команда Android добавила некоторую логику в onLayoutдля установки размера края.

Поэтому я использовал исходное решение, но вместо того, чтобы использовать его в действии, я создал настраиваемое представление на основе DrawerLayout.

Итак, вот мой пользовательский класс:

      class CustomDrawerLayout : DrawerLayout {
    var swipeEdgeSize = 0

    constructor(context: Context) : this(context, null, 0)
    constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        var leftDraggerField = DrawerLayout::class.java.getDeclaredField("mLeftDragger")
        leftDraggerField.isAccessible = true
        val viewDragHelper = leftDraggerField[this] as ViewDragHelper

        val edgeSizeField = ViewDragHelper::class.java.getDeclaredField("mEdgeSize")
        edgeSizeField.isAccessible = true
        val origEdgeSize = edgeSizeField[viewDragHelper] as Int
        edgeSizeField.setInt(viewDragHelper, max(swipeEdgeSize, origEdgeSize))
    }
}

и внутри активности я буду использовать что-то подобное

      class MainActivity :....{
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(....)
        setSideMenuAreaRatio(0.8)
        ....
    }

private fun setSideMenuAreaRatio(ration: Double) {
        val displaySize = Point()
        windowManager.defaultDisplay.getSize(displaySize)
        binding.drawerLayout.swipeEdgeSize = (displaySize.x * ration).toInt()
    }
}

Но если вы начинаете свой новый проект, используйте jetpack compose. У него нет этой проблемы.


Также убедитесь, что это решение работает только с левым/начальным ящиком, а не с правым/конечным.

Другие вопросы по тегам