代码之家  ›  专栏  ›  技术社区  ›  Paul Spiesberger

Android Jetpack导航-带抽屉项目的自定义操作

  •  3
  • Paul Spiesberger  · 技术社区  · 6 年前

    我用的是新的 Jetpack Android Navigation

    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val navController = findNavController(R.id.navigation_host_fragment)
            setupActionBarWithNavController(navController, find(R.id.drawer_layout))
            val navigationView = findViewById<NavigationView>(R.id.nav_view)
            navigationView.setupWithNavController(findNavController(R.id.navigation_host_fragment))
    }
    

    我现在还想触发自定义操作/代码,而不是在单击抽屉菜单中的项目时执行片段事务。 我有以下菜单,并想注销用户时,点击“注销” :

    Current menu with logout item

    2 回复  |  直到 5 年前
        1
  •  20
  •   Paul Spiesberger    6 年前

    我找到了解决办法:

    val navigationView = findViewById<NavigationView>(R.id.nav_view)
    val logoutItem = navigationView.menu.findItem(R.id.nav_logout)
    logoutItem.setOnMenuItemClickListener {
         toast("Log me out")
         true
    }
    
        2
  •  0
  •   Abdulatif Yusupov    6 年前

    我也找到了解决办法。

    首先,您需要创建自定义导航UI。

    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    
    import com.google.android.material.bottomsheet.BottomSheetBehavior;
    import com.google.android.material.navigation.NavigationView;
    
    import java.lang.ref.WeakReference;
    
    import androidx.annotation.IdRes;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.coordinatorlayout.widget.CoordinatorLayout;
    import androidx.drawerlayout.widget.DrawerLayout;
    import androidx.navigation.NavController;
    import androidx.navigation.NavDestination;
    import androidx.navigation.ui.NavigationUI;
    
    public class CustomNavigationUI {
    
        public static void setupWithNavController(@NonNull final NavigationView navigationView,
                                                  @NonNull final NavController navController,
                                                  @Nullable final NavigationView.OnNavigationItemSelectedListener customListener) {
            navigationView.setNavigationItemSelectedListener(
                    item -> {
                        boolean handled = NavigationUI.onNavDestinationSelected(item, navController);
                        if (handled) {
                            ViewParent parent = navigationView.getParent();
                            if (parent instanceof DrawerLayout) {
                                ((DrawerLayout) parent).closeDrawer(navigationView);
                            } else {
                                BottomSheetBehavior bottomSheetBehavior =
                                        findBottomSheetBehavior(navigationView);
                                if (bottomSheetBehavior != null) {
                                    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                                }
                            }
                        } else {
                            if (customListener != null) {
                                customListener.onNavigationItemSelected(item);
                            }
                        }
                        return handled;
                    });
            final WeakReference<NavigationView> weakReference = new WeakReference<>(navigationView);
            navController.addOnDestinationChangedListener(
                    new NavController.OnDestinationChangedListener() {
                        @Override
                        public void onDestinationChanged(@NonNull NavController controller,
                                                         @NonNull NavDestination destination, @Nullable Bundle arguments) {
                            NavigationView view = weakReference.get();
                            if (view == null) {
                                navController.removeOnDestinationChangedListener(this);
                                return;
                            }
                            Menu menu = view.getMenu();
                            for (int h = 0, size = menu.size(); h < size; h++) {
                                MenuItem item = menu.getItem(h);
                                item.setChecked(matchDestination(destination, item.getItemId()));
                            }
                        }
                    });
        }
    
        static BottomSheetBehavior findBottomSheetBehavior(@NonNull View view) {
            ViewGroup.LayoutParams params = view.getLayoutParams();
            if (!(params instanceof CoordinatorLayout.LayoutParams)) {
                ViewParent parent = view.getParent();
                if (parent instanceof View) {
                    return findBottomSheetBehavior((View) parent);
                }
                return null;
            }
            CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params)
                    .getBehavior();
            if (!(behavior instanceof BottomSheetBehavior)) {
                // We hit a CoordinatorLayout, but the View doesn't have the BottomSheetBehavior
                return null;
            }
            return (BottomSheetBehavior) behavior;
        }
    
        @SuppressWarnings("WeakerAccess") /* synthetic access */
        static boolean matchDestination(@NonNull NavDestination destination,
                                        @IdRes int destId) {
            NavDestination currentDestination = destination;
            while (currentDestination.getId() != destId && currentDestination.getParent() != null) {
                currentDestination = currentDestination.getParent();
            }
            return currentDestination.getId() == destId;
        }
    
    }
    

    第二,叫这个 自定义导航UI 导航UI 活动中

    /* NavigationUI.setupWithNavController(binding.navigationView, navController); */
    CustomNavigationUI.setupWithNavController(binding.navigationView, navController, item -> {
                switch (item.getItemId()){
                    case R.id.sign_out:
                        //todo sign out
                        break;
                }
                return true;
            });
    

    这就是全部!

        3
  •  0
  •   Taha Körkem    3 年前

    fun NavigationView.setSafeNavigationItemSelectedListener(vararg listener: Pair<Int, () -> Unit>) =
    listener.forEach { (itemId, act) ->
        menu.findItem(itemId)?.setOnMenuItemClickListener { act(); true }
    }
    

        val navigationView = findViewById<NavigationView>(R.id.nav_view)
        navigationView.setSafeNavigationItemSelectedListener(
            R.id.shareIntent to {
                shareIntent()
                drawerLayout.closeDrawer(GravityCompat.START)
            },
            R.id.mySchedulesIntent to {
                val i = Intent(this, MySchedulesActivity::class.java)
                startActivity(i)
                drawerLayout.closeDrawer(GravityCompat.START)
            },
            R.id.importantDetailsIntent to {
                displayImportantDetailsDialog()
                drawerLayout.closeDrawer(GravityCompat.START)
            },
            R.id.infoIntent to {
                val i = Intent(this, InfoActivity::class.java)
                startActivity(i)
                drawerLayout.closeDrawer(GravityCompat.START)
            },
            R.id.settingsIntent to {
                val i = Intent(this, SettingsActivity::class.java)
                startActivity(i)
                drawerLayout.closeDrawer(GravityCompat.START)
            },
        )