From addf8d89962bf3de6d70330f9264d0e4d866613e Mon Sep 17 00:00:00 2001 From: cyberta Date: Sat, 29 Jul 2023 17:15:05 +0200 Subject: update design and UX for provider setup --- .../se/leap/bitmaskclient/base/StartActivity.java | 3 +- .../leap/bitmaskclient/base/utils/ViewHelper.java | 63 ++++++++++++++++++++++ .../bitmaskclient/base/views/ProgressSpinner.java | 53 ++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java (limited to 'app/src/main/java/se/leap/bitmaskclient/base') diff --git a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java index 94000a0f..4748b22e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java @@ -56,6 +56,7 @@ import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.providersetup.ProviderListActivity; import se.leap.bitmaskclient.providersetup.activities.CustomProviderSetupActivity; +import se.leap.bitmaskclient.providersetup.activities.SetupActivity; /** * Activity shown at startup. Evaluates if App is started for the first time or has been upgraded @@ -249,7 +250,7 @@ public class StartActivity extends Activity{ getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); } if (isDefaultBitmask()) { - startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, SetupActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } else { // custom branded app startActivityForResult(new Intent(this, CustomProviderSetupActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java index 51bcb2b1..efc6d093 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java @@ -1,5 +1,10 @@ package se.leap.bitmaskclient.base.utils; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +import android.animation.Animator; +import android.animation.ValueAnimator; import android.app.Activity; import android.app.Notification; import android.content.Context; @@ -16,10 +21,12 @@ import android.view.WindowManager; import androidx.annotation.ColorRes; import androidx.annotation.DimenRes; +import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.AppCompatTextView; +import androidx.appcompat.widget.LinearLayoutCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; @@ -146,4 +153,60 @@ public class ViewHelper { bar.setTitle(spannableTitle); } + public interface AnimationInterface { + void onAnimationEnd(); + } + + public static void animateContainerVisibility(View container, boolean isExpanded) { + animateContainerVisibility(container, isExpanded, null); + } + + public static void animateContainerVisibility(View container, boolean isExpanded, AnimationInterface animationInterface) { + + int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + + container.measure(widthMeasureSpec, heightMeasureSpec); + int measuredHeight = container.getMeasuredHeight(); + + int targetHeight = isExpanded ? 0 : measuredHeight; // Get the actual content height of the view + int initialHeight = isExpanded ? measuredHeight : 0; + + ValueAnimator animator = ValueAnimator.ofInt(initialHeight, targetHeight); + animator.setDuration(250); // Set the duration of the animation in milliseconds + + animator.addUpdateListener(animation -> { + container.getLayoutParams().height = (int) animation.getAnimatedValue(); + container.requestLayout(); + }); + animator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(@NonNull Animator animation) { + if (initialHeight == 0 && container.getVisibility() == GONE) { + container.setVisibility(VISIBLE); + } + } + + @Override + public void onAnimationEnd(@NonNull Animator animation) { + if (targetHeight == 0) { + container.setVisibility(GONE); + } + if (animationInterface != null) { + animationInterface.onAnimationEnd(); + } + } + + @Override + public void onAnimationCancel(@NonNull Animator animation) { + container.setVisibility(targetHeight == 0 ? GONE : VISIBLE); + } + + @Override + public void onAnimationRepeat(@NonNull Animator animation) {} + }); + + animator.start(); + } + } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java b/app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java new file mode 100644 index 00000000..b0b81624 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java @@ -0,0 +1,53 @@ +package se.leap.bitmaskclient.base.views; + +import android.annotation.TargetApi; +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.RelativeLayout; + +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.core.content.ContextCompat; + +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.databinding.VProgressSpinnerBinding; + +public class ProgressSpinner extends RelativeLayout { + + private static final String TAG = ProgressSpinner.class.getSimpleName(); + + AppCompatImageView spinnerView; + AppCompatTextView textView; + + public ProgressSpinner(Context context) { + super(context); + initLayout(context); + } + + public ProgressSpinner(Context context, AttributeSet attrs) { + super(context, attrs); + initLayout(context); + } + + public ProgressSpinner(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initLayout(context); + } + + + public ProgressSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + initLayout(context); + } + + private void initLayout(Context context) { + VProgressSpinnerBinding binding = VProgressSpinnerBinding.inflate(LayoutInflater.from(context), this, true); + spinnerView = binding.spinnerView; + textView = binding.tvProgress; + } + + public void update(int progress) { + textView.setText(textView.getContext().getString(R.string.percentage, progress)); + } +} -- cgit v1.2.3