如何在Android MVVM架构中实现对话框选择选项
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Android MVVM架构中实现对话框选择选项相关的知识,希望对你有一定的参考价值。
我正试图进入MVVM模式,我的问题是我不确定我是否正确使用它。 View负责所有UI操作(比如show stuff?)但是当我们需要在逻辑中改变某些东西时会发生什么。
所以我真正想做的是,显示一个包含某些选项的对话框,选择一个并重新加载应用程序。
我已经实现了MainActivity类中的函数,并且在需要操作时使用mCountrySelection.show()。
public void createCountriesDialog()
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
dialogBuilder.setTitle("Available Countries");
GridView gridView = new GridView(MainActivity.this);
final String[] countries = getResources().getStringArray(R.array.countries);
final String[] codes = getResources().getStringArray(R.array.codes);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, countries);
gridView.setAdapter(arrayAdapter);
dialogBuilder.setView(gridView);
dialogBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
mCountrySelection = dialogBuilder.create();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
fragmentTransaction.commit();
mCountrySelection.dismiss();
}
});
}
public void createAboutDialog()
{
AlertDialog.Builder aboutBuilder = new AlertDialog.Builder(MainActivity.this);
aboutBuilder.setTitle("Top News v1.0");
aboutBuilder.setMessage("Simple application for displaying Top Headlines from newsapi.org.
Icons made by Freepik from www.flaticon.com.");
aboutBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
}
});
mAbout = aboutBuilder.create();
}
创建1个接口ItemClick并从您调用Dialog的位置实现此接口。
public interface ItemClick{
public void onClick(int position, String country);
}
将此接口引用传递给对话框方法
public void createCountriesDialog(ItemClick listner)
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
dialogBuilder.setTitle("Available Countries");
GridView gridView = new GridView(MainActivity.this);
final String[] countries = getResources().getStringArray(R.array.countries);
final String[] codes = getResources().getStringArray(R.array.codes);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, countries);
gridView.setAdapter(arrayAdapter);
dialogBuilder.setView(gridView);
dialogBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
listener = null;
}
});
mCountrySelection = dialogBuilder.create();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
listener.onclick(position, countries[position]);
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
fragmentTransaction.commit();
mCountrySelection.dismiss();
}
});
}
然后,当您单击网格项时,使用接口引用调用onclick方法现在,当您将在onClick(int pos,String country)中收到回调时
使用您的视图模型进行api调用和重新加载屏幕。
在对话框关闭时设置listener = null以避免内存泄漏
1-在你的LiveData
中暴露一个可变的Observer
或ViewModel
public MutableLiveData<Pair<String, String>> countryInfo = new MutableLiveData<>()
2-将用户选择传递给ViewModel
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
viewModel.countryInfo.setValue(new Pair(countries[position], codes[position]))
mCountrySelection.dismiss();
}
3-在ViewModel
中运行用例(业务逻辑)(将信息上传到服务器,将其保存在数据库中等)
4-通过暴露另一个View
更新Observable
(在这种情况下相同的countryInfo
将起作用)在MainActivity中观察countryInfo
:
viewmodel.countryInfo.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
getSupportFragmentManager().beginTransaction();
.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
.commit();
}
});
P.S:最好将此行移至ViewModel,因为它包含业务逻辑的一部分:
PreferencesManager.setCountry(countries[position], codes[position]);
以上是关于如何在Android MVVM架构中实现对话框选择选项的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染
如何在 MVVM-C RxSwift 中实现 firebase 身份验证