[英]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 );
< }
< }
< //----------------------------------------------------------------------------------------------
@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.