繁体   English   中英

在Flow中使用Dispatcher的正确方法?

[英]Proper way to use Dispatcher in Flow?

我有一个简单的两屏应用程序。 第一个屏幕为用户提供登录选项,第二个屏幕是用户在登录时看到内容的位置。

用户登录后,我用Flow.get( view ).set( Screens.CHAT )设置密钥。

一切都很好,但我遇到了一个问题,使我的观点看起来像这样:

在此处输入图片说明

当用户通过按下主屏幕按钮离开应用程序然后返回到应用程序时(基本上在onRestart( ) ),就会发生这种视图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逻辑中进行哪些更改,以防止相同的布局被夸大并再次添加?

问题是您的root ViewGroup没有被清除。

我相信这里的差异会解决您的问题( <删除, >添加)。

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

Flow回购提供了一个示例,示例非常接近您已有的示例

@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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM