gpt4 book ai didi

android - 使用新的android架构(MVVM)的 Activity fragment 通信

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:44:18 25 4
gpt4 key购买 nike

目标是从 Fragment 获取信息,以便托管 Activity 可以显示它。让我们举一个简单的例子,假设当一个 Fragment 发生变化时,我们想要从我们的 Activity 的 Action Bar 中显示 Fragment 的标题。

这是我以前的做法:

Activity

@Override
protected void onCreate( @Nullable Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );

getSupportFragmentManager().addOnBackStackChangedListener( this );
}

@Override
public void onBackStackChanged( )
{
BaseFragment fragment = mNavigationManager.getCurrentFragment( );

if( fragment != null && fragment instanceof ActionBarProvider )
mActionBarTitle.setText( ( ( ActionBarProvider ) fragment ).getTitle( ) );
}

ActionBarProvider

public interface ActionBarProvider
{
String getTitle( );
}

fragment

// implements ActionBarProvider

@Override
protected String getTitle( )
{
return "Hello world";
}

这是我想用 MVVM 做的事情:

Activity

@Override
protected void onCreate( @Nullable Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );

mViewModel = ViewModelProviders.of( this, mViewModelFactory ).get( MainViewModel.class );
mViewModel.getTitle( ).observe( this, s -> mActionBarTitle.setText( s ) );
}

主视图模型

private MutableLiveData< String > mTitle = new MutableLiveData<>( );

public MutableLiveData< String > getTitle( )
{
return mTitle;
}

public void setTitle( String title )
{
mTitle.postValue( title );
}

fragment

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

MainViewModel viewModel = ViewModelProviders
.of( getActivity( ), mViewModelFactory )
.get( MainViewModel.class );

viewModel.setTitle( "hello world" );
}

MVVM 看起来更干净,但它假设 Fragment 知道它的主要 Activity ViewModel:

MainViewModel viewModel = ViewModelProviders
.of( getActivity( ), mViewModelFactory )
.get( MainViewModel.class );

因此,如果您将 Fragment 移动到另一个 Activity,这将不起作用。我应该保持旧的方式吗?或者你们还有其他方法可以使用 MVVM 进行这种通信吗?

谢谢!

最佳答案

使用 ViewModel 有一条黄金法则。除了 *.arch 包之外,导入中以 Android 包开头的所有内容都是错误的。

您无需在 Activity 中设置标题,因为它已绑定(bind)到 fragment 。

在 fragment 的 onStart/onResume 方法中使用 getActivity().setTitle()

ViewModel 绑定(bind)到 fragment 或宿主 Activity 。更改 Activity 还将在您的 ViewModel 中调用 onCleared()。您无法使用 ViewModel 在多个 Activity 之间共享数据。

创建一个接口(interface)来共享数据不是 MVVM。它是 MVP,应避免使用 MVVM 和 Google's AAC .

由于多个 Activity 可能是您的 fragment 的宿主,因此您永远不应直接访问 Activity 。最好在 fragment 中使用 if (getActivity() != null) { getActivity().setTitle(...) }

顺便说一下,如果您不修改 getter/setter,您还应该使用 public final LiveData 并避免使用 getter 和 setter。您的 LiveData 实例不会改变,但数据会改变。意味着 final 就好了。

public final LiveData<String> mTitle = new MutableLiveData<String>();

如果您不想追加而是替换数据,您还应该考虑使用 setValue() 来设置数据。

因此,如果您将 fragment 移动到另一个 Activity ,这将不起作用。我应该保持旧的方式吗?或者你们有没有其他方法使用 MVVM 进行这种通信?

ViewModels 只能在 fragment 和托管 Activity 之间共享,但不能使用多个 Activity 共享。

关于android - 使用新的android架构(MVVM)的 Activity fragment 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46683082/

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