diff --git a/app/src/main/java/protect/card_locker/LetterBitmap.java b/app/src/main/java/protect/card_locker/LetterBitmap.java
new file mode 100644
index 000000000..44c65d087
--- /dev/null
+++ b/app/src/main/java/protect/card_locker/LetterBitmap.java
@@ -0,0 +1,141 @@
+package protect.card_locker;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.text.TextPaint;
+
+/**
+ * Original from https://github.com/andOTP/andOTP/blob/master/app/src/main/java/org/shadowice/flocke/andotp/Utilities/LetterBitmap.java
+ * which was originally from http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail
+ * Used to create a {@link Bitmap} that contains a letter used in the English
+ * alphabet or digit, if there is no letter or digit available, a default image
+ * is shown instead.
+ *
+ * Only English language supported.
+ */
+class LetterBitmap
+{
+
+ /**
+ * The number of available tile colors
+ */
+ private static final int NUM_OF_TILE_COLORS = 8;
+
+ /**
+ * The {@link TextPaint} used to draw the letter onto the tile
+ */
+ private final TextPaint mPaint = new TextPaint();
+ /**
+ * The bounds that enclose the letter
+ */
+ private final Rect mBounds = new Rect();
+ /**
+ * The {@link Canvas} to draw on
+ */
+ private final Canvas mCanvas = new Canvas();
+ /**
+ * The first char of the name being displayed
+ */
+ private final char[] mFirstChar = new char[1];
+
+ /**
+ * The background colors of the tile
+ */
+ private final TypedArray mColors;
+ /**
+ * The font size used to display the letter
+ */
+ private final int mTileLetterFontSize;
+ /**
+ * The default image to display
+ */
+ private final Bitmap mDefaultBitmap;
+
+ /**
+ * Constructor for LetterTileProvider
+ *
+ * @param context The {@link Context} to use
+ */
+ public LetterBitmap(Context context)
+ {
+ final Resources res = context.getResources();
+
+ mPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.BOLD));
+ mPaint.setColor(Color.WHITE);
+ mPaint.setTextAlign(Paint.Align.CENTER);
+ mPaint.setAntiAlias(true);
+
+ mColors = res.obtainTypedArray(R.array.letter_tile_colors);
+ mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
+
+ mDefaultBitmap = BitmapFactory.decodeResource(res, android.R.drawable.sym_def_app_icon);
+ }
+
+ /**
+ * @param displayName The name used to create the letter for the tile
+ * @param key The key used to generate the background color for the tile
+ * @param width The desired width of the tile
+ * @param height The desired height of the tile
+ * @return A {@link Bitmap} that contains a letter used in the English
+ * alphabet or digit, if there is no letter or digit available, a
+ * default image is shown instead
+ */
+ public Bitmap getLetterTile(String displayName, String key, int width, int height)
+ {
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ char firstChar = displayName.charAt(0);
+
+ final Canvas c = mCanvas;
+ c.setBitmap(bitmap);
+ c.drawColor(pickColor(key));
+
+ if (!isEnglishLetterOrDigit(firstChar))
+ {
+ firstChar = 'A';
+ }
+ mFirstChar[0] = Character.toUpperCase(firstChar);
+ mPaint.setTextSize(mTileLetterFontSize);
+ mPaint.getTextBounds(mFirstChar, 0, 1, mBounds);
+ c.drawText(mFirstChar, 0, 1, width / 2, height / 2
+ + (mBounds.bottom - mBounds.top) / 2, mPaint);
+ return bitmap;
+ }
+
+ /**
+ * @param c The char to check
+ * @return True if c is in the English alphabet or is a digit,
+ * false otherwise
+ */
+ private static boolean isEnglishLetterOrDigit(char c)
+ {
+ return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9';
+ }
+
+ /**
+ * @param key The key used to generate the tile color
+ * @return A new or previously chosen color for key used as the
+ * tile background color
+ */
+ private int pickColor(String key)
+ {
+ // String.hashCode() is not supposed to change across java versions, so
+ // this should guarantee the same key always maps to the same color
+ final int color = Math.abs(key.hashCode()) % NUM_OF_TILE_COLORS;
+ try
+ {
+ return mColors.getColor(color, Color.BLACK);
+ }
+ finally
+ {
+ mColors.recycle();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java
index 85110ac16..32e4f3797 100644
--- a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java
+++ b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java
@@ -6,6 +6,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
+import android.widget.ImageView;
import android.widget.TextView;
class LoyaltyCardCursorAdapter extends CursorAdapter
@@ -29,6 +30,7 @@ class LoyaltyCardCursorAdapter extends CursorAdapter
public void bindView(View view, Context context, Cursor cursor)
{
// Find fields to populate in inflated template
+ ImageView thumbnail = view.findViewById(R.id.thumbnail);
TextView storeField = (TextView) view.findViewById(R.id.store);
TextView cardIdField = (TextView) view.findViewById(R.id.cardId);
@@ -49,5 +51,9 @@ class LoyaltyCardCursorAdapter extends CursorAdapter
String cardIdLabel = view.getResources().getString(R.string.cardId);
String cardIdText = String.format(cardIdFormat, cardIdLabel, loyaltyCard.cardId);
cardIdField.setText(cardIdText);
+
+ LetterBitmap letterBitmap = new LetterBitmap(context);
+ int pixelSize = context.getResources().getDimensionPixelSize(R.dimen.cardThumbnailSize);
+ thumbnail.setImageBitmap(letterBitmap.getLetterTile(loyaltyCard.store, loyaltyCard.store, pixelSize, pixelSize));
}
}
diff --git a/app/src/main/res/layout/loyalty_card_layout.xml b/app/src/main/res/layout/loyalty_card_layout.xml
index ae6fc80dc..188297d66 100644
--- a/app/src/main/res/layout/loyalty_card_layout.xml
+++ b/app/src/main/res/layout/loyalty_card_layout.xml
@@ -8,6 +8,14 @@
android:baselineAligned="false"
android:padding="@dimen/activity_margin">
+
+
8dp
16dp
+
+
+ 33sp
diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml
new file mode 100644
index 000000000..aa416bb2a
--- /dev/null
+++ b/app/src/main/res/values/settings.xml
@@ -0,0 +1,13 @@
+
+
+
+ - #f16364
+ - #f58559
+ - #f9a43e
+ - #e4c62e
+ - #67bf74
+ - #59a2be
+ - #2093cd
+ - #ad62a7
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 41aa29c83..4b8072c7b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -85,6 +85,8 @@
Card ID copied to clipboard
+ Thumbnail for card
+
Start Intro
Welcome to Loyalty Card Keychain\n
Manage your barcode-based store/loyalty cards on your phone!\n\n