Android - Jetpack 导航
Android - Jetpack Navigation
在 Android Studio 中使用 Kotlin 语言创建新项目和 select 导航抽屉 Activity 后,导航效果非常好。但是当我用 Java 语言生成同一个项目时,它不会导航到另一个片段。这有什么问题吗?谁能帮帮我?
我遇到了同样的问题。
我的解决方案是:
修改main_activity.xml:将NavigationView标签移动到DrawerLayout的末尾
如何解决这个问题
环境:
- Android工作室:3.5
- compileSdkVersion: 29
- buildToolsVersion: "29.0.0"
- targetSdkVersion: 29
步骤:
- 走进Android工作室
- 文件 -> 新建 -> 新建模块 -> Phone & 平板电脑模块 -> 下一步 -> 输入 "test" 作为 Application/Library 名称 -> 下一步 -> 导航抽屉 Activity -> 下一步 -> 完成
- Select 模块 "test" 并单击
Run button
- 进入 android phone
- 页面默认显示 HomeFragment
- 点击
menu button
在DrawerLayout中滑动
- 点击菜单中的
gallery
- DrawerLayout 关闭但 fragment 未更改为 GalleryFragment
解决方案
最后,我找到了解决方案:
修改main_activity.xml:将NavigationView标签移动到DrawerLayout
的末尾
android工作室默认生成的main_activity.xml是:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
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" />
</androidx.drawerlayout.widget.DrawerLayout>
我们应该这样改(将NavigationView
移动到DrawerLayout
的末尾):
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
这个问题是怎么来的
我们可以通过DrawerLayout和ViewDragHelper的源码找到原因:
抽屉布局
public class DrawerLayout extends ViewGroup {
//..........
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
//.........
boolean interceptForTap = false;
switch (action) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
if (mScrimOpacity > 0) {
/////////////////
//
// take a look at: ViewDragHelper.findTopChildUnder(x, y)
// it finds child from last to first
//
/////////////////
final View child = mLeftDragger.findTopChildUnder((int) x, (int) y);
if (child != null && isContentView(child)) {
// if child is the contentView of DrawerLayout, intercept it
interceptForTap = true;
}
}
//.........
break;
}
//...........
}
return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch;
}
//...........
}
ViewDragHelper
public class ViewDragHelper {
//.........
@Nullable
public View findTopChildUnder(int x, int y) {
final int childCount = mParentView.getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
final View child = mParentView.getChildAt(mCallback.getOrderedChildIndex(i));
if (x >= child.getLeft() && x < child.getRight()
&& y >= child.getTop() && y < child.getBottom()) {
return child;
}
}
return null;
}
//........
}
在 Android Studio 中使用 Kotlin 语言创建新项目和 select 导航抽屉 Activity 后,导航效果非常好。但是当我用 Java 语言生成同一个项目时,它不会导航到另一个片段。这有什么问题吗?谁能帮帮我?
我遇到了同样的问题。
我的解决方案是:
修改main_activity.xml:将NavigationView标签移动到DrawerLayout的末尾
如何解决这个问题
环境:
- Android工作室:3.5
- compileSdkVersion: 29
- buildToolsVersion: "29.0.0"
- targetSdkVersion: 29
步骤:
- 走进Android工作室
- 文件 -> 新建 -> 新建模块 -> Phone & 平板电脑模块 -> 下一步 -> 输入 "test" 作为 Application/Library 名称 -> 下一步 -> 导航抽屉 Activity -> 下一步 -> 完成
- Select 模块 "test" 并单击
Run button
- 进入 android phone
- 页面默认显示 HomeFragment
- 点击
menu button
在DrawerLayout中滑动 - 点击菜单中的
gallery
- DrawerLayout 关闭但 fragment 未更改为 GalleryFragment
解决方案
最后,我找到了解决方案:
修改main_activity.xml:将NavigationView标签移动到DrawerLayout
的末尾android工作室默认生成的main_activity.xml是:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
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" />
</androidx.drawerlayout.widget.DrawerLayout>
我们应该这样改(将NavigationView
移动到DrawerLayout
的末尾):
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
这个问题是怎么来的
我们可以通过DrawerLayout和ViewDragHelper的源码找到原因:
抽屉布局
public class DrawerLayout extends ViewGroup {
//..........
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
//.........
boolean interceptForTap = false;
switch (action) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
if (mScrimOpacity > 0) {
/////////////////
//
// take a look at: ViewDragHelper.findTopChildUnder(x, y)
// it finds child from last to first
//
/////////////////
final View child = mLeftDragger.findTopChildUnder((int) x, (int) y);
if (child != null && isContentView(child)) {
// if child is the contentView of DrawerLayout, intercept it
interceptForTap = true;
}
}
//.........
break;
}
//...........
}
return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch;
}
//...........
}
ViewDragHelper
public class ViewDragHelper {
//.........
@Nullable
public View findTopChildUnder(int x, int y) {
final int childCount = mParentView.getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
final View child = mParentView.getChildAt(mCallback.getOrderedChildIndex(i));
if (x >= child.getLeft() && x < child.getRight()
&& y >= child.getTop() && y < child.getBottom()) {
return child;
}
}
return null;
}
//........
}