2017-01-05 1 views
1

J'ai déjà recherché de nombreuses réponses à propos de cette question mais pour la vie de moi, je n'arrive pas à résoudre ce problème de mon côté et j'ai besoin d'aide.Comment réparer "call non coché à 'attachView (V)' en tant que membre du type 'BasePresenter' brut" "?

BasePresenter:

public abstract class BasePresenter<V> { 

    private V mView; 

    public void attachView(V view) { mView = view; } 
    public void detachView() { mView = null; } 

} 

BaseFragment:

public abstract class BaseFragment<P extends BasePresenter> extends Fragment { 

    @Inject protected P mPresenter; 

    @Override 
    public void onResume() { 
     super.onResume(); 
     mPresenter.attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter' 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     mPresenter.detachView(); 
    } 

} 

MyPresenter:

public class MyPresenter extends BasePresenter<MyPresenter.MyView> { 

    @Inject 
    public MyPresenter() {} 

    public interface MyView {} 

} 

MyFragment:

public class MyFragment extends BaseFragment implements MyPresenter.MyView {} 
+0

Vous pouvez jeter un oeil à cet exemple de projet http://github.com/mmirhoseini/marvel et cet article https://hackernoon.com/yet- un autre-mvp-article-part-1-permet d'apprendre à connaître le projet-d3fd553b3e21 pour se familiariser avec MVP. –

Répondre

1

simple, au lieu de

public abstract class BaseFragment<P extends BasePresenter> extends Fragment { 

Il devrait être

public abstract class BaseFragment<V, P extends BasePresenter<V>> extends Fragment { 

ou

public abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> extends Fragment { 

ou

public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment { 

Fondamentalement, assurez-vous que le BasePresenter est paramétré avec quelque chose.




EDIT:

D'accord, basé sur ce que vous essayez de faire en fait, vous devriez le faire comme ceci:

public abstract class BasePresenter<V> { 

    private V mView; 

    public void attachView(V view) { mView = view; } 
    public void detachView() { mView = null; } 
} 

public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment { 

    protected abstract P getPresenter(); 

    @Override 
    public void onResume() { 
     super.onResume(); 
     getPresenter().attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter' 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     getPresenter().detachView(); 
    } 
} 

public class MyPresenter extends BasePresenter<MyPresenter.MyView> { 
    @Inject 
    public MyPresenter() {} 

    public interface MyView {} 
} 

public class MyFragment extends BaseFragment<MyFragment, MyPresenter> implements MyPresenter.MyView { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     MyFragmentComponent component = ((MainActivity)getActivity()).getComponent().myFragmentComponent(); 
     component.inject(this); 
     View view = inflater.inflate(R.layout.blah, container, false); 
     ButterKnife.bind(this, view); 
     return view; 
    } 
} 



EDIT2: Sur la base exemple fourni:

public class RexTester { 
    // MAIN CLASS 

    static class Rextester { 
     public static void main(String args[]) { 
      new MyFragment(); 
     } 
    } 

// MVP CODE 

    interface BaseView {} 

    final static class MyPresenter extends BasePresenter<MyPresenter.MyView> { 

     public MyPresenter() {} 

     public void executeAction() { 
      mView.onCallback(); 
     } 

     interface MyView extends BaseView { 
      void onCallback(); 
     } 

    } 

    abstract static class BasePresenter<V extends BaseView> { 

     protected V mView; 

     public void attachView(V view) { mView = view;} 
     public void detachView() { mView = null; } 

    } 

    final static class MyFragment extends BaseFragment<MyPresenter.MyView, MyPresenter> implements MyPresenter.MyView { 

     private MyPresenter mPresenter; 

     public MyFragment() { 
      mPresenter = new MyPresenter(); 

      onResume(); // Mock onResume() lifecycle event! 

      mPresenter.executeAction(); 

      onPause(); // Mock onPause() lifecycle event! 
     } 

     protected MyPresenter getPresenter() { 
      return mPresenter; 
     } 

     @Override 
     protected MyPresenter.MyView getThis() { 
      return this; 
     } 

     public void onCallback() { 
      System.out.println("Hello AndroidMVP!"); 
     } 
    } 

    abstract static class BaseFragment<V extends BaseView, P extends BasePresenter<V>> extends Fragment implements BaseView { 

     protected abstract P getPresenter(); 

     protected void onResume() { 
      super.onResume(); 
      getPresenter().attachView(getThis()); 
     } 

     protected abstract V getThis(); 

     protected void onPause() { 
      super.onPause(); 
      getPresenter().detachView(); 
     } 
    } 

// ANDROID FRAMEWORK MOCK 

    abstract static class Fragment { 

     protected void onResume() {} 

     protected void onPause() {} 

    } 
} 
+0

Pourriez-vous clarifier ceci: "Bien que si vous attachez le fragment en tant que vue, alors il devrait implémenter une interface qui en fait une vue."? –

+1

effectivement, j'ai enlevé tout cela et juste ajouté quelque chose qui fonctionnerait. – EpicPandaForce

+0

Regardons de plus près à ce demain au travail. Merci. –

3

Le problème est dans la déclaration de type variable:

class BaseFragment<P extends BasePresenter> 

BasePresenter est une classe générique, vous devez spécifier ce que son paramètre de type est. A partir de cet extrait:

mPresenter.attachView(this); 

Il semblerait que vous attendez BaseFragment à être lié au V de type variable BasePresenter - donc je réécrire votre déclaration de BaseFragment comme suit:

abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> { ... } 

Cela devrait prendre soin de l'avertissement non contrôlé. Cela dit, je soupçonne fortement que ce que vous êtes vraiment après quelque chose comme ceci:

abstract class BaseFragment<P extends BasePresenter<V>, V> { ... } 

Où V est une modélisation de type variable indépendante la « vue ».

+0

Je pourrais faire fonctionner votre première solution et je la comprends, mais cela semble trop compliqué. Au sujet du second, je ne pouvais pas le faire fonctionner. Pourriez-vous poster un exemple de travail basé sur mon code de question initiale? –

+1

Je suppose que vous devez vraiment réfléchir à la relation que vous voulez entre BaseFragment, BasePresenter et View. Est-ce qu'un BaseFragment peut être associé à un BasePresenter? Ou doit-il être un BasePresenter avec une vue spécifique? –

+0

Bonne question. Mais j'ai du mal à répondre avec un commentaire ... Par exemple, prenez l'exemple suivant (http://pastebin.com/MLwEczgK). Je veux fondamentalement déplacer la logique 'attachView (this)' et 'detachView()' vers 'BaseFragment' de sorte que chaque fragment prolongeant la base n'ait pas à se soucier de ça. J'aimerais aussi que 'BaseFragment' expose un champ' presenter' protégé qui représente chaque présentateur en fonction du fragment qui étend la base. Quelle est la meilleure façon d'y parvenir sans erreurs/avertissements? –