kotlin

Android-JetPack(一) ViewModel

2021-05-10  本文已影响0人  陆笪_刑道荣

效果:点击按钮,数字加一
控件:一个TestView,一个Button。

activity_main.xml

<TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_weight="1"
        android:textColor="#000000"
        android:gravity="center"
        android:textSize="50dp"/>
    <Button
        android:id="@+id/button"
        android:layout_width="1px"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="+1"
        android:textSize="50dp"
        android:textColor="#000000"/>

MyViewModel (这里只定义一个简单的变量number)

public class MyViewModel extends ViewModel {
    public int number = 0;
}

MainActivity

public class MainActivity extends FragmentActivity{
    private MyViewModel myViewModel;
    private TextView textView;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    
    private void initView(){
        myViewModel = new ViewModelProvider(this,new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class); //绑定ViewModel
        textView = findViewById(R.id.textview);
        textView.setText(String.valueOf(myViewModel.number));// Activity重新创建时保存number值

        button = findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myViewModel.number++;
                textView.setText(String.valueOf(myViewModel.number));
            }
        });
    }
}

1. ViewModel的生命周期


上图是官网给的生命周期图,我们可以知道ViewModel存在于Activity各种生命周期。这样我们就不用担心Activity被destory、重新create时、或者旋转时,数据被销毁。比如上面的demo,旋转屏幕时,ViewModel不会重新创建,我们可以直接获取number的值。

2.优化使用(在Fragment之间共享数据)

Activity中两个或多个Fragment之间需要通信是很常见的。这些Fragment可以使用同一个Activity作用范围下的ViewModel来处理通信。

public class TestViewModel extends ViewModel {
    private final MutableLiveData<String> data = new MutableLiveData<>();
    public void setData(String s){
        data.setValue(s);
    }
    public MutableLiveData<String> getData(){
        return data;
    }
}
public class AFragment extends Fragment {
    private TestViewModel model;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_a, null);
        model = new ViewModelProvider(getActivity(),new ViewModelProvider.NewInstanceFactory()).get(TestViewModel.class);
        model.setData("a");
        return v;
    }
}
public class BFragment extends Fragment {
    private TestViewModel model;
    private TextView textView;
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_b, null);
        textView = v.findViewById(R.id.txt_b);
        model = new ViewModelProvider(getActivity(),new ViewModelProvider.NewInstanceFactory()).get(TestViewModel.class);
        model.getData().observe(getActivity(), new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });
        return v;
    }
}

注意这两个Fragment在使用ViewModelProvider获取ViewModel时是用的getActivity()。因此,这两个Fragment都会收到相同的TestViewModel 实例,这个实例作用域是Activity。

这种方法提供了以下好处:

这个Activity不需要做任何事情,也不需要了解有关此通信的任何信息;
Fragment之间不需要了解彼此,除了TestViewModel 的联系。如果一个fragment消失了,其他fragment还可以继续正常工作;每个Fragment都有其自己的生命周期,并且不受其他生命周期的影响。如果一个Fragment替换另一个Fragment,UI将继续工作而不会出现任何问题。

上一篇下一篇

猜你喜欢

热点阅读