Установить маркер для 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
. У него нет этой проблемы.
Также убедитесь, что это решение работает только с левым/начальным ящиком, а не с правым/конечным.