Android ViewModel介绍

2018-09-26  本文已影响0人  Yim_

ViewModel是什么

ViewModel用来存储和管理UI相关的数据。

ViewModel的功能

用来存储和管理UI相关的数据,当Activity或者Fragment被系统销毁时(例如:发生屏幕转动,低内存时被系统回收)可以保存数据不被销毁;
可以实现Activity和Fragment之间,再加到同一个Activity上的不同Fragment之间的数据通信。

ViewModel的生命周期

下面这张图是左侧是Activity的生命周期右侧是与之对应的Activity中ViewModes的生命周期


viewmodel-lifecycle.png

如何使用ViewModel

1.引入相关依赖到项目中

dependencies {
    def lifecycle_version = "1.1.1"

    // ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" // use -ktx for Kotlin
    // alternatively - just LiveData
    implementation "android.arch.lifecycle:livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData).
    //     Support library depends on this lightweight import
    implementation "android.arch.lifecycle:runtime:$lifecycle_version"

    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // use kapt for Kotlin
    // alternately - if using Java8, use the following instead of compiler
    implementation "android.arch.lifecycle:common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "android.arch.lifecycle:reactivestreams:$lifecycle_version"

    // optional - Test helpers for LiveData
    testImplementation "android.arch.core:core-testing:$lifecycle_version"
}

2.创建MViewModel类继承系统的AndroidViewModel(ViewModel的子类AndroidViewModel

package com.architecture.demo.viewModel;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import android.util.Log;

import com.architecture.demo.util.CONSTANT;

import java.util.Map;

public class MViewModel extends AndroidViewModel {
    private MutableLiveData<Map<String, String>> mLanguage;
    private MutableLiveData<String> mLanguageDes;

    public MViewModel(@NonNull Application application) {
        super(application);
    }

    public MutableLiveData<Map<String, String>> getLanguage() {
        if (mLanguage == null) {
            mLanguage = new MutableLiveData<>();
        }
        return mLanguage;
    }

    public MutableLiveData<String> getLanguageDes() {
        if (mLanguageDes == null) {
            mLanguageDes = new MutableLiveData<>();
        }
        return mLanguageDes;
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        Log.i(CONSTANT.TAG_VIEW_MODEL, "PagingViewModel.onCleared");
    }
}

3.在Activity中获取MViewModel类的实例

package com.architecture.demo;

import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.architecture.demo.util.CONSTANT;
import com.architecture.demo.viewModel.Fragment;
import com.architecture.demo.viewModel.Fragment2;
import com.architecture.demo.viewModel.MViewModel;

import java.util.HashMap;
import java.util.Map;

public class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_model);
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.add(R.id.frame1, Fragment.getInstance());
        fragmentTransaction.add(R.id.frame2, Fragment2.getInstance());
        fragmentTransaction.commit();
        initViewModel();
    }

    private void initViewModel() {
        MViewModel mMViewModel = ViewModelProviders.of(this).get(MViewModel.class);
        Log.i(CONSTANT.TAG_VIEW_MODEL, "ViewModelActivity_mMViewModel:" + mMViewModel.toString());
        Map<String, String> map = new HashMap<>();
        map.put("Java", "Java good");
        map.put("Dart", "Dart good");
        map.put("Kotlin", "Kotlin good");
        mMViewModel.getLanguage().setValue(map);
    }
}

4.在Fragment中获取MViewModel类的实例

package com.architecture.demo.viewModel;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.architecture.demo.R;
import com.architecture.demo.util.CONSTANT;

import java.util.Map;
import java.util.Set;

public class Fragment extends android.support.v4.app.Fragment implements View.OnClickListener {
    private MViewModel mMViewModel;
    TextView textView;
    TextView textView1;
    TextView textView2;

    public static Fragment getInstance() {
        return new Fragment();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        textView = view.findViewById(R.id.text);
        textView1 = view.findViewById(R.id.text1);
        textView2 = view.findViewById(R.id.text2);
        textView.setOnClickListener(this);
        textView1.setOnClickListener(this);
        textView2.setOnClickListener(this);
        initViewModel();
        return view;
    }

    private void initViewModel() {
        if (getActivity() == null) return;
        mMViewModel = ViewModelProviders.of(getActivity()).get(MViewModel.class);
        Log.i(CONSTANT.TAG_VIEW_MODEL, "Fragment_mMViewModel:" + mMViewModel.toString());
        mMViewModel.getLanguage().observe(this, new Observer<Map<String, String>>() {
            @Override
            public void onChanged(@Nullable Map<String, String> map) {
                if (map == null) return;
                Set<Map.Entry<String, String>> entries = map.entrySet();
                int i = 0;
                for (Map.Entry<String, String> entry : entries) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    if (i == 0) {
                        textView.setText(key);
                        textView.setTag(value);
                    } else if (i == 1) {
                        textView1.setText(key);
                        textView1.setTag(value);
                    } else if (i == 2) {
                        textView2.setText(key);
                        textView2.setTag(value);
                    }
                    i++;
                }
            }
        });
    }

    @Override
    public void onClick(View v) {
        String tag = "";
        textView.setSelected(false);
        textView1.setSelected(false);
        textView2.setSelected(false);
        if (v == textView) {
            tag = (String) textView.getTag();
            textView.setSelected(true);
        } else if (v == textView1) {
            tag = (String) textView1.getTag();
            textView1.setSelected(true);
        } else if (v == textView2) {
            tag = (String) textView2.getTag();
            textView2.setSelected(true);
        }
        mMViewModel.getLanguageDes().setValue(tag);
    }
}

4.在Fragment2中获取MViewModel类的实例

package com.architecture.demo.viewModel;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.architecture.demo.util.CONSTANT;
import com.architecture.demo.R;

public class Fragment2 extends android.support.v4.app.Fragment {
    TextView textView;

    public static Fragment2 getInstance() {
        return new Fragment2();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, container, false);
        textView = view.findViewById(R.id.text);
        initViewModel();
        return view;
    }

    private void initViewModel() {
        if (getActivity() == null) return;
        MViewModel mMViewModel = ViewModelProviders.of(getActivity()).get(MViewModel.class);
        Log.i(CONSTANT.TAG_VIEW_MODEL, "Fragment2_mMViewModel:" + mMViewModel.toString());
        mMViewModel.getLanguageDes().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String des) {
                textView.setText(des);
            }
        });
    }
}

通过以上步骤既可完成ViewModel的简单使用。
Demo地址:
https://github.com/CongYiMing/ArchitectureDemo

上一篇 下一篇

猜你喜欢

热点阅读