标签: android-viewmodel

ViewModel、LiveData 和 Transformations.map

Kotlin 和 Android 开发及相关领域的新手,我不确定如何应用某些业务逻辑并转换值。我有一个类的列表,我想修改类中的一个值,同时不影响类中的其他所有内容。一旦我进入视图模型,我不确定如何访问我的类中的时间值来修改它。如果有人能指出我正确的方向,我将不胜感激。

实体与道

import org.threeten.bp.Instant

data class ActionDetails(val time: Instant,
                     val firstName: String,
                     ... )

@Query("SELECT time, first_name as firstName...")
fun liveStatus(): LiveData<List<ActionDetails>>
Run Code Online (Sandbox Code Playgroud)

视图模型

class MainViewModel(private val repository: DataRepository) : ViewModel() {

    private val _actions: LiveData<List<ActionDetails>>
    val actions: LiveData<List<ActionDetails>>
        get() = _actions

    init {
        _actions = Transformations.map(repository.liveStatus()) {
            //Convert Instant value per business rules and convert to formatted string
            time -> ...

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

android kotlin android-livedata android-viewmodel

5
推荐指数
1
解决办法
3232
查看次数

Android ViewModel - 如何强制重新创建某些配置更改

ViewModel的目的是保留有关生命周期事件和配置更改的数据。

但是对于某些配置更改,例如locale change,我想获得一个新的 viewModel 实例。我怎样才能强迫娱乐?

class HomeActivity : AppCompatActivity() {

    var viewModelFactory: ViewModelProvider.Factory

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // How to get new instance on locale change?
        var viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(HomeViewModel::class.java)
    }
}
Run Code Online (Sandbox Code Playgroud)

android android-viewmodel android-architecture-components android-jetpack

5
推荐指数
1
解决办法
659
查看次数

如何使用 ViewModel 在活动之间发送数据

我使用相同的过程在片段之间发送数据并且它可以工作,但现在我没有在接收器活动中获取数据。当我点击提交按钮时,甚至日志消息标签也没有显示。我检查了发件人活动日志消息,它显示数据但无法在接收方活动中获取这些数据。

请帮我获取数据。谢谢!!

在发送活动的日志消息中获取数据

接收器活动,甚至不显示日志消息的标签

视图模型类:

public class ViewModelClass extends ViewModel {

private final MutableLiveData message = new MutableLiveData();

public void setMessage(HomeModelClass data){
    message.setValue(data);
}

public MutableLiveData getMessage() {
    return message;
   }
}
Run Code Online (Sandbox Code Playgroud)

发件人活动:

    public class EditHomeData extends AppCompatActivity {

    private ViewModelClass viewModelClass;

    HomeModelClass homeModelClassData = new HomeModelClass();

    @Override
    protected void onCreate(Bundle savedInsatancestate) {
    super.onCreate(savedInsatancestate);
    setContentView(R.layout.first_page);

    viewModelClass = ViewModelProviders.of(this).get(ViewModelClass.class);

    setValues();

  });

    public void setValues() {

    if (yes.isChecked()) {
        rent_value = String.valueOf(1);
    } else if (no.isChecked()) {
        rent_value = String.valueOf(0);
    }

    homeModelClassData.setWard_id(ward_id + ""); …
Run Code Online (Sandbox Code Playgroud)

android android-mvvm android-viewmodel

5
推荐指数
1
解决办法
6588
查看次数

观察片段和活动中的 LiveData 实例

我有一个简单的场景,我在片段中做一些事情,当我收到 LiveData 时,我想在 Activity 中做一些事情。

视图模型:

class MyViewModel(application: Application) : AndroidViewModel(application) {
    
   ...
    
    fun getUser(id: String): LiveData<User> {
        return repository.getUser(id)
    }
}
Run Code Online (Sandbox Code Playgroud)

分段:

class MyFragment : Fragment() {

    private lateinit var myViewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activity?.run {
            myViewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        button.setOnClickListener {
            showProgressBar()
            myViewModel.getUser(editText.text.toString()).observe(this, Observer { it ->
                //TODO …
Run Code Online (Sandbox Code Playgroud)

android mvvm android-fragments android-livedata android-viewmodel

5
推荐指数
2
解决办法
1万
查看次数

在BottomSheetDialogFragment 与普通Fragment 之间共享Viewmodel 不起作用(观察函数未触发)

我想在我的基本片段和打开的 BottomSheetDialogFragment 之间共享相同的 Viewmodel

所以这就是我如何观察这两个片段之间的相同视图模型。

BottomSheetDialogFragment

public class TasteFilterBottomDialogFragment extends BottomSheetDialogFragment {

    private FilterTasteListViewModel filterTasteListViewModel;

    @Inject
    ViewModelProvider.Factory viewModelFactory;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        filterTasteListViewModel = ViewModelProviders.of(getActivity(),
                viewModelFactory).get(FilterTasteListViewModel.class);

        filterTasteListViewModel.init();
        observeViewModel(filterTasteListViewModel);
    }

    private void observeViewModel(FilterTasteListViewModel filterTasteListViewModel) {
        filterTasteListViewModel.getFilterTastes().observe(this, new Observer<ArrayList<String>>() {
            @Override
            public void onChanged(@Nullable ArrayList<String> tasteList) {
                // Only this one trigger when viewModel is updated
                Log.d("Bottom Dialog", tasteList.toString());
                filterTasteList = tasteList;
                setFilterButtonState(filterTasteList);
            }
        });
    }

}
Run Code Online (Sandbox Code Playgroud)

我的基础片段

public class FoodListFragment extends BaseFragment {

    private static TasteFilterBottomDialogFragment tasteFilterBottomDialogFragment; …
Run Code Online (Sandbox Code Playgroud)

android mvvm viewmodel bottom-sheet android-viewmodel

5
推荐指数
0
解决办法
1647
查看次数

MVVM - 在应用程序关闭时从通知开始访问 BroadcastReceiver 中的 ViewModel/SQLite

我有每隔几天发送一次的提醒通知。

该通知的发送由重复触发AlarmManager。该通知本身是建立在onReceive我的BroadcastReceiver(如描述在这里)。所以当onReceive被触发时,应用程序甚至没有打开/运行。

现在我想访问我的(本地)SQLite 数据库并获得正确的内容来构建通知,但是我如何ViewModelProvider在这个地方获得一个(代码中的 xxx)来访问我的ViewModel?

public void onReceive(Context context, Intent intent) {    

    NotificationViewModel viewModel = 
    ViewModelProviders.of(XXX).get(NotificationViewModel.class);

    //do stuff
}
Run Code Online (Sandbox Code Playgroud)

或者问一个更好的问题,这甚至是好的做法吗?
另一种可能性是PendingIntent将触发 的所有内容填充到 中onReceive,因此我可以在收到后一一检索它。但这会更难,因为它是一个重复的警报,每次都需要不同的内容,但只触发一次。


我查看了一些搜索结果,但它们没有解决我的问题:

  • Android 上自定义视图的 MVVM 架构
    -> 对于这样一个小问题,似乎有很多代码,再加上是 Kotlin,这对我来说很难理解
  • 使用 Model View Presenter 设计模式处理 BroadcastReceivers
    -> 这里似乎有必要先在活动中设置一些东西,然后才能使用它,但我需要在没有运行我的应用程序的情况下启动此代码
  • 在 Viewmodel 中访问 BroadCastReceiver
    ->这似乎最接近我需要的,但它也需要之前的设置。我想试试这个,但我需要手动创建我的 MainActivity 来访问它的变量。这不会在没有警告的情况下在用户的设备上打开一个新活动吗?
    甚至可以在我的应用程序不在前台的情况下访问我的数据库吗?

编辑:

读取LiveData 超出 ViewModel [...],据说

如果您的应用程序的一部分不影响 UI,则您可能不需要 LiveData。

所以这意味着我应该简单地使用上下文访问我的存储库并从中获取原始数据, …

android mvvm broadcastreceiver viewmodel android-viewmodel

5
推荐指数
1
解决办法
2530
查看次数

CountDownTimer :在 Activity、ViewModel 或单独的类中?

我想创建一个CountdownTimer将触发更新 UI 的事件(触发弹出窗口、启动动画等)。

我想知道如何做到这一点,这是我的假设以及原因:

  1. 一个单独的组件EventCountdownTimer。然后我可以受益于使用LifecycleObserver,但我想知道如何将信息传达回活动(我尝试在活动中扩展CountdownTimer和使用它,但出现错误并且无法编译)
  2. 就其Activity本身而言,它是最简单的,但我不确定它属于那里,因为它不是 UI 组件,我无法从中受益LifecycleObserver
  3. ViewModel. 我认为因为它与活动相关并且CountdownTimer有点逻辑数据,所以它应该放在这里,但这也意味着要观察活动的生命周期,并在其中保留任何Activity相关领域ViewModel是不好的做法。

你认为最好的选择是什么?为什么?

android android-lifecycle countdowntimer android-viewmodel

5
推荐指数
2
解决办法
2316
查看次数

Dagger2.10+:在具有运行时依赖关系的 Fragment/Activity 中注入 ViewModel

对于ViewModels只有编译时依赖项,我使用ViewModelProvider.Factory来自架构的组件,如下所示:

class ViewModelFactory<T : ViewModel> @Inject constructor(private val viewModel: Lazy<T>) : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel?> create(modelClass: Class<T>): T = viewModel.get() as T
}
Run Code Online (Sandbox Code Playgroud)

在我ActivityFragment我得到ViewModel以下方式:

@Inject
lateinit var viewModelFactory: ViewModelFactory<ProductsViewModel>
Run Code Online (Sandbox Code Playgroud)

这工作正常,直到我ViewModel需要一个仅在运行时可用的依赖项。

场景是,我有一个列表Product,我在RecyclerView. 对于每个Product,我都有ProductViewModel

现在,ProductViewModel需要各种依赖关系的喜欢ResourceProviderAlertManager等这些都可以编译时,我可以Inject他们使用 constructor 或者我可以Provide他们使用Module。但是,除了上述依赖项之外,它还需要Product对象,该对象仅在运行时可用,因为我通过 API 调用获取产品列表。

我不知道如何注入仅在运行时可用的依赖项。所以我现在正在做以下事情: …

android dependency-injection assisted-inject dagger-2 android-viewmodel

5
推荐指数
1
解决办法
723
查看次数

viewModelScope 未取消

在观看了Sean 在 Android (Google I/O'19) 上的解释后,我尝试了同样的方法:

init{
    viewModelScope.launch {
        Timber.i("coroutine awake")
        while (true){
            delay(2_000)
            Timber.i("another round trip")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,onCleared它在活动被终止时被调用,而不是在它被置于后台时调用(“当我们离开活动时......”,背景正在“移开”恕我直言^^)。
我得到以下输出:

> ---- Activity in Foreground
> 12:41:10.195  TEST: coroutine awake
> 12:41:12.215  TEST: another round trip
> 12:41:14.231  TEST: another round trip
> 12:41:16.245  TEST: another round trip
> 12:41:18.259  TEST: another round trip
> 12:41:20.270  TEST: another round trip
> ----- Activity in Background (on onCleared not fired)
> 12:41:22.283  TEST: another round …
Run Code Online (Sandbox Code Playgroud)

android android-lifecycle kotlin android-viewmodel kotlin-coroutines

5
推荐指数
1
解决办法
2584
查看次数

为什么在调用 ViewModel onCleared() 方法后 ViewModelScoped 协程无法使用

我在当前 Android 应用程序中的多个 Fragment 之间共享一个 ActivityScoped viewModel。

viewModel 使用 Coroutine Scope viewModelScope.launch{}

我的问题是在调用.launch{}拥有ViewModel onCleared()方法之前唯一有效。

这是 ViewModel 作用域协程应该如何工作?

有没有一种方法可以用来“重置”viewModelScope,以便 .launch{} 在调用 onCleared() 方法之后工作?

继承人我的代码::

分段

RxSearchView.queryTextChangeEvents(search)
        .doOnSubscribe {
            compositeDisposable.add(it)
        }
        .throttleLast(300, TimeUnit.MILLISECONDS)
        .debounce(300, TimeUnit.MILLISECONDS)
        .map { event -> event.queryText().toString() }
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe { charactersResponse ->
            launch {
                viewModel.search(charactersResponse.trim())
            }
        }
Run Code Online (Sandbox Code Playgroud)

. . .

override fun onDetach() {
    super.onDetach()
    viewModel.cancelSearch()
    compositeDisposable.clear()
}
Run Code Online (Sandbox Code Playgroud)

视图模型

suspend fun search(searchString: String) {
    cancelSearch()

    if (TextUtils.isEmpty(searchString)) {
        return
    }

    job = viewModelScope.launch { …
Run Code Online (Sandbox Code Playgroud)

android dagger-2 android-viewmodel kotlin-coroutines

5
推荐指数
2
解决办法
2659
查看次数