Podgląd listy zakupów wygenerowany. Kolejny krok naprzód na drodze do zakończenia podstawowej wersji aplikacji 😉
A zatem po kolei 🙂
Główne menu wzbogaciło się o ikonkę:
Jak dodać własną ikonkę?
Dla plików png wybieramy Image Asset, dla SVG, PSD wybieramy Vector Asset.
To wygeneruje wszystkie potrzebne ikonki i wstawi je do odpowiedniego folderu źródłowego.
Po kliknięciu w przycisk wywołuję metodę, która z listy obiadów na ten tydzień wyłuskuje mi posiłki:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void showShoppingListDialog() { | |
MealIngredientContract mealIngredientContract = new MealIngredientContract(); | |
Dinner[] dinners = dinnerContract.getDinners(dbHelper); | |
List<Meal> meals = new ArrayList<>(); | |
for (Dinner dinner : dinners) { | |
Meal meal = dinner.getMeal(); | |
meals.add(meal); | |
} | |
AlertDialog d = new AlertDialog.Builder(this) | |
.setTitle(R.string.shopping_list) | |
.setPositiveButton(android.R.string.ok, null) | |
.setMessage(mealIngredientContract.getShoppingList(meals, dbHelper)) | |
.create(); | |
d.show(); | |
} |
Posiłki przekazuję do metody z mealIngredientContract, żeby skorzystać z tego, że mam tam już query, którego, po drobnych modyfikacjach, mogę użyć ponownie. Najpierw budowa query:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@NonNull | |
private String getShoppingListQuery(List<Meal> meals) { | |
StringBuffer sb = new StringBuffer(); | |
sb.append("select name, count(name) from ("); | |
for (int i = 0; i < meals.size(); i++) { | |
sb.append(getIngredientsQuery()); | |
if (i < meals.size() – 1) { | |
sb.append(" union all "); | |
} | |
} | |
sb.append(") group by name order by name collate nocase;"); | |
return sb.toString(); | |
} |
Dla każdej potrawy pobieram zapytanie zwracające listę składników i łączę wyniki w jedno za pomocą ” union all”. Tak połączone zapytanie opakowuję w selecta, którym grupuje wszystkie składniki i zliczam ile razy pojawiły się na liście.
Pozostaje tylko przekazanie zapytania do bazy danych i przekazanie wyniku na zewnątrz funkcji.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public String getShoppingList(List<Meal> meals, SQLiteOpenHelper helper) { | |
ArrayList<String> array_list = new ArrayList<>(); | |
String[] queryArgs = getMealIds(meals); | |
String query = getShoppingListQuery(meals); | |
SQLiteDatabase db = helper.getReadableDatabase(); | |
Cursor res = db.rawQuery(query, queryArgs); | |
if (res != null && res.getCount() > 0) { | |
res.moveToFirst(); | |
do { | |
String name = res.getString(0); | |
int count = res.getInt(1); | |
array_list.add(count + " x " + name + "\n"); | |
} while (res.moveToNext()); | |
} | |
db.close(); | |
return TextUtils.join("\n", array_list); | |
} |
Jak na razie jako zwykły string, ale kto wie do czego dojdę w kolejnych krokach 😉
Brakuje jeszcze jednej metody do domknięcia tematu.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@NonNull | |
private String[] getMealIds(List<Meal> meals) { | |
String[] stringArgs = new String[meals.size()]; | |
for (int i = 0; i < meals.size(); i++) { | |
stringArgs[i] = Long.toString(meals.get(i).getId()); | |
} | |
return stringArgs; | |
} |
Planuję dać użytkownikowi możliwość otworzenia tej listy poza okienkiem alertu i umożliwić mu odznaczanie elementów z listy.
Eh, kolejne plany, a koniec konkursu już niebawem 🙂