2017-11-14 31 views
11

मैं BaseFragment है। उदाहरण 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); 
     } 
} 

मैं प्रत्येक खंड और प्रस्तोता के जीवन चक्र तुल्यकालन कोड दोहरा बचना चाहते हैं। इसलिए मैं इस प्रक्रिया को BaseFragment में कार्यान्वित करना चाहता हूं। जावा में यह लाइन presenter.onAttachView(this); काम करती है लेकिन चेतावनी के साथ "अनचेक कॉल 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" 
    } 

//... 
} 

पर ऐसा करने की अनुमति नहीं देता है।

संपादित:

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) { 

     } 
} 

यहाँ पूरे परीक्षण कोड https://github.com/AlexNikolaTest/Test/tree/master/app/src/main/java/com/example/mytest

+0

क्या आप प्रस्तुतकर्ता से 'onAttachView' विधि दिखा सकते हैं? – OsipXD

उत्तर

3

शायद आप इसे इस

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() { 
    } 
} 
+0

मैं मूल प्रस्तुतकर्ता –

+0

क्षमा करें @AlexNik में दृश्य संलग्न करना चाहता हूं, मुझे लगता है कि मैं आपके प्रश्न के कुछ बिंदु छोड़ देता हूं। तो मैंने अभी अपना जवाब संपादित किया। मैंने कुछ हिस्सों को हटा दिया है, केवल 'अटैच व्यू' और 'डिटेच व्यू' शामिल है क्योंकि मुझे लगता है कि इन 2 विधियों में आप सबसे अधिक रुचि रखते हैं। –

+0

हाय @AlexNik बस उत्सुक है, क्या मेरा अद्यतन उत्तर आपकी मदद करता है? : डी –

3

आप इस तरह की कोशिश कर सकते कर सकते हैं, तो आप कर सकते हैं कोटलिन में अनचेक चेतावनी भी ;-)

if (presenter != null) { 
     val p = presenter as BasePresenter<BaseMvpView> 
     p.onAttachView(this) 
    } 

अपने MainFragment

syncLifeCycle(presenter as BasePresenter<BaseMvpView>) 

सुनिश्चित नहीं हैं कि अगर यह काम करता है, बस इंटेलीजे में थोड़ा के आसपास खेला। लेकिन चूंकि जनरेटिक्स संकलन के दौरान मिटा दिए जाते हैं और मुख्य प्रस्तुतकर्ता को बेसपेंडरर को कास्ट करना भी ठीक होना चाहिए, यह एक अच्छा मौका है।

5

मैं star-projectionBaseMvpView साथ की जगह में मदद मिलेगी

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) 
    } 

//... 
} 

कारण यह है कि Kotlin out और in प्रकार पैरामीटर (भी covariant और contravariant पैरामीटर प्रकार क्रमश: कहा जाता है) के बीच अलग करता है लगता है।

in प्रकार पैरामीटर राज्य है कि प्रकार पैरामीटर है, जबकि out प्रकार पैरामीटर राज्य है कि सामान्य वर्ग का उत्पादन करेगा के एक मूल्य भस्म सामान्य वर्ग, यानी द्वारा एक समारोह के एक पैरामीटर के रूप में प्रयोग की जाने वाली हो रहा है पास प्रकार पैरामीटर, यानी कुछ फ़ंक्शन के लिए रिटर्न प्रकार के रूप में उपयोग किया जाना है।

onAttachView(V mvpView) एक contravariant प्रकार पैरामीटर जिसका मतलब है कि यह V किसी भी प्रकार के बाद से आप लेने वाली कि मान रहे हैं (यह प्रकार BaseMvpView या एक उपवर्ग के हो गया है) की होने के लिए अनुमति नहीं है लेता है। यही है, अगर V पूरी तरह से अज्ञात था, तो हम V से BaseMvpView का उदाहरण होने की उम्मीद कर रहे हैं, इसलिए हम पैरामीटर को सुरक्षित रूप से पढ़ नहीं सकते हैं।हालांकि, अगर यह मामला था कि onAttachView का उत्पादन कर रहा है, यानी। लौटने, V ऑब्जेक्ट तब स्टार-प्रोजेक्शन काम करेगा।

आशा है कि इससे मदद मिलती है!

+0

उस स्थिति में मैं मेनफ्रेगमेंट से विधि सिंक लाइफसाइकल (प्रस्तुतकर्ता) को कॉल नहीं कर सकता (जेनेरिक प्रकार MainMvpView को बेसएमवीपी व्यू में नहीं डाला जा सकता है) –

संबंधित मुद्दे