Navigation组件
简单案例
创建
创建一个fragment
创建好之后,会帮我们生成四个文件
然后,创建Navigation资源
结果生成一个目录和文件
编写界面
配置导航
右边可以修改名称
效果
进入到activity_main.xml文件中
选择一个navigation
配置导航逻辑
有两种方式
-
HomeFragment
@Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Button button = getView().findViewById(R.id.button); button.setOnClickListener(v -> { NavController controller = Navigation.findNavController(v); controller.navigate(R.id.action_homeFragment_to_detailFragment); }); }
-
DetailFragment
@Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getView().findViewById(R.id.button2).setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_detailFragment_to_homeFragment)); }
添加动画
添加一个界面返回图标
这个东西是要定义到我们的main_avtivity中的
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavController controller = Navigation.findNavController(this, R.id.fragment);
NavigationUI.setupActionBarWithNavController(this,controller);
}
@Override
public boolean onSupportNavigateUp() {
NavController controller = Navigation.findNavController(this, R.id.fragment);
return controller.navigateUp();
//return super.onSupportNavigateUp();
}
}
效果演示
传递参数
静态传递
获取数据并显示
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String name = getArguments().getString("name");
TextView textView = getView().findViewById(R.id.textView);
textView.setText(name);
}
很显然,这种方式只能传递静态的数据
动态传递
样例
传递方:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getView().findViewById(R.id.button).setOnClickListener(v->{
EditText editText = getView().findViewById(R.id.editText);
String str = editText.getText().toString();
if(TextUtils.isEmpty(str)){
Toast.makeText(getActivity(),"请输入名字!",Toast.LENGTH_SHORT).show();;
return;
}
//将数据放在Bundle中
Bundle bundle = new Bundle();
bundle.putString("my_name", str);
NavController controller = Navigation.findNavController(v);
controller.navigate(R.id.action_homeFragment2_to_detailFragment2,bundle);
});
}
接收方:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String myName = getArguments().getString("my_name");
TextView textView = getView().findViewById(R.id.textView);
textView.setText(myName);
}
演示:
基于ViewModel(※)
-
修改配置build.gradle,为了简单,就不导入savedstate的依赖了
dependencies { implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0' } buildFeatures { dataBinding = true }
-
创建两个Fragment,并绘制样式
-
创建导航,进行导航配置,然后在activity_main.xml中配置NavHostFragment
-
创建ViewModel
public class MyViewModel extends ViewModel { private MutableLiveData<Integer> number; public MutableLiveData<Integer> getNumber() { if(number == null){ number = new MutableLiveData<>(); number.setValue(0); } return number; } public void add(int x) { number.setValue(number.getValue()+x); if(number.getValue()<0){ number.setValue(0); } } }
-
修改fragment_home.xml,转为data binding layout,再修改代码(显示修改的部分)
<data> <variable name="data" type="com.example.navigation3.MyViewModel" /> </data> <TextView android:text="@{String.valueOf(data.number)}"/>
-
修改fragment_detail.xml,转为data binding layout,再修改代码(显示修改的部分)
<data> <variable name="data" type="com.example.navigation3.MyViewModel" /> </data> <TextView android:text="@{String.valueOf(data.number)}"/> <Button android:onClick="@{()->data.add(1)}"/> <Button android:onClick="@{()->data.add(-1)}"/>
注意:我们的界面xml文件中只用于显示数据和进行数据相关的操作,导航跳转等与数据无关的操作放在我们的具体代码逻辑中,比如下方
-
修改HomeFragment
LayoutInflater主要是用于加载布局的
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyViewModel myViewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class); FragmentHomeBinding binding = DataBindingUtil.inflate(inflater,R.layout.fragment_home,container,false); binding.setData(myViewModel); binding.setLifecycleOwner(getActivity()); //监听点击事件,进行导航 binding.button.setOnClickListener(v->{ NavController controller = Navigation.findNavController(v); controller.navigate(R.id.action_homeFragment_to_detailFragment); }); binding.seekBar.setProgress(myViewModel.getNumber().getValue()); //监听seekBar的改变 binding.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myViewModel.getNumber().setValue(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); return binding.getRoot(); }
-
修改DetailFragment
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyViewModel viewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class); FragmentDetailBinding binding = DataBindingUtil.inflate(inflater,R.layout.fragment_detail,container,false); binding.setData(viewModel); binding.setLifecycleOwner(getActivity()); //监听点击事件,进行导航 binding.button4.setOnClickListener(v->{ NavController controller = Navigation.findNavController(v); controller.navigate(R.id.action_detailFragment_to_homeFragment); }); return binding.getRoot(); }
-
演示
自定义动画
创建Animation资源
编写代码
滑动效果
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="-100%"
android:toXDelta="0%">
</translate>
</set>
复制一下文件slide_from_left.xml,创建slide_to_right.xml文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0%"
android:toXDelta="100%">
</translate>
</set>
添加动画
演示
缩放和旋转
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="1000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
<rotate
android:duration="1000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
</set>
效果