android 导航抽屉_Android导航抽屉

android 导航抽屉

Learn the easiest way to implement Nav Drawer in your apps

了解在您的应用中实施Nav Drawer的最简单方法

什么是导航抽屉? (What is Navigation Drawer?)

A Navigation Drawer is nothing but a panel of options on the left edge of the screen. Usually, it is hidden from view, however, it can be revealed when the user swipes from the left or clicks on the “hamburger” icon. Also if there is enough space on the screen for instance consider a tablet in landscape mode so here we can display the Navigation Drawer permanently without hiding it. It’s generally referred with many names like Nav Drawer, Nav menu, Left Nav, Navigation Menu, etc.

导航抽屉不过是屏幕左边缘的一组选项。 通常,它是从视图中隐藏的,但是,当用户从左侧滑动或单击“汉堡”图标时,可以将其显示出来。 另外,如果屏幕上有足够的空间,例如考虑使用横向模式的平板电脑,那么在这里我们可以永久显示导航抽屉而不隐藏它。 通常用很多名称来引用它,例如导航抽屉,导航菜单,左导航,导航菜单等。

为什么我们需要导航抽屉? (Why do we need a Navigation Drawer?)

Nav Drawer is one of the standard practices implemented in most apps that have more options to expose to their users. It provides a flexible and easiest way for the users to reach a particular destination rather than searching for the options they require. Navigation Drawer is the best solution for quick navigation between unrelated destinations.

导航抽屉是大多数应用程序中实施的标准做法之一,可以向用户公开更多选项。 它为用户提供了一种灵活,最简单的方法来到达特定的目的地,而不是搜索他们所需的选项。 导航抽屉是在不相关的目的地之间进行快速导航的最佳解决方案。

如何实现导航抽屉? (How to implement a Navigation Drawer?)

Navigation Drawer is nothing but a container where our navigation menu resides. Either we can use NavigationView for creating a highly customizable menu or we can simply use a RecyclerView to provide the menu items. Here let’s check the implementation with Navigation View. Navigation View is a widget provided by the android which we can use inside a Drawer. This is most commonly used in conjunction with DrawerLayout while implementing Material navigation drawers. Navigation View makes it very easy to create a navigation menu inside your app.

导航抽屉不过是我们的导航菜单所在的容器。 我们可以使用NavigationView创建高度可定制的菜单,也可以简单地使用RecyclerView提供菜单项。 在这里,让我们检查一下导航视图的实现。 Navigation View是android提供的小部件,我们可以在Drawer内部使用。 在实现Material导航抽屉时,这通常与DrawerLayout结合使用。 导航视图使在应用程序内部创建导航菜单变得非常容易。

Before going to the implementation we need to be assured of a few things related to the nav items. Each item in the side nav should have a particular purpose & properties that should define them. Let’s check the properties initially. Side Nav item should have a name, icon for display purpose, and an id for identification. We can provide the nav items through a menu file & handle the click with callbacks it would be easier. But here let’s set up a RecyclerView to provide the items which we can customize according to our requirement.

在执行之前,我们需要确保与导航项有关的一些事情。 侧面导航中的每个项目均应具有特定的用途和属性,以对其进行定义。 让我们首先检查属性。 Side Nav项目应具有名称,用于显示目的的图标和用于标识的ID。 我们可以通过菜单文件提供导航项,并通过回调处理单击,这将更加容易。 但是在这里,我们设置一个RecyclerView来提供我们可以根据需要自定义的项目。

实作 (Implementation)

Adding a navigation drawer in an app requires few steps to be followed. Let’s check each step individually for better understanding.

在应用程序中添加导航抽屉仅需遵循几个步骤。 让我们单独检查每个步骤,以更好地理解。

第1步: (Step 1:)

Let’s define a model class which contains the side nav item properties

让我们定义一个包含侧面导航项属性的模型类

package com.example.sidenav


data class SideNavItem(
    var id:Int,
    var itemName:String,
    var resourceId:Int
)

第2步: (Step 2:)

Add the required dependencies in the app or module level build.gradle file

在应用程序或模块级别的build.gradle文件中添加所需的依赖项

implementation 'com.google.android.material:material:1.0.0'// For NavigationView
   
   implementation 'androidx.fragment:fragment:1.2.0'// For FragmentContainView

FragmentContainerView is a customized layout designed to handle fragments. Check out more about FragmentContainerView. Using this we no need to add the SideNavFragment programmatically.

FragmentContainerView是用于处理片段的自定义布局。 进一步了解FragmentContainerView 。 使用此方法,我们无需以编程方式添加SideNavFragment。

步骤3:设置DasBoardActivity (Step 3: Setting Up the DasBoardActivity)

Design the layout file to host the Navigation View. This was the layout used by HomeActivity or DashboardActivity

设计布局文件以承载导航视图。 这是HomeActivity或DashboardActivity使用的布局

<?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"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/theme_color">




    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
     <androidx.appcompat.widget.AppCompatImageView
            android:layout_width="wrap_content"
            android:id="@+id/im_hamburger"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/spacing_10"
            android:padding="13dp"
            app:srcCompat="@drawable/ic_left_menu"
            tools:ignore="VectorDrawableCompat" />
        
        ......


    </RelativeLayout>
        
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/side_nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start">


        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/side_nav_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:name="com.example.SideNavFragment"
            tools:layout="@layout/fragment_side_nav" />


    </com.google.android.material.navigation.NavigationView>


</androidx.drawerlayout.widget.DrawerLayout>

In the FragmentContainerView there was an attribute called name which defines the path of the class to be hosted as SideNavFragment. And the activity would look like something below

在FragmentContainerView中,有一个名为name的属性,该属性定义了要作为SideNavFragment托管的类的路径。 该活动如下所示

package com.example.sidenav


import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity


class DashboardActivity:AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
          im_hamburger?.setOnClickListener {
            drawer_layout.openDrawer(GravityCompat.START)
        }
    }
    
    
    fun closeDrawer(item: SideNavItem) {
        drawer_layout?.closeDrawer(GravityCompat.START)
        when (item.id) {
            1 -> {
                handleUpgrade()
            }
            2 -> {
                rateUs()
            }
            3 -> {
                shareApp()
            }
            4 -> {
                handlesettings()
            }
          
        }
    }


}

第4步: (Step 4:)

Let’s implement the layout file for SideNavFragment.

让我们实现SideNavFragment的布局文件。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@color/white">


    //View That displays bg color for header
    <View
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/theme_color"
        app:layout_constraintBottom_toBottomOf="@+id/txt_app_name"
        app:layout_constraintTop_toTopOf="parent" />




    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/txt_app_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:paddingBottom="70dp"
        android:layout_marginTop="70dp"
        android:textColor="@color/white"
        android:textSize="40sp"
        app:fontFamily="@font/sample"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="Side Nav" />


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_side_nav_options"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="10dp"
        android:clipToPadding="false"
        app:layout_constraintTop_toBottomOf="@id/header"
        tools:layout_editor_absoluteX="0dp" />


</androidx.constraintlayout.widget.ConstraintLayout>

You can implement this in your own style. This was just for a reference. This was the layout that we will see when we click on a hamburger or dragging layout from the left side.

您可以按照自己的样式来实现。 这仅供参考。 这是单击汉堡包或从左侧拖动布局时将看到的布局。

步骤5: (Step 5:)

Now it’s time to set up the SideNavFragment. In this class, we create the instance of the adapter that displays the nav items.

现在是时候设置SideNavFragment。 在此类中,我们创建显示导航项的适配器实例。

package com.example.sidenav


import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.sidenav.SideNavAdapter
import com.example.sidenav.SideNavItem
import kotlinx.android.synthetic.main.fragment_side_nav.*


class SideNavFragment :Fragment(){


    private val sideNavAdapter: SideNavAdapter = SideNavAdapter {position, item ->
        onItemClick(position,item)
    }


    private fun onItemClick(position: Int, item: SideNavItem) {
        Toast.makeText(requireContext(),""+item.itemName,Toast.LENGTH_LONG).show()
        (activity as MenuScreen).closeDrawer(item)
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View?  = inflater.inflate(R.layout.fragment_side_nav, container, false)


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setUpViews()
    }


    private fun setUpViews() {
        rv_side_nav_options?.layoutManager = LinearLayoutManager(requireActivity(), LinearLayoutManager.VERTICAL, false)
        rv_side_nav_options?.adapter = sideNavAdapter
        sideNavAdapter.setNavItemsData(prrepareNavItems())
    }


   //Create List of items to be displayed on the sidenav
    private fun prrepareNavItems(): List<SideNavItem> {
        val menuItemsList = ArrayList<SideNavItem>()
        menuItemsList.add(SideNavItem(1,"Upgrade",R.drawable.ic_upgrade))
        menuItemsList.add(SideNavItem(2,"Rate us",R.drawable.ic_rate))
        menuItemsList.add(SideNavItem(3,"Share",R.drawable.ic_share))
        menuItemsList.add(SideNavItem(5,"Settings",R.drawable.ic_settings))
        return menuItemsList
    }
}

步骤6: (Step 6:)

The final step of creating the Nav Items adapter with its layout file.

使用其布局文件创建Nav Items适配器的最后一步。

Create the layout file of the item depending on how do you want the item to be appearing.

根据您希望项目如何显示来创建项目的布局文件。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
    android:paddingBottom="@dimen/spacing_10"
    android:background="?android:attr/selectableItemBackground">


    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/iv_nav_option"
        android:layout_width="@dimen/spacing_30"
        android:layout_height="@dimen/spacing_30"
        android:layout_marginStart="@dimen/sidenav_horizontal_margin"
        android:layout_marginLeft="@dimen/sidenav_horizontal_margin"
        android:layout_marginTop="@dimen/spacing_10"
        android:layout_marginBottom="@dimen/spacing_10"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tv_nav_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="15dp"
        android:layout_marginLeft="15dp"
        android:ellipsize="end"
        android:textColor="@color/black"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="@id/iv_nav_option"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/iv_nav_option"
        app:layout_constraintTop_toTopOf="@id/iv_nav_option"
        tools:text="Rate" />




    <View
        android:layout_width="0dp"
        android:layout_height="10dp"
        android:background="@color/grey"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />




</androidx.constraintlayout.widget.ConstraintLayout>

Now it’s time for SideNavAdapter

现在是时候使用SideNavAdapter

package com.example.sidenav


import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.sidenav.R
import com.example.sidenav.SideNavItem
import kotlinx.android.synthetic.main.item_side_nav.view.*


class SideNavAdapter(private val onItemClick: ((position: Int, item: SideNavItem) -> Unit)) :
    RecyclerView.Adapter<SideNavAdapter.SideNavVH>() {
    var menuItemsList = ArrayList<SideNavItem>()


    fun setNavItemsData( list: List<SideNavItem>){
        menuItemsList.addAll(list)
        notifyDataSetChanged()
    }


    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): SideNavAdapter.SideNavVH {
        return SideNavVH(
            LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.item_side_nav, viewGroup, false)
        )
    }


    inner class SideNavVH(inflate: View) : RecyclerView.ViewHolder(inflate) {
        fun setData(sideNavItem: SideNavItem) {
            itemView.setOnClickListener {
                sideNavItem.let {
                    onItemClick.invoke(adapterPosition, sideNavItem)
                }
            }
            itemView.iv_nav_option?.setImageResource(sideNavItem.resourceId)
            itemView.tv_nav_text?.text = sideNavItem.itemName
        }
    }


    override fun getItemCount(): Int {
        return menuItemsList.size
    }


    override fun onBindViewHolder(holder: SideNavVH, position: Int) {
        holder.setData(menuItemsList[position])
    }
}

摘要 (Summary)

That’s it we are done. This was the easy and customizable implementation of Side Nav. If you implement it using some menu later if someone wants to customize the look of an item it would be difficult. So even it takes a bit of time it’s good to implement reusable and customizable code.

就是这样,我们完成了。 这是Side Nav的简单且可自定义的实现。 如果以后要使用某些菜单来实现它,而又有人要自定义项目的外观,那将很困难。 因此,即使花费一些时间,实现可重用和可自定义的代码也很好。

If interested check out my posts on Kotlin series

如果有兴趣,请查看我关于Kotlin系列的帖子

Please let me know your suggestions and comments.

请让我知道您的建议和意见。

You can find me on Medium and LinkedIn

您可以在MediumLinkedIn上找到我…

Thanks for reading…

谢谢阅读…

翻译自: https://medium.com/@pavan.careers5208/android-navigation-drawer-4ea0e6bee4ab

android 导航抽屉

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值