0

我一直被這個問題困住了兩天,現在仍然不知道問題是什麼。我正在觀察活動的生命週期事件。我使用combineLatest將rxLifecycle observable和test observable結合起來。在按鈕單擊並顯示progressBar後,訂閱combinedResultObservable。在這個可觀察元素被處置後,進度條不再顯示。 它工作正常。但是,當屏幕方向更改時,即使日誌語句正確打印,progressBar也不會更改View.GONE的可見性。在代碼進度條在方向更改後不會改變可視性

.doOnDispose(() ->{ 
       progressBarIsShowing = false; 
       mRetainedFragment.setProgressBarIsShowing(progressBarIsShowing); 
       log("doondispose"); 
       findViewById(R.id.progressBar).setVisibility(View.GONE); 
       log("doondispose2"); 
      }) 

doondispose和doondispose2被正確打印,但其間 findViewById(R.id.progressBar).setVisibility(View.GONE)行通知;不管用。 請看看並幫我解決這個問題。

MainActivity.java

public class MainActivity extends AppCompatActivity implements LifeCycleEventListener { 


LifeCycleEventListener lifeCycleEventListener = this; 
private CombinedResult combinedResult; 
private ObservableEmitter<String> eventEmitter = new ObservableEmitter<String>() { 
    @Override 
    public void setDisposable(Disposable d) { 

    } 

    @Override 
    public void setCancellable(Cancellable c) { 

    } 

    @Override 
    public boolean isDisposed() { 
     return false; 
    } 

    @Override 
    public ObservableEmitter<String> serialize() { 
     return null; 
    } 

    @Override 
    public void onNext(@NonNull String value) { 

    } 

    @Override 
    public void onError(@NonNull Throwable error) { 

    } 

    @Override 
    public void onComplete() { 

    } 
}; 
private Observable<String> rxLifecycle = Observable.create(e -> { 
    e.onNext("onResume"); 
    eventEmitter = e; 
}); 

private Observable<Integer> test = Observable.create(e -> { 
    try { 
     e.onNext(-1); 
     for (int i = 0; i < 25; i++) { 
      Thread.sleep(500); 
      if (i == 24) { 
       e.onNext(i); 
      } 
     } 
     e.onComplete(); 
    } catch (Exception x) { 
     e.onError(x); 
    } 
}); 

private Disposable disposable; 
boolean progressBarIsShowing; 
private static final String TAG_RETAINED_FRAGMENT = "RetainedFragment"; 

private RetainedFragment mRetainedFragment; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    FragmentManager fm = getSupportFragmentManager(); 
    mRetainedFragment = (RetainedFragment) fm.findFragmentByTag(TAG_RETAINED_FRAGMENT); 

    if (mRetainedFragment == null) { 

     mRetainedFragment = new RetainedFragment(); 
     fm.beginTransaction().add(mRetainedFragment, TAG_RETAINED_FRAGMENT).commit(); 
     mRetainedFragment.setLifeCycleEventListener(lifeCycleEventListener); 
     mRetainedFragment.setEventEmitter(eventEmitter); 
     mRetainedFragment.setRxLifecycle(rxLifecycle); 
     if (progressBarIsShowing) { 
      findViewById(R.id.progressBar).setVisibility(View.VISIBLE); 
     } else { 
      findViewById(R.id.progressBar).setVisibility(View.GONE); 
     } 
    } else { 
     Log.e("myapp","dhukse"); 
     lifeCycleEventListener = mRetainedFragment.getLifeCycleEventListener(); 
     eventEmitter = mRetainedFragment.getEventEmitter(); 
     rxLifecycle = mRetainedFragment.getRxLifecycle(); 
     progressBarIsShowing = mRetainedFragment.isProgressBarIsShowing(); 
     disposable = mRetainedFragment.getDisposable(); 
     if (progressBarIsShowing) { 
      findViewById(R.id.progressBar).setVisibility(View.VISIBLE); 
     } else { 
      findViewById(R.id.progressBar).setVisibility(View.GONE); 
     } 
    } 


    Button button = (Button) findViewById(R.id.button); 
    button.setOnClickListener(v -> start()); 
    lifeCycleEventListener.emitEvent("onCreate"); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    lifeCycleEventListener.emitEvent("onStart"); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    lifeCycleEventListener.emitEvent("onResume"); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    lifeCycleEventListener.emitEvent("onPause"); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    lifeCycleEventListener.emitEvent("onStop"); 

} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    lifeCycleEventListener.emitEvent("onDestroy"); 
} 

@Override 
public void onBackPressed() { 
    if (!progressBarIsShowing) { 
     super.onBackPressed(); 
     FragmentManager fm = getSupportFragmentManager(); 
     fm.beginTransaction().remove(mRetainedFragment).commit(); 
    } 
    else{ 
     moveTaskToBack(true); 
    } 
} 

private void start() { 
    findViewById(R.id.progressBar).setVisibility(View.VISIBLE); 
    progressBarIsShowing = true; 
    mRetainedFragment.setProgressBarIsShowing(progressBarIsShowing); 

    Observable<CombinedResult> combinedResultObservable = Observable.combineLatest(rxLifecycle, test, this::getCombinedResult); 
    combinedResultObservable 
      .subscribeOn(Schedulers.io()) 
      .observeOn(Schedulers.io()) 
      .doOnNext(this::setResult) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .doOnDispose(() ->{ 
       progressBarIsShowing = false; 
       mRetainedFragment.setProgressBarIsShowing(progressBarIsShowing); 
       log("doondispose"); 
       findViewById(R.id.progressBar).setVisibility(View.GONE); 
       log("doondispose2"); 
      }) 
      .subscribe(new Observer<CombinedResult>() { 
       @Override 
       public void onSubscribe(Disposable d) { 

        disposable = d; 
        mRetainedFragment.setDisposable(disposable); 
       } 

       @Override 
       public void onNext(CombinedResult combinedResult) { 
        log(combinedResult.getLifeEvent() + ":" + combinedResult.getUser()); 
        if (combinedResult.getUser() == 24) { 
         progressBarIsShowing = false; 
         mRetainedFragment.setProgressBarIsShowing(progressBarIsShowing); 
         findViewById(R.id.progressBar).setVisibility(View.GONE); 
         checkResult(); 
         disposable.dispose(); 
        } 
       } 

       @Override 
       public void onError(Throwable e) { 
        progressBarIsShowing = false; 
        mRetainedFragment.setProgressBarIsShowing(progressBarIsShowing); 
        findViewById(R.id.progressBar).setVisibility(View.GONE); 
       } 

       @Override 
       public void onComplete() { 

       } 
      }); 


} 

private void checkResult() { 
    if (combinedResult.getUser() == 24) { 
     progressBarIsShowing = false; 
     mRetainedFragment.setProgressBarIsShowing(progressBarIsShowing); 
     findViewById(R.id.progressBar).setVisibility(View.GONE); 
     log("successful"); 
    } 
} 

private void setResult(CombinedResult combinedResult) { 
    this.combinedResult = combinedResult; 
} 

private class CombinedResult { 
    private String lifeEvent; 
    private Integer user; 

    CombinedResult(String lifeEvent, Integer user) { 
     this.lifeEvent = lifeEvent; 
     this.user = user; 
    } 

    String getLifeEvent() { 
     return lifeEvent; 
    } 

    Integer getUser() { 
     return user; 
    } 
} 

private CombinedResult getCombinedResult(String lifeEvent, Integer user) { 
    return new CombinedResult(lifeEvent, user); 
} 

private void log(String s) { 
    Log.e("myapp", s); 
} 

@Override 
public void emitEvent(String event) { 

    eventEmitter.onNext(event); 

} 
} 

在配置變化RetainedFragment.java的情況下節省活動實例

public class RetainedFragment extends Fragment { 


private LifeCycleEventListener lifeCycleEventListener; 
private ObservableEmitter<String> eventEmitter; 
private Observable<String> rxLifecycle; 
private boolean progressBarIsShowing; 
private Disposable disposable; 
public RetainedFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // retain this fragment 
    setRetainInstance(true); 
} 

public LifeCycleEventListener getLifeCycleEventListener() { 
    return lifeCycleEventListener; 
} 

public void setLifeCycleEventListener(LifeCycleEventListener lifeCycleEventListener) { 
    this.lifeCycleEventListener = lifeCycleEventListener; 
} 

public ObservableEmitter<String> getEventEmitter() { 
    return eventEmitter; 
} 

public void setEventEmitter(ObservableEmitter<String> eventEmitter) { 
    this.eventEmitter = eventEmitter; 
} 

public boolean isProgressBarIsShowing() { 
    return progressBarIsShowing; 
} 

public void setProgressBarIsShowing(boolean progressBarIsShowing) { 
    this.progressBarIsShowing = progressBarIsShowing; 
} 

public Observable<String> getRxLifecycle() { 
    return rxLifecycle; 
} 

public void setRxLifecycle(Observable<String> rxLifecycle) { 
    this.rxLifecycle = rxLifecycle; 
} 

public Disposable getDisposable() { 
    return disposable; 
} 

public void setDisposable(Disposable disposable) { 
    this.disposable = disposable; 
} 
} 

接口生命週期變化LifeCycleEventListener.java

public interface LifeCycleEventListener { 
void emitEvent(String event); 
} 

在片段任何人都想知道th有什麼問題È佈局 activity_main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/activity_main" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context="com.example.fahim.rxlifecycle.MainActivity"> 

<Button 
    android:text="@string/start" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentStart="true" 
    android:layout_marginStart="109dp" 
    android:layout_marginTop="35dp" 
    android:id="@+id/button" /> 

<ProgressBar 
    style="?android:attr/progressBarStyle" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/progressBar" 
    android:layout_marginStart="44dp" 
    android:layout_alignTop="@+id/button" 
    android:layout_toEndOf="@+id/button" 
    android:visibility="gone"/> 
</RelativeLayout> 

的logcat的按下按鈕後

E/myapp: onResume:-1 

E/myapp: dhukse 
E/myapp: onPause:-1 
E/myapp: onStop:-1 
E/myapp: onDestroy:-1 
E/myapp: onCreate:-1 
E/myapp: onStart:-1 
E/myapp: onResume:-1 
E/myapp: onResume:24 
E/myapp: successful 

(處置後)

E/myapp: doondispose 
E/myapp: doondispose2 

在(改變取向之後) Ë nd進度條仍然可見。請幫助我一個人。

回答

0

你面臨這個問題,因爲當方向改變android系統殺死活動,並且如果你保存活動狀態(就像你這樣做),你可以得到活動數據。

現在的問題是當方向改變發生時,你正在保存活動狀態,當你獲得進度條的老對象時。但你在新的對象findViewById(R.id.progressBar).setVisibility(View.GONE);

設置公開程度根據你的條件,申報進度條全球varaible

ProgressBar progressBar; 

現在initaliize在onCreate方法

progressBar = findViewById(R.id.progressBar); 

現在設置可見此對象。

希望這會幫助你。

+0

我照你說的去做了。但沒有成功。 ProgressBar仍然可見。我還將progressBar對象保存在fragment中(這不太好),但是這樣做使得在組合observable被處置之前進度條在方向更改後立即消失。 –