2017-12-08 7 views
0

Ich versuche, eine MVP Android Ansicht (nicht-Aktivität oder ein Fragment) mit Mosby jedoch zu implementieren, wenn der Ansicht in einem Android-Adapter verwenden, und es innerhalb eines onBindViewHolder zugreifen, ist der Moderator zu diesem Zeitpunkt nicht initialisiert. Offenbar wird das onAttachWindow erst aufgerufen, nachdem der onBindViewHolder abgeschlossen ist, da der Moderator Null ist. Hier ist die abstrakte Klasse, die ich erstellt habe.Implementierung nicht Viewgroup MVP Android View mit Mosby

public abstract class MvpImageView<V extends MvpView, P extends MvpPresenter<V>> 
    extends AppCompatImageView implements MvpView, ViewGroupDelegateCallback<V, P> { 

    protected P presenter; 
    protected ViewGroupMvpDelegate<V, P> mvpDelegate; 
    private boolean retainInstance = false; 

    public MvpImageView(Context context) { 
    super(context); 
    } 

    public MvpImageView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    } 

    public MvpImageView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    } 

    /** 
    * Get the mvp delegate. This is internally used for creating presenter, attaching and detaching 
    * view from presenter etc. 
    * 
    * <p><b>Please note that only one instance of mvp delegate should be used per android.view.View 
    * instance</b>. 
    * </p> 
    * 
    * <p> 
    * Only override this method if you really know what you are doing. 
    * </p> 
    * 
    * @return {@link ViewGroupMvpDelegate} 
    */ 
    @NonNull protected ViewGroupMvpDelegate<V, P> getMvpDelegate() { 
    if (mvpDelegate == null) { 
     mvpDelegate = new ViewGroupMvpDelegateImpl<>(this, this, true); 
    } 

    return mvpDelegate; 
    } 

    @Override protected void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    Log.d(getClass().getName(), "Attaching to Window"); 
    getMvpDelegate().onAttachedToWindow(); 
    } 

    @Override protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 
    Log.d(getClass().getName(), "Detaching from Window"); 
    getMvpDelegate().onDetachedFromWindow(); 
    } 

    @SuppressLint("MissingSuperCall") @Override protected Parcelable onSaveInstanceState() { 
    return getMvpDelegate().onSaveInstanceState(); 
    } 

    @SuppressLint("MissingSuperCall") @Override 
    protected void onRestoreInstanceState(Parcelable state) { 
    getMvpDelegate().onRestoreInstanceState(state); 
    } 

    /** 
    * Instantiate a presenter instance 
    * 
    * @return The {@link MvpPresenter} for this view 
    */ 
    public abstract P createPresenter(); 

    @Override public P getPresenter() { 
    return presenter; 
    } 

    @Override public void setPresenter(P presenter) { 
    this.presenter = presenter; 
    } 

    @Override public V getMvpView() { 
    return (V) this; 
    } 

    @Override public final Parcelable superOnSaveInstanceState() { 
    return super.onSaveInstanceState(); 
    } 

    @Override public final void superOnRestoreInstanceState(Parcelable state) { 
    super.onRestoreInstanceState(state); 
    } 
} 

Dies basiert auf der Implementierung von MvpLinearLayout. Ich habe eine andere MVP-Bibliothek in der Vergangenheit genannt Moxy verwendet und es hatte Delegatmethoden für onCreate sowie onAttachToWindow.

Ich könnte eine Initialisierungsroutine hinzufügen, die getMvpDelegate() .AttachWindow in den Konstruktoren aufrufen, aber das scheint mehr wie ein Hack als alles andere. Irgendwelche Ideen, wie man das funktioniert, wenn es in einem onBindViewHolder und RecyclerView verwendet wird?

Antwort

0

Sie MVP in Ihrem Adapter verwenden. Es macht die Dinge nur kompliziert und umständlich zu arbeiten.

Beispiel: Views/ViewHolder recycelt werden kann, sollte Presenter auch recycelt werden? Wenn ja, wie implementieren Sie das und stellen Sie sicher, dass der interne Presenter frisch ist? Wie binden Sie Presenter wieder an, während Sie scrollen? Was passiert, wenn Ihr AdapterSet geändert wird? Was ist mit Bildschirmausrichtung Änderungen?

einfach nicht tun.

+0

So mosby mvp mit Blick verwendet werden, es sei denn, er hat die Ansicht in einem einem RecyclerView oder einem Adapter aufgenommen werden. Ich würde sagen, wenn ein View oder ViewHolder recycelt wird, dann wird ein Presenter zu diesem Zeitpunkt ebenfalls neu erstellt. Ein anderer Ansatz scheint hier mit dem ViewHolder-Handling skizziert zu sein, https://android.jlelse.eu/recyclerview-in-mvp-passive-views-approach-8dd74633158 – kingargyle

+0

In der Theorie kann es auch in RecyclerView verwendet werden, aber der "Lebenszyklus" "einer View (onAttachToWindow() und onDetachToWindow()) unterscheiden sich von dem, was Sie erwarten, weil Sie über ViewHolder" lifecycle "(onBindViewHolder() und onRecycleViewHolder() oder etwas wie diesen) im Vergleich zu View später oder früher aufgerufen werden Lebensdauer Also, wenn Sie wirklich die MVP-Sache in einem RecyclerView tun wollen (ich denke, es ist ein großer Fehler) sollten Sie Ihre eigene Sache schreiben, die "ViewHolder Lebenszyklus" statt View Lifecycle – sockeqwe

+0

Ich denke nur an sagen Einkaufswagen-Anwendung, wo Sie eine Ansicht innerhalb des Einkaufswagens haben können, die mehr als ein einfaches Display sein muss, aber etwas Interaktivität benötigt und dynamische Aktualisierung benötigt. Vielleicht werde ich einen Blick darauf werfen, wenn das so ist, kann ich immer eine Pull-Anfrage für eine mögliche Aufnahme in das Projekt einreichen. Es kann am Ende eine MvpRecyclerView oder etwas ähnliches sein. – kingargyle

Verwandte Themen