Merge pull request #3174 from mvanhorn/feat/2742-display-card-id

Add option to display card ID in card list
This commit is contained in:
Matt Van Horn
2026-07-04 13:07:12 -07:00
committed by GitHub
parent 9452c65438
commit 888869d5fc
6 changed files with 133 additions and 4 deletions

View File

@@ -105,6 +105,12 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
inputHolder.setNoteField(null);
}
if (mLoyaltyCardListDisplayOptions.showingCardId() && !loyaltyCard.cardId.isEmpty()) {
inputHolder.setExtraField(inputHolder.mCardIdField, loyaltyCard.cardId, null, showDivider);
} else {
inputHolder.setExtraField(inputHolder.mCardIdField, null, null, false);
}
if (mLoyaltyCardListDisplayOptions.showingBalance() && !loyaltyCard.balance.equals(new BigDecimal("0"))) {
inputHolder.setExtraField(inputHolder.mBalanceField, Utils.formatBalance(mContext, loyaltyCard.balance, loyaltyCard.balanceType), null, showDivider);
} else {
@@ -211,7 +217,7 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
public class LoyaltyCardListItemViewHolder extends RecyclerView.ViewHolder {
public TextView mCardText, mStoreField, mNoteField, mBalanceField, mValidFromField, mExpiryField;
public TextView mCardText, mStoreField, mNoteField, mCardIdField, mBalanceField, mValidFromField, mExpiryField;
public ImageView mCardIcon, mTickIcon;
public MaterialCardView mRow;
public ConstraintLayout mStar, mArchived;
@@ -224,6 +230,7 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
mDivider = loyaltyCardLayoutBinding.infoDivider;
mStoreField = loyaltyCardLayoutBinding.store;
mNoteField = loyaltyCardLayoutBinding.note;
mCardIdField = loyaltyCardLayoutBinding.cardId;
mBalanceField = loyaltyCardLayoutBinding.balance;
mValidFromField = loyaltyCardLayoutBinding.validFrom;
mExpiryField = loyaltyCardLayoutBinding.expiry;

View File

@@ -35,6 +35,7 @@ public class LoyaltyCardListDisplayOptionsManager {
private boolean mShowNameBelowThumbnail;
private boolean mShowNote;
private boolean mShowCardId;
private boolean mShowBalance;
private boolean mShowValidity;
private boolean mShowArchivedCards;
@@ -50,6 +51,7 @@ public class LoyaltyCardListDisplayOptionsManager {
Context.MODE_PRIVATE);
mShowNameBelowThumbnail = mCardDetailsPref.getBoolean(mContext.getString(R.string.sharedpreference_card_details_show_name_below_thumbnail), false);
mShowNote = mCardDetailsPref.getBoolean(mContext.getString(R.string.sharedpreference_card_details_show_note), true);
mShowCardId = mCardDetailsPref.getBoolean(mContext.getString(R.string.sharedpreference_card_details_show_card_id), false);
mShowBalance = mCardDetailsPref.getBoolean(mContext.getString(R.string.sharedpreference_card_details_show_balance), true);
mShowValidity = mCardDetailsPref.getBoolean(mContext.getString(R.string.sharedpreference_card_details_show_validity), true);
mShowArchivedCards = mCardDetailsPref.getBoolean(mContext.getString(R.string.sharedpreference_card_details_show_archived_cards), true);
@@ -83,6 +85,17 @@ public class LoyaltyCardListDisplayOptionsManager {
return mShowNote;
}
public void showCardId(boolean show) {
mShowCardId = show;
mRefreshCardsCallback.run();
saveDetailState(R.string.sharedpreference_card_details_show_card_id, show);
}
public boolean showingCardId() {
return mShowCardId;
}
public void showBalance(boolean show) {
mShowBalance = show;
mRefreshCardsCallback.run();
@@ -137,6 +150,11 @@ public class LoyaltyCardListDisplayOptionsManager {
showingNote(),
this::showNote
));
displayOptions.add(new LoyaltyCardDisplayOption(
mContext.getString(R.string.show_card_id),
showingCardId(),
this::showCardId
));
displayOptions.add(new LoyaltyCardDisplayOption(
mContext.getString(R.string.show_balance),
showingBalance(),

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M2,6h2v12L2,18L2,6zM5,6h1v12L5,18L5,6zM7,6h3v12L7,18L7,6zM11,6h1v12h-1L11,6zM13,6h2v12h-2L13,6zM16,6h2v12h-2L16,6zM19,6h1v12h-1L19,6zM21,6h1v12h-1L21,6z"/>
</vector>

View File

@@ -158,10 +158,31 @@
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintTop_toBottomOf="@+id/note"
app:layout_constraintBottom_toTopOf="@+id/balance"
app:layout_constraintBottom_toTopOf="@+id/cardId"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/cardId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="4dp"
android:textAppearance="?attr/textAppearanceBody2"
app:drawableLeftCompat="@drawable/ic_card_id_24dp"
android:drawablePadding="4dp"
android:maxLines="1"
android:ellipsize="end"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/info_divider"
app:layout_constraintBottom_toTopOf="@+id/balance"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible"
tools:text="1234567890"/>
<TextView
android:id="@+id/balance"
android:layout_width="match_parent"
@@ -174,7 +195,7 @@
app:drawableLeftCompat="@drawable/ic_baseline_payments_24"
android:drawablePadding="4dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/info_divider"
app:layout_constraintTop_toBottomOf="@+id/cardId"
app:layout_constraintBottom_toTopOf="@+id/validFrom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@@ -280,10 +280,12 @@
<string name="show_note">Show note</string>
<string name="show_balance">Show balance</string>
<string name="show_validity">Show validity</string>
<string name="show_card_id">Show card ID</string>
<string name="sharedpreference_card_details_show_name_below_thumbnail" translatable="false">sharedpreference_card_details_show_name_below_thumbnail</string>
<string name="sharedpreference_card_details_show_note" translatable="false">sharedpreference_card_details_show_note</string>
<string name="sharedpreference_card_details_show_balance" translatable="false">sharedpreference_card_details_show_balance</string>
<string name="sharedpreference_card_details_show_validity" translatable="false">sharedpreference_card_details_show_validity</string>
<string name="sharedpreference_card_details_show_card_id" translatable="false">sharedpreference_card_details_show_card_id</string>
<string name="sharedpreference_card_details_show_archived_cards" translatable="false">sharedpreference_card_details_show_archived_cards</string>
<string name="settings_category_title_cards">Card view</string>
<string name="settings_category_title_cards_overview">Cards overview</string>

View File

@@ -20,6 +20,7 @@ import android.widget.TextView;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.core.app.ApplicationProvider;
import com.google.android.material.tabs.TabLayout;
import com.google.zxing.BarcodeFormat;
@@ -116,6 +117,76 @@ public class MainActivityTest {
database.close();
}
@Test
public void cardIdHiddenByDefault() {
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
Activity mainActivity = (Activity) activityController.get();
activityController.start();
activityController.resume();
activityController.visible();
RecyclerView list = mainActivity.findViewById(R.id.list);
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
DBHelper.insertLoyaltyCard(database, "store", "", null, null, new BigDecimal("0"), null, "1234567890", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), StandardCharsets.ISO_8859_1, Color.BLACK, 0, null, 0);
activityController.pause();
activityController.resume();
activityController.visible();
assertEquals(1, list.getAdapter().getItemCount());
// Make sure there is enough space to render all
list.measure(0, 0);
list.layout(0, 0, 100, 1000);
// Card ID is hidden by default
TextView cardIdField = list.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.cardId);
assertEquals(View.GONE, cardIdField.getVisibility());
database.close();
}
@Test
public void showCardIdDisplayOption() {
// The display option is read in the adapter's constructor (during onCreate), so the
// preference must be set before the activity is built.
SharedPreferences cardDetailsPref = ApplicationProvider.getApplicationContext().getSharedPreferences(
ApplicationProvider.getApplicationContext().getString(R.string.sharedpreference_card_details),
Activity.MODE_PRIVATE);
cardDetailsPref.edit().putBoolean(
ApplicationProvider.getApplicationContext().getString(R.string.sharedpreference_card_details_show_card_id), true).apply();
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
Activity mainActivity = (Activity) activityController.get();
activityController.start();
activityController.resume();
activityController.visible();
RecyclerView list = mainActivity.findViewById(R.id.list);
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
DBHelper.insertLoyaltyCard(database, "store", "", null, null, new BigDecimal("0"), null, "1234567890", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), StandardCharsets.ISO_8859_1, Color.BLACK, 0, null, 0);
activityController.pause();
activityController.resume();
activityController.visible();
assertEquals(1, list.getAdapter().getItemCount());
// Make sure there is enough space to render all
list.measure(0, 0);
list.layout(0, 0, 100, 1000);
TextView cardIdField = list.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.cardId);
assertEquals(View.VISIBLE, cardIdField.getVisibility());
assertEquals("1234567890", cardIdField.getText().toString());
database.close();
}
@Test
public void addFourLoyaltyCardsTwoStarred() // Main screen showing starred cards on top correctly
{
@@ -510,4 +581,4 @@ public class MainActivityTest {
database.close();
}
}
}