Fix the flickering on display/font size page
In framework design, framework needs to have a snapshot when there's a config change event since redrawing window takes some time. Flickering problem is caused by the timing issue between the snapshot mechinsm and local preview update. User can observe the flickering problem if config commit()-> snapshot in framework(old screenshot) -> app update the preview -> snapshot(old screen) fade out. To prevent this problem, we make sure that we update the local preview first and then we do the commit later. In this proposal, snapshot action is able to get the new snaptshot for the new preview. So, the core workaround is commitOnNextFrame, we ask a delay before we submit the commit(). Note: It doesn't matter that we use Choreographer or main thread handler since the delay time is longer than 1 frame. Use Choreographer to let developer understand it's a window update. Fix: 148192402 Test: manual test Change-Id: I9bfc5eb39e7a9ebce2fe1414d6f0a9dd470708e8
This commit is contained in:
@@ -19,6 +19,8 @@ package com.android.settings.display;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.view.Choreographer;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -58,14 +60,35 @@ public abstract class PreviewSeekBarPreferenceFragment extends SettingsPreferenc
|
||||
private View mLarger;
|
||||
private View mSmaller;
|
||||
|
||||
private static final long MIN_COMMIT_INTERVAL_MS = 800;
|
||||
private long mLastCommitTime;
|
||||
|
||||
private class onPreviewSeekBarChangeListener implements OnSeekBarChangeListener {
|
||||
private static final long CHANGE_BY_SEEKBAR_DELAY_MS = 100;
|
||||
private static final long CHANGE_BY_BUTTON_DELAY_MS = 300;
|
||||
|
||||
private boolean mSeekByTouch;
|
||||
private boolean mIsChanged;
|
||||
private long mCommitDelayMs;
|
||||
|
||||
private final Choreographer.FrameCallback mCommit = f -> {
|
||||
commit();
|
||||
mLastCommitTime = SystemClock.elapsedRealtime();
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (mCurrentIndex == progress) {
|
||||
mIsChanged = false;
|
||||
return;
|
||||
}
|
||||
mIsChanged = true;
|
||||
setPreviewLayer(progress, false);
|
||||
if (!mSeekByTouch) {
|
||||
commit();
|
||||
if (mSeekByTouch) {
|
||||
mCommitDelayMs = CHANGE_BY_SEEKBAR_DELAY_MS;
|
||||
} else {
|
||||
mCommitDelayMs = CHANGE_BY_BUTTON_DELAY_MS;
|
||||
commitOnNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,18 +99,39 @@ public abstract class PreviewSeekBarPreferenceFragment extends SettingsPreferenc
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
if (mPreviewPagerAdapter.isAnimating()) {
|
||||
mPreviewPagerAdapter.setAnimationEndAction(() -> commit());
|
||||
} else {
|
||||
commit();
|
||||
}
|
||||
mSeekByTouch = false;
|
||||
if (!mIsChanged) {
|
||||
return;
|
||||
}
|
||||
if (mPreviewPagerAdapter.isAnimating()) {
|
||||
mPreviewPagerAdapter.setAnimationEndAction(this::commitOnNextFrame);
|
||||
} else {
|
||||
commitOnNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void commitOnNextFrame() {
|
||||
if (SystemClock.elapsedRealtime() - mLastCommitTime < MIN_COMMIT_INTERVAL_MS) {
|
||||
mCommitDelayMs += MIN_COMMIT_INTERVAL_MS;
|
||||
}
|
||||
final Choreographer choreographer = Choreographer.getInstance();
|
||||
choreographer.removeFrameCallback(mCommit);
|
||||
choreographer.postFrameCallbackDelayed(mCommit, mCommitDelayMs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putLong("mLastCommitTime", mLastCommitTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
mLastCommitTime = savedInstanceState.getLong("mLastCommitTime");
|
||||
}
|
||||
final View root = super.onCreateView(inflater, container, savedInstanceState);
|
||||
final ViewGroup listContainer = root.findViewById(android.R.id.list_container);
|
||||
listContainer.removeAllViews();
|
||||
@@ -240,4 +284,4 @@ public abstract class PreviewSeekBarPreferenceFragment extends SettingsPreferenc
|
||||
setPagerIndicatorContentDescription(position);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user