BottomNavigation

  • 导航布局navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/navigation"
app:startDestination="@id/firstFragment"> <fragment
android:id="@+id/firstFragment"
android:name="com.example.mybottomnavigation.fragment.FirstFragment"
android:label="旋转"
tools:layout="@layout/first_fragment" />
<fragment
android:id="@+id/thirdFragment"
android:name="com.example.mybottomnavigation.fragment.ThirdFragment"
android:label="移动"
tools:layout="@layout/third_fragment" />
<fragment
android:id="@+id/secondFragment"
android:name="com.example.mybottomnavigation.fragment.SecondFragment"
android:label="缩放"
tools:layout="@layout/second_fragment" />
</navigation>
  • 菜单布局menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/firstFragment"
android:icon="@drawable/ic_baseline_looks_one_24"
android:title="旋转" />
<item
android:id="@+id/secondFragment"
android:icon="@drawable/ic_baseline_looks_two_24"
android:title="缩放" />
<item
android:id="@+id/thirdFragment"
android:icon="@drawable/ic_baseline_looks_3_24"
android:title="移动" />
</menu>
  • activity_main.xml
<?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"
tools:context=".activity.MainActivity"> <fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation" /> <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • first_fragment.xml(另外两个类似)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".fragment.FirstFragment"> <ImageView
android:id="@+id/imageView1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_pedal_bike_24" />
</FrameLayout>
  • MainActivity.java
package com.example.mybottomnavigation.activity;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI; import com.example.mybottomnavigation.R;
import com.google.android.material.bottomnavigation.BottomNavigationView; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
NavController navController = Navigation.findNavController(this, R.id.fragment); // AppBarConfiguration configuration = new AppBarConfiguration.Builder(navController.getGraph()).build(); // 向上按钮会显示
// AppBarConfiguration configuration = new AppBarConfiguration.Builder(R.id.firstFragment, R.id.secondFragment, R.id.thirdFragment).build();
AppBarConfiguration configuration = new AppBarConfiguration.Builder(bottomNavigationView.getMenu()).build();
NavigationUI.setupActionBarWithNavController(this, navController, configuration);
NavigationUI.setupWithNavController(bottomNavigationView, navController); }
}
  • FirstFragment.java
package com.example.mybottomnavigation.fragment;

import androidx.lifecycle.ViewModelProvider;

import android.animation.ObjectAnimator;
import android.os.Bundle; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import com.example.mybottomnavigation.viewmodel.FirstViewModel;
import com.example.mybottomnavigation.R; public class FirstFragment extends Fragment { private FirstViewModel mViewModel;
private View root;
private ImageView imageView; public static FirstFragment newInstance() {
return new FirstFragment();
} @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.first_fragment, container, false);
imageView = root.findViewById(R.id.imageView1);
return root;
} @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); // mViewModel = new ViewModelProvider(this).get(FirstViewModel.class); // 范围是fragment,切换到别的fragment再回来数据就没了
mViewModel = new ViewModelProvider(requireActivity()).get(FirstViewModel.class); imageView.setRotation(mViewModel.rotationPosition); // 属性动画
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "rotation", 0, 0);
objectAnimator.setDuration(500);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!objectAnimator.isRunning()) {
objectAnimator.setFloatValues(imageView.getRotation(), imageView.getRotation() + 100);
mViewModel.rotationPosition += 100;
objectAnimator.start();
}
}
});
} }
  • SecondFragment.java
package com.example.mybottomnavigation.fragment;

import androidx.lifecycle.ViewModelProvider;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.os.Bundle; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import com.example.mybottomnavigation.R;
import com.example.mybottomnavigation.viewmodel.SecondViewModel; public class SecondFragment extends Fragment { private ImageView imageView;
private View root;
private SecondViewModel mViewModel; public static SecondFragment newInstance() {
return new SecondFragment();
} @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.second_fragment, container, false);
imageView = root.findViewById(R.id.imageView2);
return root;
} @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = new ViewModelProvider(requireActivity()).get(SecondViewModel.class);
// 初始化
imageView.setScaleX(mViewModel.scaleFactor);
imageView.setScaleY(mViewModel.scaleFactor); ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(imageView, "scaleX", 0);
ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(imageView, "scaleY", 0);
// 一起操作
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(objectAnimatorX, objectAnimatorY);
animatorSet.setDuration(500);
// objectAnimatorX.setDuration(500);
// objectAnimatorY.setDuration(500); imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!animatorSet.isRunning()){
objectAnimatorX.setFloatValues(imageView.getScaleX() + 0.1f);
objectAnimatorY.setFloatValues(imageView.getScaleY() + 0.1f); mViewModel.scaleFactor += 0.1;
animatorSet.start();
}
}
});
} }
  • ThirdFragment.java
package com.example.mybottomnavigation.fragment;

import androidx.lifecycle.ViewModelProvider;

import android.animation.ObjectAnimator;
import android.os.Bundle; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import com.example.mybottomnavigation.R;
import com.example.mybottomnavigation.viewmodel.ThirdViewModel; import java.util.Random; public class ThirdFragment extends Fragment { private ImageView imageView;
private View root;
private ThirdViewModel mViewModel; public static ThirdFragment newInstance() {
return new ThirdFragment();
} @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.third_fragment, container, false);
imageView = root.findViewById(R.id.imageView3);
return root;
} @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = new ViewModelProvider(requireActivity()).get(ThirdViewModel.class);
// 初始化
imageView.setX(mViewModel.dx); ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "x", 0, 0);
objectAnimator.setDuration(500); imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!objectAnimator.isRunning()) {
float dx = new Random().nextBoolean() ? 100 : -100;
objectAnimator.setFloatValues(imageView.getX(), imageView.getX() + dx);
objectAnimator.start();
mViewModel.dx += dx;
}
}
});
} }
  • FirstViewModel.java
package com.example.mybottomnavigation.viewmodel;

import androidx.lifecycle.ViewModel;

public class FirstViewModel extends ViewModel {
public float rotationPosition = 0;
}
  • SecondViewModel.java
package com.example.mybottomnavigation.viewmodel;

import androidx.lifecycle.ViewModel;

public class SecondViewModel extends ViewModel {
public float scaleFactor = 1;
}
  • ThirdViewModel.java
package com.example.mybottomnavigation.viewmodel;

import androidx.lifecycle.ViewModel;

public class ThirdViewModel extends ViewModel {
public float dx;
}

BottomNavigation的更多相关文章

  1. Jetpack Compose之隐藏Scaffold的BottomNavigation

    做主页导航时会用到底部导航栏,Jetpack Compose提供了基础槽位的布局Scaffold,使用Scaffold可以构建底部导航栏,例如: @Composable fun Greeting(vm ...

  2. 自定义CoordinatorLayout Behavior 隐藏Footer View

    在用新的控件中,我们可以用Toolbar与CoordinatorLayout实现 向上滚动隐藏的效果,可是官方并没有找到向上隐藏底部导航的功能,有一些第三方的框架实现了. 在Android M,Coo ...

  3. bottomNavigationBar 底部导航tab MD

    1.先上图: 此底部Tab完全可以满足日常的开发 2.使用: 很简单,使用Gradle构建:compile ‘com.ashokvarma.android:bottom-navigation-bar: ...

  4. Android底部导航栏创建——ViewPager + RadioGroup

    原创文章,引用请注明出处:http://www.cnblogs.com/baipengzhan/p/6270201.html Android底部导航栏有多种实现方式,本文详解其中的ViewPager ...

  5. Android开源项目库汇总

    最近做了一个Android开源项目库汇总,里面集合了OpenDigg 上的优质的Android开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个star. 抽 ...

  6. Android开发之漫漫长途 XIII——Fragment最佳实践

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  7. GitHub上受欢迎的Android UI Library

    GitHub上受欢迎的Android UI Library 内容 抽屉菜单 ListView WebView SwitchButton 按钮 点赞按钮 进度条 TabLayout 图标 下拉刷新 Vi ...

  8. Android BottomNavigationBar底部导航控制器的使用(包含默认postion的设置)

    转载请标明出处:http://blog.csdn.net/u010046908/article/details/50962081本文出自:[李东的博客] 最近Google在自己推出的Material ...

  9. BottomNavigationBar使用详解

    gitHub地址:https://github.com/Ashok-Varma/BottomNavigation 一.基本使用 1.在AndroidStudio下添加依赖: compile 'com. ...

  10. Android UI相关开源项目库汇总

    最近做了一个Android UI相关开源项目库汇总,里面集合了OpenDigg 上的优质的Android开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个st ...

随机推荐

  1. 运行openai的gym代码报错提示import pyglet,安装后依然报错:ImportError: sys.meta_path is None, Python is likely shutting down

    运行代码: import gym def cartpole(): environment = gym.make('CartPole-v1') environment.reset() for _ in ...

  2. Java中0.2减0.1 结果为什么不是0.1?

    double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值).绝大部 分应用程序都采用double 类型.在很多情况下,float 类型的精度很难满足需求.实际上,只 有很少 ...

  3. [考试记录] 2024.7.15 csp-s模拟赛4

    2024.7.15 csp-s模拟赛4 T1 传送带 题面翻译 有一个长度为 \(n\) 的一维网格.网格的第 \(i\) 个单元格包含字符 \(s_i\) ,是"<"或&q ...

  4. AtCoder Beginner Contest 318

    AtCoder Beginner Contest 318 A - Full Moon (atcoder.jp) 以\(M\)为首项,\(P\)为公差,看\(1 \sim N\)里包含了多少项的个数 # ...

  5. 学习SSD—day1_20240814

    1.SSD的基本概念以及结构 SSD是一种以半导体(半导体闪存)作为存储介质吗,使用纯电子电路实现的存储设备. SSD硬件包括几大组成部分:主控.闪存.缓存芯片DRAM(可选,有些SSD上可能只有SR ...

  6. Linux库概念,动态库和静态库的制作,如何移植第三方库

    一.什么是库? 在windows平台和linux平台下都大量存在着库.一般是软件作者为了发布方便.替换方便或二次开发目的,而发布的一组可以单独与应用程序进行compile time或runtime链接 ...

  7. Elsa V3学习之Flowchart详解(上)

    前面我们通过界面学习了Elsa的一些基本使用,若是有实操的小伙伴们,应该可以发现,我们工作流定义中的root,既我们的工作流画布其实也是一个activity,就是Flowchart.那么本文将来解读以 ...

  8. Gmail 别名

    Gmail 有一个很少人知道但是非常实用的功能,那就是别名.Gmail 允许用户通过在基本邮箱地址中添加特定符号和文本来创建多个别名.这些别名都指向同一个 Gmail 账户,方便用户进行邮件管理.过滤 ...

  9. maven 插件之 maven-shade-plugin,解决同包同名 class 共存问题的神器

    开心一刻 有一天螃蟹出门,不小心撞倒了泥鳅泥鳅很生气地说:你是不是瞎啊!螃蟹说:不是啊,我是螃蟹 概述 maven-shade-plugin 官网已经介绍的很详细了,我给大家简单翻译一下 This p ...

  10. Error:java: JDK isn't specified for module

    报错: Error:java: JDK isn't specified for module 背景: 删除原项目文件夹内所有文件,copy的新的配置文件与src文件夹等,期间打开该项目的IDEA一直处 ...