使用ViewModel实现多个Activity间数据共享(Kotlin版)

参考资料 https://www.jianshu.com/p/f211ca175a25

工程目录如下:

首先定义一个注解,确定ViewModel的store作用域,内容如下

/**
 * 用于标记viewmodel的作用域
 */
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class VMScope(val scopeName:String) {
}

 自定义一个  ViewModelStoreOwner,来处理 ViewModel复用问题

private val vMStores = HashMap<String, VMStore>()

fun LifecycleOwner.injectViewModel() {
    //根据作用域创建商店
    this::class.java.declaredFields.forEach { field ->
        field.getAnnotation(VMScope::class.java)?.also { scope ->
            val element = scope.scopeName
            var store: VMStore
            if (vMStores.keys.contains(element)) {
                store = vMStores[element]!!
            } else {
                store = VMStore()
                vMStores[element] = store
            }
            store.register(this)
            val clazz = field.type as Class<ViewModel>
            val vm = ViewModelProvider(store, ViewModelProvider.NewInstanceFactory()).get(clazz)
            field.set(this, vm)
        }
    }
}

class VMStore : ViewModelStoreOwner {

    private val bindTargets = ArrayList<LifecycleOwner>()
    private var vmStore: ViewModelStore? = null

    fun register(host: LifecycleOwner) {
        if (!bindTargets.contains(host)) {
            bindTargets.add(host)
            host.lifecycle.addObserver(object : LifecycleEventObserver {
                override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                    if (event == Lifecycle.Event.ON_DESTROY) {
                        host.lifecycle.removeObserver(this)
                        bindTargets.remove(host)
                        if (bindTargets.isEmpty()) {//如果当前商店没有关联对象,则释放资源
                            vMStores.entries.find { it.value == this@VMStore }?.also {
                                vmStore?.clear()
                                vMStores.remove(it.key)
                            }
                        }
                    }
                }
            })
        }
    }

    override fun getViewModelStore(): ViewModelStore {
        if (vmStore == null)
            vmStore = ViewModelStore()
        return vmStore!!
    }
}

我们定义一个ViewModel来实现计数器

class CountViewModel : ViewModel() {
    val count: MutableLiveData<Int> by lazy { MutableLiveData() }
    fun setCount(value: Int?) {
        count.value = value
    }
}

 最后就是在activity里面使用。

class MainActivity : AppCompatActivity() {

    @VMScope("count")
    lateinit var viewModel:CountViewModel


    @RequiresApi(Build.VERSION_CODES.P)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        injectViewModel()
        setContentView(R.layout.activity_main)
    }

}

CSDN下载地址 (免费下载) 使用ViewModel解决多个Activity数据共享问题(Kotlin版)-Android文档类资源-CSDN下载

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
多个Fragment之间共享ViewModel,可以使用以下步骤: 1. 创建一个ViewModel类,该类包含需要共享的数据和方法。 ```java public class SharedViewModel extends ViewModel { private MutableLiveData<String> selected = new MutableLiveData<String>(); public void select(String item) { selected.setValue(item); } public LiveData<String> getSelected() { return selected; } } ``` 2. 在需要共享ViewModel的Fragment中,通过ViewModelProvider获取ViewModel实例。 ```java public class Fragment1 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } // ... } ``` 3. 在其他需要访问ViewModel的Fragment中,也通过ViewModelProvider获取同一个ViewModel实例。 ```java public class Fragment2 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } // ... } ``` 4. 在Fragment中使用ViewModel中的数据和方法。这样就可以在多个Fragment之间共享ViewModel了。 ```java public class Fragment1 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1, container, false); Button button = view.findViewById(R.id.button); final EditText editText = view.findViewById(R.id.editText); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { model.select(editText.getText().toString()); } }); return view; } } public class Fragment2 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment2, container, false); final TextView textView = view.findViewById(R.id.textView); model.getSelected().observe(getViewLifecycleOwner(), new Observer<String>() { @Override public void onChanged(String item) { textView.setText(item); } }); return view; } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值