2.4 学习总计 之 自己实现底部导航
说在前面
昨天 | 完成了分页查询展示数据 |
今天 | 学习底部导航的实现过程 |
一、相关知识
1、底部所导航的几个界面是相互独立的,没有前后层次关系。
二、构建导航框架
1、构建三个静态页面结构(Fragment)和相应的ViewModel(保存UI数据)。
2、创建底部导航(实质是一个菜单)。
1)创建一个菜单,添加三个MenuItem
2)在main_activity.xml中拖一个:
3)将菜单加入
4)移动到底部
3、创建一个navigation组件,用来三个页面进行动态的切换等管理。
注意事项:界面的id,和菜单中MenuItem的id相同
界面:
菜单项:
1)完善界面
2)导入界面
3)在main_activity.xml中拖一个:
并关联刚才的navigation
三、完善逻辑结构
1、完成界面切换(装配BottomNavigationView和NAVHostFragment)
MainActive.java
package com.example.bottomnavigationdemo; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; import android.os.Bundle; 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(bottomNavigationView.getMenu()).build(); NavigationUI.setupActionBarWithNavController(this,navController,configuration); NavigationUI.setupWithNavController(bottomNavigationView,navController); } }
2、设置各个界面的功能
1)旋转 FirstFragment.java 实现动作 ,FirstViewModel.java保存数据
package com.example.bottomnavigationdemo; import android.animation.ObjectAnimator; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; public class FirstFragment extends Fragment { private static final String TAG = "hello"; private FirstViewModel mViewModel; private ImageView imageView; public static FirstFragment newInstance() { return new FirstFragment(); } @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.first_fragment, container, false); imageView = view.findViewById(R.id.imageView); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mViewModel = ViewModelProviders.of(requireActivity()).get(FirstViewModel.class); imageView.setRotation(mViewModel.rotationPosition); final ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "rotation", 0, 0); objectAnimator.setDuration(500); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!objectAnimator.isRunning()) { objectAnimator.setFloatValues(imageView.getRotation(), imageView.getRotation() + 100); mViewModel.rotationPosition += 100; objectAnimator.start(); } } }); } }
package com.example.bottomnavigationdemo; import androidx.lifecycle.ViewModel; public class FirstViewModel extends ViewModel { // TODO: Implement the ViewModel float rotationPosition = 0; }
2)缩放 SecondFragment.java 实现动作 ,SecondViewModel.java保存数据
package com.example.bottomnavigationdemo; import android.animation.ObjectAnimator; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; public class SecondFragment extends Fragment { private SecondViewModel mViewModel; private ImageView imageView; public static SecondFragment newInstance() { return new SecondFragment(); } @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.second_fragment, container, false); imageView = view.findViewById(R.id.imageView); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mViewModel = ViewModelProviders.of(requireActivity()).get(SecondViewModel.class); imageView.setScaleX(mViewModel.scaleFactor); imageView.setScaleY(mViewModel.scaleFactor); // TODO: Use the ViewModel final ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 0); final ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(imageView, "scaleY", 0, 0); objectAnimatorX.setDuration(500); objectAnimatorY.setDuration(500); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!objectAnimatorX.isRunning()) { objectAnimatorX.setFloatValues(imageView.getScaleX() + 0.1f); objectAnimatorY.setFloatValues(imageView.getScaleY() + 0.1f); mViewModel.scaleFactor += 0.1; objectAnimatorX.start(); objectAnimatorY.start(); } } }); } }
package com.example.bottomnavigationdemo; import androidx.lifecycle.ViewModel; public class SecondViewModel extends ViewModel { // TODO: Implement the ViewModel float scaleFactor = 1; }
3)移动 ThirdFragment.java 实现动作 ,ThirdViewModel.java保存数据
package com.example.bottomnavigationdemo; import android.animation.ObjectAnimator; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; import java.util.Random; public class ThirdFragment extends Fragment { private ThirdViewModel mViewModel; private ImageView imageView; public static ThirdFragment newInstance() { return new ThirdFragment(); } @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.third_fragment, container, false); imageView = view.findViewById(R.id.imageView); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mViewModel = ViewModelProviders.of(requireActivity()).get(ThirdViewModel.class); imageView.setX(imageView.getX() + mViewModel.dX); // TODO: Use the ViewModel final ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "x", 0, 0); objectAnimator.setDuration(500); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!objectAnimator.isRunning()) { float dx = new Random().nextBoolean() ? 100 : -100; objectAnimator.setFloatValues(imageView.getX(), imageView.getX() + dx); mViewModel.dX += dx; objectAnimator.start(); } } }); } }
package com.example.bottomnavigationdemo; import androidx.lifecycle.ViewModel; public class ThirdViewModel extends ViewModel { // TODO: Implement the ViewModel float dX; }
四、运行测试