diff --git a/CHANGELOG.md b/CHANGELOG.md index 58d61ad5b..2768d380e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased - 120 + +- Complete redesign of main and loyalty card view screens + ## v2.22.1 - 119 - Use Material You colours on more devices (Google library update) diff --git a/app/src/main/java/protect/card_locker/BarcodeImageWriterResultCallback.java b/app/src/main/java/protect/card_locker/BarcodeImageWriterResultCallback.java new file mode 100644 index 000000000..a2616459e --- /dev/null +++ b/app/src/main/java/protect/card_locker/BarcodeImageWriterResultCallback.java @@ -0,0 +1,5 @@ +package protect.card_locker; + +public interface BarcodeImageWriterResultCallback { + void onBarcodeImageWriterResult(boolean success); +} diff --git a/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java b/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java index 43d9405ae..031e89278 100644 --- a/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java +++ b/app/src/main/java/protect/card_locker/BarcodeImageWriterTask.java @@ -42,12 +42,12 @@ public class BarcodeImageWriterTask implements CompatCallable { private final int imageHeight; private final int imageWidth; private final boolean showFallback; - private final Runnable callback; + private final BarcodeImageWriterResultCallback callback; BarcodeImageWriterTask( Context context, ImageView imageView, String cardIdString, CatimaBarcode barcodeFormat, TextView textView, - boolean showFallback, Runnable callback, boolean roundCornerPadding + boolean showFallback, BarcodeImageWriterResultCallback callback, boolean roundCornerPadding ) { mContext = context; @@ -282,7 +282,7 @@ public class BarcodeImageWriterTask implements CompatCallable { } if (callback != null) { - callback.run(); + callback.onBarcodeImageWriterResult(isSuccesful); } } diff --git a/app/src/main/java/protect/card_locker/GroupCursorAdapter.java b/app/src/main/java/protect/card_locker/GroupCursorAdapter.java index 96b350d08..33460aae9 100644 --- a/app/src/main/java/protect/card_locker/GroupCursorAdapter.java +++ b/app/src/main/java/protect/card_locker/GroupCursorAdapter.java @@ -17,7 +17,6 @@ import protect.card_locker.databinding.GroupLayoutBinding; import protect.card_locker.preferences.Settings; public class GroupCursorAdapter extends BaseCursorAdapter { - Settings mSettings; public final Context mContext; private final GroupAdapterListener mListener; SQLiteDatabase mDatabase; @@ -25,7 +24,6 @@ public class GroupCursorAdapter extends BaseCursorAdapter { private int mCurrentSelectedIndex = -1; - Settings mSettings; boolean mDarkModeEnabled; public final Context mContext; private final CardAdapterListener mListener; @@ -47,7 +46,6 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter mListener.onRowClicked(inputPosition)); @@ -241,28 +218,25 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter currencies = new HashMap<>(); LoyaltyCard tempLoyaltyCard; @@ -348,13 +346,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { enterButton = binding.enterButton; - barcodeImageGenerationFinishedCallback = () -> { - if (!(boolean) barcodeImage.getTag()) { - barcodeImageLayout.setVisibility(View.GONE); - Toast.makeText(LoyaltyCardEditActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show(); - } - }; - storeFieldEdit.addTextChangedListener(new SimpleTextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { @@ -1150,6 +1141,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { } } + @Override + public void onBarcodeImageWriterResult(boolean success) { + if (!success) { + barcodeImageLayout.setVisibility(View.GONE); + Toast.makeText(LoyaltyCardEditActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show(); + } + } + class EditCardIdAndBarcode implements View.OnClickListener { @Override public void onClick(View v) { @@ -1547,13 +1546,13 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this); Log.d(TAG, "ImageView size now known"); - BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, barcodeImageGenerationFinishedCallback, true); + BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, LoyaltyCardEditActivity.this, true); mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter); } }); } else { Log.d(TAG, "ImageView size known known, creating barcode"); - BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, barcodeImageGenerationFinishedCallback, true); + BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, this, true); mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter); } } diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 04a23e2fa..57afa8368 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -9,8 +9,6 @@ import android.content.res.Configuration; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.Color; -import android.graphics.Outline; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; @@ -23,13 +21,10 @@ import android.text.style.ForegroundColorSpan; import android.text.util.Linkify; import android.util.Log; import android.util.TypedValue; -import android.view.GestureDetector; import android.view.Menu; import android.view.MenuItem; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowInsets; @@ -47,23 +42,17 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.content.res.AppCompatResources; -import androidx.appcompat.widget.AppCompatTextView; import androidx.appcompat.widget.Toolbar; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.constraintlayout.widget.Guideline; -import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.FileProvider; import androidx.core.graphics.BlendModeColorFilterCompat; import androidx.core.graphics.BlendModeCompat; import androidx.core.graphics.ColorUtils; import androidx.core.graphics.drawable.DrawableCompat; -import androidx.core.view.WindowInsetsControllerCompat; +import androidx.core.view.ViewCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.widget.TextViewCompat; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.bottomappbar.BottomAppBar; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.textfield.TextInputEditText; import java.io.File; @@ -82,31 +71,10 @@ import protect.card_locker.async.TaskHandler; import protect.card_locker.databinding.LoyaltyCardViewLayoutBinding; import protect.card_locker.preferences.Settings; -public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements GestureDetector.OnGestureListener { +public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements BarcodeImageWriterResultCallback { private LoyaltyCardViewLayoutBinding binding; private static final String TAG = "Catima"; - private GestureDetector mGestureDetector; - - CoordinatorLayout coordinatorLayout; - ConstraintLayout mainLayout; - TextView cardIdFieldView; - BottomAppBar bottomAppBar; - ImageButton bottomAppBarInfoButton; - ImageButton bottomAppBarPreviousButton; - ImageButton bottomAppBarNextButton; - ImageButton bottomAppBarUpdateBalanceButton; - AppCompatTextView storeName; - ImageButton maximizeButton; - ImageView mainImage; - LinearLayout dotIndicator; - ImageButton minimizeButton; - View collapsingToolbarLayout; - AppBarLayout appBarLayout; - ImageView iconImage; - Toolbar portraitToolbar; - Toolbar landscapeToolbar; - int loyaltyCardId; ArrayList cardList; @@ -121,56 +89,36 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements String barcodeIdString; CatimaBarcode format; - FloatingActionButton editButton; - - Guideline centerGuideline; - SeekBar barcodeScaler; - Bitmap frontImageBitmap; Bitmap backImageBitmap; - boolean starred; boolean backgroundNeedsDarkIcons; boolean isFullscreen = false; + ImageView barcodeRenderTarget; int mainImageIndex = 0; List imageTypes; - private ImageView[] dots; boolean isBarcodeSupported = true; static final String STATE_IMAGEINDEX = "imageIndex"; static final String STATE_FULLSCREEN = "isFullscreen"; - private final int HEADER_FILTER_ALPHA = 127; - final private TaskHandler mTasks = new TaskHandler(); Runnable barcodeImageGenerationFinishedCallback; - @Override - public boolean onDown(MotionEvent e) { - return true; - } - - @Override - public void onShowPress(MotionEvent e) { - - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - if (imageTypes.size() > 1) { - Toast.makeText(this, getString(R.string.swipeToSwitchImages), Toast.LENGTH_SHORT).show(); + public void onMainImageTap() { + // If we're in fullscreen, leave fullscreen + if (isFullscreen) { + setFullscreen(false); + return; } - return false; - } + // If the barcode is shown, switch to fullscreen layout + if (imageTypes.get(mainImageIndex) == ImageType.BARCODE) { + setFullscreen(true); + return; + } - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - return false; - } - - @Override - public void onLongPress(MotionEvent e) { + // If this is an image, open it in the gallery. openCurrentMainImageInGallery(); } @@ -212,46 +160,17 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements } @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - Log.d(TAG, "On fling"); + public void onBarcodeImageWriterResult(boolean success) { + if (!success) { + imageTypes.remove(ImageType.BARCODE); - if (Math.abs(velocityY) > (0.75 * Math.abs(velocityX))) { - // Vertical swipe - // Swipe up - if (velocityY < -150) { - if (!isFullscreen) { - setFullscreen(true); - } - return false; - } + setStateBasedOnImageTypes(); - // Swipe down - if (velocityY > 150) { - if (isFullscreen) { - setFullscreen(false); - } - return false; - } - } else if (Math.abs(velocityX) > (0.75 * Math.abs(velocityY))) { - // Horizontal swipe - // Swipe right - if (velocityX < -150) { - setMainImage(true, false); - return false; - } + // Call correct drawMainImage + setFullscreen(isFullscreen); - // Swipe left - if (velocityX > 150) { - setMainImage(false, false); - return false; - } + Toast.makeText(LoyaltyCardViewActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show(); } - - if (imageTypes.size() > 1) { - Toast.makeText(this, getString(R.string.swipeToSwitchImages), Toast.LENGTH_SHORT).show(); - } - - return true; } enum ImageType { @@ -268,40 +187,13 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements Log.d(TAG, "View activity: id=" + loyaltyCardId); } - private Drawable getDotIcon(boolean active, boolean darkMode) { - Drawable unwrappedIcon = AppCompatResources.getDrawable(this, active ? R.drawable.active_dot : R.drawable.inactive_dot); - assert unwrappedIcon != null; - Drawable wrappedIcon = DrawableCompat.wrap(unwrappedIcon); - if (darkMode) { - DrawableCompat.setTint(wrappedIcon, Color.WHITE); - } else { - DrawableCompat.setTint(wrappedIcon, Color.BLACK); - } - - return wrappedIcon; - } - - private Drawable getIcon(int icon, boolean dark) { - Drawable unwrappedIcon = AppCompatResources.getDrawable(this, icon); - assert unwrappedIcon != null; - Drawable wrappedIcon = DrawableCompat.wrap(unwrappedIcon); - wrappedIcon.mutate(); - if (dark) { - DrawableCompat.setTint(wrappedIcon, Color.BLACK); - } else { - DrawableCompat.setTintList(wrappedIcon, null); - } - - return wrappedIcon; - } - - private void setCenterGuideline(int zoomLevel) { + private void setScalerGuideline(int zoomLevel) { float scale = zoomLevel / 100f; if (format != null && format.isSquare()) { - centerGuideline.setGuidelinePercent(0.75f * scale); + binding.scalerGuideline.setGuidelinePercent(0.75f * scale); } else { - centerGuideline.setGuidelinePercent(0.5f * scale); + binding.scalerGuideline.setGuidelinePercent(0.5f * scale); } } @@ -329,6 +221,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements super.onCreate(savedInstanceState); binding = LoyaltyCardViewLayoutBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + Toolbar toolbar = binding.toolbar; + setSupportActionBar(toolbar); settings = new Settings(this); @@ -355,43 +250,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements database = new DBHelper(this).getWritableDatabase(); importURIHelper = new ImportURIHelper(this); - coordinatorLayout = binding.coordinatorLayout; - mainLayout = binding.mainLayout; - cardIdFieldView = binding.cardIdView; - storeName = binding.storeName; - maximizeButton = binding.maximizeButton; - mainImage = binding.mainImage; - mainImage.setClipToOutline(true); - dotIndicator = binding.dotIndicator; - minimizeButton = binding.minimizeButton; - collapsingToolbarLayout = binding.collapsingToolbarLayout; - appBarLayout = binding.appBarLayout; - bottomAppBar = binding.bottomAppBar; - iconImage = binding.iconImage; - portraitToolbar = binding.toolbar; - landscapeToolbar = binding.toolbarLandscape; - - bottomAppBarInfoButton = binding.buttonShowInfo; - bottomAppBarPreviousButton = binding.buttonPrevious; - bottomAppBarNextButton = binding.buttonNext; - bottomAppBarUpdateBalanceButton = binding.buttonUpdateBalance; - - barcodeImageGenerationFinishedCallback = () -> { - if (!(boolean) mainImage.getTag()) { - mainImage.setVisibility(View.GONE); - imageTypes.remove(ImageType.BARCODE); - - // Redraw UI - setDotIndicator(Utils.isDarkModeEnabled(LoyaltyCardViewActivity.this)); - setFullscreen(isFullscreen); - - Toast.makeText(LoyaltyCardViewActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show(); - } - }; - - centerGuideline = binding.centerGuideline; - barcodeScaler = binding.barcodeScaler; - barcodeScaler.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + binding.barcodeScaler.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (!fromUser) { @@ -399,14 +258,14 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements return; } Log.d(TAG, "Progress is " + progress); - Log.d(TAG, "Max is " + barcodeScaler.getMax()); - float scale = (float) progress / (float) barcodeScaler.getMax(); + Log.d(TAG, "Max is " + binding.barcodeScaler.getMax()); + float scale = (float) progress / (float) binding.barcodeScaler.getMax(); Log.d(TAG, "Scaling to " + scale); loyaltyCard.zoomLevel = progress; DBHelper.updateLoyaltyCardZoomLevel(database, loyaltyCardId, loyaltyCard.zoomLevel); - setCenterGuideline(loyaltyCard.zoomLevel); + setScalerGuideline(loyaltyCard.zoomLevel); drawMainImage(mainImageIndex, true, isFullscreen); } @@ -424,12 +283,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements rotationEnabled = true; - // Allow making barcode fullscreen on tap - maximizeButton.setOnClickListener(v -> setFullscreen(true)); - minimizeButton.setOnClickListener(v -> setFullscreen(false)); + binding.fullscreenButtonMinimize.setOnClickListener(v -> setFullscreen(false)); - editButton = binding.fabEdit; - editButton.setOnClickListener(v -> { + binding.fabEdit.setOnClickListener(v -> { Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class); Bundle bundle = new Bundle(); bundle.putInt("id", loyaltyCardId); @@ -438,35 +294,21 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements startActivity(intent); finish(); }); - editButton.bringToFront(); + binding.fabEdit.bringToFront(); - appBarLayout.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - ViewOutlineProvider.BACKGROUND.getOutline(view, outline); - outline.setAlpha(0f); - } + binding.bottomAppBarInfoButton.setOnClickListener(view -> showInfoDialog()); + binding.bottomAppBarPreviousButton.setOnClickListener(view -> prevNextCard(false)); + binding.bottomAppBarNextButton.setOnClickListener(view -> prevNextCard(true)); + binding.bottomAppBarUpdateBalanceButton.setOnClickListener(view -> showBalanceUpdateDialog()); + + binding.mainImage.setOnClickListener(view -> onMainImageTap()); + // This long-press was originally only intended for when Talkback was used but sadly limiting + // this doesn't seem to work well + binding.mainImage.setOnLongClickListener(view -> { + setMainImage(true, true); + return true; }); - - bottomAppBarInfoButton.setOnClickListener(view -> showInfoDialog()); - bottomAppBarPreviousButton.setOnClickListener(view -> prevNextCard(false)); - bottomAppBarNextButton.setOnClickListener(view -> prevNextCard(true)); - bottomAppBarUpdateBalanceButton.setOnClickListener(view -> showBalanceUpdateDialog()); - - mGestureDetector = new GestureDetector(this, this); - View.OnTouchListener gestureTouchListener = (v, event) -> mGestureDetector.onTouchEvent(event); - mainImage.setOnTouchListener(gestureTouchListener); - - appBarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - iconImage.setLayoutParams(new CoordinatorLayout.LayoutParams( - CoordinatorLayout.LayoutParams.MATCH_PARENT, appBarLayout.getHeight()) - ); - iconImage.setClipBounds(new Rect(left, top, right, bottom)); - } - }); - this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + binding.fullscreenImage.setOnClickListener(view -> onMainImageTap()); } private SpannableStringBuilder padSpannableString(SpannableStringBuilder spannableStringBuilder) { @@ -493,7 +335,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements dialogContentPadding, dialogTitlePadding ); - infoTitleView.setTextSize(settings.getFontSizeMax(settings.getMediumFont())); infoTitleView.setText(loyaltyCard.store); infoDialog.setCustomTitle(infoTitleView); infoDialog.setTitle(loyaltyCard.store); @@ -630,20 +471,20 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements private void setBottomAppBarButtonState() { if (!loyaltyCard.note.isEmpty() || !loyaltyCardGroups.isEmpty() || hasBalance(loyaltyCard) || loyaltyCard.validFrom != null || loyaltyCard.expiry != null) { - bottomAppBarInfoButton.setVisibility(View.VISIBLE); + binding.bottomAppBarInfoButton.setVisibility(View.VISIBLE); } else { - bottomAppBarInfoButton.setVisibility(View.GONE); + binding.bottomAppBarInfoButton.setVisibility(View.GONE); } if (cardList == null || cardList.size() == 1) { - bottomAppBarPreviousButton.setVisibility(View.GONE); - bottomAppBarNextButton.setVisibility(View.GONE); + binding.bottomAppBarPreviousButton.setVisibility(View.GONE); + binding.bottomAppBarNextButton.setVisibility(View.GONE); } else { - bottomAppBarPreviousButton.setVisibility(View.VISIBLE); - bottomAppBarNextButton.setVisibility(View.VISIBLE); + binding.bottomAppBarPreviousButton.setVisibility(View.VISIBLE); + binding.bottomAppBarNextButton.setVisibility(View.VISIBLE); } - bottomAppBarUpdateBalanceButton.setVisibility(hasBalance(loyaltyCard) ? View.VISIBLE : View.GONE); + binding.bottomAppBarUpdateBalanceButton.setVisibility(hasBalance(loyaltyCard) ? View.VISIBLE : View.GONE); } private void prevNextCard(boolean next) { @@ -738,6 +579,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements return; } + setTitle(loyaltyCard.store); + loyaltyCardGroups = DBHelper.getLoyaltyCardGroups(database, loyaltyCardId); setupOrientation(); @@ -746,19 +589,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements cardIdString = loyaltyCard.cardId; barcodeIdString = loyaltyCard.barcodeId; - cardIdFieldView.setText(loyaltyCard.cardId); - TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(cardIdFieldView, - settings.getFontSizeMin(settings.getLargeFont()), settings.getFontSizeMax(settings.getLargeFont()), - 1, TypedValue.COMPLEX_UNIT_SP); - - storeName.setText(loyaltyCard.store); - storeName.setTextSize(settings.getFontSizeMax(settings.getLargeFont())); - TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration( - storeName, - settings.getFontSizeMin(settings.getLargeFont()), - settings.getFontSizeMax(settings.getLargeFont()), - 1, - TypedValue.COMPLEX_UNIT_DIP); + binding.cardIdView.setText(loyaltyCard.cardId); int backgroundHeaderColor; if (loyaltyCard.headerColor != null) { @@ -767,72 +598,29 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements backgroundHeaderColor = LetterBitmap.getDefaultColor(this, loyaltyCard.store); } - int textColor; - if (Utils.needsDarkForeground(backgroundHeaderColor)) { - textColor = Color.BLACK; - } else { - textColor = Color.WHITE; - } - storeName.setTextColor(textColor); - landscapeToolbar.setTitleTextColor(textColor); - // Also apply colours to UI elements int darkenedColor = ColorUtils.blendARGB(backgroundHeaderColor, Color.BLACK, 0.1f); - barcodeScaler.setProgressTintList(ColorStateList.valueOf(darkenedColor)); - barcodeScaler.setThumbTintList(ColorStateList.valueOf(darkenedColor)); - maximizeButton.setBackgroundColor(darkenedColor); - minimizeButton.setBackgroundColor(darkenedColor); - bottomAppBar.setBackgroundColor(darkenedColor); - maximizeButton.setColorFilter(textColor); - minimizeButton.setColorFilter(textColor); + binding.barcodeScaler.setProgressTintList(ColorStateList.valueOf(darkenedColor)); + binding.barcodeScaler.setThumbTintList(ColorStateList.valueOf(darkenedColor)); + binding.bottomAppBar.setBackgroundColor(darkenedColor); int complementaryColor = Utils.getComplementaryColor(darkenedColor); - editButton.setBackgroundTintList(ColorStateList.valueOf(complementaryColor)); - Drawable editButtonIcon = editButton.getDrawable(); + binding.fabEdit.setBackgroundTintList(ColorStateList.valueOf(complementaryColor)); + Drawable editButtonIcon = binding.fabEdit.getDrawable(); editButtonIcon.mutate(); editButtonIcon.setTint(Utils.needsDarkForeground(complementaryColor) ? Color.BLACK : Color.WHITE); - editButton.setImageDrawable(editButtonIcon); + binding.fabEdit.setImageDrawable(editButtonIcon); - Bitmap icon = Utils.retrieveCardImage(this, loyaltyCard.id, ImageLocationType.icon); - if (icon != null) { - int backgroundAlphaColor = Utils.needsDarkForeground(backgroundHeaderColor) ? Color.WHITE : Color.BLACK; - Log.d("onResume", "setting icon image"); - iconImage.setImageBitmap(icon); - int backgroundWithAlpha = Color.argb(HEADER_FILTER_ALPHA, Color.red(backgroundAlphaColor), Color.green(backgroundAlphaColor), Color.blue(backgroundAlphaColor)); - // for images that has alpha - appBarLayout.setBackgroundColor(backgroundWithAlpha); - } else { - Bitmap plain = Bitmap.createBitmap(new int[]{backgroundHeaderColor}, 1, 1, Bitmap.Config.ARGB_8888); - iconImage.setImageBitmap(plain); - appBarLayout.setBackgroundColor(Color.TRANSPARENT); - } + Utils.setIconOrTextWithBackground(this, loyaltyCard, binding.iconImage, binding.iconText); // If the background is very bright, we should use dark icons backgroundNeedsDarkIcons = Utils.needsDarkForeground(backgroundHeaderColor); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setHomeAsUpIndicator(getIcon(R.drawable.home_arrow_back_white, backgroundNeedsDarkIcons)); - } - fixImageButtonColor(bottomAppBarInfoButton); - fixImageButtonColor(bottomAppBarPreviousButton); - fixImageButtonColor(bottomAppBarNextButton); - fixImageButtonColor(bottomAppBarUpdateBalanceButton); + fixBottomAppBarImageButtonColor(binding.bottomAppBarInfoButton); + fixBottomAppBarImageButtonColor(binding.bottomAppBarPreviousButton); + fixBottomAppBarImageButtonColor(binding.bottomAppBarNextButton); + fixBottomAppBarImageButtonColor(binding.bottomAppBarUpdateBalanceButton); setBottomAppBarButtonState(); - // Make notification area light if dark icons are needed - if (Build.VERSION.SDK_INT >= 23) { - View decorView = getWindow().getDecorView(); - WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(getWindow(), decorView); - wic.setAppearanceLightStatusBars(backgroundNeedsDarkIcons); - window.setStatusBarColor(Color.TRANSPARENT); - } else { - // Darken statusbar if icons won't be visible otherwise - window.setStatusBarColor(backgroundNeedsDarkIcons ? ColorUtils.blendARGB(backgroundHeaderColor, Color.BLACK, 0.15f) : Color.TRANSPARENT); - } - - // Set shadow colour of store text so even same color on same color would be readable - storeName.setShadowLayer(1, 1, 1, backgroundNeedsDarkIcons ? Color.BLACK : Color.WHITE); - if (format != null && !format.isSupported()) { isBarcodeSupported = false; @@ -857,11 +645,29 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements imageTypes.add(ImageType.IMAGE_BACK); } - setDotIndicator(Utils.isDarkModeEnabled(this)); + setStateBasedOnImageTypes(); setFullscreen(isFullscreen); DBHelper.updateLoyaltyCardLastUsed(database, loyaltyCard.id); + + invalidateOptionsMenu(); + } + + private void setStateBasedOnImageTypes() { + // Decrease the card holder size to only fit the value if there is no barcode + // This looks much cleaner + ViewGroup.LayoutParams cardHolderLayoutParams = binding.cardHolder.getLayoutParams(); + if (imageTypes.isEmpty()) { + cardHolderLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + } else { + cardHolderLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; + } + binding.cardHolder.setLayoutParams(cardHolderLayoutParams); + + // Ensure buttons and accessibility are correct + setMainImagePreviousNextButtons(); + setMainImageAccessibility(); } @SuppressWarnings("deprecation") @@ -870,7 +676,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); } - private void fixImageButtonColor(ImageButton imageButton) { + private void fixBottomAppBarImageButtonColor(ImageButton imageButton) { imageButton.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(backgroundNeedsDarkIcons ? Color.BLACK : Color.WHITE, BlendModeCompat.SRC_ATOP)); } @@ -887,18 +693,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.card_view_menu, menu); - starred = loyaltyCard.starStatus != 0; - - if (loyaltyCard.archiveStatus != 0) { - menu.findItem(R.id.action_unarchive).setVisible(true); - menu.findItem(R.id.action_archive).setVisible(false); - } else { - menu.findItem(R.id.action_unarchive).setVisible(false); - menu.findItem(R.id.action_archive).setVisible(true); - } - - menu.findItem(R.id.action_overflow).setIcon(getIcon(R.drawable.ic_overflow_menu, backgroundNeedsDarkIcons)); - menu.findItem(R.id.action_share).setIcon(getIcon(R.drawable.ic_share_white, backgroundNeedsDarkIcons)); return super.onCreateOptionsMenu(menu); } @@ -907,13 +701,27 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - if (starred) { - menu.findItem(R.id.action_star_unstar).setIcon(getIcon(R.drawable.ic_starred_white, backgroundNeedsDarkIcons)); - menu.findItem(R.id.action_star_unstar).setTitle(R.string.unstar); - } else { - menu.findItem(R.id.action_star_unstar).setIcon(getIcon(R.drawable.ic_unstarred_white, backgroundNeedsDarkIcons)); - menu.findItem(R.id.action_star_unstar).setTitle(R.string.star); + + if (loyaltyCard != null) { + // Update star status + if (loyaltyCard.starStatus == 1) { + menu.findItem(R.id.action_star_unstar).setIcon(R.drawable.ic_starred); + menu.findItem(R.id.action_star_unstar).setTitle(R.string.unstar); + } else { + menu.findItem(R.id.action_star_unstar).setIcon(R.drawable.ic_unstarred); + menu.findItem(R.id.action_star_unstar).setTitle(R.string.star); + } + + // Update archive/unarchive button + if (loyaltyCard.archiveStatus != 0) { + menu.findItem(R.id.action_unarchive).setVisible(true); + menu.findItem(R.id.action_archive).setVisible(false); + } else { + menu.findItem(R.id.action_unarchive).setVisible(false); + menu.findItem(R.id.action_archive).setVisible(true); + } } + return true; } @@ -942,11 +750,11 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements return true; } else if (id == R.id.action_star_unstar) { - starred = !starred; - DBHelper.updateLoyaltyCardStarStatus(database, loyaltyCardId, starred ? 1 : 0); + DBHelper.updateLoyaltyCardStarStatus(database, loyaltyCardId, loyaltyCard.starStatus == 0 ? 1 : 0); // Re-init loyaltyCard with new data from DB onResume(); + invalidateOptionsMenu(); return true; } else if (id == R.id.action_archive) { @@ -955,6 +763,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements // Re-init loyaltyCard with new data from DB onResume(); + invalidateOptionsMenu(); return true; } else if (id == R.id.action_unarchive) { @@ -963,6 +772,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements // Re-init loyaltyCard with new data from DB onResume(); + invalidateOptionsMenu(); return true; } else if (id == R.id.action_delete) { @@ -993,23 +803,10 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements int orientation = getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_LANDSCAPE) { Log.d(TAG, "Detected landscape mode"); - setTitle(loyaltyCard.store); - - collapsingToolbarLayout.setVisibility(View.GONE); - portraitToolbar.setVisibility(View.GONE); - landscapeToolbar.setVisibility(View.VISIBLE); - - setSupportActionBar(landscapeToolbar); + binding.iconContainer.setVisibility(View.GONE); } else { Log.d(TAG, "Detected portrait mode"); - - setTitle(""); - - collapsingToolbarLayout.setVisibility(View.VISIBLE); - portraitToolbar.setVisibility(View.VISIBLE); - landscapeToolbar.setVisibility(View.GONE); - - setSupportActionBar(portraitToolbar); + binding.iconContainer.setVisibility(View.VISIBLE); } enableToolbarBackButton(); @@ -1017,15 +814,16 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements private void drawBarcode(boolean addPadding) { mTasks.flushTaskList(TaskHandler.TYPE.BARCODE, true, false, false); + if (format != null) { BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask( getApplicationContext(), - mainImage, + barcodeRenderTarget, barcodeIdString != null ? barcodeIdString : cardIdString, format, null, false, - barcodeImageGenerationFinishedCallback, + this, addPadding); mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter); } @@ -1033,11 +831,11 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements private void redrawBarcodeAfterResize(boolean addPadding) { if (format != null) { - mainImage.getViewTreeObserver().addOnGlobalLayoutListener( + barcodeRenderTarget.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { - mainImage.getViewTreeObserver().removeOnGlobalLayoutListener(this); + barcodeRenderTarget.getViewTreeObserver().removeOnGlobalLayoutListener(this); Log.d(TAG, "ImageView size now known"); drawBarcode(addPadding); @@ -1048,25 +846,18 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements private void drawMainImage(int index, boolean waitForResize, boolean isFullscreen) { if (imageTypes.isEmpty()) { - mainImage.setVisibility(View.GONE); + barcodeRenderTarget.setVisibility(View.GONE); return; } - if (dots != null) { - boolean darkMode = Utils.isDarkModeEnabled(getApplicationContext()); - for (int i = 0; i < dots.length; i++) { - dots[i].setImageDrawable(getDotIcon(i == index, darkMode)); - } - } - ImageType wantedImageType = imageTypes.get(index); if (wantedImageType == ImageType.BARCODE) { // Use border in non-fullscreen mode if (!isFullscreen) { - mainImage.setBackground(AppCompatResources.getDrawable(this, R.drawable.round_outline)); + barcodeRenderTarget.setBackground(AppCompatResources.getDrawable(this, R.drawable.round_outline)); } else { - mainImage.setBackgroundColor(Color.WHITE); + barcodeRenderTarget.setBackgroundColor(Color.WHITE); } if (waitForResize) { @@ -1075,27 +866,27 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements drawBarcode(!isFullscreen); } - mainImage.setContentDescription(getString(R.string.barcodeImageDescriptionWithType, format.prettyName())); + barcodeRenderTarget.setContentDescription(getString(R.string.barcodeImageDescriptionWithType, format.prettyName())); } else if (wantedImageType == ImageType.IMAGE_FRONT) { - mainImage.setImageBitmap(frontImageBitmap); - mainImage.setBackgroundColor(Color.TRANSPARENT); - mainImage.setContentDescription(getString(R.string.frontImageDescription)); + barcodeRenderTarget.setImageBitmap(frontImageBitmap); + barcodeRenderTarget.setBackgroundColor(Color.TRANSPARENT); + barcodeRenderTarget.setContentDescription(getString(R.string.frontImageDescription)); } else if (wantedImageType == ImageType.IMAGE_BACK) { - mainImage.setImageBitmap(backImageBitmap); - mainImage.setBackgroundColor(Color.TRANSPARENT); - mainImage.setContentDescription(getString(R.string.backImageDescription)); + barcodeRenderTarget.setImageBitmap(backImageBitmap); + barcodeRenderTarget.setBackgroundColor(Color.TRANSPARENT); + barcodeRenderTarget.setContentDescription(getString(R.string.backImageDescription)); } else { throw new IllegalArgumentException("Unknown image type: " + wantedImageType); } - mainImage.setVisibility(View.VISIBLE); + barcodeRenderTarget.setVisibility(View.VISIBLE); } private void setMainImage(boolean next, boolean overflow) { int newIndex = mainImageIndex + (next ? 1 : -1); if (newIndex >= imageTypes.size() && overflow) { - newIndex = 0; + newIndex = 0; } if (newIndex == -1 || newIndex >= imageTypes.size()) { @@ -1105,24 +896,85 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements mainImageIndex = newIndex; drawMainImage(newIndex, false, isFullscreen); + + setMainImagePreviousNextButtons(); + setMainImageAccessibility(); } - private void setDotIndicator(boolean darkMode) { - dotIndicator.removeAllViews(); - if (imageTypes.size() >= 2) { - dots = new ImageView[imageTypes.size()]; - - for (int i = 0; i < imageTypes.size(); i++) { - dots[i] = new ImageView(this); - dots[i].setImageDrawable(getDotIcon(false, darkMode)); - - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); - params.setMargins(8, 0, 8, 0); - - dotIndicator.addView(dots[i], params); + private void setMainImageAccessibility() { + // Single-click actions + if (mainImageIndex == 0) { + ViewCompat.replaceAccessibilityAction( + binding.mainImage, + AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK, + getString(R.string.moveBarcodeToTopOfScreen), + null + ); + } else { + int accessibilityClickAction; + if (mainImageIndex == 1) { + accessibilityClickAction = R.string.openFrontImageInGalleryApp; + } else if (mainImageIndex == 2) { + accessibilityClickAction = R.string.openBackImageInGalleryApp; + } else { + throw new IndexOutOfBoundsException("setMainImageAccessibility was out of range (action_click)"); } - dotIndicator.setVisibility(View.VISIBLE); + ViewCompat.replaceAccessibilityAction( + binding.mainImage, + AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK, + getString(accessibilityClickAction), + null + ); + } + + // Long-press actions + int accessibilityLongPressAction; + if (mainImageIndex == 0) { + accessibilityLongPressAction = R.string.switchToFrontImage; + } else if (mainImageIndex == 1) { + accessibilityLongPressAction = R.string.switchToBackImage; + } else if (mainImageIndex == 2) { + accessibilityLongPressAction = R.string.switchToBarcode; + } else { + throw new IndexOutOfBoundsException("setMainImageAccessibility was out of range (action_long_click)"); + } + + ViewCompat.replaceAccessibilityAction( + binding.mainImage, + AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK, + getString(accessibilityLongPressAction), + null + ); + } + + private void setMainImagePreviousNextButtons() { + if (imageTypes.size() < 2) { + binding.mainLeftButton.setVisibility(View.INVISIBLE); + binding.mainRightButton.setVisibility(View.INVISIBLE); + + binding.mainLeftButton.setOnClickListener(null); + binding.mainRightButton.setOnClickListener(null); + + return; + } + + // Enable left button if we can go further left + if (mainImageIndex > 0) { + binding.mainLeftButton.setVisibility(View.VISIBLE); + binding.mainLeftButton.setOnClickListener(view -> setMainImage(false, false)); + } else { + binding.mainLeftButton.setVisibility(View.INVISIBLE); + binding.mainLeftButton.setOnClickListener(null); + } + + // Enable right button if we can go further right + if (mainImageIndex < (imageTypes.size() - 1)) { + binding.mainRightButton.setVisibility(View.VISIBLE); + binding.mainRightButton.setOnClickListener(view -> setMainImage(true, false)); + } else { + binding.mainRightButton.setVisibility(View.INVISIBLE); + binding.mainRightButton.setOnClickListener(null); } } @@ -1133,37 +985,31 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements * by machines which offer no space to insert the complete device. */ private void setFullscreen(boolean enabled) { - isFullscreen = enabled; ActionBar actionBar = getSupportActionBar(); + isFullscreen = enabled; if (enabled && !imageTypes.isEmpty()) { Log.d(TAG, "Move into fullscreen"); + barcodeRenderTarget = binding.fullscreenImage; + + // Show only fullscreen view + binding.container.setVisibility(View.GONE); + binding.fullscreenLayout.setVisibility(View.VISIBLE); + drawMainImage(mainImageIndex, true, isFullscreen); - barcodeScaler.setProgress(loyaltyCard.zoomLevel); - setCenterGuideline(loyaltyCard.zoomLevel); - - // Hide maximize and show minimize button and scaler - maximizeButton.setVisibility(View.GONE); - minimizeButton.setVisibility(View.VISIBLE); - barcodeScaler.setVisibility(View.VISIBLE); + binding.barcodeScaler.setProgress(loyaltyCard.zoomLevel); + setScalerGuideline(loyaltyCard.zoomLevel); // Hide actionbar if (actionBar != null) { actionBar.hide(); } - // Hide toolbars - appBarLayout.setVisibility(View.INVISIBLE); - iconImage.setVisibility(View.INVISIBLE); - collapsingToolbarLayout.setVisibility(View.GONE); - landscapeToolbar.setVisibility(View.GONE); - // Hide other UI elements - cardIdFieldView.setVisibility(View.GONE); - bottomAppBar.setVisibility(View.GONE); - editButton.setVisibility(View.GONE); + binding.bottomAppBar.setVisibility(View.GONE); + binding.fabEdit.setVisibility(View.GONE); // Set Android to fullscreen mode if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { @@ -1178,31 +1024,22 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements } else { Log.d(TAG, "Move out of fullscreen"); - // Reset center guideline - setCenterGuideline(100); + barcodeRenderTarget = binding.mainImage; + + // Show only regular view + binding.container.setVisibility(View.VISIBLE); + binding.fullscreenLayout.setVisibility(View.GONE); drawMainImage(mainImageIndex, true, isFullscreen); - // Show maximize and hide minimize button and scaler - maximizeButton.setVisibility(imageTypes.isEmpty() ? View.GONE : View.VISIBLE); - - minimizeButton.setVisibility(View.GONE); - barcodeScaler.setVisibility(View.GONE); - // Show actionbar if (actionBar != null) { actionBar.show(); } - // Show appropriate toolbar - appBarLayout.setVisibility(View.VISIBLE); - setupOrientation(); - iconImage.setVisibility(View.VISIBLE); - // Show other UI elements - cardIdFieldView.setVisibility(View.VISIBLE); - editButton.setVisibility(View.VISIBLE); - bottomAppBar.setVisibility(View.VISIBLE); + binding.bottomAppBar.setVisibility(View.VISIBLE); + binding.fabEdit.setVisibility(View.VISIBLE); // Unset fullscreen mode if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { @@ -1216,7 +1053,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements } } - Log.d("setFullScreen", "Is full screen enabled? " + enabled + " Zoom Level = " + barcodeScaler.getProgress()); + Log.d("setFullScreen", "Is full screen enabled? " + enabled + " Zoom Level = " + binding.barcodeScaler.getProgress()); } @SuppressWarnings("deprecation") diff --git a/app/src/main/java/protect/card_locker/MainActivity.java b/app/src/main/java/protect/card_locker/MainActivity.java index 083817518..905925aae 100644 --- a/app/src/main/java/protect/card_locker/MainActivity.java +++ b/app/src/main/java/protect/card_locker/MainActivity.java @@ -50,7 +50,7 @@ import protect.card_locker.databinding.MainActivityBinding; import protect.card_locker.databinding.SortingOptionBinding; import protect.card_locker.preferences.SettingsActivity; -public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener, GestureDetector.OnGestureListener { +public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener { private MainActivityBinding binding; private ArchiveActivityBinding archiveActivityBinding; private ContentMainBinding contentMainBinding; @@ -63,7 +63,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard private LoyaltyCardCursorAdapter mAdapter; private ActionMode mCurrentActionMode; private SearchView mSearchView; - private GestureDetector mGestureDetector; private int mLoyaltyCardCount = 0; protected String mFilter = ""; protected Object mGroup = null; @@ -282,19 +281,11 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard } }); - mGestureDetector = new GestureDetector(this, this); - - View.OnTouchListener gestureTouchListener = (v, event) -> mGestureDetector.onTouchEvent(event); - mHelpSection = contentMainBinding.helpSection; mNoMatchingCardsText = contentMainBinding.noMatchingCardsText; mNoGroupCardsText = contentMainBinding.noGroupCardsText; mCardList = contentMainBinding.list; - mNoMatchingCardsText.setOnTouchListener(gestureTouchListener); - mCardList.setOnTouchListener(gestureTouchListener); - mNoGroupCardsText.setOnTouchListener(gestureTouchListener); - mAdapter = new LoyaltyCardCursorAdapter(this, null, this); mCardList.setAdapter(mAdapter); registerForContextMenu(mCardList); @@ -768,83 +759,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard updateLoyaltyCardList(false); } - @Override - public boolean onDown(MotionEvent e) { - return false; - } - - @Override - public void onShowPress(MotionEvent e) { - - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - return false; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - return false; - } - - @Override - public void onLongPress(MotionEvent e) { - - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - mGestureDetector.onTouchEvent(ev); - return super.dispatchTouchEvent(ev); - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - Log.d(TAG, "On fling"); - - // Don't swipe if we have too much vertical movement - if (Math.abs(velocityY) > (0.75 * Math.abs(velocityX))) { - return false; - } - - if (groupsTabLayout.getTabCount() < 2) { - return false; - } - - Integer currentTab = groupsTabLayout.getSelectedTabPosition(); - Log.d("onFling", "Current Tab " + currentTab); - // Swipe right - if (velocityX < -150) { - Log.d("onFling", "Right Swipe detected " + velocityX); - Integer nextTab = currentTab + 1; - - if (nextTab == groupsTabLayout.getTabCount()) { - groupsTabLayout.selectTab(groupsTabLayout.getTabAt(0)); - } else { - groupsTabLayout.selectTab(groupsTabLayout.getTabAt(nextTab)); - } - - return true; - } - - // Swipe left - if (velocityX > 150) { - Log.d("onFling", "Left Swipe detected " + velocityX); - Integer nextTab = currentTab - 1; - - if (nextTab < 0) { - groupsTabLayout.selectTab(groupsTabLayout.getTabAt(groupsTabLayout.getTabCount() - 1)); - } else { - groupsTabLayout.selectTab(groupsTabLayout.getTabAt(nextTab)); - } - - return true; - } - - return false; - } - @Override public void onRowLongClicked(int inputPosition) { enableActionMode(inputPosition); diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java index e443e6835..e99873707 100644 --- a/app/src/main/java/protect/card_locker/Utils.java +++ b/app/src/main/java/protect/card_locker/Utils.java @@ -18,6 +18,9 @@ import android.provider.MediaStore; import android.util.Log; import android.util.TypedValue; import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.RawRes; @@ -599,4 +602,24 @@ public class Utils { return result.toString(); } + + public static void setIconOrTextWithBackground(Context context, LoyaltyCard loyaltyCard, ImageView backgroundOrIcon, TextView textWhenNoImage) { + Bitmap icon = Utils.retrieveCardImage(context, loyaltyCard.id, ImageLocationType.icon); + if (icon != null) { + Log.d("onResume", "setting icon image"); + textWhenNoImage.setVisibility(View.GONE); + + backgroundOrIcon.setImageBitmap(icon); + backgroundOrIcon.setBackgroundColor(Color.TRANSPARENT); + } else { + textWhenNoImage.setVisibility(View.VISIBLE); + + int headerColor = loyaltyCard.headerColor != null ? loyaltyCard.headerColor : LetterBitmap.getDefaultColor(context, loyaltyCard.store); + + backgroundOrIcon.setImageBitmap(null); + backgroundOrIcon.setBackgroundColor(headerColor); + textWhenNoImage.setText(loyaltyCard.store); + textWhenNoImage.setTextColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE); + } + } } diff --git a/app/src/main/java/protect/card_locker/preferences/Settings.java b/app/src/main/java/protect/card_locker/preferences/Settings.java index dfa701a04..167456791 100644 --- a/app/src/main/java/protect/card_locker/preferences/Settings.java +++ b/app/src/main/java/protect/card_locker/preferences/Settings.java @@ -63,30 +63,6 @@ public class Settings { return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; } - public double getFontSizeScale() { - return getInt(R.string.settings_key_max_font_size_scale, R.integer.settings_max_font_size_scale_pct) / 100.0; - } - - public int getSmallFont() { - return 14; - } - - public int getMediumFont() { - return 28; - } - - public int getLargeFont() { - return 40; - } - - public int getFontSizeMin(int fontSize) { - return (int) (Math.round(fontSize / 2.0) - 1); - } - - public int getFontSizeMax(int fontSize) { - return (int) Math.round(fontSize * getFontSizeScale()); - } - public boolean useMaxBrightnessDisplayingBarcode() { return getBoolean(R.string.settings_key_display_barcode_max_brightness, true); } diff --git a/app/src/main/res/drawable/active_dot.xml b/app/src/main/res/drawable/active_dot.xml deleted file mode 100644 index 093c5de27..000000000 --- a/app/src/main/res/drawable/active_dot.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_baseline_chevron_left_24.xml b/app/src/main/res/drawable/ic_baseline_chevron_left_24.xml index f0d71e1f4..650c7ae22 100644 --- a/app/src/main/res/drawable/ic_baseline_chevron_left_24.xml +++ b/app/src/main/res/drawable/ic_baseline_chevron_left_24.xml @@ -1,4 +1,4 @@ - diff --git a/app/src/main/res/drawable/ic_baseline_chevron_right_24.xml b/app/src/main/res/drawable/ic_baseline_chevron_right_24.xml index a749bde77..a211254a9 100644 --- a/app/src/main/res/drawable/ic_baseline_chevron_right_24.xml +++ b/app/src/main/res/drawable/ic_baseline_chevron_right_24.xml @@ -1,4 +1,4 @@ - diff --git a/app/src/main/res/drawable/ic_baseline_expand_more_24.xml b/app/src/main/res/drawable/ic_baseline_expand_more_24.xml new file mode 100644 index 000000000..9f8220528 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_expand_more_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_starred.xml b/app/src/main/res/drawable/ic_starred.xml new file mode 100644 index 000000000..78ab4c9f1 --- /dev/null +++ b/app/src/main/res/drawable/ic_starred.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_unstarred.xml b/app/src/main/res/drawable/ic_unstarred.xml new file mode 100644 index 000000000..01517ff50 --- /dev/null +++ b/app/src/main/res/drawable/ic_unstarred.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/inactive_dot.xml b/app/src/main/res/drawable/inactive_dot.xml deleted file mode 100644 index 91fb8b14a..000000000 --- a/app/src/main/res/drawable/inactive_dot.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/loyalty_card_layout.xml b/app/src/main/res/layout/loyalty_card_layout.xml index 4afe53ed3..ff8b07cda 100644 --- a/app/src/main/res/layout/loyalty_card_layout.xml +++ b/app/src/main/res/layout/loyalty_card_layout.xml @@ -9,8 +9,7 @@ + android:layout_height="wrap_content"> + + - - - + android:fitsSystemWindows="false"> + android:layout_width="match_parent" + android:layout_height="wrap_content"> + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + style="?attr/toolbarStyle" /> + - + + + android:layout_marginBottom="20dp"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:contentDescription="@string/setBarcodeHeight" + android:max="100" /> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 19910f4b5..5dd2c4500 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -313,4 +313,12 @@ Any date Choose valid from date Valid from: %s + Height: + Switch to front image + Switch to back image + Switch to barcode + Open image in gallery app + Open front image in gallery app + Open back image in gallery app + Set barcode height diff --git a/app/src/test/java/protect/card_locker/LoyaltyCardCursorAdapterTest.java b/app/src/test/java/protect/card_locker/LoyaltyCardCursorAdapterTest.java index 7665638f5..f005bd308 100644 --- a/app/src/test/java/protect/card_locker/LoyaltyCardCursorAdapterTest.java +++ b/app/src/test/java/protect/card_locker/LoyaltyCardCursorAdapterTest.java @@ -60,25 +60,13 @@ public class LoyaltyCardCursorAdapterTest { return viewHolder.itemView; } - private void checkView(final View view, final String store, final String note, final String validFrom, final String expiry, final String balance, boolean checkFontSizes) { - final TextView storeField = view.findViewById(R.id.store); + private void checkView(final View view, final String store, final String note, final String validFrom, final String expiry, final String balance) { + final TextView storeField = view.findViewById(R.id.thumbnail_text); final TextView noteField = view.findViewById(R.id.note); final TextView validFromField = view.findViewById(R.id.validFrom); final TextView expiryField = view.findViewById(R.id.expiry); final TextView balanceField = view.findViewById(R.id.balance); - if (checkFontSizes) { - Settings preferences = new Settings(activity.getApplicationContext()); - int mediumFontSize = preferences.getFontSizeMax(preferences.getMediumFont()); - int smallFontSize = preferences.getFontSizeMax(preferences.getSmallFont()); - - assertEquals(mediumFontSize, (int) storeField.getTextSize()); - assertEquals(smallFontSize, (int) noteField.getTextSize()); - assertEquals(smallFontSize, (int) validFromField.getTextSize()); - assertEquals(smallFontSize, (int) expiryField.getTextSize()); - } - - assertEquals(store, storeField.getText().toString()); if (!note.isEmpty()) { assertEquals(View.VISIBLE, noteField.getVisibility()); assertEquals(note, noteField.getText().toString()); @@ -119,7 +107,7 @@ public class LoyaltyCardCursorAdapterTest { View view = createView(cursor); - checkView(view, card.store, card.note, "", "", "", false); + checkView(view, card.store, card.note, "", "", ""); cursor.close(); } @@ -134,30 +122,7 @@ public class LoyaltyCardCursorAdapterTest { View view = createView(cursor); - checkView(view, card.store, card.note, "", "", "", false); - - cursor.close(); - } - - @Test - public void TestCursorAdapterFontSizes() { - Date date = new Date(); - String dateString = DateFormat.getDateInstance(DateFormat.LONG).format(date); - - DBHelper.insertLoyaltyCard(mDatabase, "store", "note", date, date, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0); - LoyaltyCard card = DBHelper.getLoyaltyCard(mDatabase, 1); - - Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase); - cursor.moveToFirst(); - - setFontScale(50); - View view = createView(cursor); - - checkView(view, card.store, card.note, dateString, dateString, "", true); - - setFontScale(200); - view = createView(cursor); - checkView(view, card.store, card.note, dateString, dateString, "", true); + checkView(view, card.store, card.note, "", "", ""); cursor.close(); } @@ -223,7 +188,7 @@ public class LoyaltyCardCursorAdapterTest { View view = createView(cursor); - checkView(view, card.store, card.note, "", "", "", false); + checkView(view, card.store, card.note, "", "", ""); cursor.close(); } @@ -238,7 +203,7 @@ public class LoyaltyCardCursorAdapterTest { View view = createView(cursor); - checkView(view, card.store, card.note, "", "", "", false); + checkView(view, card.store, card.note, "", "", ""); cursor.close(); } @@ -253,7 +218,7 @@ public class LoyaltyCardCursorAdapterTest { View view = createView(cursor); - checkView(view, card.store, card.note, "", "", "100 points", false); + checkView(view, card.store, card.note, "", "", "100 points"); cursor.close(); } @@ -268,7 +233,7 @@ public class LoyaltyCardCursorAdapterTest { View view = createView(cursor); - checkView(view, card.store, card.note, "", "", "$10.00", false); + checkView(view, card.store, card.note, "", "", "$10.00"); cursor.close(); } diff --git a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java index 63501e5cf..62c0c3cc1 100644 --- a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java +++ b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java @@ -59,6 +59,7 @@ import java.util.Currency; import java.util.Date; import androidx.appcompat.app.AlertDialog; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.widget.TextViewCompat; import androidx.preference.PreferenceManager; @@ -309,7 +310,7 @@ public class LoyaltyCardViewActivityTest { final String barcodeId, final String barcodeType, final Bitmap frontImage, final Bitmap backImage) { if (mode == ViewMode.VIEW_CARD) { - checkFieldProperties(activity, R.id.cardIdView, View.VISIBLE, cardId, FieldTypeView.TextView); + checkFieldProperties(activity, R.id.card_id_view, View.VISIBLE, cardId, FieldTypeView.TextView); } else { int editVisibility = View.VISIBLE; @@ -621,7 +622,7 @@ public class LoyaltyCardViewActivityTest { } @Test - public void startWithLoyaltyCardViewModeCheckDisplay() throws IOException { + public void startWithLoyaltyCardViewModeCheckDisplay() { ActivityController activityController = createActivityWithLoyaltyCard(false); Activity activity = (Activity) activityController.get(); final Context context = activity.getApplicationContext(); @@ -1131,40 +1132,6 @@ public class LoyaltyCardViewActivityTest { database.close(); } - @Test - public void startCheckFontSizes() { - ActivityController activityController = createActivityWithLoyaltyCard(false); - - Activity activity = (Activity) activityController.get(); - SQLiteDatabase database = TestHelpers.getEmptyDb(activity).getWritableDatabase(); - DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null,0); - - final int LARGE_FONT_SIZE = 40; - - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity); - settings.edit() - .putInt(activity.getResources().getString(R.string.settings_key_max_font_size_scale), 100) - .apply(); - - activityController.start(); - activityController.visible(); - activityController.resume(); - - assertEquals(false, activity.isFinishing()); - - TextView storeName = activity.findViewById(R.id.storeName); - TextView cardIdFieldView = activity.findViewById(R.id.cardIdView); - - TextViewCompat.getAutoSizeMaxTextSize(storeName); - TextViewCompat.getAutoSizeMaxTextSize(storeName); - assertEquals(LARGE_FONT_SIZE, TextViewCompat.getAutoSizeMaxTextSize(cardIdFieldView)); - - shadowOf(activity).clickMenuItem(android.R.id.home); - assertEquals(true, activity.isFinishing()); - - database.close(); - } - @Test public void checkPushStarIcon() { ActivityController activityController = createActivityWithLoyaltyCard(false); @@ -1213,13 +1180,12 @@ public class LoyaltyCardViewActivityTest { assertFalse(activity.isFinishing()); - View collapsingToolbarLayout = activity.findViewById(R.id.collapsingToolbarLayout); BottomAppBar bottomAppBar = activity.findViewById(R.id.bottom_app_bar); - ImageButton maximizeButton = activity.findViewById(R.id.maximizeButton); - ImageButton minimizeButton = activity.findViewById(R.id.minimizeButton); - LinearLayout dotIndicator = activity.findViewById(R.id.dotIndicator); + ImageView mainImage = activity.findViewById(R.id.main_image); + LinearLayout container = activity.findViewById(R.id.container); + ConstraintLayout fullScreenLayout = activity.findViewById(R.id.fullscreen_layout); + ImageButton minimizeButton = activity.findViewById(R.id.fullscreen_button_minimize); FloatingActionButton editButton = activity.findViewById(R.id.fabEdit); - SeekBar barcodeScaler = activity.findViewById(R.id.barcodeScaler); // Android should not be in fullscreen mode assertTrue(activity.getWindow().getDecorView().getRootWindowInsets().isVisible(WindowInsets.Type.statusBars())); @@ -1227,16 +1193,13 @@ public class LoyaltyCardViewActivityTest { assertEquals(WindowInsetsController.BEHAVIOR_DEFAULT, activity.getWindow().getInsetsController().getSystemBarsBehavior()); // Elements should be visible (except minimize button and scaler) - assertEquals(View.VISIBLE, collapsingToolbarLayout.getVisibility()); assertEquals(View.VISIBLE, bottomAppBar.getVisibility()); - assertEquals(View.VISIBLE, maximizeButton.getVisibility()); - assertEquals(View.GONE, minimizeButton.getVisibility()); + assertEquals(View.VISIBLE, container.getVisibility()); + assertEquals(View.GONE, fullScreenLayout.getVisibility()); assertEquals(View.VISIBLE, editButton.getVisibility()); - assertEquals(View.GONE, barcodeScaler.getVisibility()); - assertEquals(View.GONE, dotIndicator.getVisibility()); // We have no images, only a barcode // Click maximize button to activate fullscreen - maximizeButton.performClick(); + mainImage.performClick(); shadowOf(getMainLooper()).idle(); // Android should be in fullscreen mode @@ -1245,13 +1208,10 @@ public class LoyaltyCardViewActivityTest { assertEquals(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE, activity.getWindow().getInsetsController().getSystemBarsBehavior()); // Elements should not be visible (except minimize button and scaler) - assertEquals(View.GONE, collapsingToolbarLayout.getVisibility()); assertEquals(View.GONE, bottomAppBar.getVisibility()); - assertEquals(View.GONE, maximizeButton.getVisibility()); - assertEquals(View.VISIBLE, minimizeButton.getVisibility()); + assertEquals(View.GONE, container.getVisibility()); + assertEquals(View.VISIBLE, fullScreenLayout.getVisibility()); assertEquals(View.GONE, editButton.getVisibility()); - assertEquals(View.VISIBLE, barcodeScaler.getVisibility()); - assertEquals(View.GONE, dotIndicator.getVisibility()); // We have no images, only a barcode // Clicking minimize button should deactivate fullscreen mode minimizeButton.performClick(); @@ -1261,29 +1221,23 @@ public class LoyaltyCardViewActivityTest { assertTrue(activity.getWindow().getDecorView().getRootWindowInsets().isVisible(WindowInsets.Type.navigationBars())); assertEquals(WindowInsetsController.BEHAVIOR_DEFAULT, activity.getWindow().getInsetsController().getSystemBarsBehavior()); - assertEquals(View.VISIBLE, collapsingToolbarLayout.getVisibility()); assertEquals(View.VISIBLE, bottomAppBar.getVisibility()); - assertEquals(View.VISIBLE, maximizeButton.getVisibility()); - assertEquals(View.GONE, minimizeButton.getVisibility()); + assertEquals(View.VISIBLE, container.getVisibility()); + assertEquals(View.GONE, fullScreenLayout.getVisibility()); assertEquals(View.VISIBLE, editButton.getVisibility()); - assertEquals(View.GONE, barcodeScaler.getVisibility()); - assertEquals(View.GONE, dotIndicator.getVisibility()); // We have no images, only a barcode // Another click back to fullscreen - maximizeButton.performClick(); + mainImage.performClick(); shadowOf(getMainLooper()).idle(); assertFalse(activity.getWindow().getDecorView().getRootWindowInsets().isVisible(WindowInsets.Type.statusBars())); assertFalse(activity.getWindow().getDecorView().getRootWindowInsets().isVisible(WindowInsets.Type.navigationBars())); assertEquals(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE, activity.getWindow().getInsetsController().getSystemBarsBehavior()); - assertEquals(View.GONE, collapsingToolbarLayout.getVisibility()); assertEquals(View.GONE, bottomAppBar.getVisibility()); - assertEquals(View.GONE, maximizeButton.getVisibility()); - assertEquals(View.VISIBLE, minimizeButton.getVisibility()); + assertEquals(View.GONE, container.getVisibility()); + assertEquals(View.VISIBLE, fullScreenLayout.getVisibility()); assertEquals(View.GONE, editButton.getVisibility()); - assertEquals(View.VISIBLE, barcodeScaler.getVisibility()); - assertEquals(View.GONE, dotIndicator.getVisibility()); // We have no images, only a barcode // In full screen mode, back button should disable fullscreen activity.onBackPressed(); @@ -1293,13 +1247,10 @@ public class LoyaltyCardViewActivityTest { assertTrue(activity.getWindow().getDecorView().getRootWindowInsets().isVisible(WindowInsets.Type.navigationBars())); assertEquals(WindowInsetsController.BEHAVIOR_DEFAULT, activity.getWindow().getInsetsController().getSystemBarsBehavior()); - assertEquals(View.VISIBLE, collapsingToolbarLayout.getVisibility()); assertEquals(View.VISIBLE, bottomAppBar.getVisibility()); - assertEquals(View.VISIBLE, maximizeButton.getVisibility()); - assertEquals(View.GONE, minimizeButton.getVisibility()); + assertEquals(View.VISIBLE, container.getVisibility()); + assertEquals(View.GONE, fullScreenLayout.getVisibility()); assertEquals(View.VISIBLE, editButton.getVisibility()); - assertEquals(View.GONE, barcodeScaler.getVisibility()); - assertEquals(View.GONE, dotIndicator.getVisibility()); // We have no images, only a barcode // Pressing back when not in full screen should finish activity activity.onBackPressed(); @@ -1323,12 +1274,10 @@ public class LoyaltyCardViewActivityTest { assertEquals(false, activity.isFinishing()); - View collapsingToolbarLayout = activity.findViewById(R.id.collapsingToolbarLayout); BottomAppBar bottomAppBar = activity.findViewById(R.id.bottom_app_bar); - ImageButton maximizeButton = activity.findViewById(R.id.maximizeButton); - ImageButton minimizeButton = activity.findViewById(R.id.minimizeButton); + ImageView mainImage = activity.findViewById(R.id.main_image); + ConstraintLayout fullScreenLayout = activity.findViewById(R.id.fullscreen_layout); FloatingActionButton editButton = activity.findViewById(R.id.fabEdit); - SeekBar barcodeScaler = activity.findViewById(R.id.barcodeScaler); // Android should not be in fullscreen mode int uiOptions = activity.getWindow().getDecorView().getSystemUiVisibility(); @@ -1336,12 +1285,10 @@ public class LoyaltyCardViewActivityTest { assertNotEquals(uiOptions | View.SYSTEM_UI_FLAG_FULLSCREEN, uiOptions); // Elements should be visible (except minimize/maximize buttons and barcode and scaler) - assertEquals(View.VISIBLE, collapsingToolbarLayout.getVisibility()); assertEquals(View.VISIBLE, bottomAppBar.getVisibility()); - assertEquals(View.GONE, maximizeButton.getVisibility()); - assertEquals(View.GONE, minimizeButton.getVisibility()); + assertEquals(View.GONE, mainImage.getVisibility()); + assertEquals(View.GONE, fullScreenLayout.getVisibility()); assertEquals(View.VISIBLE, editButton.getVisibility()); - assertEquals(View.GONE, barcodeScaler.getVisibility()); // Pressing back when not in full screen should finish activity activity.onBackPressed(); diff --git a/app/src/test/java/protect/card_locker/MainActivityTest.java b/app/src/test/java/protect/card_locker/MainActivityTest.java index 19a9d47d5..c76386c83 100644 --- a/app/src/test/java/protect/card_locker/MainActivityTest.java +++ b/app/src/test/java/protect/card_locker/MainActivityTest.java @@ -153,10 +153,10 @@ public class MainActivityTest { list.measure(0, 0); list.layout(0, 0, 100, 1000); - assertEquals("storeC", ((TextView) list.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.store)).getText()); - assertEquals("storeD", ((TextView) list.findViewHolderForAdapterPosition(1).itemView.findViewById(R.id.store)).getText()); - assertEquals("storeA", ((TextView) list.findViewHolderForAdapterPosition(2).itemView.findViewById(R.id.store)).getText()); - assertEquals("storeB", ((TextView) list.findViewHolderForAdapterPosition(3).itemView.findViewById(R.id.store)).getText()); + assertEquals("storeC", ((TextView) list.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.thumbnail_text)).getText()); + assertEquals("storeD", ((TextView) list.findViewHolderForAdapterPosition(1).itemView.findViewById(R.id.thumbnail_text)).getText()); + assertEquals("storeA", ((TextView) list.findViewHolderForAdapterPosition(2).itemView.findViewById(R.id.thumbnail_text)).getText()); + assertEquals("storeB", ((TextView) list.findViewHolderForAdapterPosition(3).itemView.findViewById(R.id.thumbnail_text)).getText()); database.close(); } diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-01.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-01.png index 740667b7f..b5cf26358 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-01.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-01.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-04.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-04.png index 1cae2094f..b8fb7ca36 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-04.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-04.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png index e337bb474..dc38089d5 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png index 71005854d..0284ffa05 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png differ