【Android】实现一个优雅的自定义底部导航栏(速通安卓大作业必备)

news2024/11/17 16:34:41

文章目录

  • 前言
  • 一、实现思路
  • 二、代码实现流程
      • ①修改theme:
      • ②在color文件中添加颜色:
      • ③添加图标文件
      • ④添加选中时布局的背景
      • ⑤修改布局文件
      • ⑥按钮效果图:
      • ⑦修改`MainActivity`中的代码
      • ⑦创建各个界面的Fragment
      • ⑧运行结果:
  • 三、 总结

在这里插入图片描述

前言

本篇文章为本人在大一时候写的一篇笔记,因此请大家轻喷(因为有部分代码并没有考虑代码规范性,其中的代码的使用也比较愚笨😭,而且当时也没学Kotlin,所以使用的Java),本篇文章主要面向想要应付安卓大作业,需要一个比较好看的底部导航栏的安卓小白🙂。

一、实现思路

实现方法非常简单粗暴(至少在我看来),观察可以发现我们要设计的底部按钮主要由文本(TextView)、图标(ImageView)和背景的椭圆(shape)这三个元素构成,这三个部分比较简单。点击逻辑其实也很简单,只要当点击按钮最外层的空间时对应设置当前按钮为选中状态,其余按钮为未选中状态,把对应的图标设置一下,因为我们要实现只有选中的按钮才会显示文本(TextView),因此在点击按钮时要设置其他未选中按钮的文本为不可见。动画则是设置ScaleAnimation,设置动画的锚点等等来实现点击时的动画。

二、代码实现流程

①修改theme:

首先修改theme文件中的代码(深色模式中的也要改):

<style name="Theme.NavigationView" parent="Theme.MaterialComponents.DayNight.NoActionBar">

②在color文件中添加颜色:

后面四个颜色是上面的那四个颜色的A%改为20得到的

image-20230621140957340

    <color name="home">#1194AA</color>
    <color name="like">#C9379D</color>
    <color name="notification">#AE7E0F</color>
    <color name="profile">#5B37B7</color>

    <color name="home_20">#331194AA</color>
    <color name="like_20">#33C9379D</color>
    <color name="notification_20">#33AE7E0F</color>
    <color name="profile_20">#335B37B7</color>

③添加图标文件

图标文件分为两部分,一部分是未选中的图标,一个是选中后的图标,文件结构如下

image-20230621142403420

选中状态的图标只需要修改path中的fileColor为之前添加的颜色即可

image-20230621142642740

④添加选中时布局的背景

在drawable文件中添加三个按钮被选中时布局的背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <solid android:color="@color/home_20"/>
    <corners android:radius="100dp"/>
</shape>
image-20230621150250710

设置背景后的情况

image-20230621150357721

⑤修改布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="4"
        android:paddingStart="20dp"
        android:paddingEnd="20dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:elevation="10dp"
        android:gravity="center"
        android:layout_alignParentBottom="true"
        android:background="@color/white"
        >

        <LinearLayout
            android:background="@drawable/round_back_home_100"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:paddingStart="5dp"
            android:paddingEnd="5dp"
            android:gravity="center"
            android:layout_weight="1"
            >
        <ImageView
            android:layout_width="20dp"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:src="@drawable/home_selected"
            />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="home"
                android:layout_marginStart="10dp"
                android:textStyle="bold"
                android:textColor="@color/home"
                android:textSize="16sp"
                />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

⑥按钮效果图:

image-20230621151339235

这样我们就实现了其中一个按钮,之后将按钮的代码赋值粘贴后,修改布局的backgroud,设置TextView的text、visibility和textColor,ImageView的src后如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/home"
    tools:context=".MainActivity"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="4"
        android:paddingStart="20dp"
        android:paddingEnd="20dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:elevation="10dp"
        android:gravity="center"
        android:layout_alignParentBottom="true"
        android:background="@color/white"
        >

        <LinearLayout
            android:id="@+id/homeLayout"
            android:background="@drawable/round_back_home_100"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:paddingStart="5dp"
            android:paddingEnd="5dp"
            android:gravity="center"
            android:layout_weight="1"
            >

            <ImageView
                android:id="@+id/home_im"
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:src="@drawable/home_selected" />

            <TextView
                android:id="@+id/home_tx"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="home"
                android:textColor="@color/home"
                android:textSize="16sp"
                android:textStyle="bold" />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/likeLayout"
            android:background="@android:color/transparent"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:paddingStart="5dp"
            android:paddingEnd="5dp"
            android:gravity="center"
            android:layout_weight="1"
            >

            <ImageView
                android:id="@+id/like_im"
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:src="@drawable/like" />
            <TextView
                android:id="@+id/like_tx"
                android:visibility="gone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="like"
                android:layout_marginStart="10dp"
                android:textStyle="bold"
                android:textColor="@color/home"
                android:textSize="16sp"
                />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/notificationLayout"
            android:background="@android:color/transparent"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:paddingStart="5dp"
            android:paddingEnd="5dp"
            android:gravity="center"
            android:layout_weight="1"
            >

            <ImageView
                android:id="@+id/nitification_im"
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:src="@drawable/notification" />
            <TextView
                android:id="@+id/notification_tx"
                android:visibility="gone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="notification"
                android:layout_marginStart="10dp"
                android:textStyle="bold"
                android:textColor="@color/home"
                android:textSize="16sp"
                />
        </LinearLayout>
        <!--        布局的宽度根据权值平局分配-->
        <LinearLayout
            android:id="@+id/profileLayout"
            android:background="@android:color/transparent"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:paddingStart="5dp"
            android:paddingEnd="5dp"
            android:gravity="center"
            android:layout_weight="1"
            >

            <ImageView
                android:id="@+id/profile_im"
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:src="@drawable/profile" />
            <TextView
                android:id="@+id/profile_tx"
                android:visibility="gone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="profile"
                android:layout_marginStart="10dp"
                android:textStyle="bold"
                android:textColor="@color/profile"
                android:textSize="16sp"
                />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>
image-20230621153213510

这样我们就实现了一个基本的底部导航栏界面,接下来要解决的是动画的问题。

⑦修改MainActivity中的代码

实现流程:

  1. 初始化布局和控件: 首先绑定控件和布局,这里只是随便写的代码(当时只是想着实现,还没考虑规范性问题),所以代码规范性勿喷😭。
  2. 设置初始状态: 初始化 selectedTab 变量,用于记录当前选中的导航项,默认值为1(即 home 导航项)。
  3. 点击事件监听: 为每个 LinearLayout 设置点击事件监听器,当某个导航项被点击时:
    • 检查是否被选中: 首先检查 selectedTab 是否等于该导航项的序号,如果是,表示该导航项已经被选中,无需做任何操作;否则继续执行后续步骤。
    • 设置其他按钮为未选中状态: 隐藏其他导航项的文本(通过设置 TextViewVisibilityGONE),将其他导航项的图标恢复为未选中状态(通过设置 ImageView 的图片资源),将其他导航项的背景颜色恢复为默认颜色。
    • 设置当前按钮为选中状态: 显示当前导航项的文本(通过设置 TextViewVisibilityVISIBLE),将当前导航项的图标设置为选中状态(通过设置 ImageView 的图片资源),将当前导航项的背景颜色设置为选中的颜色。
    • 添加动画: 创建 ScaleAnimation 对象,设置动画的起始和结束缩放比例,动画的持续时间和动画的填充方式,然后将动画应用到当前导航项的 LinearLayout 上。每个导航项的动画都从 0.8f 缩放到 1.0f,且动画的锚点不同,分别为 RELATIVE_TO_SELF0.0f1.0f
    • 更新选中项: 最后,将 selectedTab 更新为当前导航项的序号。
/**
 * 主界面
 *
 * @className: MainActivity
 * @author: Voyager
 * @description: 主界面
 * @date: 2023/5/20
 **/
public class MainActivity extends AppCompatActivity {
    /**
     * 被选中的底部按钮的序号,默认值为1
     */
    private int selectedTab =1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final LinearLayout homeLayout=findViewById(R.id.homeLayout);
        final LinearLayout likeLayout=findViewById(R.id.likeLayout);
        final LinearLayout notificationLayout=findViewById(R.id.notificationLayout);
        final LinearLayout profileLayout=findViewById(R.id.profileLayout);

        final ImageView homeImage =findViewById(R.id.home_im);
        final ImageView likeImage =findViewById(R.id.like_im);
        final ImageView notificationImage =findViewById(R.id.notification_im);
        final ImageView profileImage =findViewById(R.id.profile_im);

        final TextView homeText=findViewById(R.id.home_tx);
        final TextView likeText=findViewById(R.id.like_tx);
        final TextView notificationText=findViewById(R.id.notification_tx);
        final TextView profileText=findViewById(R.id.profile_tx);

        homeLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=1){

                //设置其他按钮为未选中状态
                likeText.setVisibility(View.GONE);
                notificationText.setVisibility(View.GONE);
                profileText.setVisibility(View.GONE);

                likeImage.setImageResource(R.drawable.like);
                notificationImage.setImageResource(R.drawable.notification);
                profileImage.setImageResource(R.drawable.profile);


                likeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                notificationLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置home按钮的选中状态
                homeText.setVisibility(View.VISIBLE);
                homeImage.setImageResource(R.drawable.home_selected);
                homeLayout.setBackgroundResource(R.drawable.round_back_home_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,0.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                homeLayout.startAnimation(scaleAnimation);

                selectedTab=1;
            }
        });

        likeLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=2){

                //设置其他按钮为未选中状态
                homeText.setVisibility(View.GONE);
                notificationText.setVisibility(View.GONE);
                profileText.setVisibility(View.GONE);

                homeImage.setImageResource(R.drawable.home);
                notificationImage.setImageResource(R.drawable.notification);
                profileImage.setImageResource(R.drawable.profile);

                homeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                notificationLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置like按钮的选中状态
                likeText.setVisibility(View.VISIBLE);
                likeImage.setImageResource(R.drawable.like_selected);
                likeLayout.setBackgroundResource(R.drawable.round_back_like_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                likeLayout.startAnimation(scaleAnimation);

                selectedTab=2;
            }
        });

        notificationLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=3){

                //设置其他按钮为未选中状态
                homeText.setVisibility(View.GONE);
                likeText.setVisibility(View.GONE);
                profileText.setVisibility(View.GONE);

                homeImage.setImageResource(R.drawable.home);
                likeImage.setImageResource(R.drawable.like);
                profileImage.setImageResource(R.drawable.profile);

                homeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                likeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置notification按钮的选中状态
                notificationText.setVisibility(View.VISIBLE);
                notificationImage.setImageResource(R.drawable.notification_selected);
                notificationLayout.setBackgroundResource(R.drawable.round_back_notification_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                notificationLayout.startAnimation(scaleAnimation);

                selectedTab=3;
            }

        });

        profileLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=4){

                //设置其他按钮为未选中状态
                homeText.setVisibility(View.GONE);
                notificationText.setVisibility(View.GONE);
                likeText.setVisibility(View.GONE);

                homeImage.setImageResource(R.drawable.home);
                notificationImage.setImageResource(R.drawable.notification);
                likeImage.setImageResource(R.drawable.like);

                homeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                notificationLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置profile按钮的选中状态
                profileText.setVisibility(View.VISIBLE);
                profileImage.setImageResource(R.drawable.profile_selected);
                profileLayout.setBackgroundResource(R.drawable.round_back_profile_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                profileLayout.startAnimation(scaleAnimation);

                selectedTab=4;
            }

        });
    }



}

⑦创建各个界面的Fragment

结构如下:

image-20230621164717363

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/home"
    tools:context=".HomeFragment">
<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="主页"
    android:textSize="20sp"
    android:textStyle="bold"
    android:textColor="@color/black"
    />
</FrameLayout>

并在activity_main.xml文件中添加Fragment的容器

image-20230621165109914

修改MainActivity中的代码,添加Fragment的切换:

public class MainActivity extends AppCompatActivity {
    /**
     * 被选中的底部按钮的序号,默认值为1
     */
    private int selectedTab =1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final LinearLayout homeLayout=findViewById(R.id.homeLayout);
        final LinearLayout likeLayout=findViewById(R.id.likeLayout);
        final LinearLayout notificationLayout=findViewById(R.id.notificationLayout);
        final LinearLayout profileLayout=findViewById(R.id.profileLayout);

        final ImageView homeImage =findViewById(R.id.home_im);
        final ImageView likeImage =findViewById(R.id.like_im);
        final ImageView notificationImage =findViewById(R.id.notification_im);
        final ImageView profileImage =findViewById(R.id.profile_im);

        final TextView homeText=findViewById(R.id.home_tx);
        final TextView likeText=findViewById(R.id.like_tx);
        final TextView notificationText=findViewById(R.id.notification_tx);
        final TextView profileText=findViewById(R.id.profile_tx);

        //设置默认界面为HomeFragment
        getSupportFragmentManager().beginTransaction()
                        .setReorderingAllowed(true)
                                .replace(R.id.fragment_container,HomeFragment.class,null)
                                        .commit();


        homeLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=1){

                //设置界面为HomeFragment
                getSupportFragmentManager().beginTransaction()
                        .setReorderingAllowed(true)
                        .replace(R.id.fragment_container,HomeFragment.class,null)
                        .commit();

                //设置其他按钮为未选中状态
                likeText.setVisibility(View.GONE);
                notificationText.setVisibility(View.GONE);
                profileText.setVisibility(View.GONE);

                likeImage.setImageResource(R.drawable.like);
                notificationImage.setImageResource(R.drawable.notification);
                profileImage.setImageResource(R.drawable.profile);


                likeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                notificationLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置home按钮的选中状态
                homeText.setVisibility(View.VISIBLE);
                homeImage.setImageResource(R.drawable.home_selected);
                homeLayout.setBackgroundResource(R.drawable.round_back_home_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,0.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                homeLayout.startAnimation(scaleAnimation);

                selectedTab=1;
            }
        });

        likeLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=2){

                //设置界面为LikeFragment
                getSupportFragmentManager().beginTransaction()
                        .setReorderingAllowed(true)
                        .replace(R.id.fragment_container,LikeFragment.class,null)
                        .commit();

                //设置其他按钮为未选中状态
                homeText.setVisibility(View.GONE);
                notificationText.setVisibility(View.GONE);
                profileText.setVisibility(View.GONE);

                homeImage.setImageResource(R.drawable.home);
                notificationImage.setImageResource(R.drawable.notification);
                profileImage.setImageResource(R.drawable.profile);

                homeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                notificationLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置like按钮的选中状态
                likeText.setVisibility(View.VISIBLE);
                likeImage.setImageResource(R.drawable.like_selected);
                likeLayout.setBackgroundResource(R.drawable.round_back_like_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                likeLayout.startAnimation(scaleAnimation);

                selectedTab=2;
            }
        });

        notificationLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=3){

                //设置界面为NotificationFragment
                getSupportFragmentManager().beginTransaction()
                        .setReorderingAllowed(true)
                        .replace(R.id.fragment_container,NotificationFragment.class,null)
                        .commit();

                //设置其他按钮为未选中状态
                homeText.setVisibility(View.GONE);
                likeText.setVisibility(View.GONE);
                profileText.setVisibility(View.GONE);

                homeImage.setImageResource(R.drawable.home);
                likeImage.setImageResource(R.drawable.like);
                profileImage.setImageResource(R.drawable.profile);

                homeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                likeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置notification按钮的选中状态
                notificationText.setVisibility(View.VISIBLE);
                notificationImage.setImageResource(R.drawable.notification_selected);
                notificationLayout.setBackgroundResource(R.drawable.round_back_notification_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                notificationLayout.startAnimation(scaleAnimation);

                selectedTab=3;
            }

        });

        profileLayout.setOnClickListener(v -> {

            //检查是否被选中
            if (selectedTab!=4){

                //设置界面为ProfileFragment
                getSupportFragmentManager().beginTransaction()
                        .setReorderingAllowed(true)
                        .replace(R.id.fragment_container,ProfileFragment.class,null)
                        .commit();

                //设置其他按钮为未选中状态
                homeText.setVisibility(View.GONE);
                notificationText.setVisibility(View.GONE);
                likeText.setVisibility(View.GONE);

                homeImage.setImageResource(R.drawable.home);
                notificationImage.setImageResource(R.drawable.notification);
                likeImage.setImageResource(R.drawable.like);

                homeLayout.setBackgroundColor(getResources().getColor(R.color.white));
                notificationLayout.setBackgroundColor(getResources().getColor(R.color.white));
                profileLayout.setBackgroundColor(getResources().getColor(R.color.white));

                //设置profile按钮的选中状态
                profileText.setVisibility(View.VISIBLE);
                profileImage.setImageResource(R.drawable.profile_selected);
                profileLayout.setBackgroundResource(R.drawable.round_back_profile_100);

                //添加动画
                ScaleAnimation scaleAnimation=new ScaleAnimation(0.8f,1.0f,1f,1f,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f);
                scaleAnimation.setDuration(200);
                scaleAnimation.setFillAfter(true);
                profileLayout.startAnimation(scaleAnimation);

                selectedTab=4;
            }

        });
    }



}

⑧运行结果:

untitled

三、 总结

本篇文章提供了一个实现自定义底部导航栏的示例,能够帮助想要水过安卓大作业实现一个较为优美的底部导航界面,希望对大家有所帮助😘。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学术会议征稿】第五届人工智能与教育国际学术会议(ICAIE 2024)

第五届人工智能与教育国际学术会议&#xff08;ICAIE 2024&#xff09; 2024 5th International Conference on Artificial Intelligence and Education 第五届人工智能与教育国际学术会议&#xff08;ICAIE 2024&#xff09;由集美大学诚毅学院主办&#xff0c;闽南师范大学…

福昕PDF编辑器v13专业版 授权版

福昕高级PDF编辑器是一款功能强大的PDF文件编辑软件&#xff0c;提供多种实用的编辑功能。 软件截图&#xff1a; 使用说明&#xff1a; 解压后&#xff0c;双击start.bat来运行软件 下载地址&#xff1a;FoxitPDFEditor-Pro-v13 解压密码&#xff1a;helloh 下载时可能会有…

动手学大模型应用开发笔记--用dash开发一个大模型知识库

简介 动手学&#xff0c;把自己学到的东西动手自己做出来并输出&#xff0c;是最好的学习方式。最近一直在关注和使用各种ai工具&#xff0c;也在学一些ai开发的知识&#xff0c;看到datawhale的开源学习教程&#xff0c;动手学大模型开发( [github.com/datawhalech…])这个教…

高频面试题基本总结回顾(含笔试高频算法整理)暂存篇

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

dockerfile部署镜像 ->push仓库 ->虚拟机安装建木 ->自动部署化 (详细步骤)

目录 创建私服仓库 vi /etc/docker/daemon.json vim deploy.sh判断脚本内容 创建 建木 后端部署 命名空间 设置密码用户名 创建git仓库 gitignore文件内容 图形项目操作 git maven docker镜像 点击流程日志 vim /etc/docker/daemon.json 执行部署脚本 ip 开发…

代码性能优化(3)——聊聊多线程

代码的性能优化&#xff0c;有些是从逻辑层面进行的&#xff0c;比如同时对50W个人发放奖励&#xff0c;可以改成用户登录的时候&#xff0c;自动领取有没奖励&#xff0c;或者统计每日的每个业务员的销售额和实时累积的销售额&#xff0c;将实时sum函数改成&#xff0c;每一笔…

24种设计模式介绍与6大设计原则(电子版教程)

前言 您是一个初级的 coder,可以从中领会到怎么设计一段优秀的代码&#xff1b;您是一个高级程序员&#xff0c;可以从中全面了解到设计模式以及 Java 的边角技术的使用&#xff1b;您是一个顶级的系统分析师&#xff0c;可以从中获得共鸣&#xff0c;寻找到项目公共问题的解决…

StarRock3.3 安装部署

服务器前置要求&#xff1a; 1、内存>32GB 2、JDK 8 is not supported, please use JDK 11 or 17 1、安装 wget https://releases.starrocks.io/starrocks/StarRocks-3.3.0.tar.gz tar zxvf StarRocks-3.3.0.tar.gz 2、FE服务启动 2.1 配置FE节点(默认配置&#xff0c;…

dns和 openELB

DNS yum -y install bind允许其他的主机来监听&#xff0c;允许其他的主机来查询&#xff0c;改这两个地方就行了。 把需要解析的文件都添加进来&#xff0c;cp -p的意思是保留原来的权限控制 注意本地dns放在 DNS1 二、负载均衡 OpenELB Layer2 模式 BGP模式 OpenELB …

DBeaver使用SQL脚本编辑器

文章目录 1 新建脚本2 选择数据库3 编写脚本【按行执行】参考 1 新建脚本 2 选择数据库 3 编写脚本【按行执行】 光标放到需要执行的行上&#xff0c;点击【最上面的按钮】 或者选中某片代码&#xff0c;然后执行 也可以编写一个脚本然后执行 参考 dbeaver安装和使用教程 …

Linux文件恢复

很麻烦 一般还是小心最好 特别恢复的时候 可能不能选择某个文件夹去扫描恢复 所以 删除的时候 用rm -i代替rm 一定小心 以及 探索下linux的垃圾箱机制 注意 一定要恢复到不同文件夹 省的出问题 法1 系统自带工具 debugfs 但是好像不能重启&#xff1f; testdisk 1、安装 …

酒店智能门锁接口pro[0922]D801 对接收银-SAAS本地化-未来之窗行业应用跨平台架构

proUSB接口函数[0922中性版]-D801 调用函数库&#xff1a; 提供Windows下的32位动态连接库proRFL.DLL&#xff0c;函数使用详细说明 //-----------------------------------------------------------------------------------// 功能&#xff1a;读DLL版本&#xff0c;不涉…

【大数据】:hdfs相关进程启停管理命令

HADOOP_HOME/sbin/start-dfs.sh&#xff0c;一键启动HDFS集群 执行原理&#xff1a; 在执行此脚本的机器上&#xff0c;启动SecondaryNameNode 读取core-site.xml内容&#xff08;fs.defaultFS项&#xff09;&#xff0c;确认NameNode所在机器&#xff0c;启动NameNode 读取wor…

AI变现:科技与商业化的交织

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经从科幻电影中的概念走进了现实生活的各个领域&#xff0c;深刻影响着经济、社会与科技的发展。AI不仅代表着技术的革新&#xff0c;更是推动商业变现的重要力量。本文将深入剖析AI的发展历程&#xff0c;…

数据结构(5.3_5)——二叉树的线索化

第一种寻找中序前驱方法 中序线索化 本质上就是一次中序遍历&#xff0c;只不过需要在一边遍历一边处理结点线索化 代码&#xff1a; //全局变量pre 指向当前访问结点的前驱 ThreadNode* pre NULL;struct ElemType {int value; };//线索二叉树结点 typedef struct ThreadNode…

姜夔,师法自然的不仕道人

姜夔&#xff08;ku&#xff09;&#xff0c;字尧章&#xff0c;号白石道人&#xff0c;约生于南宋绍兴二十四年&#xff08;公元1154年&#xff09;&#xff0c;卒于南宋嘉定十四年&#xff08;公元1221年&#xff09;&#xff0c;享年67岁。他的艺术成就涵盖了诗词、散文、书…

JAVA (IO流) day7.25

ok了家人们今天继续学习io流&#xff0c;废话不多说&#xff0c;我们一起看看吧 一.File类 1.1 File类的概述 通过 File 类与 IO 流进行搭配使用就可以通过 Java 代码将数 据从内存写入到硬盘文件 或者从硬盘文件读取到内存 中。 File 类就是文件和目录路径名的抽象表示形式…

ElasticSearch(es)倒排索引

目录 一、ElasticSearch 二、倒排索引 1. 正向索引 2. 倒排索引 具体细节 1. 文档分析 2. 索引构建 3. 索引存储 4. 词条编码 5. 索引优化 6. 查询处理 示例 总结 3. 正向和倒排 三、总结 倒排索引的基本概念 为什么倒排索引快 一、ElasticSearch Elasticsear…

让开发者生活更轻松的 JavaScript 字符串方法

前端岗位内推来了 JavaScript 最初被引入作为一种简单的客户端脚本语言&#xff0c;但现在&#xff0c;它已经成为一种真正的 WORA&#xff08;一次编写到处运行&#xff09;语言&#xff0c;使开发者能够构建桌面、移动、电视、CLI 和嵌入式应用程序。JavaScript 的初学者友好…

HiveSQL题——炸裂+开窗

一、每个学科的成绩第一名是谁&#xff1f; 0 问题描述 基于学生成绩表输出每个科目的第一名是谁呢&#xff1f; 1 数据准备 with t1 as(selectzs as name,[{"Chinese":80},{"Math":70}],{"English"…