Manual group ordering

This commit is contained in:
Sylvia van Os
2020-11-27 22:33:59 +01:00
committed by GitHub
parent cc895353a9
commit c1606fef62
10 changed files with 175 additions and 65 deletions

View File

@@ -15,6 +15,7 @@ android {
targetSdkVersion 29
versionCode 47
versionName "1.3.0"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {

View File

@@ -14,12 +14,13 @@ public class DBHelper extends SQLiteOpenHelper
{
public static final String DATABASE_NAME = "Catima.db";
public static final int ORIGINAL_DATABASE_VERSION = 1;
public static final int DATABASE_VERSION = 5;
public static final int DATABASE_VERSION = 6;
static class LoyaltyCardDbGroups
{
public static final String TABLE = "groups";
public static final String ID = "_id";
public static final String ORDER = "orderId";
}
static class LoyaltyCardDbIds
@@ -52,7 +53,8 @@ public class DBHelper extends SQLiteOpenHelper
{
// create table for card groups
db.execSQL("create table " + LoyaltyCardDbGroups.TABLE + "(" +
LoyaltyCardDbGroups.ID + " TEXT primary key not null)");
LoyaltyCardDbGroups.ID + " TEXT primary key not null," +
LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0')");
// create table for cards
db.execSQL("create table " + LoyaltyCardDbIds.TABLE + "(" +
@@ -109,6 +111,13 @@ public class DBHelper extends SQLiteOpenHelper
LoyaltyCardDbIdsGroups.groupID + " TEXT," +
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID +"))");
}
// Upgrade from version 5 to 6
if(oldVersion < 6 && newVersion >= 6)
{
db.execSQL("ALTER TABLE " + LoyaltyCardDbGroups.TABLE
+ " ADD COLUMN " + LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0'");
}
}
public long insertLoyaltyCard(final String store, final String note, final String cardId,
@@ -376,7 +385,7 @@ public class DBHelper extends SQLiteOpenHelper
SQLiteDatabase db = getReadableDatabase();
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE +
" ORDER BY " + LoyaltyCardDbGroups.ID + " COLLATE NOCASE ASC", null, null);
" ORDER BY " + LoyaltyCardDbGroups.ORDER + " ASC," + LoyaltyCardDbGroups.ID + " COLLATE NOCASE ASC", null, null);
return res;
}
@@ -398,6 +407,26 @@ public class DBHelper extends SQLiteOpenHelper
return groups;
}
public void reorderGroups(final List<Group> groups)
{
Integer order = 0;
SQLiteDatabase db = getWritableDatabase();
ContentValues contentValues;
for (Group group : groups)
{
contentValues = new ContentValues();
contentValues.put(LoyaltyCardDbGroups.ORDER, order);
db.update(LoyaltyCardDbGroups.TABLE, contentValues,
LoyaltyCardDbGroups.ID + "=?",
new String[]{group._id});
order++;
}
}
public Group getGroup(final String groupName)
{
SQLiteDatabase db = getReadableDatabase();
@@ -467,6 +496,7 @@ public class DBHelper extends SQLiteOpenHelper
SQLiteDatabase db = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(LoyaltyCardDbGroups.ID, name);
contentValues.put(LoyaltyCardDbGroups.ORDER, getGroupCount());
final long newId = db.insert(LoyaltyCardDbGroups.TABLE, null, contentValues);
return newId;
}
@@ -475,6 +505,7 @@ public class DBHelper extends SQLiteOpenHelper
{
ContentValues contentValues = new ContentValues();
contentValues.put(LoyaltyCardDbGroups.ID, name);
contentValues.put(LoyaltyCardDbGroups.ORDER, getGroupCount());
final long newId = db.insert(LoyaltyCardDbGroups.TABLE, null, contentValues);
return (newId != -1);
}

View File

@@ -37,8 +37,8 @@ class GroupCursorAdapter extends CursorAdapter
public void bindView(View view, Context context, Cursor cursor)
{
// Find fields to populate in inflated template
TextView nameField = (TextView) view.findViewById(R.id.name);
TextView countField = (TextView) view.findViewById(R.id.cardCount);
TextView nameField = view.findViewById(R.id.name);
TextView countField = view.findViewById(R.id.cardCount);
// Extract properties from cursor
Group group = Group.toGroup(cursor);

View File

@@ -15,6 +15,8 @@ import android.widget.TextView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
@@ -112,12 +114,16 @@ public class ManageGroupsActivity extends AppCompatActivity
return super.onOptionsItemSelected(item);
}
public void moveGroupUp(View view) {
moveGroup(view, true);
}
public void moveGroupDown(View view) {
moveGroup(view, false);
}
public void editGroup(View view) {
LinearLayout parentRow = (LinearLayout) view.getParent();
TextView groupNameTextView = (TextView) parentRow.findViewById(R.id.name);
final String groupName = (String) groupNameTextView.getText();
final String groupName = getGroupname(view);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.enter_group_name);
@@ -131,8 +137,6 @@ public class ManageGroupsActivity extends AppCompatActivity
public void onClick(DialogInterface dialog, int which) {
db.updateGroup(groupName, input.getText().toString());
updateGroupList();
// Rename may change ordering, so invalidate
invalidateHomescreenActiveTab();
}
});
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@@ -146,11 +150,7 @@ public class ManageGroupsActivity extends AppCompatActivity
}
public void deleteGroup(View view) {
LinearLayout parentRow = (LinearLayout) view.getParent();
TextView groupNameTextView = (TextView) parentRow.findViewById(R.id.name);
final String groupName = (String) groupNameTextView.getText();
final String groupName = getGroupname(view);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.deleteConfirmationGroup);
@@ -187,8 +187,6 @@ public class ManageGroupsActivity extends AppCompatActivity
public void onClick(DialogInterface dialog, int which) {
db.insertGroup(input.getText().toString());
updateGroupList();
// Create may change ordering, so invalidate
invalidateHomescreenActiveTab();
}
});
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@@ -201,4 +199,56 @@ public class ManageGroupsActivity extends AppCompatActivity
return dialog;
}
private String getGroupname(View view) {
LinearLayout parentRow = (LinearLayout) view.getParent().getParent();
TextView groupNameTextView = parentRow.findViewById(R.id.name);
return (String) groupNameTextView.getText();
}
private void moveGroup(View view, boolean up) {
final String groupName = getGroupname(view);
List<Group> groups = db.getGroups();
int currentIndex = -1;
Integer newIndex;
// Get current index in group list
for (int i = 0; i < groups.size(); i++) {
if (groups.get(i)._id.equals(groupName)) {
currentIndex = i;
break;
}
}
if (currentIndex == -1) {
throw new IndexOutOfBoundsException();
}
// Reinsert group in correct position
if (up) {
newIndex = currentIndex - 1;
} else {
newIndex = currentIndex + 1;
}
// Don't try to move out of bounds
if (newIndex < 0 || newIndex >= groups.size()) {
return;
}
Group group = groups.remove(currentIndex);
groups.add(newIndex, group);
// Update database
db.reorderGroups(groups);
// Update UI
updateGroupList();
// Ordering may have changed, so invalidate
invalidateHomescreenActiveTab();
}
}

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7,10l5,5 5,-5z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7,14l5,-5 5,5z"/>
</vector>

View File

@@ -2,7 +2,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
@@ -11,58 +11,74 @@
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/valueLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/storeNameTextSize"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:textSize="@dimen/storeNameTextSize"
android:textStyle="bold"/>
<TextView
android:id="@+id/cardCount"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/noteTextSize"/>
</LinearLayout>
<ImageButton
android:id="@+id/edit"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_marginLeft="@dimen/activity_margin"
android:src="@drawable/ic_mode_edit_white_24dp"
android:contentDescription="@string/edit"
app:tint="#000000"
android:onClick="editGroup" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageButton
android:id="@+id/delete"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_marginLeft="@dimen/activity_margin"
android:src="@drawable/ic_delete_white_24dp"
android:contentDescription="@string/delete"
app:tint="#000000"
android:onClick="deleteGroup"/>
<ImageButton
android:id="@+id/moveUp"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_weight="1"
app:srcCompat="@drawable/ic_baseline_arrow_drop_up_24"
android:contentDescription="@string/moveUp"
app:tint="#000000"
android:onClick="moveGroupUp"/>
<ImageButton
android:id="@+id/moveDown"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_weight="1"
app:srcCompat="@drawable/ic_baseline_arrow_drop_down_24"
android:contentDescription="@string/moveDown"
app:tint="#000000"
android:onClick="moveGroupDown"/>
<ImageButton
android:id="@+id/edit"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_weight="1"
android:src="@drawable/ic_mode_edit_white_24dp"
android:contentDescription="@string/edit"
app:tint="#000000"
android:onClick="editGroup" />
<ImageButton
android:id="@+id/delete"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_weight="1"
android:src="@drawable/ic_delete_white_24dp"
android:contentDescription="@string/delete"
app:tint="#000000"
android:onClick="deleteGroup"/>
</LinearLayout>
</LinearLayout>

View File

@@ -134,6 +134,8 @@
<string name="all">All</string>
<string name="deleteConfirmationGroup">Please confirm you want to delete this group</string>
<string name="failedOpeningFileManager">Failed opening a file manager. Please make sure one is installed.</string>
<string name="moveUp">Move up in list</string>
<string name="moveDown">Move down in list</string>
<string name="leaveWithoutSaveTitle">Leave without saving</string>
<string name="leaveWithoutSaveConfirmation">Are you sure you want to leave this screen? Changed made will not be saved.</string>
<string name="addWithCamera">Scan the barcode with your camera</string>

View File

@@ -202,7 +202,7 @@ public class ImportExportTest
private void checkGroups()
{
Cursor cursor = db.getGroupCursor();
int index = 1;
int index = db.getGroupCount();
while(cursor.moveToNext())
{
@@ -212,7 +212,7 @@ public class ImportExportTest
assertEquals(expectedGroupName, group._id);
index++;
index--;
}
cursor.close();
}

View File

@@ -193,14 +193,14 @@ public class MainActivityTest
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
// Adding another group should have them sorted alphabetically
// Adding another group should have it added to the end
db.insertGroup("Alphabetical two");
activityController.pause();
activityController.resume();
assertEquals(3, groupTabs.getTabCount());
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
assertEquals("Alphabetical two", groupTabs.getTabAt(1).getText().toString());
assertEquals("One", groupTabs.getTabAt(2).getText().toString());
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
assertEquals("Alphabetical two", groupTabs.getTabAt(2).getText().toString());
// Removing a group should also change the list
db.deleteGroup("Alphabetical two");