2016-03-04 49 views
0

我有一個簡單的兩個屏幕的應用程序。第一個屏幕向用戶顯示登錄選項,第二個屏幕是他們在登錄時看到內容的位置。在Flow中使用Dispatcher的正確方法?

一旦用戶登錄,我將密鑰設置爲Flow.get(view).set(Screens.CHAT)

一切都很好,很正常,但我碰上,使我的看法是這樣的一個問題:

enter image description here

當用戶通過按下home鍵離開應用程序的視圖這種重新繪製發生和然後回到它(基本上在onRestart()之後)。未填充的RecyclerView將再次添加到視圖層次結構中。

Dispatcher邏輯是這樣的:

public void dispatch(Traversal traversal, TraversalCallback callback) { 
    Object dest = traversal.destination.top(); 
    Object source = traversal.origin == null ? null : traversal.origin.top(); 

    ViewGroup root = (ViewGroup) activity.findViewById(R.id.root); 

    if (traversal.origin != null) { 
     int childCount = root.getChildCount(); 
     // Our container has a root view with an ImageView in it. 
     // If child count > 1, we need to remove the child at position = 1 
     // because ImageView is at position = 0 
     if (childCount > 1) { 
      // save state 
      traversal.getState(traversal.origin.top()).save(root.getChildAt(1)); 
      // remove the added views 
      removeAllViewsAfter(root,0); 
     } 
    } 

    @LayoutRes int layout; 
    if(dest.equals(Screens.WELCOME)){ 
     layout = R.layout.view_welcome; 
    }else if(dest.equals(Screens.CHAT)){ 
     layout = R.layout.view_chat; 
    }else{ 
     throw new IllegalArgumentException("Unrecognized Screen"); 
    } 

    View incomingView = LayoutInflater 
      .from(traversal.createContext(dest, activity)) 
      .inflate(layout, root, false); 
    traversal.getState(traversal.destination.top()).restore(incomingView); 
    root.addView(incomingView); 
    callback.onTraversalCompleted(); 
} 
//---------------------------------------------------------------------------------------------- 
private void removeAllViewsAfter(ViewGroup root, int index){ 
    for(int i = root.getChildCount() - 1; i > index; i--){ 
     root.removeViewAt(i); 
    } 
} 
//---------------------------------------------------------------------------------------------- 

什麼我在Dispatcher邏輯,以避免被誇大了相同的佈局改變並重新添加?

回答

0

問題是您的rootViewGroup沒有得到清除。

這裏的差異,我相信會解決您的問題(<刪除,>添加)。

12c12 
<   if (childCount > 1) { 
--- 
>   if (childCount > 0) { 
14c14 
<    traversal.getState(traversal.origin.top()).save(root.getChildAt(1)); 
--- 
>    traversal.getState(traversal.origin.top()).save(root.getChildAt(0)); 
16c16 
<    removeAllViewsAfter(root,0); 
--- 
>    frame.removeAllViews(); 
36,42d35 
< //---------------------------------------------------------------------------------------------- 
< private void removeAllViewsAfter(ViewGroup root, int index){ 
<  for(int i = root.getChildCount() - 1; i > index; i--){ 
<   root.removeViewAt(i); 
<  } 
< } 
< //---------------------------------------------------------------------------------------------- 

流回購有一個example with something pretty close你已經有。

@Override 
public void dispatch(@NonNull Traversal traversal, @NonNull TraversalCallback callback) { 
    Log.d("BasicDispatcher", "dispatching " + traversal); 
    Object destKey = traversal.destination.top(); 

    ViewGroup frame = (ViewGroup) activity.findViewById(R.id.basic_activity_frame); 

    // We're already showing something, clean it up. 
    if (frame.getChildCount() > 0) { 
    final View currentView = frame.getChildAt(0); 

    // Save the outgoing view state. 
    if (traversal.origin != null) { 
     traversal.getState(traversal.origin.top()).save(currentView); 
    } 

    // Short circuit if we would just be showing the same view again. 
    final Object currentKey = Flow.getKey(currentView); 
    if (destKey.equals(currentKey)) { 
     callback.onTraversalCompleted(); 
     return; 
    } 

    frame.removeAllViews(); 
    } 

    @LayoutRes final int layout; 
    if (destKey instanceof HelloScreen) { 
    layout = R.layout.hello_screen; 
    } else if (destKey instanceof WelcomeScreen) { 
    layout = R.layout.welcome_screen; 
    } else { 
    throw new AssertionError("Unrecognized screen " + destKey); 
    } 

    View incomingView = LayoutInflater.from(traversal.createContext(destKey, activity)) // 
     .inflate(layout, frame, false); 

    frame.addView(incomingView); 
    traversal.getState(traversal.destination.top()).restore(incomingView); 

    callback.onTraversalCompleted(); 
} 
相關問題