mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-05-04 20:30:36 +00:00
Merge pull request #458 from alexbakker/respect-anim-settings
Respect the global animator duration scale setting
This commit is contained in:
commit
49c8c2d57d
10 changed files with 102 additions and 103 deletions
|
@ -1,10 +1,8 @@
|
||||||
package com.beemdevelopment.aegis.ui;
|
package com.beemdevelopment.aegis.ui;
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
@ -47,9 +45,6 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply a dirty hack to make progress bars work even if animations are disabled
|
|
||||||
setGlobalAnimationDurationScale();
|
|
||||||
|
|
||||||
// register a callback to listen for lock events
|
// register a callback to listen for lock events
|
||||||
_app.registerLockListener(this);
|
_app.registerLockListener(this);
|
||||||
}
|
}
|
||||||
|
@ -152,17 +147,6 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp
|
||||||
return !(this instanceof MainActivity) && _app.isVaultLocked();
|
return !(this instanceof MainActivity) && _app.isVaultLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setGlobalAnimationDurationScale() {
|
|
||||||
float durationScale = Settings.Global.getFloat(getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 0);
|
|
||||||
if (durationScale != 1) {
|
|
||||||
try {
|
|
||||||
ValueAnimator.class.getMethod("setDurationScale", float.class).invoke(null, 1f);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
Toast.makeText(this, R.string.progressbar_error, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Theme getCurrentTheme() {
|
protected Theme getCurrentTheme() {
|
||||||
return _currentTheme;
|
return _currentTheme;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
} else {
|
} else {
|
||||||
for (EntryHolder holder : _holders) {
|
for (EntryHolder holder : _holders) {
|
||||||
holder.refreshCode();
|
holder.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private boolean _hidden;
|
private boolean _hidden;
|
||||||
|
|
||||||
private PeriodProgressBar _progressBar;
|
private TotpProgressBar _progressBar;
|
||||||
private View _view;
|
private View _view;
|
||||||
|
|
||||||
private UiRefresher _refresher;
|
private UiRefresher _refresher;
|
||||||
|
@ -84,8 +84,6 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
if (!_hidden) {
|
if (!_hidden) {
|
||||||
refreshCode();
|
refreshCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
_progressBar.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,10 +197,17 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
public void startRefreshLoop() {
|
public void startRefreshLoop() {
|
||||||
_refresher.start();
|
_refresher.start();
|
||||||
|
_progressBar.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopRefreshLoop() {
|
public void stopRefreshLoop() {
|
||||||
_refresher.stop();
|
_refresher.stop();
|
||||||
|
_progressBar.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
|
_progressBar.restart();
|
||||||
|
refreshCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshCode() {
|
public void refreshCode() {
|
||||||
|
|
|
@ -23,8 +23,6 @@ import com.beemdevelopment.aegis.R;
|
||||||
import com.beemdevelopment.aegis.SortCategory;
|
import com.beemdevelopment.aegis.SortCategory;
|
||||||
import com.beemdevelopment.aegis.ViewMode;
|
import com.beemdevelopment.aegis.ViewMode;
|
||||||
import com.beemdevelopment.aegis.helpers.SimpleItemTouchHelperCallback;
|
import com.beemdevelopment.aegis.helpers.SimpleItemTouchHelperCallback;
|
||||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.ListPreloader;
|
import com.bumptech.glide.ListPreloader;
|
||||||
|
@ -46,13 +44,11 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
private RecyclerView _recyclerView;
|
private RecyclerView _recyclerView;
|
||||||
private RecyclerView.ItemDecoration _dividerDecoration;
|
private RecyclerView.ItemDecoration _dividerDecoration;
|
||||||
private ViewPreloadSizeProvider<VaultEntry> _preloadSizeProvider;
|
private ViewPreloadSizeProvider<VaultEntry> _preloadSizeProvider;
|
||||||
private PeriodProgressBar _progressBar;
|
private TotpProgressBar _progressBar;
|
||||||
private boolean _showProgress;
|
private boolean _showProgress;
|
||||||
private ViewMode _viewMode;
|
private ViewMode _viewMode;
|
||||||
private LinearLayout _emptyStateView;
|
private LinearLayout _emptyStateView;
|
||||||
|
|
||||||
private UiRefresher _refresher;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -97,19 +93,6 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
int resId = R.anim.layout_animation_fall_down;
|
int resId = R.anim.layout_animation_fall_down;
|
||||||
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(getContext(), resId);
|
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(getContext(), resId);
|
||||||
_recyclerView.setLayoutAnimation(animation);
|
_recyclerView.setLayoutAnimation(animation);
|
||||||
|
|
||||||
_refresher = new UiRefresher(new UiRefresher.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onRefresh() {
|
|
||||||
refresh(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getMillisTillNextRefresh() {
|
|
||||||
return TotpInfo.getMillisTillNextRotation(_adapter.getMostFrequentPeriod());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_emptyStateView = view.findViewById(R.id.vEmptyList);
|
_emptyStateView = view.findViewById(R.id.vEmptyList);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -121,7 +104,6 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
_refresher.destroy();
|
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +157,9 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
|
|
||||||
public void refresh(boolean hard) {
|
public void refresh(boolean hard) {
|
||||||
if (_showProgress) {
|
if (_showProgress) {
|
||||||
_progressBar.refresh();
|
_progressBar.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
_adapter.refresh(hard);
|
_adapter.refresh(hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,13 +207,12 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
public void onPeriodUniformityChanged(boolean isUniform, int period) {
|
public void onPeriodUniformityChanged(boolean isUniform, int period) {
|
||||||
setShowProgress(isUniform);
|
setShowProgress(isUniform);
|
||||||
if (_showProgress) {
|
if (_showProgress) {
|
||||||
_refresher.stop();
|
|
||||||
_progressBar.setVisibility(View.VISIBLE);
|
_progressBar.setVisibility(View.VISIBLE);
|
||||||
_progressBar.setPeriod(period);
|
_progressBar.setPeriod(period);
|
||||||
_refresher.start();
|
_progressBar.start();
|
||||||
} else {
|
} else {
|
||||||
_progressBar.setVisibility(View.GONE);
|
_progressBar.setVisibility(View.GONE);
|
||||||
_refresher.stop();
|
_progressBar.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package com.beemdevelopment.aegis.ui.views;
|
|
||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.animation.LinearInterpolator;
|
|
||||||
import android.widget.ProgressBar;
|
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
|
|
||||||
public class PeriodProgressBar extends ProgressBar {
|
|
||||||
private int _period;
|
|
||||||
|
|
||||||
public PeriodProgressBar(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PeriodProgressBar(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PeriodProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public PeriodProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPeriod(int period) {
|
|
||||||
_period = period;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh() {
|
|
||||||
// reset the progress bar
|
|
||||||
int maxProgress = getMax();
|
|
||||||
setProgress(maxProgress);
|
|
||||||
|
|
||||||
// calculate the progress the bar should start at
|
|
||||||
long millisTillRotation = TotpInfo.getMillisTillNextRotation(_period);
|
|
||||||
long period = _period * maxProgress;
|
|
||||||
int currentProgress = maxProgress - (int) ((((double) period - millisTillRotation) / period) * maxProgress);
|
|
||||||
|
|
||||||
// start progress animation
|
|
||||||
ObjectAnimator animation = ObjectAnimator.ofInt(this, "progress", currentProgress, 0);
|
|
||||||
animation.setDuration(millisTillRotation);
|
|
||||||
animation.setInterpolator(new LinearInterpolator());
|
|
||||||
animation.start();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.beemdevelopment.aegis.ui.views;
|
||||||
|
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
|
|
||||||
|
public class TotpProgressBar extends ProgressBar {
|
||||||
|
private int _period = 30;
|
||||||
|
private Handler _handler;
|
||||||
|
private float _animDurationScale;
|
||||||
|
|
||||||
|
public TotpProgressBar(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TotpProgressBar(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TotpProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public TotpProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeriod(int period) {
|
||||||
|
_period = period;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
stop();
|
||||||
|
_handler = new Handler();
|
||||||
|
_animDurationScale = Settings.Global.getFloat(getContext().getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (_handler != null) {
|
||||||
|
_handler.removeCallbacksAndMessages(null);
|
||||||
|
_handler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restart() {
|
||||||
|
stop();
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refresh() {
|
||||||
|
// calculate the current progress the bar should start at
|
||||||
|
int maxProgress = getMax();
|
||||||
|
long millisTillRotation = TotpInfo.getMillisTillNextRotation(_period);
|
||||||
|
int currentProgress = (int) (maxProgress * ((float) millisTillRotation / (_period * 1000)));
|
||||||
|
|
||||||
|
// start progress animation, compensating for any changes to the animator duration scale settings
|
||||||
|
int animPart = maxProgress / _period;
|
||||||
|
int animEnd = (currentProgress / animPart) * animPart;
|
||||||
|
int animPartDuration = (int) (1000 / _animDurationScale);
|
||||||
|
float animDurationFraction = (float) (currentProgress - animEnd) / animPart;
|
||||||
|
int realAnimDuration = (int) (1000 * animDurationFraction);
|
||||||
|
int animDuration = (int) (animPartDuration * animDurationFraction);
|
||||||
|
ObjectAnimator animation = ObjectAnimator.ofInt(this, "progress", currentProgress, animEnd);
|
||||||
|
animation.setDuration(animDuration);
|
||||||
|
animation.setInterpolator(new LinearInterpolator());
|
||||||
|
animation.start();
|
||||||
|
|
||||||
|
// the animation only lasts for (less than) one second, so restart it after that
|
||||||
|
_handler.postDelayed(this::refresh, realAnimDuration);
|
||||||
|
}
|
||||||
|
}
|
|
@ -152,12 +152,12 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.beemdevelopment.aegis.ui.views.PeriodProgressBar
|
<com.beemdevelopment.aegis.ui.views.TotpProgressBar
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="4dp"
|
android:layout_height="4dp"
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:max="1000"
|
android:max="5000"
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.beemdevelopment.aegis.ui.views.PeriodProgressBar
|
<com.beemdevelopment.aegis.ui.views.TotpProgressBar
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="3dp"
|
android:layout_height="3dp"
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.beemdevelopment.aegis.ui.views.PeriodProgressBar
|
<com.beemdevelopment.aegis.ui.views.TotpProgressBar
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="3dp"
|
android:layout_height="3dp"
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
android:background="?attr/background"
|
android:background="?attr/background"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.beemdevelopment.aegis.ui.views.PeriodProgressBar
|
<com.beemdevelopment.aegis.ui.views.TotpProgressBar
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="4dp"
|
android:layout_height="4dp"
|
||||||
android:progressDrawable="@drawable/progress_horizontal"
|
android:progressDrawable="@drawable/progress_horizontal"
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:max="1000"/>
|
android:max="5000"/>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue