📜  如何在 Android 中创建用于显示图像的滑动抽屉?(1)

📅  最后修改于: 2023-12-03 15:24:06.498000             🧑  作者: Mango

如何在 Android 中创建用于显示图像的滑动抽屉?

在 Android 应用程序中,使用滑动抽屉(Navigation Drawer)可以实现侧边栏的效果,用户可以通过滑动屏幕边缘或点击按钮来显示或隐藏抽屉栏。滑动抽屉通常用于显示应用程序的主菜单或导航菜单。在此,我们将介绍如何在 Android 中创建一个滑动抽屉,用于显示图像。

步骤
1. 创建项目

首先,打开 Android Studio,创建一个新的空白项目。

2. 添加依赖

在 build.gradle 文件中添加以下依赖:

dependencies {
    implementation 'com.android.support:design:28.0.0'
}
3. 创建布局文件

创建布局文件 activity_main.xml,该布局文件包含一个 DrawerLayout 和两个 FrameLayout,一个用于主内容(content),一个用于侧边栏(navigation drawer)。

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

</androidx.drawerlayout.widget.DrawerLayout>

这里我们使用了一个 FragmentContainerView 来代替 FrameLayout 来创建容器,可以方便的用来承载 fragment。

4. 添加侧边栏的内容

在 res 目录下创建一个 menu 目录,并添加一个图片菜单文件 image_menu.xml,用于填充侧边栏。

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">

        <item
            android:id="@+id/action_camera"
            android:icon="@drawable/ic_camera"
            android:title="Camera" />

        <item
            android:id="@+id/action_gallery"
            android:icon="@drawable/ic_gallery"
            android:title="Gallery" />

        <item
            android:id="@+id/action_settings"
            android:icon="@drawable/ic_settings"
            android:title="Settings" />

        <item
            android:id="@+id/action_share"
            android:icon="@drawable/ic_share"
            android:title="Share" />

        <item
            android:id="@+id/action_about"
            android:icon="@drawable/ic_info"
            android:title="About" />

    </group>
</menu>
5. 创建一个 fragment

将侧边栏关联到一个 fragment 上,在 res/layout 目录下创建一个 fragment_layout.xml 文件,用于展示图片。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop" />
    </RelativeLayout>
6. 创建一个导航图 nav_graph.xml

在 res/navigation 目录下创建一个 nav_graph.xml 文件,用于添加导航图,将 fragment 添加到导航图中。

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:startDestination="@id/fragment_layout">

    <fragment
        android:id="@+id/fragment_layout"
        android:name=".MyFragment"
        android:label="FragmentLayout"
        tools:layout="@layout/fragment_layout" />
</navigation>
7. 创建一个 MainActivity

在 MainActivity 中,初始化 DrawerLayout,并设置 ActionBarDrawerToggle,让工具栏和侧边栏一起滑动。还需要设置导航组件 NavController,以便在抽屉中呈现正确的目的地。

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;
    private NavController navController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        drawerLayout = findViewById(R.id.drawer_layout);
        navigationView = findViewById(R.id.navigation_view);

        navController = Navigation.findNavController(this, R.id.nav_host_fragment);

        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout,
                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        navigationView.setNavigationItemSelectedListener(item -> {
            item.setChecked(true);
            drawerLayout.closeDrawers();
            switch (item.getItemId()) {
                case R.id.action_camera:
                    navController.navigate(R.id.action_camera);
                    break;
                case R.id.action_gallery:
                    navController.navigate(R.id.action_gallery);
                    break;
                case R.id.action_settings:
                    navController.navigate(R.id.action_settings);
                    break;
                case R.id.action_share:
                    navController.navigate(R.id.action_share);
                    break;
                case R.id.action_about:
                    navController.navigate(R.id.action_about);
                    break;
            }

            return true;
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, drawerLayout)
                || super.onSupportNavigateUp();
    }
}

这里我们使用 NavigationUI 来处理菜单项的选中和导航,需要为每个菜单项定义一个 action。

8. 创建一个 MyFragment

创建一个 MyFragment,并在 onActivityCreated 方法中设置图片资源,以便在 fragment_layout.xml 中展示图片。

public class MyFragment extends Fragment {

    private ImageView imageView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_layout, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        imageView = getView().findViewById(R.id.image_view);
        Bundle bundle = getArguments();
        if (bundle != null) {
            int imageResource = bundle.getInt("imageResource");
            imageView.setImageResource(imageResource);
        }
    }
}
9. 在导航图中添加 action

在 nav_graph.xml 文件中添加 action。

<action
    android:id="@+id/action_camera"
    app:destination="@id/fragment_layout"
    app:enterAnim="@android:anim/slide_in_left"
    app:exitAnim="@android:anim/slide_out_right"
    app:popEnterAnim="@android:anim/slide_in_left"
    app:popExitAnim="@android:anim/slide_out_right">
    <argument
        android:name="imageResource"
        android:defaultValue="@drawable/ic_camera"
        app:argType="integer" />
</action>

<action
    android:id="@+id/action_gallery"
    app:destination="@id/fragment_layout"
    app:enterAnim="@android:anim/slide_in_left"
    app:exitAnim="@android:anim/slide_out_right"
    app:popEnterAnim="@android:anim/slide_in_left"
    app:popExitAnim="@android:anim/slide_out_right">
    <argument
        android:name="imageResource"
        android:defaultValue="@drawable/ic_gallery"
        app:argType="integer" />
</action>

<action
    android:id="@+id/action_settings"
    app:destination="@id/fragment_layout"
    app:enterAnim="@android:anim/slide_in_left"
    app:exitAnim="@android:anim/slide_out_right"
    app:popEnterAnim="@android:anim/slide_in_left"
    app:popExitAnim="@android:anim/slide_out_right">
    <argument
        android:name="imageResource"
        android:defaultValue="@drawable/ic_settings"
        app:argType="integer" />
</action>

<action
    android:id="@+id/action_share"
    app:destination="@id/fragment_layout"
    app:enterAnim="@android:anim/slide_in_left"
    app:exitAnim="@android:anim/slide_out_right"
    app:popEnterAnim="@android:anim/slide_in_left"
    app:popExitAnim="@android:anim/slide_out_right">
    <argument
        android:name="imageResource"
        android:defaultValue="@drawable/ic_share"
        app:argType="integer" />
</action>

<action
    android:id="@+id/action_about"
    app:destination="@id/fragment_layout"
    app:enterAnim="@android:anim/slide_in_left"
    app:exitAnim="@android:anim/slide_out_right"
    app:popEnterAnim="@android:anim/slide_in_left"
    app:popExitAnim="@android:anim/slide_out_right">
    <argument
        android:name="imageResource"
        android:defaultValue="@drawable/ic_info"
        app:argType="integer" />
</action>

至此,滑动抽屉就已经创建完毕了。

结论

在 Android 应用程序中,通过以上的步骤创建了一个滑动抽屉 Navigation Drawer,并用于显示图片,代码的可读性和维护性都很不错,在日后开发类似的应用上还是比较方便的。