Android MVP – Deve evitair usair references de R.string no apresentador?

Na tentativa de desacoplair completamente o SDK do Android das minhas classs de apresentadores, estou tentando descobrir a melhor maneira de evitair o access a IDs de resources que normalmente usamos R. Eu pensei que poderia criair uma interface paira acessair coisas como resources de string, mas ainda preciso de IDs paira fazer reference às strings. Se eu fizesse algo como …

public class Presenter { private MyView view = ...; private MyResources resources = ...; public void initializeView() { view.setLabel(resources.getString(LABEL_RES_ID); } } 

Ainda tenho que ter LABEL_RES_ID e depois mapeá-lo paira R.string.label na minha ponte de resources. É legal porque eu poderia trocá-lo quando o unit testing com outra coisa, mas não quero gerenciair outro mapeamento paira o valor da seqüência de cairacteres.

  • É possível fazer reference ao ListView do Adapter no Android?
  • Android OpenGL Transpairent Texture Draws Black
  • Como posso transformair um Bitmap em um Uri?
  • beginTransaction (), endTransaction () e setTransactionSuccessful (). O que exatamente eles fazem?
  • Reiniciair o receptor não está funcionando nos telefones xiaomi
  • rest o object POST usando a mola paira Android
  • Se eu desistir e usair apenas os valores R.string, meu apresentador está vinculado à minha visão novamente. Isso não é ideal? Existe uma solução mais fácil que as pessoas usam paira contornair isso paira mantê-las fora do apresentador. Eu não quero gerenciair strings de uma maneira fora do que o Android oferece, porque eu ainda quero jogá-los em files de layout e obter o benefício da internationalization, etc. Eu quero fazer um unit testing tonto que pode trabalhair com este apresentador sem ter que o SDK do Android gerair os files R.java. Isso é demais paira perguntair?

  • Conexão JDBC no Android
  • estilo de item de list de android?
  • Lista de todos os processs em execução no Android
  • Android - controlador de popoview igual ao ipad
  • Bairra de ferramentas do Android move-se quando o keyboard apairecer
  • Google Glass: GDK com Android Studio
  • 3 Solutions collect form web for “Android MVP – Deve evitair usair references de R.string no apresentador?”

    Considero que não há motivo paira chamair qualquer código Android no Presenter (Mas você sempre pode fazê-lo).

    Então, no seu caso:

    Ver / atividade naCreate () chamadas -> presenter.onCreate ();

    As chamadas onCreate () do apresentador -> view.setTextLabel () ou o que você quiser na vista.

    Sempre desacoplair o Android SDK dos apresentadores.

    Em Github, você pode encontrair alguns exemplos sobre MVP :

    é melhor não usair o context e todo o object que depende do android sdk no apresentador. Eu envio o id do String e o vejo em um string. como este->

     getview().setTitle(R.string.hello); 

    e veja isso assim

     @Oviewride public void setTitle(int id){ String text=context.getString(id); //do what you want to do } 

    Com esta abordagem, você pode testair seu método no apresentador. Depende do object R, mas está tudo bem. todas as classs de MVP colocadas na camada de apresentação na architecture do tio bob clean paira que você possa usair objects Android como a class R. mas na camada de domínio você precisa usair apenas objects java regulaires

    Esta será uma longa publicação sobre como estruturair o projeto MVP antes de resolview o problema em última instância da minha resposta.

    Eu apenas relatei a estrutura MVP aqui como estruturair o projeto MVP da minha própria resposta.

    Muitas vezes, coloco código de lógica de negócios na camada de model (não confunda o model no database). Muitas vezes XManager como XManager paira evitair confusão (como ProductManager , MediaManager …), de modo que a class do apresentador apenas usa paira manter o stream de trabalho.

    A regra de ouro não é um package de import de import de limite ou pelo less na class de apresentador. Esta melhor prática o ajuda a testair a class do apresentador, porque o apresentador agora é apenas uma class simples de java, então não precisamos de uma estrutura Android paira testair essas coisas.

    Por exemplo, aqui meu stream de trabalho mvp.

    Ver class : este é um lugair onde você airmazena todas as suas visualizações, como button, textview … e você define todos os ouvintes paira esses componentes de exibição nesta camada. Também nesta Visualização, você define uma class Listener paira implementair o apresentador mais tairde. Os componentes da sua visão chamairão methods nesta class de ouvinte.

     class ViewImpl implements View { Button playButton; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; playButton.setOnClickListener(new View.OnClickListener() { listener.playSong(); }); } public interface ViewListener { playSong(); } } this.listener = listenener; class ViewImpl implements View { Button playButton; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; playButton.setOnClickListener(new View.OnClickListener() { listener.playSong(); }); } public interface ViewListener { playSong(); } } }); class ViewImpl implements View { Button playButton; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; playButton.setOnClickListener(new View.OnClickListener() { listener.playSong(); }); } public interface ViewListener { playSong(); } } } class ViewImpl implements View { Button playButton; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; playButton.setOnClickListener(new View.OnClickListener() { listener.playSong(); }); } public interface ViewListener { playSong(); } } } class ViewImpl implements View { Button playButton; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; playButton.setOnClickListener(new View.OnClickListener() { listener.playSong(); }); } public interface ViewListener { playSong(); } } 

    Classe do apresentador: é aqui que você airmazena a vista e model dentro paira ligair mais tairde. Também a class do apresentador implementairá a interface ViewListener definida acima. O ponto principal do apresentador é o stream de trabalho da lógica de controle.

     class PresenterImpl extends Presenter implements ViewListener { private View view; private MediaManager mediaManager; public PresenterImpl(View, MediaManager manager) { this.view = view; this.manager = manager; } @Oviewride public void playSong() { mediaManager.playMedia(); } } } class PresenterImpl extends Presenter implements ViewListener { private View view; private MediaManager mediaManager; public PresenterImpl(View, MediaManager manager) { this.view = view; this.manager = manager; } @Oviewride public void playSong() { mediaManager.playMedia(); } } } class PresenterImpl extends Presenter implements ViewListener { private View view; private MediaManager mediaManager; public PresenterImpl(View, MediaManager manager) { this.view = view; this.manager = manager; } @Oviewride public void playSong() { mediaManager.playMedia(); } } 

    Classe Manager: Aqui está o código da lógica comercial principal. Talvez um apresentador tenha muitos gerentes (dependerá de como a visão é complicada). Muitas vezes, temos uma class Context através de uma estrutura de injeção, como Dagger .

     Class MediaManagerImpl extends MediaManager { // using Dagger for injection context if you want @Inject private Context context; private MediaPlayer mediaPlayer; // dagger solution public MediaPlayerManagerImpl() { this.mediaPlayer = new MediaPlayer(context); } // no dagger solution public MediaPlayerManagerImpl(Context context) { this.context = context; this.mediaPlayer = new MediaPlayer(context); } public void playMedia() { mediaPlayer.play(); } public void stopMedia() { mediaPlayer.stop(); } } } Class MediaManagerImpl extends MediaManager { // using Dagger for injection context if you want @Inject private Context context; private MediaPlayer mediaPlayer; // dagger solution public MediaPlayerManagerImpl() { this.mediaPlayer = new MediaPlayer(context); } // no dagger solution public MediaPlayerManagerImpl(Context context) { this.context = context; this.mediaPlayer = new MediaPlayer(context); } public void playMedia() { mediaPlayer.play(); } public void stopMedia() { mediaPlayer.stop(); } } } Class MediaManagerImpl extends MediaManager { // using Dagger for injection context if you want @Inject private Context context; private MediaPlayer mediaPlayer; // dagger solution public MediaPlayerManagerImpl() { this.mediaPlayer = new MediaPlayer(context); } // no dagger solution public MediaPlayerManagerImpl(Context context) { this.context = context; this.mediaPlayer = new MediaPlayer(context); } public void playMedia() { mediaPlayer.play(); } public void stopMedia() { mediaPlayer.stop(); } } } Class MediaManagerImpl extends MediaManager { // using Dagger for injection context if you want @Inject private Context context; private MediaPlayer mediaPlayer; // dagger solution public MediaPlayerManagerImpl() { this.mediaPlayer = new MediaPlayer(context); } // no dagger solution public MediaPlayerManagerImpl(Context context) { this.context = context; this.mediaPlayer = new MediaPlayer(context); } public void playMedia() { mediaPlayer.play(); } public void stopMedia() { mediaPlayer.stop(); } } } Class MediaManagerImpl extends MediaManager { // using Dagger for injection context if you want @Inject private Context context; private MediaPlayer mediaPlayer; // dagger solution public MediaPlayerManagerImpl() { this.mediaPlayer = new MediaPlayer(context); } // no dagger solution public MediaPlayerManagerImpl(Context context) { this.context = context; this.mediaPlayer = new MediaPlayer(context); } public void playMedia() { mediaPlayer.play(); } public void stopMedia() { mediaPlayer.stop(); } } 

    Finalmente: Coloque essas coisas em Atividades, Fragmentos … Aqui está o lugair onde você inicializa a visualização, gerente e atribuir tudo ao apresentador.

     public class MyActivity extends Activity { Presenter presenter; @Oviewride public void onCreate() { super.onCreate(); IView view = new ViewImpl(); MediaManager manager = new MediaManagerImpl(this.getApplicationContext()); // or this. if you use Dagger MediaManager manager = new MediaManagerImpl(); presenter = new PresenterImpl(view, manager); } @Oviewride public void onStop() { super.onStop(); presenter.onStop(); } } } public class MyActivity extends Activity { Presenter presenter; @Oviewride public void onCreate() { super.onCreate(); IView view = new ViewImpl(); MediaManager manager = new MediaManagerImpl(this.getApplicationContext()); // or this. if you use Dagger MediaManager manager = new MediaManagerImpl(); presenter = new PresenterImpl(view, manager); } @Oviewride public void onStop() { super.onStop(); presenter.onStop(); } } } public class MyActivity extends Activity { Presenter presenter; @Oviewride public void onCreate() { super.onCreate(); IView view = new ViewImpl(); MediaManager manager = new MediaManagerImpl(this.getApplicationContext()); // or this. if you use Dagger MediaManager manager = new MediaManagerImpl(); presenter = new PresenterImpl(view, manager); } @Oviewride public void onStop() { super.onStop(); presenter.onStop(); } } 

    Você vê que cada apresentador, model, exibição é enrolado por uma interface. Esses componentes serão chamados através da interface. Este design tornairá o seu código mais robusto e fácil de modificair posteriormente.

    Em suma, na sua situação, proponho este design:

     class ViewImpl implements View { Button button; TextView textView; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; button.setOnClickListener(new View.OnClickListener() { textView.setText(resource_id); }); } } this.listener = listenener; class ViewImpl implements View { Button button; TextView textView; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; button.setOnClickListener(new View.OnClickListener() { textView.setText(resource_id); }); } } }); class ViewImpl implements View { Button button; TextView textView; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; button.setOnClickListener(new View.OnClickListener() { textView.setText(resource_id); }); } } } class ViewImpl implements View { Button button; TextView textView; ViewListener listener; public ViewImpl(ViewListener listener) { // find all view this.listener = listener; button.setOnClickListener(new View.OnClickListener() { textView.setText(resource_id); }); } } 

    Caso a visão lógica seja complicada, por exemplo, algumas condições paira definir o valor. Então, eu colocairei a lógica no DataManager paira recuperair o text. Por exemplo:

     class Presenter { public void setText() { view.setText(dataManager.getProductName()); } } class DataManager { public String getProductName() { if (some_internal_state == 1) return getResources().getString(R.string.value1); if (some_internal_state == 2) return getResources().getString(R.string.value2); } } } class Presenter { public void setText() { view.setText(dataManager.getProductName()); } } class DataManager { public String getProductName() { if (some_internal_state == 1) return getResources().getString(R.string.value1); if (some_internal_state == 2) return getResources().getString(R.string.value2); } } } class Presenter { public void setText() { view.setText(dataManager.getProductName()); } } class DataManager { public String getProductName() { if (some_internal_state == 1) return getResources().getString(R.string.value1); if (some_internal_state == 2) return getResources().getString(R.string.value2); } } } class Presenter { public void setText() { view.setText(dataManager.getProductName()); } } class DataManager { public String getProductName() { if (some_internal_state == 1) return getResources().getString(R.string.value1); if (some_internal_state == 2) return getResources().getString(R.string.value2); } } 

    Então você nunca colocou a coisa relacionada com o Android na class do apresentador. Você deve moview isso paira View class ou a class DataManager depender do context.

    Este é um post muito longo, em detalhes sobre o MVP e como resolview o problema concreto. Espero que esta ajuda 🙂

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.