2017-01-05 12 views
1

Я уже искал много ответов здесь об этой проблеме, но для жизни меня я не могу решить эту проблему на моем конце, и мне нужна помощь.Как исправить «непроверенный вызов« attachView (V) »в качестве элемента исходного типа« BasePresenter »?

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

Вы можете посмотреть на этом примере проекта http://github.com/mmirhoseini/marvel и эта статья может https://hackernoon.com/yet- another-mvp-article-part-1-lets-get-to-know-the-project-d3fd553b3e21, чтобы лучше узнать MVP. –

ответ

1

Простой, вместо

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

Это должно быть

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

или

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

или

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

В принципе, убедитесь, что BasePresenter параметризуется чем-то.




EDIT:

Хорошо, основываясь на том, что вы на самом деле пытаетесь сделать, вы должны сделать это следующим образом:

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: На основании предоставленной например:

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

Не могли бы вы прояснить это? Хотя, если вы прикрепляете фрагмент как представление, тогда он должен реализовать интерфейс, который делает его видным. "? –

+1

На самом деле, я удалил все это и добавил что-то, что сработает. – EpicPandaForce

+0

Позаботьтесь об этом завтра на работе. Благодарю. –

3

Проблема заключается в объявлении типа переменный:

class BaseFragment<P extends BasePresenter> 

BasePresenter это общий класс, так что вы должны указать, что его параметр типа. Из этого фрагмента:

mPresenter.attachView(this); 

Казалось бы, что вы ожидаете BaseFragment быть связан с типом переменной V в BasePresenter - так что я бы переписать декларацию BaseFragment следующим образом:

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

Это должно принять уход за непроверенным предупреждением. Тем не менее, я сильно подозреваю, что вы на самом деле после того, как что-то вроде этого:

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

где V представляет самостоятельный тип переменной, моделирующей «вид».

+0

Я мог бы сделать ваше первое решение работающим, и я это понимаю, но кажется слишком сложным. О втором я не мог заставить его работать. Не могли бы вы разместить рабочий пример на основе моего исходного кода вопроса? –

+1

Думаю, вам действительно нужно подумать о том, какие отношения вам нужны между BaseFragment, BasePresenter и View. Может ли BaseFragment ассоциироваться с любым BasePresenter? Или это должен быть BasePresenter с конкретным представлением? –

+0

Хороший вопрос. Но мне сложно ответить с комментарием ... Например, возьмите следующий [пример] (http://pastebin.com/MLwEczgK). Я в основном хочу переместить логику 'attachView (this)' и 'detachView()' в 'BaseFragment', так что каждый фрагмент, расширяющий базовый, не должен беспокоиться об этом. Я также хотел бы, чтобы «BaseFragment» открывал защищенное поле «ведущий», которое представляет каждого ведущего в соответствии с фрагментом, который расширяет базовый. Каков наилучший способ достичь этого без каких-либо ошибок/предупреждений? –