Короче говоря, я новичок в среде Android и немного больше, чем могу понять, пытаясь выучить Android и Kotlin. Я создал свои контроллеры пользовательского интерфейса в Kotlin и использовал пример кода Google для выполнения навигации по фрагментам. После этого я обнаружил, что для меня гораздо эффективнее программировать весь свой бэкэнд на Java. Не желая иметь дело с двумя языками в одном приложении, я успешно перенес все свои контроллеры пользовательского интерфейса с Kotlin на Java. Тем не менее, я застрял в моем классе MainActivity. Ниже приведена версия Kotlin, два файла макета XML и моя попытка Java-версии MainActivity.
Путаница связана с двумя вызовами методов setupBottomNavMenu () и setupNavigation Menu () в onCreate ().
Класс BottomNavigationView, по-видимому, не имеет метода setupWithNavController (NavController navController), как в Kotlin. Самое близкое, что я могу найти, это setupWithNavController (BottomNavigationView bottomNavigationView, NavController navController). Если я выберу это и закомментирую вызов в setupNavigation Menu (), приложение будет работать в портретном режиме, но вылетает, когда я наклоняю свой телефон (альбомный режим).
Класс NavigationView также не предлагает метод, который принимает один параметр типа NavController, как в версии Kotlin. Я снова выбрал аналогичный метод setupWithNavController (NavigationView navigationView, NavController navController), но после запуска моего приложения происходит сбой.
Может кто-нибудь пролить свет на это для меня? В этот момент я вращаю свои колеса, пытаясь понять, что происходит.
Мой импорт Gradle для навигации:
def nav_version = "2.1.0-alpha03"
implementation "androidx.navigation:navigation-fragment:$nav_version" // For Kotlin use navigation-fragment-ktx
implementation "androidx.navigation:navigation-ui:$nav_version" // For Kotlin use navigation-ui-ktx
Макет XML-портрета и ландшафта
<LinearLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<fragment
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu" />
<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"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<fragment
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
</LinearLayout>
<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"
app:menu="@menu/nav_drawer_menu" />
MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.NavController
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.navigation.NavigationView
class MainActivity : AppCompatActivity(){
private lateinit var appBarConfiguration : AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val host: NavHostFragment = supportFragmentManager
.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return
// Set up Action Bar
val navController = host.navController
//Create AppBarConfiguration with the correct top-level destinations
val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
appBarConfiguration = AppBarConfiguration(
setOf(R.id.home_dest),
drawerLayout)
//set up bottom navigation (in portrait mode)
setupBottomNavMenu(navController)
//set up side navigation menu (in landscape mode)
setupNavigationMenu(navController)
//configure action bar for popping back on the stack.
setupActionBar(navController, appBarConfiguration)
}
private fun setupBottomNavMenu(navController: NavController)
{
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav_view)
bottomNav?.setupWithNavController(navController)
}
private fun setupNavigationMenu(navController: NavController)
{
// In split screen mode, you can drag this view out from the left
// This does NOT modify the actionbar
val sideNavView = findViewById<NavigationView>(R.id.nav_view)
sideNavView?.setupWithNavController(navController)
}
private fun setupActionBar(navController: NavController, appBarConfig : AppBarConfiguration)
{
// This allows NavigationUI to decide what label to show in the action bar
// By using appBarConfig, it will also determine whether to
// show the up arrow or drawer menu icon
setupActionBarWithNavController(navController, appBarConfig)
}
override fun onSupportNavigateUp(): Boolean
{
// Allows NavigationUI to support proper up navigation or the drawer layout
// drawer menu, depending on the situation
return findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
}
}
MainActivity.java
import android.os.Bundle;
import androidx.appcompat.widget.Toolbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
import static androidx.navigation.Navigation.findNavController;
import static androidx.navigation.ui.NavigationUI.setupWithNavController;
public class MainActivity extends AppCompatActivity{
private AppBarConfiguration appBarConfiguration;
private NavController navController;
private DrawerLayout drawerLayout;
private Toolbar toolbar;
public MainActivity()
{
//do nothing
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
navController = Navigation.findNavController(this, R.id.my_nav_host_fragment);
drawerLayout = findViewById(R.id.drawer_layout);
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph())
.setDrawerLayout(drawerLayout)
.build();
//set up bottom navigation (in portrait mode)
setupBottomNavMenu(navController);
//set up side navigation menu (in landscape mode)
setupNavigationMenu(navController);
//configure action bar for popping back on the stack.
setupActionBar(navController, appBarConfiguration);
}
private void setupBottomNavMenu(NavController navController)
{
BottomNavigationView bottomNav = findViewById(R.id.bottom_nav_view);
setupWithNavController(bottomNav, navController);
}
private void setupNavigationMenu(NavController navController)
{
// In split screen mode, you can drag this view out from the left
// This does NOT modify the actionbar
NavigationView sideNavView = findViewById(R.id.nav_view);
setupWithNavController(sideNavView, navController);
}
private void setupActionBar(NavController navController, AppBarConfiguration appBarConfig)
{
// This allows NavigationUI to decide what label to show in the action bar
// By using appBarConfig, it will also determine whether to
// show the up arrow or drawer menu icon
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfig);
}
@Override
public boolean onSupportNavigateUp()
{
// Allows NavigationUI to support proper up navigation or the drawer layout
// drawer menu, depending on the situation
return findNavController(findViewById(R.id.my_nav_host_fragment)).navigateUp();
}
}