如何在Android MVVM架构中实现对话框选择选项



我正在尝试进入MVVM模式,我的问题是我不确定我是否正确使用它。View 负责所有 UI 操作(如显示内容?(,但是当我们需要更改逻辑中的某些内容时会发生什么。

所以我真正想做的是,显示一个带有某些选项的对话框,选择一个并重新加载应用程序。

我已经在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.nnIcons 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,字符串国家/地区(中收到回调时

使用视图模型进行 api 调用和重新加载屏幕。

当对话框关闭时设置侦听器 =null 以避免内存泄漏

1-在ViewModel中公开可变LiveDataObserver

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-通过公开另一个Observable来更新View(在这种情况下,相同的countryInfo将起作用(在主活动中,观察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]);

最新更新