Po co przerywać użytkownikowi dodawanie składników do posiłku i wysyłać go na ekran dodawania składników? Zrobię to mądrzej 🙂
Jedną z rzeczy, które lubię w programowaniu jest to, że jeżeli sobie coś wymyślę, to z reguły okazuje się, że da się to zrobić. Problemem jest tylko ilość czasu, który trzeba na to poświęcić.
Mam filtrowaną listę składników, które mogę dodać do posiłku, ale w momencie kiedy wyszukiwanego składnika nie ma jeszcze w bazie użytkownik będzie zmuszony przerywać proces, przechodzić do ekranu dodawania składnika i wracać żeby go przypisać do posiłku. Męczące i nieefektowne.
Wymyśliłam sobie, że jeżeli przefiltrowana lista przestaje zwracać cokolwiek, to przy szukajce pojawia się klikalny przycisk dodawania. Po kliknięciu na plus składnik dodaje się do bazy i od razu przypisuje do posiłku + użytkownik dostaje wiadomość o poprawnym dorzuceniu składnika do bazy.
Tak to wygląda w praktyce:
a tak w kodzie:
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
final EditText filterEditText = (EditText) addIngredientView.findViewById(R.id.name_filter); | |
filterEditText.addTextChangedListener(new TextWatcher() { | |
@Override | |
public void onTextChanged(CharSequence s, int start, int before, int count) { | |
Filter filter = ingredientListAdapter.getFilter(); | |
filter.filter(s, new Filter.FilterListener() { | |
@Override | |
public void onFilterComplete(int count) { | |
int icon = count == 0 ? android.R.drawable.ic_menu_add : 0; | |
filterEditText.setCompoundDrawablesWithIntrinsicBounds(0, 0, icon, 0); | |
} | |
}); | |
} | |
@Override | |
public void beforeTextChanged(CharSequence s, int start, int count, int after) { | |
} | |
@Override | |
public void afterTextChanged(Editable s) { | |
} | |
}); |
Do wywołania metody filter.filter(s) dorzucamy listener, który zostanie odpalony po zakończeniu filtrowania. Dzięki temu możemy sprawdzić ile rezultatów zostało zwróconych i w zależności od tego pokazać przycisk dodawania. Zależało mi na tym żeby przycisk dodawania był wyświetlany kiedy zostaną spełnione takie a nie inne warunki, stąd ta dziwna komenda setCompoundDrawablesWithIntrinsicBounds. Gdyby przycisk miał być widoczny zawsze wsadziłabym go w xml-a.
Trochę więcej trudności sprawia obsługa kliknięcia w taki „przycisk”. Niestety trzeba wyliczać czy obszar, na który kliknął użytkownik zawiera się w obszarze wyświetlania ikonki… no cóż, skoro tak trzeba, to trzeba. Nikt nie wymyślił nic mądrzejszego.
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
filterEditText.setOnTouchListener(new View.OnTouchListener() { | |
@Override | |
public boolean onTouch(View v, MotionEvent event) { | |
if (event.getAction() == MotionEvent.ACTION_UP) { | |
Drawable drawable = filterEditText.getCompoundDrawables()[DRAWABLE_RIGHT]; | |
if (drawable != null) { | |
Rect bounds = drawable.getBounds(); | |
if (event.getRawX() >= (filterEditText.getRight() – bounds.width())) { | |
String text = filterEditText.getText().toString().trim(); | |
if (text.length() != 0) { | |
long ingredientId = ingredientContract.insert(dbHelper, text); | |
mealIngredientContract.insert(dbHelper, meal.getId(), ingredientId); | |
ingredientListAdapter.updateResults(mealIngredientContract.getIngredientsWithMeal(meal, dbHelper)); | |
filterEditText.setText(""); | |
Toast.makeText(v.getContext(), R.string.ingredient_added_message, Toast.LENGTH_SHORT).show(); | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
}); |
Po tym jak stwierdzimy, że użytkownik kliknął w ikonkę i ma coś wpisane dodajemy to do bazy – dokładnie do dwóch tabelek, tej ze składnikami i tej asocjacyjnej dla posiłków i składników. Przeładowujemy listę, czyścimy filtr i wyświetlamy użytkownikowi wiadomość, żeby się nie zdziwił, że coś się nagle dzieje.
To tyle na dziś, czas chyba opracować funkcję tworzącą listę zakupów 🙂