diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..c6cbe562a --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 000000000..b9acfb4b5 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.2" + + defaultConfig { + applicationId "protect.card_locker" + minSdkVersion 17 + targetSdkVersion 23 + versionCode 1 + versionName "0.1" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions { + disable "GoogleAppIndexingWarning" + disable "ButtonStyle" + disable "AlwaysShowAction" + } + + // This is for Robolectric support for SDK 23 + useLibrary 'org.apache.http.legacy' +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:23.1.1' + compile 'com.android.support:design:23.1.1' + compile 'com.journeyapps:zxing-android-embedded:3.0.1@aar' + compile 'com.google.zxing:core:3.2.0' + testCompile 'junit:junit:4.12' + testCompile "org.robolectric:robolectric:3.0" +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 000000000..147200682 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/brarcher/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/protect/card_locker/ApplicationTest.java b/app/src/androidTest/java/protect/card_locker/ApplicationTest.java new file mode 100644 index 000000000..802030b5b --- /dev/null +++ b/app/src/androidTest/java/protect/card_locker/ApplicationTest.java @@ -0,0 +1,15 @@ +package protect.card_locker; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase +{ + public ApplicationTest() + { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..52c803ddc --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/protect/card_locker/DBHelper.java b/app/src/main/java/protect/card_locker/DBHelper.java new file mode 100644 index 000000000..6d2890b4f --- /dev/null +++ b/app/src/main/java/protect/card_locker/DBHelper.java @@ -0,0 +1,128 @@ +package protect.card_locker; + + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +public class DBHelper extends SQLiteOpenHelper +{ + public static final String DATABASE_NAME = "LoyaltyCards.db"; + public static final int DATABASE_VERSION = 1; + + class LoyaltyCardDbIds + { + public static final String TABLE = "cards"; + public static final String ID = "_id"; + public static final String STORE = "store"; + public static final String CARD_ID = "cardid"; + public static final String BARCODE_TYPE = "barcodetype"; + } + + public DBHelper(Context context) + { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) + { + // create table for gift cards + db.execSQL("create table " + LoyaltyCardDbIds.TABLE + "(" + + LoyaltyCardDbIds.ID + " INTEGER primary key autoincrement," + + LoyaltyCardDbIds.STORE + " TEXT not null," + + LoyaltyCardDbIds.CARD_ID + " TEXT not null," + + LoyaltyCardDbIds.BARCODE_TYPE + " TEXT not null)"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) + { + // Do not support versioning yet + db.execSQL("DROP TABLE IF EXISTS " + LoyaltyCardDbIds.TABLE); + onCreate(db); + } + + public boolean insertLoyaltyCard(final String store, final String cardId, final String barcodeType) + { + SQLiteDatabase db = getWritableDatabase(); + ContentValues contentValues = new ContentValues(); + contentValues.put(LoyaltyCardDbIds.STORE, store); + contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId); + contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType); + final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues); + return (newId != -1); + } + + + public boolean updateLoyaltyCard(final int id, final String store, final String cardId, + final String barcodeType) + { + SQLiteDatabase db = getWritableDatabase(); + ContentValues contentValues = new ContentValues(); + contentValues.put(LoyaltyCardDbIds.STORE, store); + contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId); + contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType); + int rowsUpdated = db.update(LoyaltyCardDbIds.TABLE, contentValues, + LoyaltyCardDbIds.ID + "=?", + new String[]{Integer.toString(id)}); + return (rowsUpdated == 1); + } + + public LoyaltyCard getLoyaltyCard(final int id) + { + SQLiteDatabase db = getReadableDatabase(); + Cursor data = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE + + " where " + LoyaltyCardDbIds.ID + "=?", new String[]{String.format("%d", id)}); + + LoyaltyCard card = null; + + if(data.getCount() == 1) + { + data.moveToFirst(); + card = LoyaltyCard.toLoyaltyCard(data); + } + + data.close(); + + return card; + } + + public boolean deleteLoyaltyCard (final int id) + { + SQLiteDatabase db = getWritableDatabase(); + int rowsDeleted = db.delete(LoyaltyCardDbIds.TABLE, + LoyaltyCardDbIds.ID + " = ? ", + new String[]{String.format("%d", id)}); + return (rowsDeleted == 1); + } + + public Cursor getLoyaltyCardCursor() + { + SQLiteDatabase db = getReadableDatabase(); + Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE + + " ORDER BY " + LoyaltyCardDbIds.STORE, null); + return res; + } + + public int getLoyaltyCardCount() + { + SQLiteDatabase db = getReadableDatabase(); + Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbIds.TABLE, null); + + int numItems = 0; + + if(data.getCount() == 1) + { + data.moveToFirst(); + numItems = data.getInt(0); + } + + data.close(); + + return numItems; + } +} + diff --git a/app/src/main/java/protect/card_locker/LoyaltyCard.java b/app/src/main/java/protect/card_locker/LoyaltyCard.java new file mode 100644 index 000000000..504692fac --- /dev/null +++ b/app/src/main/java/protect/card_locker/LoyaltyCard.java @@ -0,0 +1,29 @@ +package protect.card_locker; + +import android.database.Cursor; + +public class LoyaltyCard +{ + public final int id; + public final String store; + public final String cardId; + public final String barcodeType; + + public LoyaltyCard(final int id, final String store, final String cardId, final String barcodeType) + { + this.id = id; + this.store = store; + this.cardId = cardId; + this.barcodeType = barcodeType; + } + + public static LoyaltyCard toLoyaltyCard(Cursor cursor) + { + int id = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ID)); + String store = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STORE)); + String cardId = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)); + String barcodeType = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)); + + return new LoyaltyCard(id, store, cardId, barcodeType); + } +} diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java new file mode 100644 index 000000000..4bec48ca0 --- /dev/null +++ b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java @@ -0,0 +1,46 @@ +package protect.card_locker; + +import android.content.Context; +import android.database.Cursor; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; +import android.widget.TextView; + +class LoyaltyCardCursorAdapter extends CursorAdapter +{ + public LoyaltyCardCursorAdapter(Context context, Cursor cursor) + { + super(context, cursor, 0); + } + + // The newView method is used to inflate a new view and return it, + // you don't bind any data to the view at this point. + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) + { + return LayoutInflater.from(context).inflate(R.layout.loyalty_card_layout, parent, false); + } + + // The bindView method is used to bind all data to a given view + // such as setting the text on a TextView. + @Override + public void bindView(View view, Context context, Cursor cursor) + { + // Find fields to populate in inflated template + TextView storeField = (TextView) view.findViewById(R.id.store); + TextView cardIdField = (TextView) view.findViewById(R.id.cardId); + + // Extract properties from cursor + LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor); + + // Populate fields with extracted properties + storeField.setText(loyaltyCard.store); + + String cardIdFormat = view.getResources().getString(R.string.cardIdFormat); + String cardIdLabel = view.getResources().getString(R.string.cardId); + String cardIdText = String.format(cardIdFormat, cardIdLabel, loyaltyCard.cardId); + cardIdField.setText(cardIdText); + } +} diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java new file mode 100644 index 000000000..c607c0dd6 --- /dev/null +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -0,0 +1,301 @@ +package protect.card_locker; + + +import android.content.Intent; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.support.design.widget.Snackbar; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + + +public class LoyaltyCardViewActivity extends AppCompatActivity +{ + private static final String TAG = "CardLocker"; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + setContentView(R.layout.loyalty_card_view_activity); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + ActionBar actionBar = getSupportActionBar(); + if(actionBar != null) + { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + @Override + public void onResume() + { + super.onResume(); + + final Bundle b = getIntent().getExtras(); + final int loyaltyCardId = b != null ? b.getInt("id") : 0; + final boolean updateLoyaltyCard = b != null && b.getBoolean("update", false); + final boolean viewLoyaltyCard = b != null && b.getBoolean("view", false); + + Log.i(TAG, "To view card: " + loyaltyCardId); + + final EditText storeField = (EditText) findViewById(R.id.storeName); + final EditText cardIdField = (EditText) findViewById(R.id.cardId); + final EditText barcodeTypeField = (EditText) findViewById(R.id.barcodeType); + final ImageView barcodeImage = (ImageView) findViewById(R.id.barcode); + final View barcodeIdLayout = findViewById(R.id.barcodeIdLayout); + final View barcodeTypeLayout = findViewById(R.id.barcodeTypeLayout); + final View barcodeImageLayout = findViewById(R.id.barcodeLayout); + final View barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout); + + final Button captureButton = (Button) findViewById(R.id.captureButton); + final Button saveButton = (Button) findViewById(R.id.saveButton); + final Button cancelButton = (Button) findViewById(R.id.cancelButton); + + final DBHelper db = new DBHelper(this); + + if(updateLoyaltyCard || viewLoyaltyCard) + { + final LoyaltyCard loyaltyCard = db.getLoyaltyCard(loyaltyCardId); + + storeField.setText(loyaltyCard.store); + + if(cardIdField.getText().length() == 0) + { + cardIdField.setText(loyaltyCard.cardId); + } + + if(barcodeTypeField.getText().length() == 0) + { + barcodeTypeField.setText(loyaltyCard.barcodeType); + } + + storeField.setEnabled(false); + + if(updateLoyaltyCard) + { + setTitle(R.string.editCardTitle); + } + else + { + barcodeCaptureLayout.setVisibility(View.GONE); + captureButton.setVisibility(View.GONE); + saveButton.setVisibility(View.GONE); + cancelButton.setVisibility(View.GONE); + setTitle(R.string.viewCardTitle); + } + } + else + { + setTitle(R.string.addCardTitle); + } + + if(cardIdField.getText().length() == 0) + { + barcodeIdLayout.setVisibility(View.GONE); + } + + barcodeTypeLayout.setVisibility(View.GONE); + + if(cardIdField.getText().length() > 0 && barcodeTypeField.getText().length() > 0) + { + MultiFormatWriter writer = new MultiFormatWriter(); + BitMatrix result; + try + { + String formatString = barcodeTypeField.getText().toString(); + BarcodeFormat format = BarcodeFormat.valueOf(formatString); + if(format == null) + { + throw new IllegalArgumentException("Unrecognized barcode format: " + formatString); + } + + String cardIdString = cardIdField.getText().toString(); + + Log.i(TAG, "Card: " + cardIdString); + + result = writer.encode(cardIdString, format, 1500, 400, null); + + final int WHITE = 0xFFFFFFFF; + final int BLACK = 0xFF000000; + + int width = result.getWidth(); + int height = result.getHeight(); + int[] pixels = new int[width * height]; + for (int y = 0; y < height; y++) + { + int offset = y * width; + for (int x = 0; x < width; x++) + { + pixels[offset + x] = result.get(x, y) ? BLACK : WHITE; + } + } + Bitmap bitmap = Bitmap.createBitmap(width, height, + Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + barcodeImage.setImageBitmap(bitmap); + + barcodeIdLayout.setVisibility(View.VISIBLE); + barcodeImageLayout.setVisibility(View.VISIBLE); + } + catch (WriterException e) + { + Log.e(TAG, "Failed to generate barcode", e); + } + catch(IllegalArgumentException e) + { + Log.e(TAG, "Failed to generate barcode", e); + } + } + + View.OnClickListener captureCallback = new View.OnClickListener() + { + @Override + public void onClick(View v) + { + IntentIntegrator integrator = new IntentIntegrator(LoyaltyCardViewActivity.this); + integrator.setDesiredBarcodeFormats(IntentIntegrator.PRODUCT_CODE_TYPES); + + String prompt = getResources().getString(R.string.scanCardBarcode); + integrator.setPrompt(prompt); + integrator.initiateScan(); + } + }; + + captureButton.setOnClickListener(captureCallback); + + saveButton.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(final View v) + { + String store = storeField.getText().toString(); + String cardId = cardIdField.getText().toString(); + String barcodeType = barcodeTypeField.getText().toString(); + + if(store.isEmpty()) + { + Snackbar.make(v, R.string.noStoreError, Snackbar.LENGTH_LONG).show(); + return; + } + + if(cardId.isEmpty() || barcodeType.isEmpty()) + { + Snackbar.make(v, R.string.noCardIdError, Snackbar.LENGTH_LONG).show(); + return; + } + + if(updateLoyaltyCard) + { + db.updateLoyaltyCard(loyaltyCardId, store, cardId, barcodeType); + Log.i(TAG, "Updated " + loyaltyCardId + " to " + cardId); + } + else + { + db.insertLoyaltyCard(store, cardId, barcodeType); + } + + finish(); + } + }); + + cancelButton.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View v) + { + finish(); + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + final Bundle b = getIntent().getExtras(); + final boolean updateLoyaltyCard = b != null && b.getBoolean("update", false); + final boolean viewLoyaltyCard = b != null && b.getBoolean("view", false); + + if(viewLoyaltyCard) + { + getMenuInflater().inflate(R.menu.card_edit_menu, menu); + } + else if(updateLoyaltyCard) + { + getMenuInflater().inflate(R.menu.card_delete_menu, menu); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) + { + int id = item.getItemId(); + + final Bundle b = getIntent().getExtras(); + final int loyaltyCardId = b != null ? b.getInt("id") : 0; + + switch(id) + { + case R.id.action_delete: + Log.e(TAG, "Deleting card: " + loyaltyCardId); + + DBHelper db = new DBHelper(this); + db.deleteLoyaltyCard(loyaltyCardId); + finish(); + return true; + case R.id.action_edit: + Intent intent = new Intent(getApplicationContext(), LoyaltyCardViewActivity.class); + Bundle bundle = new Bundle(); + bundle.putInt("id", loyaltyCardId); + bundle.putBoolean("update", true); + intent.putExtras(bundle); + startActivity(intent); + finish(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent intent) + { + IntentResult result = + IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); + if (result != null) + { + String contents = result.getContents(); + String format = result.getFormatName(); + if(contents != null && contents.isEmpty() == false && + format != null && format.isEmpty() == false) + { + Log.i(TAG, "Read Contents from scan: " + contents); + Log.i(TAG, "Read Format: " + format); + + final EditText cardIdField = (EditText) findViewById(R.id.cardId); + cardIdField.setText(contents); + final EditText barcodeTypeField = (EditText) findViewById(R.id.barcodeType); + barcodeTypeField.setText(format); + onResume(); + } + } + } +} diff --git a/app/src/main/java/protect/card_locker/MainActivity.java b/app/src/main/java/protect/card_locker/MainActivity.java new file mode 100644 index 000000000..b7819033e --- /dev/null +++ b/app/src/main/java/protect/card_locker/MainActivity.java @@ -0,0 +1,97 @@ +package protect.card_locker; + +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.TextView; + +public class MainActivity extends AppCompatActivity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main_activity); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + updateLoyaltyCardList(); + } + + @Override + protected void onResume() + { + super.onResume(); + + updateLoyaltyCardList(); + } + + private void updateLoyaltyCardList() + { + final ListView cardList = (ListView) findViewById(R.id.list); + final TextView helpText = (TextView) findViewById(R.id.helpText); + final DBHelper db = new DBHelper(this); + + if(db.getLoyaltyCardCount() > 0) + { + cardList.setVisibility(View.VISIBLE); + helpText.setVisibility(View.GONE); + } + else + { + cardList.setVisibility(View.GONE); + helpText.setVisibility(View.VISIBLE); + } + + Cursor cardCursor = db.getLoyaltyCardCursor(); + + final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor); + cardList.setAdapter(adapter); + + cardList.setOnItemClickListener(new AdapterView.OnItemClickListener() + { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) + { + Cursor selected = (Cursor) parent.getItemAtPosition(position); + LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected); + + Intent i = new Intent(view.getContext(), LoyaltyCardViewActivity.class); + final Bundle b = new Bundle(); + b.putInt("id", loyaltyCard.id); + b.putBoolean("view", true); + i.putExtras(b); + startActivity(i); + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + getMenuInflater().inflate(R.menu.main_menu, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) + { + int id = item.getItemId(); + + if (id == R.id.action_add) + { + Intent i = new Intent(getApplicationContext(), LoyaltyCardViewActivity.class); + startActivity(i); + return true; + } + + return super.onOptionsItemSelected(item); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png new file mode 100644 index 000000000..694179bd4 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_delete_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_delete_white_24dp.png new file mode 100644 index 000000000..4a9f76947 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_delete_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png new file mode 100644 index 000000000..595ff10ac Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png new file mode 100644 index 000000000..3856041d7 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_delete_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_delete_white_24dp.png new file mode 100644 index 000000000..e2f5f3555 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_delete_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png new file mode 100644 index 000000000..12b09f1d9 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png new file mode 100644 index 000000000..67bb598e5 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png new file mode 100644 index 000000000..388b5b060 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png new file mode 100644 index 000000000..5a06bff5a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png new file mode 100644 index 000000000..0fdced8fc Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png new file mode 100644 index 000000000..3fcdfdb55 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png new file mode 100644 index 000000000..02e19d045 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png new file mode 100644 index 000000000..d64c22e9e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png new file mode 100644 index 000000000..8d322aa9b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png new file mode 100644 index 000000000..d6668a051 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png differ diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml new file mode 100644 index 000000000..fab4bdcdd --- /dev/null +++ b/app/src/main/res/layout/content_main.xml @@ -0,0 +1,29 @@ + + + + + + + diff --git a/app/src/main/res/layout/loyalty_card_layout.xml b/app/src/main/res/layout/loyalty_card_layout.xml new file mode 100644 index 000000000..6679ab575 --- /dev/null +++ b/app/src/main/res/layout/loyalty_card_layout.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/loyalty_card_view_activity.xml b/app/src/main/res/layout/loyalty_card_view_activity.xml new file mode 100644 index 000000000..5e53fbb1b --- /dev/null +++ b/app/src/main/res/layout/loyalty_card_view_activity.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +