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) 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
我使用相同的过程在片段之间发送数据并且它可以工作,但现在我没有在接收器活动中获取数据。当我点击提交按钮时,甚至日志消息标签也没有显示。我检查了发件人活动日志消息,它显示数据但无法在接收方活动中获取这些数据。
请帮我获取数据。谢谢!!
视图模型类:
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) 我有一个简单的场景,我在片段中做一些事情,当我收到 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
我想在我的基本片段和打开的 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) 我有每隔几天发送一次的提醒通知。
该通知的发送由重复触发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,因此我可以在收到后一一检索它。但这会更难,因为它是一个重复的警报,每次都需要不同的内容,但只触发一次。
我查看了一些搜索结果,但它们没有解决我的问题:
读取LiveData 超出 ViewModel [...],据说
如果您的应用程序的一部分不影响 UI,则您可能不需要 LiveData。
所以这意味着我应该简单地使用上下文访问我的存储库并从中获取原始数据, …
我想创建一个CountdownTimer将触发更新 UI 的事件(触发弹出窗口、启动动画等)。
我想知道如何做到这一点,这是我的假设以及原因:
EventCountdownTimer。然后我可以受益于使用LifecycleObserver,但我想知道如何将信息传达回活动(我尝试在活动中扩展CountdownTimer和使用它,但出现错误并且无法编译)Activity本身而言,它是最简单的,但我不确定它属于那里,因为它不是 UI 组件,我无法从中受益LifecycleObserverViewModel. 我认为因为它与活动相关并且CountdownTimer有点逻辑数据,所以它应该放在这里,但这也意味着要观察活动的生命周期,并在其中保留任何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)
在我Activity或Fragment我得到ViewModel以下方式:
@Inject
lateinit var viewModelFactory: ViewModelFactory<ProductsViewModel>
Run Code Online (Sandbox Code Playgroud)
这工作正常,直到我ViewModel需要一个仅在运行时可用的依赖项。
场景是,我有一个列表Product,我在RecyclerView. 对于每个Product,我都有ProductViewModel。
现在,ProductViewModel需要各种依赖关系的喜欢ResourceProvider,AlertManager等这些都可以编译时,我可以Inject他们使用 constructor 或者我可以Provide他们使用Module。但是,除了上述依赖项之外,它还需要Product对象,该对象仅在运行时可用,因为我通过 API 调用获取产品列表。
我不知道如何注入仅在运行时可用的依赖项。所以我现在正在做以下事情: …
android dependency-injection assisted-inject dagger-2 android-viewmodel
在观看了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
我在当前 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 ×10
mvvm ×3
dagger-2 ×2
kotlin ×2
viewmodel ×2
android-architecture-components ×1
android-mvvm ×1
bottom-sheet ×1