Я пытаюсь войти в шаблон MVVM, и моя проблема в том, что я не совсем уверен, правильно ли я его использую. View отвечает за все операции пользовательского интерфейса (например, 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.\n\nIcons 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- Предоставьте изменяемую 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();
}
});
PS: Лучше всего переместить эту строку во ViewModel, поскольку она содержит часть бизнес-логики:
PreferencesManager.setCountry(countries[position], codes[position]);
Сделайте 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 при закрытии диалога, чтобы избежать утечек памяти