Navigation--实现Fragment之间数据传递和数据共享

导航图表中的Arugments静态传递

在构建的多可视化导航图中,选中需要接受数据的Fragment,比如选中这里的detailFragment。
Navigation--实现Fragment之间数据传递和数据共享_第1张图片
然后在Attributes栏的Arguments列表项中点击“+”按钮增加键值对,填写需要传递的数据的名称、类型、值等信息。
Navigation--实现Fragment之间数据传递和数据共享_第2张图片

然后在DetailFragment.java文件中编写代码接受数据,具体如下:

通过**getArguments().getString(“name”)**获取数据,getArugments具体调用什么方法根据数据类型决定。

public class DetailFragment extends Fragment {

    public DetailFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_detail, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        TextView tv = view.findViewById(R.id.tv1); 
        String text = getArguments().getString("name"); // 通过getArguments().getString("name")获取数据
        tv.setText(text);
    }
}

Bundle

使用Argument增加键值对的方法传递数据只能实现静态传递,如果数据是动态变化的,那这个方法就难以实现了。通过Bundle方法实现数据传递也很简单,只需要创建Bundle对象,然后增加键值对,在实现页面切换的时候将Bundle对象传递过去即可,接受数据的页面获取数据的方法不变。

HomeFragment.java

public class HomeFragment extends Fragment {


    public HomeFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button button = view.findViewById(R.id.btn1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = new Bundle();
                bundle.putString("name","小红");
                NavController controller = Navigation.findNavController(v);
                controller.navigate(R.id.action_homeFragment_to_detailFragment,bundle);
            }
        });
    }
}

通过ViewModel+LiveData+Databinding实现Fragment之间的数据共享与传递

创建两个Fragment,写好布局,在布局中实现数据回绑,构建导航图,最终形成的效果如下图所示,具体如何实现就不再详细介绍,因为这里主要讲的是如何实现数据共享。可以看到在页面的跳转过程中,数字没有发生改变。
Navigation--实现Fragment之间数据传递和数据共享_第3张图片
自定义ViewModel类:

public class MyViewModel extends ViewModel {

    private MutableLiveData<Integer> liveData;

    public MutableLiveData<Integer> getCurrent() {
        if(liveData == null) {
            liveData = new MutableLiveData<Integer>();
            liveData.setValue(0); // 必须设置,要不然获取的时候可能会出现空指针异常。
        }
        return liveData;
    }

    public void add(int num) {
        liveData.setValue(liveData.getValue() + num);
    }

}

在HomeFragment类的onCreateView方法中,进行数据绑定操作,这里与之前的数据绑定不同的是,之前是采用setContentView来设置布局文件,而这里是采用inflate来设置布局文件的。

对于一个Activity中的两个或多个Fragment,因为这些Fragment隶属的Activity是同一个,在这些Fragment中使用getActivity()方法获取到的是同一个Activity,所以通过ViewModelProvider获取到的ViewModel其实是同一个对象,这也是单例模式的含义,所以就能实现Fragment之间的数据共享。

HomeFragment.java

public class HomeFragment extends Fragment implements View.OnClickListener {

    private MyViewModel viewModel;

    public HomeFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        // 数据绑定
        FragmentHomeBinding binding = DataBindingUtil.inflate(inflater,R.layout.fragment_home,container,false);
        viewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class);
        binding.setData(viewModel);
        binding.setLifecycleOwner(getActivity());
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button button = view.findViewById(R.id.btn1);
        Button addBtn = view.findViewById(R.id.addBtn);
        Button subBtn = view.findViewById(R.id.subBtn);

        button.setOnClickListener(this);
        addBtn.setOnClickListener(this);
        subBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn1:
                NavController controller = Navigation.findNavController(v);
                controller.navigate(R.id.action_homeFragment_to_detailFragment2);
                break;
            case R.id.addBtn:
                viewModel.add(1);
                break;
            case R.id.subBtn:
                viewModel.add(-1);
                break;
        }
    }
}

在DetailFragment类中也是类似的。

DetailFragment.java

public class DetailFragment extends Fragment implements View.OnClickListener{

    private MyViewModel viewModel;

    public DetailFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        FragmentDetailBinding binding = DataBindingUtil.inflate(inflater,R.layout.fragment_detail,container,false);
        viewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class);
        binding.setData(viewModel);
        binding.setLifecycleOwner(getActivity());
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button button = view.findViewById(R.id.btn1);
        Button addBtn = view.findViewById(R.id.addBtn);
        Button subBtn = view.findViewById(R.id.subBtn);

        button.setOnClickListener(this);
        addBtn.setOnClickListener(this);
        subBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        MyViewModel viewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class);
        switch (v.getId()) {
            case R.id.btn1:
                NavController controller = Navigation.findNavController(v);
                controller.navigate(R.id.action_detailFragment_to_homeFragment);
                break;
            case R.id.addBtn:
                viewModel.add(1);
                break;
            case R.id.subBtn:
                viewModel.add(-1);
                break;
        }
    }
}

项目地址:https://gitee.com/yxl-17/jet-pack_-navigation

你可能感兴趣的:(JetPack学习,android,android,jetpack)