gpt4 book ai didi

android - 在 Android 中正确实现 MVVM

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:25:14 26 4
gpt4 key购买 nike

我一直在努力寻找在 Android 中实现 MVVM 的正确方法。

整个想法对我来说仍然很模糊,模式是有一个单独的层来完成逻辑(ViewModel)。

这段代码仅对背景的 alpha 进行动画处理,其中存在一堆 fragment 。

public class StartActivity extends AppCompatActivity implements EntryFragment.EntryFragementListener {

private static final float MINIMUM_ALPHA = 0.4f;
private static final float MAXIMUM_ALPHA = 0.7f;

@State
float mCurrentAlpha = MINIMUM_ALPHA;

@State
String mCurrentTag = EntryFragment.TAG;

private ActivityStartBinding mBinding;

private StartViewModel mStartViewModel = new StartViewModel();

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_start);
mBinding.setStartViewModel(mStartViewModel);
mBinding.bgBlackLayer.setAlpha(mCurrentAlpha);

if (getSupportFragmentManager().findFragmentByTag(mCurrentTag) == null) {
switch (mCurrentTag) {
case EntryFragment.TAG:
setEntryFragment();
break;
case FreeTrialFragment.TAG:
setFreeTrialFragment();
break;
}
}
}

private void setEntryFragment() {
mCurrentAlpha = MINIMUM_ALPHA;
mCurrentTag = EntryFragment.TAG;
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = new EntryFragment();
fm.beginTransaction().
add(R.id.fragment_content, fragment, EntryFragment.TAG).commit();
}

private void setFreeTrialFragment() {
mCurrentTag = FreeTrialFragment.TAG;
Fragment fragment = new FreeTrialFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.anim_enter_right, R.anim.anim_exit_left, R.anim.anim_enter_left, R.anim.anim_exit_right);
ft.replace(R.id.fragment_content, fragment, FreeTrialFragment.TAG);
ft.addToBackStack(FreeTrialFragment.TAG);
ft.commit();
StartViewModel.setAnimation(mBinding.bgBlackLayer,true, MAXIMUM_ALPHA);
}

private void setForgotPasswordFragmet() {
}

private void setLoginFragment() {
}

@Override
public void onBackPressed() {
super.onBackPressed();
StartViewModel.setAnimation(mBinding.bgBlackLayer,true, MINIMUM_ALPHA);
mCurrentAlpha = MINIMUM_ALPHA;
}

@Override
public void onEntryLoginButton() {
setLoginFragment();
}

@Override
public void onEntryFreeTrialButton() {
setFreeTrialFragment();
}
}

-ViewModel 只做动画的逻辑- fragment 有一个监听器来将事件传递给 Activity - 绑定(bind)有助于定义 View

public class StartViewModel {

public ObservableBoolean hasToAnimate = new ObservableBoolean(false);
public float alpha;

@BindingAdapter(value={"animation", "alpha"}, requireAll=false)
public static void setAnimation(View view, boolean hasToAnimate, float alpha) {
if (hasToAnimate) {
view.animate().alpha(alpha);
}
}
}

问题是,所有的逻辑都应该驻留在 View 模型中,包括 fragment 事务、方向变化的管理等等吗?有没有更好的方法来实现 MVVM?

最佳答案

至于我 - MVVM、MVP 和其他真正酷的人的非常酷的模式没有直接的收据/流程。当然,您有很多教程/建议/模式以及如何实现它们的方法。但这实际上就是所有编程的目的——你只需要想出一个适合你需要的解决方案。根据您的开发人员的愿景,您可以将许多原则应用于您的解决方案,以使其更容易/更快地开发/测试/支持。
在你的情况下,我认为最好将这种逻辑转移到 fragment 转换中(就像你在 setFreeTrialFragment() 中所做的那样),它更可定制且使用起来更舒适。但是,如果您的方法应该保持不变 - 现有的方法是正常的。实际上 @BindingAdapter 比直接使用更适合 xml 属性。
至于我——所有的 UI 逻辑都应该驻留在 Activity 中,主要目的是将业务逻辑与 UI 分开。因为所有动画、 fragment 事务等都在 Activity 内部处理——这是我的方法。 ViewModel - 负责通知 View 相应模型中发生了某些更改,并且 View 应自行安排这些更改。在完美世界中,您应该能够实现双向绑定(bind)这样一个流行的术语,但这并不总是必要的,而且 UI 更改也不总是应该在 ViewModel 内部处理。像往常一样,过多的 MVVM 对您的项目不利。它会导致 Spaghetti code ,“那是哪里来的?”,“如何回收站 View ?”等热门话题。因此,它应该只用于让生活更轻松,而不是让一切都变得理想,因为像其他所有模式一样,它会让人很头疼,查看你的代码的人会说“OVERENGINEERING!!11”。

每个请求,MVP 示例:

这里有一些有用的文章:

  • 很简单example .
  • Here你对集成指南有很好的描述。
  • Firstsecond这篇文章的一部分可能会更多有帮助。
  • one简短而真实。

简短示例(一般化),您应该使其适合您的架构:

包表示:
enter image description here

实现:

型号:

public class GalleryItem {

private String mImagePath;
//other variables/getters/setters
}

主持人:

//cool presenter with a lot of stuff
public class GalleryPresenter {

private GalleryView mGalleryView;

public void loadPicturesBySomeCreteria(Criteria criteria){
//perform loading here
//notify your activity
mGalleryView.setGalleryItems(yourGaleryItems);
}

//you can use any other suitable name
public void bind(GalleryView galleryView) {
mGalleryView = galleryView;
}

public void unbind() {
mGalleryView = null;
}

//Abstraction for basic communication with activity.
//We can say that this is our protocol
public interface GalleryView {
void setGalleryItems(List<GalleryItem> items);

}
}

View :

public class NiceGalleryView extends View {
public NiceGalleryView(Context context) {
super(context);
}

public NiceGalleryView(Context context, AttributeSet attrs) {
super(context, attrs);
}

// TODO: 29.12.16 do your stuff here
}

当然还有 Activity 代码:

public class GalleryActivity extends AppCompatActivity implements GalleryPresenter.GalleryView {

private GalleryPresenter mPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
//init views and so on
mPresenter = new GalleryPresenter();
mPresenter.bind(this);

}

@Override
public void setGalleryItems(List<GalleryItem> items) {
//use RecyclerView or any other stuff to fill your UI
}

@Override
protected void onDestroy() {
super.onDestroy();
mPresenter.unbind();
}
}

另请注意,在使用 MVP 时,您甚至有很多不同的方法。我只想强调,我更喜欢在 Activity 中初始化 View ,而不是将它们传出 Activity 。您可以通过界面进行管理,这不仅对开发非常方便,甚至对仪器测试也是如此。

关于android - 在 Android 中正确实现 MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41287535/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com