📅  最后修改于: 2023-12-03 14:58:47.587000             🧑  作者: Mango
在移动应用程序设计中,底部导航栏通常用来给用户提供快速、轻松的导航方式。为了增强用户的交互体验,设计师与开发人员常常会为底部导航栏添加一个颤动效果。当用户点击导航栏中的某个项目时,该项目会通过颤动效果来提示用户已经选中。
本文介绍如何通过编写代码实现“颤动底部导航栏所选项目填充”的效果。
以下是构建颤动底部导航栏所选项目填充效果的步骤:
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal" android:background="@color/colorBackground">
<ImageView android:id="@+id/navigation_home" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_weight="1"
android:src="@drawable/ic_home" android:contentDescription="@string/nav_home"
android:padding="8dp" android:layout_margin="8dp"
android:background="@drawable/nav_item_selector"/>
<ImageView android:id="@+id/navigation_dashboard" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_weight="1"
android:src="@drawable/ic_dashboard" android:contentDescription="@string/nav_dashboard"
android:padding="8dp" android:layout_margin="8dp"
android:background="@drawable/nav_item_selector"/>
<ImageView android:id="@+id/navigation_notifications" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_weight="1"
android:src="@drawable/ic_notifications" android:contentDescription="@string/nav_notifications"
android:padding="8dp" android:layout_margin="8dp"
android:background="@drawable/nav_item_selector"/>
</LinearLayout>
在这里,nav_item_selector
是一个 XML 文件,定义了导航栏项目的选中和未选中状态。下面是示例代码:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_home_selected" android:state_selected="true"/>
<item android:drawable="@drawable/ic_home_unselected"/>
</selector>
public class MainActivity extends AppCompatActivity {
private ImageView mHomeImageView;
private ImageView mDashboardImageView;
private ImageView mNotificationsImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHomeImageView = findViewById(R.id.navigation_home);
mDashboardImageView = findViewById(R.id.navigation_dashboard);
mNotificationsImageView = findViewById(R.id.navigation_notifications);
// 为每个导航栏选项添加选中状态监听器
mHomeImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHomeImageView.setSelected(true);
mDashboardImageView.setSelected(false);
mNotificationsImageView.setSelected(false);
}
});
mDashboardImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDashboardImageView.setSelected(true);
mHomeImageView.setSelected(false);
mNotificationsImageView.setSelected(false);
}
});
mNotificationsImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mNotificationsImageView.setSelected(true);
mHomeImageView.setSelected(false);
mDashboardImageView.setSelected(false);
}
});
}
}
public class MainActivity extends AppCompatActivity {
private ImageView mHomeImageView;
private ImageView mDashboardImageView;
private ImageView mNotificationsImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHomeImageView = findViewById(R.id.navigation_home);
mDashboardImageView = findViewById(R.id.navigation_dashboard);
mNotificationsImageView = findViewById(R.id.navigation_notifications);
// 为每个导航栏选项添加选中状态监听器
mHomeImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHomeImageView.setSelected(true);
mDashboardImageView.setSelected(false);
mNotificationsImageView.setSelected(false);
animateSelected(mHomeImageView);
}
});
mDashboardImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDashboardImageView.setSelected(true);
mHomeImageView.setSelected(false);
mNotificationsImageView.setSelected(false);
animateSelected(mDashboardImageView);
}
});
mNotificationsImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mNotificationsImageView.setSelected(true);
mHomeImageView.setSelected(false);
mDashboardImageView.setSelected(false);
animateSelected(mNotificationsImageView);
}
});
}
// 颤动选中的导航栏项目
private void animateSelected(View view) {
int duration = 100;
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setInterpolator(new FastOutSlowInInterpolator());
animator.setDuration(duration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
float interpolation = -0.5f * (float) Math.cos(progress * Math.PI) + 0.5f;
view.setScaleX(interpolation);
view.setScaleY(interpolation);
}
});
animator.start();
}
}
其中,animateSelected()
方法使用了 ofFloat()
方法来创建动画,指定了动画的起始和结束值。setInterpolator()
方法则设置了动画的插值器来调整动画速度和变化率。addUpdateListener()
方法为动画添加更新监听器。在更新监听器中,我们根据动画时间计算当前的动画进度,然后使用余弦函数来计算缩放系数,最后更新所选的导航栏项目的缩放比例。start()
方法则开始运行动画。
通过实现上述三个步骤,我们可以为底部导航栏的项目添加点击效果,提高用户的交互体验。这个效果在许多使用场景下非常有用,比如移动应用程序主页、菜单选项卡等。