【问题标题】:progressbar does not change visibility after orientation change方向改变后进度条不改变可见性
【发布时间】:2017-03-16 11:11:41
【问题描述】:

我已经被这个问题困扰了两天了,仍然不知道问题是什么。我正在观察活动的生命周期事件。我使用 combineLatest 将 rxLifecycle observable 与 test observable 结合起来。 combineResultObservable 在按钮点击后被订阅并显示一个progressBar。处理此 observable 后,不再显示进度条。 它工作正常。但是当屏幕方向改变时,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);

}
}

配置更改时保存Activity实例的Fragment 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);
}

如果有人想知道布局有问题 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

最后进度条仍然可见。请帮助我。

【问题讨论】:

    标签: android screen-orientation rx-android activity-lifecycle rx-java2


    【解决方案1】:

    您正面临这个问题,因为当方向更改时,android 系统会终止 Activity,如果您正在保存 Activity 状态(就像您所做的那样),您可以获得 Activity 数据。

    现在的问题是,当方向改变发生并且您在获得进度条的旧对象时保留活动状态。但是您正在为新对象设置可见性findViewById(R.id.progressBar).setVisibility(View.GONE);

    为进度条声明一个全局变量

    ProgressBar progressBar;
    

    现在在 onCreate 方法中初始化

    progressBar = findViewById(R.id.progressBar);
    

    现在根据您的条件设置此对象的可见性。

    希望这会对你有所帮助。

    【讨论】:

    • 我照你说的做了。但没有成功。 ProgressBar 仍然可见。我还将 progressBar 对象保存在片段中(这不好),但是这样做会使进度条在方向更改后立即消失,然后再释放组合可观察对象。
    猜你喜欢
    • 1970-01-01
    • 2021-09-03
    • 2013-07-30
    • 2016-07-20
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多