目标是从a获取信息Fragment
,以便托管Activity
可以显示它.让我们举个简单的例子,假设Fragment
我们想要在Fragment
我们Activity
的动作栏中显示标题.
这是我以前的做法:
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( ) );
}
Run Code Online (Sandbox Code Playgroud)
ActionBarProvider
public interface ActionBarProvider
{
String getTitle( );
}
Run Code Online (Sandbox Code Playgroud)
分段
// implements ActionBarProvider
@Override
protected String getTitle( )
{
return "Hello world";
}
Run Code Online (Sandbox Code Playgroud)
以下是我对MVVM的看法:
活动
@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 ) );
}
Run Code Online (Sandbox Code Playgroud)
MainViewModel
private MutableLiveData< String > mTitle = new MutableLiveData<>( );
public MutableLiveData< String > getTitle( )
{
return mTitle;
}
public void setTitle( String title )
{
mTitle.postValue( title );
}
Run Code Online (Sandbox Code Playgroud)
分段
@Override
public void onActivityCreated( @Nullable Bundle savedInstanceState )
{
super.onActivityCreated( savedInstanceState );
MainViewModel viewModel = ViewModelProviders
.of( getActivity( ), mViewModelFactory )
.get( MainViewModel.class );
viewModel.setTitle( "hello world" );
}
Run Code Online (Sandbox Code Playgroud)
MVVM看起来更干净,但它假设Fragment
知道它的主要Activity
ViewModel:
MainViewModel viewModel = ViewModelProviders
.of( getActivity( ), mViewModelFactory )
.get( MainViewModel.class );
Run Code Online (Sandbox Code Playgroud)
所以,如果你转移Fragment
到另一个,Activity
这将无法正常工作.我应该保持旧的方式吗?或者你们有其他方式使用MVVM进行这种通信吗?
谢谢!
使用ViewModels有一条黄金法则.除了*.arch软件包之外,导入中以Android软件包开头的所有内容都是错误的.
您没有在动作中设置标题,因为它与片段绑定.
getActivity().setTitle()
在片段中的onStart
/ onResume
method中使用.
ViewModels绑定到主机活动的片段OR.更改活动也将调用onCleared()
ViewModel.您无法使用ViewModel在多个活动之间共享数据.
创建共享数据的接口不是MVVM.它是MVP,应该避免使用MVVM和谷歌的AAC.
由于多个活动可能是您的片段的主机,因此您不应直接访问该活动.更好地使用if (getActivity() != null) { getActivity().setTitle(...) }
你的片段.
顺便说一句,如果你不修改getter/setter,你也应该使用public final LiveData
并避免使用getter和setter.您的LiveData
实例不会更改,但数据会更改.手段final
很好.
public final LiveData<String> mTitle = new MutableLiveData<String>();
Run Code Online (Sandbox Code Playgroud)
setValue()
如果您不想附加但是替换数据,您还应该考虑使用设置数据.
因此,如果您将片段移动到另一个活动,这将无效.我应该保持旧的方式吗?或者你们有其他方式使用MVVM进行这种通信吗?
ViewModel只能在片段和托管活动之间共享,但不能使用多个活动共享.
归档时间: |
|
查看次数: |
1614 次 |
最近记录: |