Ale*_*Nik 11 generics android kotlin
我有BaseFragment:
public abstract class BaseFragment extends Fragment implements BaseMvpView {
private BasePresenter presenter;
protected void syncLifeCycle(BasePresenter presenter) {
this.presenter = presenter;
this.presenter.onCreate();
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//noinspection unchecked
presenter.onAttachView(this); //it works with a warning
}
@Override
public void onResume() {
super.onResume();
presenter.onResume();
}
@Override
public void onPause() {
super.onPause();
presenter.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
presenter.onDetachView();
}
@Override
public void onDestroy() {
super.onDestroy();
presenter.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
presenter.onActivityResult(requestCode, resultCode, data);
}
}
Run Code Online (Sandbox Code Playgroud)
以及许多扩展它的类.例如MainFragment:
public class MainFragment extends BaseFragment implements MainMvpView {
MainPresenter<MainMvpView> presenter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
syncLifeCycle(presenter);
//presenter.onCreate();
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//presenter.onAttachView(this);
}
@Override
public void onResume() {
super.onResume();
//presenter.onResume();
}
@Override
public void onPause() {
super.onPause();
//presenter.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
//presenter.onDetachView();
}
@Override
public void onDestroy() {
super.onDestroy();
//presenter.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//presenter.onActivityResult(requestCode, resultCode, data);
}
}
Run Code Online (Sandbox Code Playgroud)
我想避免重复每个片段和演示者的生命周期同步代码.因此我想在中实现这个过程BaseFragment.在Java中,这一行presenter.onAttachView(this);可以正常工作但有一个警告"Unchecked call onAttachView(V)"(我可以忍受这个).但是Kotlin根本不允许我这样做
abstract class BaseFragmentKotlin : Fragment(), BaseMvpView {
private var presenter: BasePresenter<*>? = null
//...
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter?.onAttachView(this) //Does not work. "Out-projected type 'BasePresenter<*>?' prohibits the use of 'public abstract fun onAttachView(mvpView: V!): Unit defined in com.example.test.BasePresenter"
}
//...
}
Run Code Online (Sandbox Code Playgroud)
我真的需要有关如何正确执行此操作的建议.
编辑:
public class BasePresenterImpl<V extends BaseMvpView> implements BasePresenter<V> {
@Nullable
public V mvpView;
@Override
public void onCreate() {
}
@Override
public void onAttachView(V mvpView) {
this.mvpView = mvpView;
}
@Override
public void onResume() {
}
@Override
public void onPause() {
}
@Override
public void onDetachView() {
mvpView = null;
}
@Override
public void onDestroy() {
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
Run Code Online (Sandbox Code Playgroud)
以下是整个测试代码https://github.com/AlexNikolaTest/Test/tree/master/app/src/main/java/com/example/mytest
我想更换星级投影与BaseMvpView将帮助
abstract class BaseFragmentKotlin : Fragment(), BaseMvpView {
private var presenter: BasePresenter<BaseMvpView>? = null
//...
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter?.onAttachView(this)
}
//...
}
Run Code Online (Sandbox Code Playgroud)
原因是Kotlin区分out和in类型参数(也分别称为协变和逆变参数类型).
in类型参数指出的类型参数是将要消耗由通用类,即,将用作的功能的参数,而out类型参数指出的一般类将产生传递型参数的值,即,将被用作一个某些功能的返回类型.
的onAttachView(V mvpView)需要,这意味着它不允许用于逆变型参数V是任何类型(它必须是类型的BaseMvpView或子类),因为你正在消耗该值.也就是说,如果V完全未知,我们无法安全地读取参数,因为V预期是一个实例BaseMvpView.然而,如果onAttachView是生产的情况,即返回,则V物体然后星形投影将起作用.
希望这可以帮助!
也许你可以这样做
interface IView
interface IPresenter {
fun attachView(v: IView)
fun detachView()
}
abstract class BasePresenter<V :IView> : IPresenter {
protected var view: V? = null
override fun attachView(v: IView) {
this.view = v as V
}
override fun detachView() {
view = null
}
}
abstract class BaseFragment<P : IPresenter> : Fragment(), IView {
protected lateinit var presenter: P
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.attachView(this)
}
override fun onDestroyView() {
super.onDestroyView()
presenter.detachView()
}
}
interface TestView : IView {
fun doSomething()
}
interface TestPresenter : IPresenter {
fun doSomething()
}
class TestPresenterImpl : BasePresenter<TestView>(), TestPresenter {
override fun doSomething() {
}
}
class TestFragment : BaseFragment<TestPresenter>(), TestView {
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter = TestPresenterImpl()
presenter.doSomething()
}
override fun doSomething() {
}
}
Run Code Online (Sandbox Code Playgroud)