diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb6828..5d19981 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/app/src/main/java/com/hikapro/backpack/MainActivity.java b/app/src/main/java/com/hikapro/backpack/MainActivity.java index 9282095..09db3d8 100644 --- a/app/src/main/java/com/hikapro/backpack/MainActivity.java +++ b/app/src/main/java/com/hikapro/backpack/MainActivity.java @@ -6,6 +6,7 @@ import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; import android.util.Log; +import android.view.MenuItem; import com.hikapro.backpack.model.AddModel; import com.hikapro.backpack.model.DetailModel; @@ -40,6 +41,21 @@ public class MainActivity extends Activity implements View.ActivityCallback { // life cycle --> + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + boolean ret; + switch (item.getItemId()) { + case android.R.id.home: + this.getFragmentManager().popBackStack(); + ret = true; + break; + default: + ret = super.onOptionsItemSelected(item); + } + return ret; + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -48,7 +64,6 @@ public class MainActivity extends Activity implements View.ActivityCallback { stateMaintainer.init(); - if (fragmentManager.getBackStackEntryCount() == 0 && savedInstanceState == null) { startSetListFragment(); } else { @@ -229,9 +244,9 @@ public class MainActivity extends Activity implements View.ActivityCallback { } @Override - public void startItemDetailFragment(Item item) { + public void startItemDetailFragment(Item item, int setId) { - ItemDetailFragment view = ItemDetailFragment.newFromItem(item); + ItemDetailFragment view = ItemDetailFragment.newInstance(item, setId); ItemDetailPresenter presenter = new ItemDetailPresenter(); DetailModel model = new DetailModel(); diff --git a/app/src/main/java/com/hikapro/backpack/StateMaintainer.java b/app/src/main/java/com/hikapro/backpack/StateMaintainer.java index 0680e97..c830f36 100644 --- a/app/src/main/java/com/hikapro/backpack/StateMaintainer.java +++ b/app/src/main/java/com/hikapro/backpack/StateMaintainer.java @@ -79,7 +79,6 @@ public class StateMaintainer { public void put(String key, Object obj) { data.put(key, obj); - Log.i(this.toString(), String.format("Put object %s Total count %d", key, data.size())); } diff --git a/app/src/main/java/com/hikapro/backpack/model/DetailModel.java b/app/src/main/java/com/hikapro/backpack/model/DetailModel.java index 57f2d30..12d9532 100644 --- a/app/src/main/java/com/hikapro/backpack/model/DetailModel.java +++ b/app/src/main/java/com/hikapro/backpack/model/DetailModel.java @@ -2,13 +2,17 @@ package com.hikapro.backpack.model; import android.graphics.Bitmap; import android.os.Message; +import android.widget.Toast; +import com.hikapro.backpack.App; import com.hikapro.backpack.model.dao.Command; import com.hikapro.backpack.model.dao.DAO; import com.hikapro.backpack.model.dao.Event; import com.hikapro.backpack.model.entities.Item; import com.hikapro.backpack.presenter.Presenter; +import java.util.Collections; + /** * Created by tariel on 23/04/16. */ @@ -18,10 +22,10 @@ public class DetailModel implements Model.Detail { private Item item; private DAO dao; private Bitmap pic; + private int currentSet; public DetailModel() { this.dao = DAO.getInstance(); - dao.registerObserver(this); } // detail --> @@ -45,17 +49,15 @@ public class DetailModel implements Model.Detail { @Override public void notifyDataSetChanged() { - presenter.notifyDataSetChanged(); + if (presenter != null) + presenter.notifyDataSetChanged(); } @Override public void onDestroy(boolean isConfigurationChanging) { if ( !isConfigurationChanging ) { presenter = null; } - } - - private void sendMessage(String message) { - presenter.showMessage(message); + dao.unregisterObserver(this); } // events <-- @@ -63,15 +65,64 @@ public class DetailModel implements Model.Detail { // process --> @Override public void executeQuery() { + dao.registerObserver(this); + + Message command = Message.obtain(); + command.what = Command.ITEM_READ; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); - notifyDataSetChanged(); - Message command; command = Message.obtain(); command.what = Command.ITEM_GET_IMAGE; command.arg1 = item.getId(); dao.executeCommand(command); - } + + @Override + public void pendingRemove(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_PENDING_REMOVAL; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + } + } + + @Override + public void pendingRemoveCancel(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_REMOVAL_CANCEL; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + } + } + + @Override + public void packItem(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_PACK; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + } + } + + @Override + public void unpackItem(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_UNPACK; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + } + } + // process <-- @@ -79,6 +130,7 @@ public class DetailModel implements Model.Detail { public void setPresenter(Presenter.ItemDetail presenter) { this.presenter = presenter; this.item = presenter.getCurrentItem(); + this.currentSet = presenter.getSetId(); } @Override @@ -90,10 +142,40 @@ public class DetailModel implements Model.Detail { public void onEvent(Message event) { switch (event.what) { - case Event.ITEM_IMAGE_LOAD_ERROR : + + case Event.ITEM_IMAGE_LOAD_ERROR: + pic = null; + if (presenter != null) + presenter.notifyPictureChanged(); break; - case Event.ITEM_IMAGE_LOAD_COMPLETED : + case Event.ITEM_READ_ERROR: + Toast.makeText(App.getAppContext(), "Item read error", Toast.LENGTH_SHORT).show(); + break; + case Event.ITEM_PACK_ERROR: + break; + case Event.ITEM_UNPACK_ERROR: + break; + case Event.ITEM_PENDING_REMOVAL_ERROR: + break; + case Event.ITEM_REMOVAL_CANCEL_ERROR: + break; + case Event.ITEM_IMAGE_LOAD_COMPLETED: pic = (Bitmap) event.obj; + if (presenter != null) + presenter.notifyPictureChanged(); + break; + case Event.ITEM_PACKED: + executeQuery(); + break; + case Event.ITEM_UNPACKED: + executeQuery(); + case Event.ITEM_PENDING_REMOVAL_COMPLETED: + executeQuery(); + case Event.ITEM_REMOVAL_CANCELED: + executeQuery(); + break; + case Event.ITEM_READ_COMPLETED: + item = (Item) event.obj; notifyDataSetChanged(); break; } diff --git a/app/src/main/java/com/hikapro/backpack/model/ItemModel.java b/app/src/main/java/com/hikapro/backpack/model/ItemModel.java index 4d2120e..efeed30 100644 --- a/app/src/main/java/com/hikapro/backpack/model/ItemModel.java +++ b/app/src/main/java/com/hikapro/backpack/model/ItemModel.java @@ -23,35 +23,133 @@ import com.hikapro.backpack.presenter.Presenter; public class ItemModel implements Model.Item { protected Presenter.ItemList presenter; - private List rawCategories; - private List sortedCategories; - private List rawItems; protected DAO dao; protected int currentSet; protected int currentSetActiveItemsQty; protected int packedQty; protected Hashtable categoriesCache; - private List itemsCache; - private List itemsDiscardCache; + protected List itemsCache; - private Hashtable> items; - protected Hashtable> cache; + protected Hashtable> items; public ItemModel() { - this.rawCategories = new ArrayList<>(); - this.rawItems = new ArrayList<>(); - this.sortedCategories = new ArrayList<>(); - this.categoriesCache = new Hashtable<>(20, 0.9f); + this.itemsCache = new ArrayList<>(256); this.packedQty = -1; - - this.itemsCache = new ArrayList<>(); - this.itemsDiscardCache = new ArrayList<>(); - this.cache = new Hashtable<>(12, 0.9f); this.dao = DAO.getInstance(); + } + + @Override + public void onEvent(Message event) { + + switch (event.what) { + case Event.SET_ITEMS_LOAD_ERROR : // TODO check + if (presenter != null) { + if (packedQty == -1) + packedQty = presenter.getCurrentSet().getPackedQty(); + presenter.notifyItemPackStatusChanged(); + } + break; + case Event.SET_UNPACK_ERROR : + break; + case Event.SET_RESTORE_ERROR : + break; + case Event.SET_GET_STAT_ERROR: + break; + case Event.ITEM_FROM_SET_ERROR : + break; + case Event.ITEM_DELETE_ERROR : + break; + case Event.ITEM_PACK_ERROR : + break; + case Event.ITEM_UNPACK_ERROR : + break; + case Event.ITEM_INSERT_ERROR : + break; + case Event.ITEM_PENDING_REMOVAL_ERROR: + break; + case Event.ITEM_REMOVAL_CANCEL_ERROR: + break; + case Event.ITEM_CATEGORY_LOAD_ERROR : + break; + case Event.SET_ITEMS_LOAD_COMPLETED : + itemsCache = (List) event.obj; + notifyDataSetChanged(); + break; + case Event.SET_GET_STAT_COMPLETED: + currentSetActiveItemsQty = event.arg1; + packedQty = event.arg2; + if (presenter != null) + presenter.notifyItemPackStatusChanged(); + break; + case Event.ITEM_PENDING_REMOVAL_COMPLETED: + executeQuery(); + break; + case Event.ITEM_REMOVAL_CANCELED: + executeQuery(); + break; + case Event.ITEM_READ_COMPLETED: + itemsCache.add((Item) event.obj); + Collections.sort(itemsCache); + notifyDataSetChanged(); + break; + case Event.SET_UNPACK_COMPLETED: + packedQty = 0; + if (presenter != null) { + presenter.notifyItemPackStatusChanged(); + } + break; + case Event.ITEM_CATEGORY_LOAD_COMPLETED: + categoriesCache = (Hashtable)event.obj; + break; + case Event.ITEM_FROM_SET_DELETED: + executeQuery(); + break; + case Event.ITEM_DELETED : + break; + case Event.ITEM_PACKED : + executeQuery(); + break; + case Event.ITEM_UNPACKED : + executeQuery(); + break; + case Event.ITEM_INSERTED : + break; + case Event.SET_RESTORE_COMPLETED : + if (presenter != null) { + presenter.notifyDataSetChanged(); + } + Toast.makeText(App.getAppContext(), "Restore completed", Toast.LENGTH_SHORT).show(); + break; + } + } + + @Override + public void executeQuery() { + Message command; dao.registerObserver(this); + + command = Message.obtain(); + command.what = Command.SET_CLEAN_PACKED; + command.arg1 = currentSet; + dao.executeCommand(command); + + if (categoriesCache.isEmpty()) { + command = Message.obtain(); + command.what = Command.ITEM_GET_CATEGORIES; + dao.executeCommand(command); + } + command = Message.obtain(); + command.what = Command.SET_GET_ITEMS; + command.arg1 = currentSet; + dao.executeCommand(command); + + command = Message.obtain(); + command.what = Command.SET_GET_STAT; + command.arg1 = presenter.getCurrentSet().getId(); + dao.executeCommand(command); } // categories --> @@ -59,8 +157,7 @@ public class ItemModel implements Model.Item { @Override public Category getCategoryByPosition(int position) { Category ret = null; - if (cache.containsKey(currentSet)) - ret = categoriesCache.get(cache.get(currentSet).get(position).getCategory()); + ret = categoriesCache.get(itemsCache.get(position).getCategory()); return ret; } @@ -68,38 +165,13 @@ public class ItemModel implements Model.Item { // items --> - @Override - public int insertItem(Item item) { - List iList = cache.get(currentSet); - iList.add(item); - Collections.sort(iList); - cache.put(currentSet, iList); - ++currentSetActiveItemsQty; - // TODO write to database - return 0; - } - @Override - public boolean deleteItem(Item item) { - if (isPendingRemoval(item)) - itemsDiscardCache.remove(item); - cache.get(currentSet).remove(item); - --currentSetActiveItemsQty; - //TODO write to ds - - return false; - } - @Override public Item findItem(int id) { - List items = cache.get(currentSet); Item item = null; - if (items != null) - { - for (Item i : items) { - if (i.getId() == id) { - item = i; - break; - } + for (Item i : itemsCache) { + if (i.getId() == id) { + item = i; + break; } } return item; @@ -107,12 +179,10 @@ public class ItemModel implements Model.Item { @Override public Item getItemByPosition(int position) { Item ret = null; - if (cache.containsKey(currentSet)) - ret = cache.get(currentSet).get(position); + ret = itemsCache.get(position); return ret; } - @Override public void filter(String query) { @@ -125,53 +195,29 @@ public class ItemModel implements Model.Item { query = query.toLowerCase(); String name; List newList = new ArrayList<>(20); - List oldList = cache.get(currentSet); - for (Item item : oldList) { + for (Item item : itemsCache) { name = item.getName().toLowerCase(); if (name.contains(query)) { newList.add(item); } } - cache.put(currentSet, newList); + itemsCache = newList; } } @Override public int getHeaderId(int position) { - return cache.containsKey(currentSet) ? cache.get(currentSet).get(position).getCategory() : -1; + return itemsCache.get(position).getCategory(); } @Override public int getItemId(int position) { - return cache.containsKey(currentSet) ? cache.get(currentSet).get(position).getId() : -1; - } - - @Override - public void clear() { - if (cache.containsKey(currentSet)) - cache.get(currentSet).clear(); - } - - @Override - public boolean isPendingRemoval(Item item) { - return itemsDiscardCache.contains(item); - } - - @Override - public void pendingRemoveCancel(Item item) { - if (itemsDiscardCache.contains(item)) - itemsDiscardCache.remove(item); - } - - @Override - public void pendingRemove(Item item) { - itemsDiscardCache.add(item); + return itemsCache.get(position).getId(); } @Override public int getItemsCount() { - boolean is = cache.containsKey(currentSet); - return is ? cache.get(currentSet).size() : 0; + return itemsCache.size(); } @Override @@ -189,7 +235,8 @@ public class ItemModel implements Model.Item { @Override public void notifyDataSetChanged() { - presenter.notifyDataSetChanged(); + if (presenter != null) + presenter.notifyDataSetChanged(); } @Override @@ -197,31 +244,62 @@ public class ItemModel implements Model.Item { if ( !isConfigurationChanging ) { presenter = null; } + dao.unregisterObserver(this); } - - private void sendMessage(String message) { - presenter.showMessage(message); - } - // events <-- // process --> - @Override - public void packItem(int itemId) { - Item item = findItem(itemId); - if (item != null) - cache.get(currentSet).remove(item); - Message command = Message.obtain(); - command.what = Command.ITEM_PACK; - command.arg1 = currentSet; - command.arg2 = itemId; - dao.executeCommand(command); + public void pendingRemove(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_PENDING_REMOVAL; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + //itemsCache.remove(item);// TODO check nn + } } @Override - public void unpackItem(int itemId) { + public void pendingRemoveCancel(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_REMOVAL_CANCEL; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + //itemsCache.remove(item); + } + } + + @Override + public void remove(Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_DELETE_FROM_SET; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + //itemsCache.remove(item); + } + } +// TODO use item itself? + @Override + public void packItem(com.hikapro.backpack.model.entities.Item item) { + if (item != null) { + itemsCache.remove(item); + Message command = Message.obtain(); + command.what = Command.ITEM_PACK; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + } + } + + @Override + public void unpackItem(com.hikapro.backpack.model.entities.Item item) { // nothing } @@ -239,98 +317,6 @@ public class ItemModel implements Model.Item { dao.executeCommand(command); } - @Override - public void executeQuery() { - Message command; - - if (cache.contains(currentSet)) { - notifyDataSetChanged(); - } else { - if (categoriesCache.isEmpty()) { - command = Message.obtain(); - command.what = Command.ITEM_GET_CATEGORIES; - dao.executeCommand(command); - } - command = Message.obtain(); - command.what = Command.SET_GET_ITEMS; - command.arg1 = presenter.getCurrentSet().getId(); - dao.executeCommand(command); - } - } - @Override - public void onEvent(Message event) { - - switch (event.what) { - case Event.SET_ITEMS_LOAD_ERROR : // TODO check - if (presenter != null) { - if (packedQty == -1) - packedQty = presenter.getCurrentSet().getPackedQty(); - presenter.notifyItemPackStatusChanged(); - } - break; - case Event.SET_UNPACK_ERROR : - break; - case Event.SET_RESTORE_ERROR : - break; - case Event.ITEM_FROM_SET_ERROR : - break; - case Event.ITEM_DELETE_ERROR : - break; - case Event.ITEM_PACK_ERROR : - break; - case Event.ITEM_UNPACK_ERROR : - break; - case Event.ITEM_INSERT_ERROR : - break; - case Event.ITEM_CATEGORY_LOAD_ERROR : - break; - case Event.SET_ITEMS_LOAD_COMPLETED : - List res = (List) event.obj; - cache.put(event.arg1, res); - notifyDataSetChanged(); - if (presenter != null) { - if (packedQty == -1) - packedQty = presenter.getCurrentSet().getPackedQty(); - presenter.notifyItemPackStatusChanged(); - } - break; - case Event.SET_UNPACK_COMPLETED : - packedQty = 0; - if (presenter != null) { - presenter.notifyItemPackStatusChanged(); - } - break; - case Event.ITEM_CATEGORY_LOAD_COMPLETED : - categoriesCache = (Hashtable)event.obj; - break; - case Event.ITEM_FROM_SET_DELETED : - break; - case Event.ITEM_DELETED : - break; - case Event.ITEM_PACKED : - //TODO something - ++packedQty; - if (presenter != null) { - presenter.notifyItemPackStatusChanged(); - } - break; - case Event.ITEM_UNPACKED : - --packedQty; - if (presenter != null) { - presenter.notifyItemPackStatusChanged(); - } - break; - case Event.ITEM_INSERTED : - break; - case Event.SET_RESTORE_COMPLETED : - if (presenter != null) { - presenter.notifyDataSetChanged(); - } - Toast.makeText(App.getAppContext(), "Restore completed", Toast.LENGTH_SHORT).show(); - break; - } - } - // process <-- // other --> @@ -341,6 +327,7 @@ public class ItemModel implements Model.Item { this.presenter = presenter; this.currentSet = presenter.getCurrentSet().getId(); this.currentSetActiveItemsQty = presenter.getCurrentSet().getActiveQty(); + //dao.registerObserver(this); } @Override @@ -348,16 +335,5 @@ public class ItemModel implements Model.Item { return presenter; } - private Category findCategory(int categoryId) { - Category category = null; - - for (Category c : rawCategories) { - if (c.getId() == categoryId) { - category = c; - break; - } - } - return category; - } // other <-- } diff --git a/app/src/main/java/com/hikapro/backpack/model/Model.java b/app/src/main/java/com/hikapro/backpack/model/Model.java index f5920bc..292847e 100644 --- a/app/src/main/java/com/hikapro/backpack/model/Model.java +++ b/app/src/main/java/com/hikapro/backpack/model/Model.java @@ -34,15 +34,13 @@ public interface Model { } interface Item extends Base { - int insertItem(com.hikapro.backpack.model.entities.Item item); - boolean deleteItem(com.hikapro.backpack.model.entities.Item item); void filter(String query); int getHeaderId(int position);//TODO review int getItemId(int position);//TODO review - void clear(); - boolean isPendingRemoval(com.hikapro.backpack.model.entities.Item item); + // leave at home void pendingRemove(com.hikapro.backpack.model.entities.Item item); void pendingRemoveCancel(com.hikapro.backpack.model.entities.Item item); + void remove(com.hikapro.backpack.model.entities.Item item); int getItemsCount(); int getActiveItemsCount(); int getPackedQty(); @@ -54,8 +52,8 @@ public interface Model { void setPresenter(Presenter.ItemList presenter); Presenter.ItemList getPresenter(); - void packItem(int itemId); - void unpackItem(int itemId); + void packItem(com.hikapro.backpack.model.entities.Item item); + void unpackItem(com.hikapro.backpack.model.entities.Item item); void unpackSet(int setId); void restoreSet(int setId); } @@ -66,6 +64,10 @@ public interface Model { Bitmap getPicture(); void setPresenter(Presenter.ItemDetail presenter); Presenter.ItemDetail getPresenter(); + void pendingRemove(com.hikapro.backpack.model.entities.Item item); + void pendingRemoveCancel(com.hikapro.backpack.model.entities.Item item); + void packItem(com.hikapro.backpack.model.entities.Item item); + void unpackItem(com.hikapro.backpack.model.entities.Item item); } interface Share extends Base { diff --git a/app/src/main/java/com/hikapro/backpack/model/PackedModel.java b/app/src/main/java/com/hikapro/backpack/model/PackedModel.java index e3b7128..584e1ec 100644 --- a/app/src/main/java/com/hikapro/backpack/model/PackedModel.java +++ b/app/src/main/java/com/hikapro/backpack/model/PackedModel.java @@ -2,6 +2,7 @@ package com.hikapro.backpack.model; import android.os.Message; +import java.util.Collections; import java.util.Hashtable; import java.util.List; @@ -22,20 +23,21 @@ public class PackedModel extends ItemModel { @Override public void executeQuery() { Message command; - - if (cache.contains(currentSet)) { - notifyDataSetChanged(); - } else { - if (categoriesCache.isEmpty()) { - command = Message.obtain(); - command.what = Command.ITEM_GET_CATEGORIES; - dao.executeCommand(command); - } + dao.registerObserver(this); + if (categoriesCache.isEmpty()) { command = Message.obtain(); - command.what = Command.SET_GET_PACKED_ITEMS; - command.arg1 = presenter.getCurrentSet().getId(); + command.what = Command.ITEM_GET_CATEGORIES; dao.executeCommand(command); } + command = Message.obtain(); + command.what = Command.SET_GET_PACKED_ITEMS; + command.arg1 = currentSet; + dao.executeCommand(command); + + command = Message.obtain(); + command.what = Command.SET_GET_STAT; + command.arg1 = presenter.getCurrentSet().getId(); + dao.executeCommand(command); } @Override @@ -47,24 +49,45 @@ public class PackedModel extends ItemModel { break; case Event.SET_UNPACK_ERROR : break; + case Event.SET_GET_STAT_ERROR: + break; case Event.ITEM_CATEGORY_LOAD_ERROR : break; case Event.ITEM_PACK_ERROR : break; case Event.ITEM_UNPACK_ERROR : break; + case Event.ITEM_PENDING_REMOVAL_ERROR: + break; + case Event.ITEM_REMOVAL_CANCEL_ERROR: + break; case Event.SET_PACKED_LOAD_COMPLETED : - List res = (List) event.obj; - cache.put(event.arg1, res); + itemsCache = (List) event.obj; notifyDataSetChanged(); - packedQty = res.size(); - if (presenter != null) { + break; + case Event.SET_GET_STAT_COMPLETED: + currentSetActiveItemsQty = event.arg1; + packedQty = event.arg2; + if (presenter != null) presenter.notifyItemPackStatusChanged(); - } + break; + case Event.ITEM_FROM_SET_DELETED: + executeQuery(); + break; + case Event.ITEM_PENDING_REMOVAL_COMPLETED:// TODO DEL + executeQuery(); + break; + case Event.ITEM_REMOVAL_CANCELED: + executeQuery(); + break; + case Event.ITEM_READ_COMPLETED: + itemsCache.add((Item) event.obj); + Collections.sort(itemsCache); + notifyDataSetChanged(); break; case Event.SET_UNPACK_COMPLETED : packedQty = 0; - cache.get(event.arg2).clear(); + itemsCache.clear(); if (presenter != null) { presenter.notifyItemPackStatusChanged(); } @@ -73,37 +96,36 @@ public class PackedModel extends ItemModel { categoriesCache = (Hashtable)event.obj; break; case Event.ITEM_PACKED : - //TODO something - ++packedQty; - if (presenter != null) { - presenter.notifyItemPackStatusChanged(); - } + executeQuery(); break; case Event.ITEM_UNPACKED : - --packedQty; - if (presenter != null) { - presenter.notifyItemPackStatusChanged(); - } + executeQuery(); break; } } @Override - public void unpackItem(int itemId) { - Message command; - command = Message.obtain(); - command.what = Command.ITEM_UNPACK; - command.arg1 = currentSet; - command.arg2 = itemId; - dao.executeCommand(command); - Item item = findItem(itemId); - if (item != null) - cache.get(currentSet).remove(item); + public void unpackItem(com.hikapro.backpack.model.entities.Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_UNPACK; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + itemsCache.remove(item); // TODO check nn + } } @Override - public void packItem(int itemId) { - // nothing + public void packItem(com.hikapro.backpack.model.entities.Item item) { + if (item != null) { + Message command = Message.obtain(); + command.what = Command.ITEM_REMOVAL_CANCEL; + command.arg1 = currentSet; + command.arg2 = item.getId(); + dao.executeCommand(command); + itemsCache.remove(item); + } } @Override diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/Command.java b/app/src/main/java/com/hikapro/backpack/model/dao/Command.java index 5aa6f89..e57a994 100644 --- a/app/src/main/java/com/hikapro/backpack/model/dao/Command.java +++ b/app/src/main/java/com/hikapro/backpack/model/dao/Command.java @@ -16,6 +16,8 @@ public interface Command { int SET_GET_PACKED_ITEMS = 0x67; int SET_UNPACK_ITEMS = 0x68; int SET_RESTORE_DEFAULT = 0x69; + int SET_GET_STAT = 0x70; + int SET_CLEAN_PACKED = 0x71; int ITEM_DELETE_FROM_SET = 0x78; int ITEM_INSERT = 0x79; @@ -24,6 +26,9 @@ public interface Command { int ITEM_GET_CATEGORIES = 0x7C; int ITEM_GET_IMAGE = 0x7D; int ITEM_GET_LIKE = 0x7E; + int ITEM_PENDING_REMOVAL = 0x7F; + int ITEM_REMOVAL_CANCEL = 0x80; + int ITEM_READ = 0x81; int MY_LIST_POST = 0x8C; int MY_LIST_ITEM_ADD = 0x8D; diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java b/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java index 1c407c8..2fbce45 100644 --- a/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java +++ b/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java @@ -85,6 +85,10 @@ public class DAO { observers.put(o.getClass().getName(), o); } + public void unregisterObserver(Model.Base o) { + observers.remove(o.getClass().getName()); + } + private ThreadPoolExecutor initPool (BlockingQueue taskQueue) { ThreadPoolExecutor ret = new ThreadPoolExecutor( CORE_POOL_SIZE @@ -158,6 +162,20 @@ public class DAO { threadPool.execute(setTask); break; + case Command.SET_GET_STAT : + setTask = new SetTask(Command.SET_GET_STAT, + Process.THREAD_PRIORITY_MORE_FAVORABLE); + setTask.setId = command.arg1; + threadPool.execute(setTask); + break; + + case Command.SET_CLEAN_PACKED : + setTask = new SetTask(Command.SET_CLEAN_PACKED, + Process.THREAD_PRIORITY_MORE_FAVORABLE); + setTask.setId = command.arg1; + threadPool.execute(setTask); + break; + case Command.ITEM_GET_CATEGORIES : itemTask = new ItemTask(Command.ITEM_GET_CATEGORIES, Process.THREAD_PRIORITY_MORE_FAVORABLE); @@ -172,6 +190,14 @@ public class DAO { threadPool.execute(itemTask); break; + case Command.ITEM_READ: + itemTask = new ItemTask(Command.ITEM_READ, + Process.THREAD_PRIORITY_DEFAULT); + itemTask.setId = command.arg1; + itemTask.itemId = command.arg2; + threadPool.execute(itemTask); + break; + case Command.ITEM_DELETE_FROM_SET : itemTask = new ItemTask(Command.ITEM_DELETE_FROM_SET, Process.THREAD_PRIORITY_BACKGROUND); @@ -180,6 +206,22 @@ public class DAO { threadPool.execute(itemTask); break; + case Command.ITEM_PENDING_REMOVAL: + itemTask = new ItemTask(Command.ITEM_PENDING_REMOVAL, + Process.THREAD_PRIORITY_BACKGROUND); + itemTask.setId = command.arg1; + itemTask.itemId = command.arg2; + threadPool.execute(itemTask); + break; + + case Command.ITEM_REMOVAL_CANCEL: + itemTask = new ItemTask(Command.ITEM_REMOVAL_CANCEL, + Process.THREAD_PRIORITY_BACKGROUND); + itemTask.setId = command.arg1; + itemTask.itemId = command.arg2; + threadPool.execute(itemTask); + break; + case Command.ITEM_PACK : itemTask = new ItemTask(Command.ITEM_PACK, Process.THREAD_PRIORITY_BACKGROUND); @@ -462,13 +504,11 @@ public class DAO { return ret; } - private List readItems(int setId, boolean packed) { - List ret = new ArrayList<>(256); + private Item readItem(SQLiteDatabase db, int setId, int itemId) { + Item ret = null; Cursor cursor = null; - SQLiteDatabase db = null; - Item item; String query = String.format( - "SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s <> 1 AND b.%s %s 1", + "SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, %s, %s FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s = ? LIMIT 1", Db.ItemsTable.COLUMN_ID, Db.ItemsTable.COLUMN_NAME, @@ -480,6 +520,102 @@ public class DAO { Db.ItemsTable.COLUMN_PHOTO_LOCAL, Db.ItemsTable.COLUMN_PHOTO_THUMB_LOCAL, Db.ItemsTable.COLUMN_USER_DEFINED, + Db.SetItemsTable.COLUMN_PENDING_REMOVAL, + Db.SetItemsTable.COLUMN_PACKED, + + Db.ItemsTable.TABLE_NAME, + Db.SetItemsTable.TABLE_NAME, + Db.ItemsTable.COLUMN_ID, + Db.SetItemsTable.COLUMN_ITEM, + Db.SetItemsTable.COLUMN_SET, + Db.SetItemsTable.COLUMN_ITEM); + + try { + cursor = db.rawQuery(query, new String[]{String.valueOf(setId), String.valueOf(itemId)}); + if (cursor.moveToNext()) { + ret = Db.ItemsTable.parseCursor(cursor); + } + } catch (SQLiteException e) { + //TODO write to log here + + } catch (Exception e) { + + //TODO write to log here + } finally { + if (cursor != null) + cursor.close(); + } + return ret; + } + + private Item readItem(int setId, int itemId) { + Item ret = null; + Cursor cursor = null; + SQLiteDatabase db = null; + String query = String.format( + "SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, %s, %s FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s = ? LIMIT 1", + + Db.ItemsTable.COLUMN_ID, + Db.ItemsTable.COLUMN_NAME, + Db.ItemsTable.COLUMN_CATEGORY, + Db.ItemsTable.COLUMN_DESCRIPTION, + Db.ItemsTable.COLUMN_BUY_URLS, + Db.ItemsTable.COLUMN_PHOTO_URL, + Db.ItemsTable.COLUMN_PHOTO_THUMB_URL, + Db.ItemsTable.COLUMN_PHOTO_LOCAL, + Db.ItemsTable.COLUMN_PHOTO_THUMB_LOCAL, + Db.ItemsTable.COLUMN_USER_DEFINED, + Db.SetItemsTable.COLUMN_PENDING_REMOVAL, + Db.SetItemsTable.COLUMN_PACKED, + + Db.ItemsTable.TABLE_NAME, + Db.SetItemsTable.TABLE_NAME, + Db.ItemsTable.COLUMN_ID, + Db.SetItemsTable.COLUMN_ITEM, + Db.SetItemsTable.COLUMN_SET, + Db.SetItemsTable.COLUMN_ITEM); + + try { + db = getReadDB(); + cursor = db.rawQuery(query, new String[]{String.valueOf(setId), String.valueOf(itemId)}); + if (cursor.moveToNext()) { + ret = Db.ItemsTable.parseCursor(cursor); + } + } catch (SQLiteException e) { + //TODO write to log here + + } catch (Exception e) { + + //TODO write to log here + } finally { + if (cursor != null) + cursor.close(); + if (db != null) + db.close(); + } + return ret; + } + + private List readItems(int setId, boolean packed) { + List ret = new ArrayList<>(256); + Cursor cursor = null; + SQLiteDatabase db = null; + Item item; + String query = String.format( + "SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, %s, %s FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s <> 1 AND b.%s %s 1", + + Db.ItemsTable.COLUMN_ID, + Db.ItemsTable.COLUMN_NAME, + Db.ItemsTable.COLUMN_CATEGORY, + Db.ItemsTable.COLUMN_DESCRIPTION, + Db.ItemsTable.COLUMN_BUY_URLS, + Db.ItemsTable.COLUMN_PHOTO_URL, + Db.ItemsTable.COLUMN_PHOTO_THUMB_URL, + Db.ItemsTable.COLUMN_PHOTO_LOCAL, + Db.ItemsTable.COLUMN_PHOTO_THUMB_LOCAL, + Db.ItemsTable.COLUMN_USER_DEFINED, + Db.SetItemsTable.COLUMN_PENDING_REMOVAL, + Db.SetItemsTable.COLUMN_PACKED, Db.ItemsTable.TABLE_NAME, Db.SetItemsTable.TABLE_NAME, @@ -494,14 +630,14 @@ public class DAO { cursor = db.rawQuery(query, new String[]{String.valueOf(setId)}); while (cursor.moveToNext()) { item = Db.ItemsTable.parseCursor(cursor); +// if (!packed && item.isPendingRemoval()) +// continue; ret.add(item); } } catch (SQLiteException e) { //TODO write to log here } catch (Exception e) { - int i = 0; - String s = null; //TODO write to log here } finally { if (cursor != null) @@ -628,6 +764,26 @@ public class DAO { return ret; } + private Set readSet(int setId) { + Set ret = null; + SQLiteDatabase db = null; + Cursor cursor = null; + try { + db = getReadDB(); + String query = String.format("SELECT * FROM %s a WHERE a.%s = %d LIMIT 1", + Db.SetsTable.TABLE_NAME, Db.SetsTable.COLUMN_ID, setId); + cursor = db.rawQuery(query, null); + if (cursor.moveToNext()) + ret = Db.SetsTable.parseCursor(cursor); + } finally { + if (cursor != null) + cursor.close(); + if (db != null) + db.close(); + } + return ret; + } + private List readSets() { List ret = new ArrayList<>(12); Cursor cursor = null; @@ -712,23 +868,116 @@ public class DAO { return ret; } + private int updateSetItemPendingRemoval(int setId, int itemId, boolean remove) { + int ret = 0; + SQLiteDatabase db = null; + ContentValues values; + Set set; + Item item; + try { + db = getWriteDB(); + db.beginTransaction(); + item = readItem(db, setId, itemId); + values = new ContentValues(); + values.put(Db.SetItemsTable.COLUMN_PENDING_REMOVAL, remove); + ret = db.update(Db.SetItemsTable.TABLE_NAME, values, String.format("%s = ? AND %s = ?", + Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ), + new String[]{String.valueOf(setId), String.valueOf(itemId)}); + + set = readSet(db, setId); + if (set != null) { + values = new ContentValues(); + values.put(Db.SetsTable.COLUMN_ACTIVE_QTY, remove ? set.getActiveQty()-1 : set.getActiveQty()+1); + if (item.isPacked() ) { + if (remove) + values.put(Db.SetsTable.COLUMN_PACKED_QTY, set.getPackedQty()-1); + else + values.put(Db.SetsTable.COLUMN_PACKED_QTY, set.getPackedQty()+1); + } + ret += db.update(Db.SetsTable.TABLE_NAME, values, String.format("%s = ?", + Db.SetsTable.COLUMN_ID), + new String[]{String.valueOf(setId)}); + } + db.setTransactionSuccessful(); + + } catch (SQLiteException e) { + //TODO write to log here + } catch (Exception e) { + //TODO write to log here + } finally { + if (db != null) { + db.endTransaction(); + db.close(); + } + } + return ret; + } + private int updateSetItemDeleted(int setId, int itemId, boolean del) { int ret = 0; SQLiteDatabase db = null; ContentValues values; + Set set; + Item item; + try { + db = getWriteDB(); + db.beginTransaction(); + item = readItem(db, setId, itemId); + values = new ContentValues(); + values.put(Db.SetItemsTable.COLUMN_DELETED, del); + values.put(Db.SetItemsTable.COLUMN_PENDING_REMOVAL, false); + values.put(Db.SetItemsTable.COLUMN_PACKED, false); + ret = db.update(Db.SetItemsTable.TABLE_NAME, values, String.format("%s = ? AND %s = ?", + Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ), + new String[]{String.valueOf(setId), String.valueOf(itemId)}); + + set = readSet(db, setId); + if (set != null) { + values = new ContentValues(); + if (del) { + if (!item.isPendingRemoval()) + values.put(Db.SetsTable.COLUMN_ACTIVE_QTY, set.getActiveQty()-1); + } else + values.put(Db.SetsTable.COLUMN_ACTIVE_QTY, set.getActiveQty()+1); + + values.put(Db.SetsTable.COLUMN_PACKED_QTY, item.isPacked() ? set.getPackedQty()-1 :set.getPackedQty()); + ret += db.update(Db.SetsTable.TABLE_NAME, values, String.format("%s = ?", + Db.SetsTable.COLUMN_ID), + new String[]{String.valueOf(setId)}); + } + db.setTransactionSuccessful(); + } catch (SQLiteException e) { + //TODO write to log here + } catch (Exception e) { + //TODO write to log here + } finally { + if (db != null) { + db.endTransaction(); + db.close(); + } + } + return ret; + } + + private int updateSetItemsCleanPacked(int setId) { + int ret = 0; + SQLiteDatabase db = null; + ContentValues values; try { db = getWriteDB(); db.beginTransaction(); values = new ContentValues(); - values.put(Db.SetItemsTable.COLUMN_DELETED, del); + values.put(Db.SetItemsTable.COLUMN_PACKED, 0); ret = db.update(Db.SetItemsTable.TABLE_NAME, values, String.format("%s = ? AND %s = ?", - Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ), - new String[]{String.valueOf(setId), String.valueOf(itemId)}); + Db.SetItemsTable.COLUMN_SET, + Db.SetItemsTable.COLUMN_PENDING_REMOVAL), + new String[]{String.valueOf(setId), "1"}); db.setTransactionSuccessful(); } catch (SQLiteException e) { + ret = -1; //TODO write to log here - } catch (Exception e) { + ret = -1; //TODO write to log here } finally { if (db != null) { @@ -781,12 +1030,14 @@ public class DAO { SQLiteDatabase db = null; ContentValues values; Set set; + Item item; try { db = getWriteDB(); db.beginTransaction(); - + item = readItem(db, setId, itemId); values = new ContentValues(); values.put(Db.SetItemsTable.COLUMN_PACKED, pack); + values.put(Db.SetItemsTable.COLUMN_PENDING_REMOVAL, 0); ret = db.update(Db.SetItemsTable.TABLE_NAME, values, String.format("%s = ? AND %s = ?", Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ), new String[]{String.valueOf(setId), String.valueOf(itemId)}); @@ -794,7 +1045,18 @@ public class DAO { set = readSet(db, setId); if (set != null) { values = new ContentValues(); - values.put(Db.SetsTable.COLUMN_PACKED_QTY, pack ? set.getPackedQty() + 1 : set.getPackedQty() - 1); + if (pack) { + values.put(Db.SetsTable.COLUMN_PACKED_QTY, set.getPackedQty() + 1); + if (item.isPendingRemoval()) + values.put(Db.SetsTable.COLUMN_ACTIVE_QTY, set.getActiveQty()+1 ); + } else { + if (!item.isPendingRemoval()) { + values.put(Db.SetsTable.COLUMN_PACKED_QTY, set.getPackedQty() - 1); + } else { + values.put(Db.SetsTable.COLUMN_ACTIVE_QTY, set.getActiveQty()+1); + } + } + ret += db.update(Db.SetsTable.TABLE_NAME, values, String.format("%s = ?", Db.SetsTable.COLUMN_ID), new String[]{String.valueOf(setId)}); @@ -825,6 +1087,7 @@ public class DAO { values = new ContentValues(); values.put(Db.SetItemsTable.COLUMN_PACKED, false); values.put(Db.SetItemsTable.COLUMN_DELETED, false); + values.put(Db.SetItemsTable.COLUMN_PENDING_REMOVAL, false); ret = db.update(Db.SetItemsTable.TABLE_NAME, values, String.format("%s = ?", @@ -1027,6 +1290,16 @@ public class DAO { Message message = Message.obtain(); switch (currentCommand) { + case Command.ITEM_READ: + message.obj = readItem(setId, itemId); + if (message.obj != null) + message.what = Event.ITEM_READ_COMPLETED; + else + message.what = Event.ITEM_READ_ERROR; + message.arg1 = setId; + message.arg2 = itemId; + break; + case Command.ITEM_DELETE_FROM_SET : message.arg1 = updateSetItemDeleted(setId, itemId, true); if (message.arg1 > 0) @@ -1035,6 +1308,26 @@ public class DAO { message.what = Event.ITEM_FROM_SET_ERROR; break; + case Command.ITEM_PENDING_REMOVAL: + message.arg1 = updateSetItemPendingRemoval(setId, itemId, true); + if (message.arg1 > 0) + message.what = Event.ITEM_PENDING_REMOVAL_COMPLETED; + else + message.what = Event.ITEM_PENDING_REMOVAL_ERROR; + message.arg1 = setId; + message.arg2 = itemId; + break; + + case Command.ITEM_REMOVAL_CANCEL: + message.arg1 = updateSetItemPendingRemoval(setId, itemId, false); + if (message.arg1 > 0) + message.what = Event.ITEM_REMOVAL_CANCELED; + else + message.what = Event.ITEM_REMOVAL_CANCEL_ERROR; + message.arg1 = setId; + message.arg2 = itemId; + break; + case Command.ITEM_INSERT : if (insertItem(item) > 0) { insertSetItem(setId, item.getId(), item.isUserDefined()); @@ -1052,6 +1345,8 @@ public class DAO { message.what = Event.ITEM_PACKED; else message.what = Event.ITEM_PACK_ERROR; + message.arg1 = setId; + message.arg2 = itemId; break; case Command.ITEM_UNPACK : @@ -1060,6 +1355,8 @@ public class DAO { message.what = Event.ITEM_UNPACKED; else message.what = Event.ITEM_UNPACK_ERROR; + message.arg1 = setId; + message.arg2 = itemId; break; case Command.ITEM_GET_CATEGORIES : @@ -1164,6 +1461,21 @@ public class DAO { else message.what = Event.SET_RESTORE_ERROR; break; + + case Command.SET_GET_STAT: + Set set = readSet(setId); + message.arg1 = set.getActiveQty(); + message.arg2 = set.getPackedQty(); + message.what = Event.SET_GET_STAT_COMPLETED; + break; + + case Command.SET_CLEAN_PACKED: + message.arg1 = updateSetItemsCleanPacked(setId); + if (message.arg1 > -1) + message.what = Event.SET_PACKED_CLEANED; + else + message.what = Event.SET_CLEAN_PACKED_ERROR; + break; } handler.sendMessage(message); } diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/Db.java b/app/src/main/java/com/hikapro/backpack/model/dao/Db.java index c70216b..cd72bfa 100644 --- a/app/src/main/java/com/hikapro/backpack/model/dao/Db.java +++ b/app/src/main/java/com/hikapro/backpack/model/dao/Db.java @@ -127,8 +127,18 @@ public class Db { item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL))); item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL))); item.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL))); - short ud = cursor.getShort(cursor.getColumnIndexOrThrow(COLUMN_USER_DEFINED)); - item.setUserDefined(ud != 0); + short buf = cursor.getShort(cursor.getColumnIndexOrThrow(COLUMN_USER_DEFINED)); + item.setUserDefined(buf != 0); + int check = cursor.getColumnIndex(SetItemsTable.COLUMN_PENDING_REMOVAL); + if (check != -1) { + buf = cursor.getShort(check); + item.setPendingRemoval(buf != 0); + } + check = cursor.getColumnIndex(SetItemsTable.COLUMN_PACKED); + if (check != -1) { + buf = cursor.getShort(check); + item.setPacked(buf != 0); + } return item; } @@ -258,6 +268,7 @@ public class Db { public static final String COLUMN_SET = "setId"; public static final String COLUMN_ITEM = "itemId"; public static final String COLUMN_DELETED = "deleted"; + public static final String COLUMN_PENDING_REMOVAL = "pending_removal"; public static final String COLUMN_PACKED = "packed"; public static final String COLUMN_USER_DEFINED = "user_defined"; @@ -266,6 +277,7 @@ public class Db { COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_SET + " INTEGER NOT NULL, " + COLUMN_DELETED + " NUMERIC, " + + COLUMN_PENDING_REMOVAL + " NUMERIC, " + COLUMN_PACKED + " NUMERIC, " + COLUMN_USER_DEFINED + " NUMERIC, " + COLUMN_ITEM + " INTEGER NOT NULL" + @@ -276,6 +288,7 @@ public class Db { values.put(COLUMN_SET, setId); values.put(COLUMN_ITEM, itemId); values.put(COLUMN_DELETED, 0); + values.put(COLUMN_PENDING_REMOVAL, 0); values.put(COLUMN_PACKED, 0); values.put(COLUMN_USER_DEFINED, 0); return values; @@ -286,6 +299,7 @@ public class Db { values.put(COLUMN_SET, setId); values.put(COLUMN_ITEM, itemId); values.put(COLUMN_DELETED, 0); + values.put(COLUMN_PENDING_REMOVAL, 0); values.put(COLUMN_PACKED, 0); values.put(COLUMN_USER_DEFINED, userDefined); return values; diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/Event.java b/app/src/main/java/com/hikapro/backpack/model/dao/Event.java index ea03d07..8cc5c70 100644 --- a/app/src/main/java/com/hikapro/backpack/model/dao/Event.java +++ b/app/src/main/java/com/hikapro/backpack/model/dao/Event.java @@ -15,6 +15,8 @@ public interface Event { int SET_PACKED_LOAD_ERROR = -0x4; int SET_UNPACK_ERROR = -0x5; int SET_RESTORE_ERROR = -0x6; + int SET_GET_STAT_ERROR = -0x7; + int SET_CLEAN_PACKED_ERROR = -0x8; int SET_LOAD_COMPLETED = 0x1; @@ -23,7 +25,8 @@ public interface Event { int SET_PACKED_LOAD_COMPLETED = 0x4; int SET_UNPACK_COMPLETED = 0x5; int SET_RESTORE_COMPLETED = 0x6; - + int SET_GET_STAT_COMPLETED = 0x7; + int SET_PACKED_CLEANED = 0x8; int ITEM_FROM_SET_ERROR = -0x14; int ITEM_INSERT_ERROR = -0x15; @@ -33,6 +36,9 @@ public interface Event { int ITEM_CATEGORY_LOAD_ERROR = -0x19; int ITEM_IMAGE_LOAD_ERROR = -0x1A; int ITEM_LIKE_LOAD_ERROR = -0x1B; + int ITEM_PENDING_REMOVAL_ERROR = -0x1C; + int ITEM_REMOVAL_CANCEL_ERROR = -0x1D; + int ITEM_READ_ERROR = -0x1E; int ITEM_FROM_SET_DELETED = 0x14; int ITEM_INSERTED = 0x15; @@ -42,7 +48,9 @@ public interface Event { int ITEM_CATEGORY_LOAD_COMPLETED = 0x19; int ITEM_IMAGE_LOAD_COMPLETED = 0x1A; int ITEM_LIKE_LOAD_COMPLETED = 0x1B; - + int ITEM_PENDING_REMOVAL_COMPLETED = 0x1C; + int ITEM_REMOVAL_CANCELED = 0x1D; + int ITEM_READ_COMPLETED = 0x1E; int MY_LIST_POST_ERROR = -0x28; int MY_LIST_ITEM_ADD_ERROR = -0x29; diff --git a/app/src/main/java/com/hikapro/backpack/model/entities/Item.java b/app/src/main/java/com/hikapro/backpack/model/entities/Item.java index ca53163..851f595 100644 --- a/app/src/main/java/com/hikapro/backpack/model/entities/Item.java +++ b/app/src/main/java/com/hikapro/backpack/model/entities/Item.java @@ -38,6 +38,10 @@ public class Item implements Comparable, Serializable { private boolean userDefined; + private boolean pendingRemoval; + + private boolean packed; + public boolean InList; public Item() { @@ -132,6 +136,22 @@ public class Item implements Comparable, Serializable { this.userDefined = userDefined; } + public boolean isPendingRemoval() { + return pendingRemoval; + } + + public void setPendingRemoval(boolean pendingRemoval) { + this.pendingRemoval = pendingRemoval; + } + + public boolean isPacked() { + return packed; + } + + public void setPacked(boolean packed) { + this.packed = packed; + } + @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; @@ -154,7 +174,16 @@ public class Item implements Comparable, Serializable { @Override public int compareTo(Item another) { + /* int cmp = Integer.valueOf(category).compareTo(Integer.valueOf(another.category)); return (cmp != 0 ? cmp : name.compareTo(another.name)); + */ + int cmp = Integer.valueOf(category).compareTo(Integer.valueOf(another.category)); + if (cmp != 0) + return cmp; + else { + cmp = Boolean.valueOf(pendingRemoval).compareTo(Boolean.valueOf(another.pendingRemoval)); + return (cmp != 0 ? cmp : name.compareTo(another.name)); + } } } diff --git a/app/src/main/java/com/hikapro/backpack/presenter/ItemDetailPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/ItemDetailPresenter.java index 99aa89c..b34d6cf 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/ItemDetailPresenter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/ItemDetailPresenter.java @@ -1,13 +1,20 @@ package com.hikapro.backpack.presenter; +import android.app.ActionBar; +import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; +import android.net.Uri; import android.os.Bundle; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.ViewGroup; +import android.webkit.URLUtil; +import android.widget.ImageView; +import android.widget.TextView; import android.widget.Toast; import java.lang.ref.WeakReference; @@ -16,6 +23,7 @@ import com.hikapro.backpack.R; import com.hikapro.backpack.model.Model; import com.hikapro.backpack.model.entities.Item; import com.hikapro.backpack.presenter.adapters.ItemDetailAdapter; +import com.hikapro.backpack.presenter.adapters.helper.items.DividerDecoration; import com.hikapro.backpack.view.View; /** @@ -27,6 +35,10 @@ public class ItemDetailPresenter implements Presenter.ItemDetail { private Model.Detail model; private ItemDetailAdapter adapter; private Item item; + private int setId; + private ImageView itemPhoto; + private TextView itemDescription; + private TextView itemLink; public ItemDetailPresenter() { this.adapter = new ItemDetailAdapter(this); @@ -46,12 +58,33 @@ public class ItemDetailPresenter implements Presenter.ItemDetail { public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { android.view.View view = inflater.inflate(R.layout.fragment_item_detail, container, false); + + itemPhoto = (ImageView) view.findViewById(R.id.item_photo); + itemDescription = (TextView) view.findViewById(R.id.item_description); + itemLink = (TextView) view.findViewById(R.id.item_link); + LinearLayoutManager llm = new LinearLayoutManager(getActivityContext()); RecyclerView detailRecycler = (RecyclerView) view.findViewById(R.id.item_detail_recycler); detailRecycler.setLayoutManager(llm); detailRecycler.setAdapter(adapter); detailRecycler.setItemAnimator(new DefaultItemAnimator()); + detailRecycler.addItemDecoration(new DividerDecoration(getActivityContext())); + detailRecycler.setHasFixedSize(true); model.executeQuery(); + + Activity activity = (Activity) getActivityContext(); + if (activity != null) { + activity.invalidateOptionsMenu(); + ActionBar actionBar = activity.getActionBar(); + if (actionBar != null) { + actionBar.show(); + actionBar.setTitle(R.string.what_is_it); + actionBar.setDisplayShowHomeEnabled(false); + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setDisplayShowCustomEnabled(false); + actionBar.setDisplayHomeAsUpEnabled(true); + } + } return view; } @Override @@ -65,6 +98,28 @@ public class ItemDetailPresenter implements Presenter.ItemDetail { @Override public void notifyDataSetChanged() { adapter.notifyDataSetChanged(); + item = model.findItem(0); + itemDescription.setText(item.getDescription()); + if (item.getBuyUrls() != null && !item.getBuyUrls().isEmpty()) { + itemLink.setVisibility(android.view.View.VISIBLE); + itemLink.setOnClickListener(new android.view.View.OnClickListener() { + @Override + public void onClick(android.view.View v) { + if (URLUtil.isValidUrl(item.getBuyUrls().get(0))) { + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.getBuyUrls().get(0))); + + Activity activity = (Activity) getActivityContext(); + if (activity != null) { + if (browserIntent.resolveActivity(activity.getPackageManager()) != null) + activity.startActivity(browserIntent); + } + } + } + }); + } else { + itemLink.setVisibility(android.view.View.GONE); + itemLink.setOnClickListener(null); + } } // process <-- @@ -75,6 +130,7 @@ public class ItemDetailPresenter implements Presenter.ItemDetail { public void setView(View.ItemDetail view) { this.view = new WeakReference<>(view); this.item = getView().getItem(); + this.setId = view.getSetId(); } @Override public void setModel(Model.Detail model) { @@ -107,15 +163,10 @@ public class ItemDetailPresenter implements Presenter.ItemDetail { return null; } } - @Override - public void showMessage(String message) { - Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show(); - } @Override - public void displayPicture(Bitmap bitmap) { - - + public void notifyPictureChanged() { + itemPhoto.setImageBitmap(model.getPicture()); } // other impl <-- @@ -125,4 +176,8 @@ public class ItemDetailPresenter implements Presenter.ItemDetail { else throw new NullPointerException("View is unavailable"); } + + public int getSetId() { + return setId; + } } diff --git a/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java index 2000ed0..3cf6e37 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java @@ -59,9 +59,10 @@ public class ItemListPresenter implements Presenter.ItemList { model = null; } } + @Override public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - +// TODO check nn if (savedInstanceState != null) set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY); else @@ -81,12 +82,7 @@ public class ItemListPresenter implements Presenter.ItemList { decoration.invalidateHeaders(); } }); - ItemSwipeCallback itemSwipeCallback = new ItemSwipeCallback(0, ItemTouchHelper.LEFT, adapter, getActivityContext()); - - ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemSwipeCallback); - itemTouchHelper.attachToRecyclerView(recycler); - adapter.setUndoOn(true); - + recycler.setHasFixedSize(true); model.executeQuery(); footer = (LinearLayout) view.findViewById(R.id.item_list_footer); packedCount = (TextView) footer.findViewById(R.id.footer_packed_count); @@ -110,15 +106,7 @@ public class ItemListPresenter implements Presenter.ItemList { actionBar.setDisplayHomeAsUpEnabled(true); } } - /* - if ( model.getPackedQty() > 0) { - footer.setVisibility(android.view.View.VISIBLE); - String str = String.format("%s %d / %d", - getActivityContext().getResources().getString(R.string.packed), model.getPackedQty(), - model.getActiveItemsCount()); - packedCount.setText(str); - } - */ + return view; } @Override @@ -172,7 +160,7 @@ public class ItemListPresenter implements Presenter.ItemList { public void showDetails(int itemId) { Item item = model.findItem(itemId); if (item != null) - getView().showItemDetail(item); + getView().showItemDetail(item, set.getId()); else showMessage(String.format("Item with Id %d is not found.", itemId)); diff --git a/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java index eab29ac..f388692 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java @@ -56,18 +56,14 @@ public class PackedListPresenter extends ItemListPresenter { decoration.invalidateHeaders(); } }); - ItemSwipeCallback itemSwipeCallback = new ItemSwipeCallback(0, ItemTouchHelper.LEFT, adapter, getActivityContext()); - - ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemSwipeCallback); - itemTouchHelper.attachToRecyclerView(recycler); - adapter.setUndoOn(true); + recycler.setHasFixedSize(true); model.executeQuery(); backToList = (TextView) view.findViewById(R.id.back_to_list); packedCount = (TextView) view.findViewById(R.id.header_packed_count); unpackButton = (Button) view.findViewById(R.id.unpack_button); - +/* if (model.getPackedQty() == model.getActiveItemsCount()) { backToList.setVisibility(View.INVISIBLE); packedCount.setVisibility(View.INVISIBLE); @@ -78,7 +74,8 @@ public class PackedListPresenter extends ItemListPresenter { unpackButton.setVisibility(View.INVISIBLE); } - +*/ + setVisibility(); unpackButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -95,12 +92,7 @@ public class PackedListPresenter extends ItemListPresenter { } }); - /* - String str = String.format("%s %d / %d", - getActivityContext().getResources().getString(R.string.packed), - model.getPackedQty(), model.getActiveItemsCount()); - packedCount.setText(str); - */ + Activity activity = (Activity) getActivityContext(); if (activity != null) { activity.invalidateOptionsMenu(); diff --git a/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java b/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java index 13f0d57..d83871b 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java @@ -67,12 +67,12 @@ public interface Presenter { void setModel(Model.Detail model); Model.Detail getModel(); void notifyDataSetChanged(); - void showMessage(String message); + void notifyPictureChanged(); void onDestroy(boolean isChangingConfiguration); android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); void onSaveInstanceState(Bundle outState); Item getCurrentItem(); - void displayPicture(Bitmap bitmap); + int getSetId(); } interface Share extends Base { diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemDetailAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemDetailAdapter.java index d4db0e5..7166541 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemDetailAdapter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemDetailAdapter.java @@ -1,22 +1,36 @@ package com.hikapro.backpack.presenter.adapters; import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Typeface; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.Toast; import com.hikapro.backpack.R; +import com.hikapro.backpack.model.entities.Item; import com.hikapro.backpack.presenter.Presenter; +import com.hikapro.backpack.presenter.adapters.helper.Util; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipableElement; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenu; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenuItem; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenuLayout; import com.hikapro.backpack.view.recycler.DetailViewHolder; +import com.hikapro.backpack.view.recycler.ItemViewHolder; /** * Created by tariel on 23/04/16. */ -public class ItemDetailAdapter extends RecyclerView.Adapter { +public class ItemDetailAdapter extends RecyclerView.Adapter { private Presenter.ItemDetail presenter; public ItemDetailAdapter(Presenter.ItemDetail presenter) { + this.presenter = presenter; } @@ -26,29 +40,143 @@ public class ItemDetailAdapter extends RecyclerView.Adapter { } @Override - public void onBindViewHolder(DetailViewHolder holder, int position) { - com.hikapro.backpack.model.entities.Item item = presenter.getModel().findItem(position); - holder.title.setText(item.getName()); - holder.description.setText(item.getDescription()); - Bitmap bitmap = presenter.getModel().getPicture(); - if (bitmap != null) - holder.photo.setImageBitmap(bitmap); - holder.title.setOnClickListener(new android.view.View.OnClickListener() { + public void onBindViewHolder(final ItemViewHolder holder, final int position) { + final Item item = presenter.getModel().findItem(position); + holder.cb_item.setChecked(item.isPacked()); + holder.tv_text.setText(item.getName() + " " + item.getId() + " pos " + position); + holder.im_info.setVisibility(View.GONE); + if (item.isPendingRemoval()) { + holder.tv_text.setPaintFlags(holder.tv_text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + holder.cb_item.setVisibility(View.GONE); + } else { + holder.cb_item.setVisibility(View.VISIBLE); + holder.tv_text.setPaintFlags(holder.tv_text.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + } + + holder.cb_item.setOnClickListener(new android.view.View.OnClickListener() { @Override - public void onClick(android.view.View view) { - presenter.showMessage("On detail click"); + public void onClick(View v) { + if (holder.cb_item.isChecked()) { + pack(item); + } else { + unpack(item); + } + } + }); + + + SwipeMenuLayout menuLayout = (SwipeMenuLayout)holder.menu; + SwipeMenu menu = new SwipeMenu(presenter.getActivityContext()); + + menuLayout.removeAllViews(); + + // create menu items here + if (!item.isPendingRemoval()) { + // create "leave at home" item + SwipeMenuItem leaveAtHomeItem = new SwipeMenuItem(menu.getContext()); + // set id + leaveAtHomeItem.setId(ItemListAdapter.ID_LEAVE_AT_HOME); + // set item background + leaveAtHomeItem.setBackground(R.color.colorLeaveAtHomeBtnBackground); + // set item width + leaveAtHomeItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + leaveAtHomeItem.setTitle(R.string.leave_at_home_button); + // set item title font size + leaveAtHomeItem.setTitleSize(14); + // set item title font color + leaveAtHomeItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(leaveAtHomeItem); + } else { + // create "add to bag" item + SwipeMenuItem addToBagItem = new SwipeMenuItem(menu.getContext()); + // set id + addToBagItem.setId(ItemListAdapter.ID_ADD_TO_BAG); + // set item background + addToBagItem.setBackground(R.color.colorAddToBagBtnBackground); + // set item width + addToBagItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + addToBagItem.setTitle(R.string.add_to_bag_button); + // set item title font size + addToBagItem.setTitleSize(14); + // set item title font color + addToBagItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(addToBagItem); + + // create "return to list" item + SwipeMenuItem returnToListItem = new SwipeMenuItem(menu.getContext()); + // set id + returnToListItem.setId(ItemListAdapter.ID_RETURN_TO_LIST); + // set item background + returnToListItem.setBackground(R.color.colorReturnToListBtnBackground); + // set item width + returnToListItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + returnToListItem.setTitle(R.string.return_to_list_button); + // set item title font size + returnToListItem.setTitleSize(14); + // set item title font color + returnToListItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(returnToListItem); + } + + menuLayout.addMenu(menu); + + menuLayout.setMenuItemClickListener(new SwipeMenuLayout.OnMenuItemClickListener() { + @Override + public void onMenuItemClick(View v) { + + switch (v.getId()) { + case ItemListAdapter.ID_DELETE: + // no delete + break; + case ItemListAdapter.ID_LEAVE_AT_HOME: + leave(item); + break; + case ItemListAdapter.ID_RETURN_TO_LIST: + leaveCancel(item); + break; + case ItemListAdapter.ID_ADD_TO_BAG: + pack(item); + break; + } } }); } @Override - public DetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - DetailViewHolder viewHolder; - android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail, - parent, false); - viewHolder = new DetailViewHolder(v); + public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + ItemViewHolder viewHolder; + View content = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_element, parent, false); + SwipeMenuLayout menu = new SwipeMenuLayout(parent.getContext()); + menu.setId(R.id.menu); + SwipableElement container = new SwipableElement(parent.getContext(), content, menu); + container.setSwipeDirection(SwipableElement.DIRECTION_LEFT); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Util.dp2px(parent.getContext(),66)); + container.setOrientation(LinearLayout.HORIZONTAL); + container.setLayoutParams(params); + viewHolder = new ItemViewHolder(container); return viewHolder; } + public void leave(Item item) { + presenter.getModel().pendingRemove(item); + } + + public void pack(Item item) { + presenter.getModel().packItem(item); + } + + public void unpack(Item item) { + presenter.getModel().unpackItem(item); + } + + public void leaveCancel(Item item) { + presenter.getModel().pendingRemoveCancel(item); + } } diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java index ce2b6fc..1599e99 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java @@ -1,12 +1,16 @@ package com.hikapro.backpack.presenter.adapters; import android.graphics.Color; +import android.graphics.Paint; import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.Toast; import java.util.HashMap; @@ -14,7 +18,12 @@ import com.hikapro.backpack.R; import com.hikapro.backpack.model.entities.Category; import com.hikapro.backpack.model.entities.Item; import com.hikapro.backpack.presenter.Presenter; +import com.hikapro.backpack.presenter.adapters.helper.Util; import com.hikapro.backpack.presenter.adapters.helper.items.StickyHeaderAdapter; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipableElement; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenu; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenuItem; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenuLayout; import com.hikapro.backpack.view.recycler.HeaderViewHolder; import com.hikapro.backpack.view.recycler.ItemViewHolder; @@ -23,14 +32,14 @@ import com.hikapro.backpack.view.recycler.ItemViewHolder; */ public class ItemListAdapter extends RecyclerView.Adapter implements StickyHeaderAdapter { - private static final int PENDING_REMOVAL_TIMEOUT = 4000; // 4sec + protected static final int ID_DELETE = 1; + protected static final int ID_LEAVE_AT_HOME = 2; + protected static final int ID_ADD_TO_BAG = 3; + protected static final int ID_RETURN_TO_LIST = 4; - boolean undoOn; // is undo on, you can turn it on from the toolbar menu - private Handler handler = new Handler(); // hanlder for running delayed runnables - HashMap pendingRunables = new HashMap<>(); // map of items to pending runnables, so we can cancel a removal if need be - private Presenter.ItemList presenter; - private boolean checkAll; - private Typeface mainFace; + protected Presenter.ItemList presenter; + protected boolean checkAll; + protected Typeface mainFace; public ItemListAdapter(Presenter.ItemList presenter) { this.presenter = presenter; @@ -52,87 +61,151 @@ public class ItemListAdapter extends RecyclerView.Adapter implem public void onBindViewHolder(final ItemViewHolder holder, final int position) { final Item item = presenter.getModel().getItemByPosition(position); - if (presenter.getModel().isPendingRemoval(item)) { - // we need to show the "undo" state of the row - holder.itemView.setBackgroundColor(Color.RED); - holder.checkBox.setVisibility(View.GONE); - holder.swipeGroup.setVisibility(View.VISIBLE); - holder.deleteButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // user wants to undo the removal, let's cancel the pending task - Runnable pendingRemovalRunnable = pendingRunables.get(item); - pendingRunables.remove(item); - if (pendingRemovalRunnable != null) handler.removeCallbacks(pendingRemovalRunnable); - presenter.getModel().pendingRemoveCancel(item); - // this will rebind the row in "normal" state - notifyItemChanged(position); - } - }); - } else { - /* - if (mainFace == null) - mainFace = Typeface.createFromAsset(presenter.getAppContext().getAssets(), - "fonts/Ubuntu-B.ttf");*/ - - holder.checkBox.setVisibility(View.VISIBLE); - holder.checkBox.setChecked(checkAll); - holder.checkBox.setText(item.getName() + " " + item.getId() + " pos " + position);//TODO del - holder.checkBox.setTypeface(mainFace); - holder.swipeGroup.setVisibility(View.GONE); - holder.id = item.getId(); - holder.checkBox.setOnClickListener(new android.view.View.OnClickListener() { - @Override - public void onClick(View v) { - if (holder.checkBox.isChecked()) { - pack(holder.id, position); - // presenter.packItem(); TODO wtf - } else { - unpack(holder.id, position); - // presenter.unpackItem(); TODO wtf - } - } - }); - holder.infoButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - presenter.showDetails(holder.id); - } - }); - holder.itemView.setBackgroundColor(0x33FF99); - holder.deleteButton.setOnClickListener(null); + holder.cb_item.setChecked(checkAll); + holder.tv_text.setText(item.getName() + " " + item.getId() + " pos " + position); + //holder.tv_text.setTypeface(mainFace); + if (item.isPendingRemoval()) { + holder.tv_text.setPaintFlags(holder.tv_text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + holder.cb_item.setVisibility(View.GONE); + } else { + holder.cb_item.setVisibility(View.VISIBLE); + holder.tv_text.setPaintFlags(holder.tv_text.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); } + holder.cb_item.setOnClickListener(new android.view.View.OnClickListener() { + @Override + public void onClick(View v) { + if (holder.cb_item.isChecked()) { + pack(item); + } else { + unpack(item); + } + } + }); + holder.im_info.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + presenter.showDetails(item.getId()); + } + }); + + SwipeMenuLayout menuLayout = (SwipeMenuLayout)holder.menu; + SwipeMenu menu = new SwipeMenu(presenter.getActivityContext()); + + menuLayout.removeAllViews(); + + // create menu items here + if (!item.isPendingRemoval()) { + // create "leave at home" item + SwipeMenuItem leaveAtHomeItem = new SwipeMenuItem(menu.getContext()); + // set id + leaveAtHomeItem.setId(ID_LEAVE_AT_HOME); + // set item background + leaveAtHomeItem.setBackground(R.color.colorLeaveAtHomeBtnBackground); + // set item width + leaveAtHomeItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + leaveAtHomeItem.setTitle(R.string.leave_at_home_button); + // set item title font size + leaveAtHomeItem.setTitleSize(14); + // set item title font color + leaveAtHomeItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(leaveAtHomeItem); + } else { + // create "add to bag" item + SwipeMenuItem addToBagItem = new SwipeMenuItem(menu.getContext()); + // set id + addToBagItem.setId(ID_ADD_TO_BAG); + // set item background + addToBagItem.setBackground(R.color.colorAddToBagBtnBackground); + // set item width + addToBagItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + addToBagItem.setTitle(R.string.add_to_bag_button); + // set item title font size + addToBagItem.setTitleSize(14); + // set item title font color + addToBagItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(addToBagItem); + + // create "return to list" item + SwipeMenuItem returnToListItem = new SwipeMenuItem(menu.getContext()); + // set id + returnToListItem.setId(ID_RETURN_TO_LIST); + // set item background + returnToListItem.setBackground(R.color.colorReturnToListBtnBackground); + // set item width + returnToListItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + returnToListItem.setTitle(R.string.return_to_list_button); + // set item title font size + returnToListItem.setTitleSize(14); + // set item title font color + returnToListItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(returnToListItem); + } + + // create "delete" item + SwipeMenuItem deleteItem = new SwipeMenuItem(menu.getContext()); + // set id + deleteItem.setId(ID_DELETE); + // set item background + deleteItem.setBackground(R.color.colorDeleteBtnBackground); + // set item width + deleteItem.setWidth(Util.dp2px(presenter.getActivityContext(),120)); + // set item title + deleteItem.setTitle(R.string.delete_button); + // set item title font size + deleteItem.setTitleSize(14); + // set item title font color + deleteItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(deleteItem); + + menuLayout.addMenu(menu); + + menuLayout.setMenuItemClickListener(new SwipeMenuLayout.OnMenuItemClickListener() { + @Override + public void onMenuItemClick(View v) { + + switch (v.getId()) { + case ID_DELETE: + remove(item); + break; + case ID_LEAVE_AT_HOME: + leave(item); + break; + case ID_RETURN_TO_LIST: + leaveCancel(item); + break; + case ID_ADD_TO_BAG: + pack(item); + break; + } + + } + }); + } @Override public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ItemViewHolder viewHolder; - View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, - parent, false); - viewHolder = new ItemViewHolder(v); + View content = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_element, parent, false); + SwipeMenuLayout menu = new SwipeMenuLayout(parent.getContext()); + menu.setId(R.id.menu); + SwipableElement container = new SwipableElement(parent.getContext(), content, menu); + container.setSwipeDirection(SwipableElement.DIRECTION_LEFT); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Util.dp2px(parent.getContext(),66)); + container.setOrientation(LinearLayout.HORIZONTAL); + container.setLayoutParams(params); + viewHolder = new ItemViewHolder(container); return viewHolder; } - public void setUndoOn(boolean undoOn) { - this.undoOn = undoOn; - } - - public boolean isUndoOn() { - return undoOn; - } - - public void add(Item item) { - presenter.getModel().insertItem(item); - notifyDataSetChanged(); - } - - - public void clear() { - presenter.getModel().clear(); - notifyDataSetChanged(); - } - public void filter(String query) { presenter.getModel().filter(query); notifyDataSetChanged(); @@ -164,58 +237,31 @@ public class ItemListAdapter extends RecyclerView.Adapter implem holder.title.setBackgroundColor(0x2B1E15); } - public void pendingRemoval(final int position) { - final Item item = presenter.getModel().getItemByPosition(position); - - if (! presenter.getModel().isPendingRemoval(item)) { - presenter.getModel().pendingRemove(item); - // this will redraw row in "undo" state - notifyItemChanged(position); - // let's create, store and post a runnable to remove the item - Runnable pendingRemovalRunnable = new Runnable() { - @Override - public void run() { - remove(item, position); - } - }; - handler.postDelayed(pendingRemovalRunnable, PENDING_REMOVAL_TIMEOUT); - pendingRunables.put(item, pendingRemovalRunnable); - } + public void leave(Item item) { + presenter.getModel().pendingRemove(item); } - public void remove(Item item, int position) { - presenter.getModel().deleteItem(item); - notifyItemRemoved(position); + public void leaveCancel(Item item) { + presenter.getModel().pendingRemoveCancel(item); } - public void remove(int position) { - Item item = presenter.getModel().getItemByPosition(position); - presenter.getModel().deleteItem(item); - notifyItemRemoved(position); + public void remove(Item item) { + presenter.getModel().remove(item); } - public boolean isPendingRemoval(int position) { - Item item = presenter.getModel().getItemByPosition(position); - return presenter.getModel().isPendingRemoval(item); - } - - public void pack(int itemId, int position) { - presenter.getModel().packItem(itemId); - notifyDataSetChanged(); + public void pack(Item item) { + presenter.getModel().packItem(item); + //notifyDataSetChanged(); // TODO check nn /* notifyItemRemoved(position); notifyItemRangeRemoved(position, getItemCount()); */ } - public void unpack(int itemId, int position) { - presenter.getModel().unpackItem(itemId); + public void unpack(Item item) { + presenter.getModel().unpackItem(item); //notifyItemRemoved(position); - notifyDataSetChanged(); - } - - public void unpackAll() { - + //notifyDataSetChanged(); // TODO check nn } public void setCheckAll(boolean checkAll) { diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/PackedListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/PackedListAdapter.java index 4568d29..41d2cac 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/PackedListAdapter.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/PackedListAdapter.java @@ -1,6 +1,18 @@ package com.hikapro.backpack.presenter.adapters; +import android.graphics.Color; +import android.graphics.Paint; +import android.view.View; +import android.widget.Toast; + +import com.hikapro.backpack.R; +import com.hikapro.backpack.model.entities.Item; import com.hikapro.backpack.presenter.Presenter; +import com.hikapro.backpack.presenter.adapters.helper.Util; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenu; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenuItem; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipeMenuLayout; +import com.hikapro.backpack.view.recycler.ItemViewHolder; /** * Created by tariel on 12/05/16. @@ -10,4 +22,151 @@ public class PackedListAdapter extends ItemListAdapter { public PackedListAdapter(Presenter.ItemList presenter) { super(presenter); } + + @Override + public void onBindViewHolder(final ItemViewHolder holder, final int position) { + + final Item item = presenter.getModel().getItemByPosition(position); + holder.cb_item.setChecked(checkAll); + holder.tv_text.setText(item.getName() + " " + item.getId() + " pos " + position); + if (item.isPendingRemoval()) { + holder.tv_text.setPaintFlags(holder.tv_text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + holder.cb_item.setVisibility(View.GONE); + } else { + holder.cb_item.setVisibility(View.VISIBLE); + holder.tv_text.setPaintFlags(holder.tv_text.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + } + + holder.cb_item.setOnClickListener(new android.view.View.OnClickListener() { + @Override + public void onClick(View v) { + if (holder.cb_item.isChecked()) { + pack(item); + } else { + unpack(item); + } + } + }); + holder.im_info.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + presenter.showDetails(item.getId()); + } + }); + + SwipeMenuLayout menuLayout = (SwipeMenuLayout)holder.menu; + SwipeMenu menu = new SwipeMenu(presenter.getActivityContext()); + + menuLayout.removeAllViews(); + + // create menu items here + if (!item.isPendingRemoval()) { + // create "leave at home" item + SwipeMenuItem leaveAtHomeItem = new SwipeMenuItem(menu.getContext()); + // set id + leaveAtHomeItem.setId(ID_LEAVE_AT_HOME); + // set item background + leaveAtHomeItem.setBackground(R.color.colorLeaveAtHomeBtnBackground); + // set item width + leaveAtHomeItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + leaveAtHomeItem.setTitle(R.string.leave_at_home_button); + // set item title font size + leaveAtHomeItem.setTitleSize(14); + // set item title font color + leaveAtHomeItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(leaveAtHomeItem); + } else { + // create "add to bag" item + SwipeMenuItem addToBagItem = new SwipeMenuItem(menu.getContext()); + // set id + addToBagItem.setId(ID_ADD_TO_BAG); + // set item background + addToBagItem.setBackground(R.color.colorAddToBagBtnBackground); + // set item width + addToBagItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + addToBagItem.setTitle(R.string.add_to_bag_button); + // set item title font size + addToBagItem.setTitleSize(14); + // set item title font color + addToBagItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(addToBagItem); + + // create "return to list" item + SwipeMenuItem returnToListItem = new SwipeMenuItem(menu.getContext()); + // set id + returnToListItem.setId(ID_RETURN_TO_LIST); + // set item background + returnToListItem.setBackground(R.color.colorReturnToListBtnBackground); + // set item width + returnToListItem.setWidth(Util.dp2px(presenter.getActivityContext(), 120)); + // set item title + returnToListItem.setTitle(R.string.return_to_list_button); + // set item title font size + returnToListItem.setTitleSize(14); + // set item title font color + returnToListItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(returnToListItem); + } + + // create "delete" item + SwipeMenuItem deleteItem = new SwipeMenuItem(menu.getContext()); + // set id + deleteItem.setId(ID_DELETE); + // set item background + deleteItem.setBackground(R.color.colorDeleteBtnBackground); + // set item width + deleteItem.setWidth(Util.dp2px(presenter.getActivityContext(),120)); + // set item title + deleteItem.setTitle(R.string.delete_button); + // set item title font size + deleteItem.setTitleSize(14); + // set item title font color + deleteItem.setTitleColor(Color.WHITE); + // add to menu + menu.addMenuItem(deleteItem); + + menuLayout.addMenu(menu); + + menuLayout.setMenuItemClickListener(new SwipeMenuLayout.OnMenuItemClickListener() { + @Override + public void onMenuItemClick(View v) { + + switch (v.getId()) { + case ID_DELETE: + remove(item); + break; + case ID_LEAVE_AT_HOME: + leave(item); + break; + case ID_RETURN_TO_LIST: + unpack(item); + break; + case ID_ADD_TO_BAG: + pack(item); + break; + } + } + }); + } + + @Override + public void remove(Item item) { + if (item.isPendingRemoval()) { + presenter.getModel().unpackItem(item); + presenter.getModel().remove(item); + } + else + presenter.getModel().pendingRemove(item); + } + + @Override + public void leave(Item item) { + presenter.getModel().pendingRemove(item); + } + } diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/Util.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/Util.java new file mode 100644 index 0000000..e12fc52 --- /dev/null +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/Util.java @@ -0,0 +1,15 @@ +package com.hikapro.backpack.presenter.adapters.helper; + +import android.content.Context; +import android.util.TypedValue; + +/** + * Created by tariel on 10/07/16. + */ +public class Util { + + public static int dp2px(Context context, int dp) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, + context.getResources().getDisplayMetrics()); + } +} diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java index 7feeccf..d5aa47f 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java @@ -52,22 +52,23 @@ public class ItemSwipeCallback extends ItemTouchHelper.SimpleCallback { @Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int position = viewHolder.getAdapterPosition(); + /* if (adapter.isUndoOn() && adapter.isPendingRemoval(position)) { return 0; - } + }*/ return super.getSwipeDirs(recyclerView, viewHolder); } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { int swipedPosition = viewHolder.getAdapterPosition(); - +/* boolean undoOn = adapter.isUndoOn(); if (undoOn) { adapter.pendingRemoval(swipedPosition); } else { adapter.remove(swipedPosition); - } + }*/ } @Override diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/BaseSwipeListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/BaseSwipeListAdapter.java deleted file mode 100644 index 387f381..0000000 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/BaseSwipeListAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; - -import android.widget.BaseAdapter; - -/** - * Created by tariel on 18/06/16. - */ -public abstract class BaseSwipeListAdapter extends BaseAdapter { - - public boolean getSwipeEnableByPosition(int position) { - return true; - } -} diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuAdapter.java deleted file mode 100644 index 9e6c9c2..0000000 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuAdapter.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; - -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ListAdapter; -import android.widget.WrapperListAdapter; - -/** - * Created by tariel on 18/06/16. - */ -public class SwipeMenuAdapter implements WrapperListAdapter, - SwipeMenuView.OnSwipeItemClickListener { - - private ListAdapter mAdapter; - private Context mContext; - private SwipeMenuListView.OnMenuItemClickListener onMenuItemClickListener; - - public SwipeMenuAdapter(Context context, ListAdapter adapter) { - mAdapter = adapter; - mContext = context; - } - - @Override - public int getCount() { - return mAdapter.getCount(); - } - - @Override - public Object getItem(int position) { - return mAdapter.getItem(position); - } - - @Override - public long getItemId(int position) { - return mAdapter.getItemId(position); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - SwipeMenuLayout layout = null; - if (convertView == null) { - View contentView = mAdapter.getView(position, convertView, parent); - SwipeMenu menu = new SwipeMenu(mContext); - menu.setViewType(getItemViewType(position)); - createMenu(menu); - SwipeMenuView menuView = new SwipeMenuView(menu, - (SwipeMenuListView) parent); - menuView.setOnSwipeItemClickListener(this); - SwipeMenuListView listView = (SwipeMenuListView) parent; - layout = new SwipeMenuLayout(contentView, menuView, - listView.getCloseInterpolator(), - listView.getOpenInterpolator()); - layout.setPosition(position); - } else { - layout = (SwipeMenuLayout) convertView; - layout.closeMenu(); - layout.setPosition(position); - View view = mAdapter.getView(position, layout.getContentView(), - parent); - } - if (mAdapter instanceof BaseSwipeListAdapter) { - boolean swipEnable = (((BaseSwipeListAdapter) mAdapter).getSwipeEnableByPosition(position)); - layout.setSwipEnable(swipEnable); - } - return layout; - } - - public void createMenu(SwipeMenu menu) { - // Test Code - SwipeMenuItem item = new SwipeMenuItem(mContext); - item.setTitle("Item 1"); - item.setBackground(new ColorDrawable(Color.GRAY)); - item.setWidth(300); - menu.addMenuItem(item); - - item = new SwipeMenuItem(mContext); - item.setTitle("Item 2"); - item.setBackground(new ColorDrawable(Color.RED)); - item.setWidth(300); - menu.addMenuItem(item); - } - - @Override - public void onItemClick(SwipeMenuView view, SwipeMenu menu, int index) { - if (onMenuItemClickListener != null) { - onMenuItemClickListener.onMenuItemClick(view.getPosition(), menu, - index); - } - } - - public void setOnSwipeItemClickListener( - SwipeMenuListView.OnMenuItemClickListener onMenuItemClickListener) { - this.onMenuItemClickListener = onMenuItemClickListener; - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - mAdapter.registerDataSetObserver(observer); - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - mAdapter.unregisterDataSetObserver(observer); - } - - @Override - public boolean areAllItemsEnabled() { - return mAdapter.areAllItemsEnabled(); - } - - @Override - public boolean isEnabled(int position) { - return mAdapter.isEnabled(position); - } - - @Override - public boolean hasStableIds() { - return mAdapter.hasStableIds(); - } - - @Override - public int getItemViewType(int position) { - return mAdapter.getItemViewType(position); - } - - @Override - public int getViewTypeCount() { - return mAdapter.getViewTypeCount(); - } - - @Override - public boolean isEmpty() { - return mAdapter.isEmpty(); - } - - @Override - public ListAdapter getWrappedAdapter() { - return mAdapter; - } -} diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuCreator.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuCreator.java deleted file mode 100644 index 5b6b3f6..0000000 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuCreator.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; - -/** - * Created by tariel on 18/06/16. - */ -public interface SwipeMenuCreator { - void create(SwipeMenu menu); -} diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuListView.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuListView.java deleted file mode 100644 index 41f1be2..0000000 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuListView.java +++ /dev/null @@ -1,339 +0,0 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; - -import android.content.Context; -import android.support.v4.view.MotionEventCompat; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.MotionEvent; -import android.view.View; -import android.view.animation.Interpolator; -import android.widget.ListAdapter; -import android.widget.ListView; - -/** - * Created by tariel on 18/06/16. - */ -public class SwipeMenuListView extends ListView { - - private static final int TOUCH_STATE_NONE = 0; - private static final int TOUCH_STATE_X = 1; - private static final int TOUCH_STATE_Y = 2; - - public static final int DIRECTION_LEFT = 1; - public static final int DIRECTION_RIGHT = -1; - private int mDirection = 1;//swipe from right to left by default - - private int MAX_Y = 5; - private int MAX_X = 3; - private float mDownX; - private float mDownY; - private int mTouchState; - private int mTouchPosition; - private SwipeMenuLayout mTouchView; - private OnSwipeListener mOnSwipeListener; - - private SwipeMenuCreator mMenuCreator; - private OnMenuItemClickListener mOnMenuItemClickListener; - private OnMenuStateChangeListener mOnMenuStateChangeListener; - private Interpolator mCloseInterpolator; - private Interpolator mOpenInterpolator; - - public SwipeMenuListView(Context context) { - super(context); - init(); - } - - public SwipeMenuListView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - public SwipeMenuListView(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - private void init() { - MAX_X = dp2px(MAX_X); - MAX_Y = dp2px(MAX_Y); - mTouchState = TOUCH_STATE_NONE; - } - - @Override - public void setAdapter(ListAdapter adapter) { - super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) { - @Override - public void createMenu(SwipeMenu menu) { - if (mMenuCreator != null) { - mMenuCreator.create(menu); - } - } - - @Override - public void onItemClick(SwipeMenuView view, SwipeMenu menu, - int index) { - boolean flag = false; - if (mOnMenuItemClickListener != null) { - flag = mOnMenuItemClickListener.onMenuItemClick( - view.getPosition(), menu, index); - } - if (mTouchView != null && !flag) { - mTouchView.smoothCloseMenu(); - } - } - }); - } - - public void setCloseInterpolator(Interpolator interpolator) { - mCloseInterpolator = interpolator; - } - - public void setOpenInterpolator(Interpolator interpolator) { - mOpenInterpolator = interpolator; - } - - public Interpolator getOpenInterpolator() { - return mOpenInterpolator; - } - - public Interpolator getCloseInterpolator() { - return mCloseInterpolator; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - //在拦截处处理,在滑动设置了点击事件的地方也能swip,点击时又不能影响原来的点击事件 - int action = ev.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - mDownX = ev.getX(); - mDownY = ev.getY(); - boolean handled = super.onInterceptTouchEvent(ev); - mTouchState = TOUCH_STATE_NONE; - mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); - View view = getChildAt(mTouchPosition - getFirstVisiblePosition()); - - //只在空的时候赋值 以免每次触摸都赋值,会有多个open状态 - if (view instanceof SwipeMenuLayout) { - //如果有打开了 就拦截. - if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) { - return true; - } - mTouchView = (SwipeMenuLayout) view; - mTouchView.setSwipeDirection(mDirection); - } - //如果摸在另外个view - if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) { - handled = true; - } - - if (mTouchView != null) { - mTouchView.onSwipe(ev); - } - return handled; - case MotionEvent.ACTION_MOVE: - float dy = Math.abs((ev.getY() - mDownY)); - float dx = Math.abs((ev.getX() - mDownX)); - if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) { - //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了 - if (mTouchState == TOUCH_STATE_NONE) { - if (Math.abs(dy) > MAX_Y) { - mTouchState = TOUCH_STATE_Y; - } else if (dx > MAX_X) { - mTouchState = TOUCH_STATE_X; - if (mOnSwipeListener != null) { - mOnSwipeListener.onSwipeStart(mTouchPosition); - } - } - } - return true; - } - } - return super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null) - return super.onTouchEvent(ev); - int action = ev.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - int oldPos = mTouchPosition; - mDownX = ev.getX(); - mDownY = ev.getY(); - mTouchState = TOUCH_STATE_NONE; - - mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); - - if (mTouchPosition == oldPos && mTouchView != null - && mTouchView.isOpen()) { - mTouchState = TOUCH_STATE_X; - mTouchView.onSwipe(ev); - return true; - } - - View view = getChildAt(mTouchPosition - getFirstVisiblePosition()); - - if (mTouchView != null && mTouchView.isOpen()) { - mTouchView.smoothCloseMenu(); - mTouchView = null; - // return super.onTouchEvent(ev); - // try to cancel the touch event - MotionEvent cancelEvent = MotionEvent.obtain(ev); - cancelEvent.setAction(MotionEvent.ACTION_CANCEL); - onTouchEvent(cancelEvent); - if (mOnMenuStateChangeListener != null) { - mOnMenuStateChangeListener.onMenuClose(oldPos); - } - return true; - } - if (view instanceof SwipeMenuLayout) { - mTouchView = (SwipeMenuLayout) view; - mTouchView.setSwipeDirection(mDirection); - } - if (mTouchView != null) { - mTouchView.onSwipe(ev); - } - break; - case MotionEvent.ACTION_MOVE: - //有些可能有header,要减去header再判断 - mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount(); - //如果滑动了一下没完全展现,就收回去,这时候mTouchView已经赋值,再滑动另外一个不可以swip的view - //会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view - if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) { - break; - } - float dy = Math.abs((ev.getY() - mDownY)); - float dx = Math.abs((ev.getX() - mDownX)); - if (mTouchState == TOUCH_STATE_X) { - if (mTouchView != null) { - mTouchView.onSwipe(ev); - } - getSelector().setState(new int[]{0}); - ev.setAction(MotionEvent.ACTION_CANCEL); - super.onTouchEvent(ev); - return true; - } else if (mTouchState == TOUCH_STATE_NONE) { - if (Math.abs(dy) > MAX_Y) { - mTouchState = TOUCH_STATE_Y; - } else if (dx > MAX_X) { - mTouchState = TOUCH_STATE_X; - if (mOnSwipeListener != null) { - mOnSwipeListener.onSwipeStart(mTouchPosition); - } - } - } - break; - case MotionEvent.ACTION_UP: - if (mTouchState == TOUCH_STATE_X) { - if (mTouchView != null) { - boolean isBeforeOpen = mTouchView.isOpen(); - mTouchView.onSwipe(ev); - boolean isAfterOpen = mTouchView.isOpen(); - if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) { - if (isAfterOpen) { - mOnMenuStateChangeListener.onMenuOpen(mTouchPosition); - } else { - mOnMenuStateChangeListener.onMenuClose(mTouchPosition); - } - } - if (!isAfterOpen) { - mTouchPosition = -1; - mTouchView = null; - } - } - if (mOnSwipeListener != null) { - mOnSwipeListener.onSwipeEnd(mTouchPosition); - } - ev.setAction(MotionEvent.ACTION_CANCEL); - super.onTouchEvent(ev); - return true; - } - break; - } - return super.onTouchEvent(ev); - } - - public void smoothOpenMenu(int position) { - if (position >= getFirstVisiblePosition() - && position <= getLastVisiblePosition()) { - View view = getChildAt(position - getFirstVisiblePosition()); - if (view instanceof SwipeMenuLayout) { - mTouchPosition = position; - if (mTouchView != null && mTouchView.isOpen()) { - mTouchView.smoothCloseMenu(); - } - mTouchView = (SwipeMenuLayout) view; - mTouchView.setSwipeDirection(mDirection); - mTouchView.smoothOpenMenu(); - } - } - } - - public void smoothCloseMenu(){ - if (mTouchView != null && mTouchView.isOpen()) { - mTouchView.smoothCloseMenu(); - } - } - - private int dp2px(int dp) { - return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, - getContext().getResources().getDisplayMetrics()); - } - - public void setMenuCreator(SwipeMenuCreator menuCreator) { - this.mMenuCreator = menuCreator; - } - - public void setOnMenuItemClickListener( - OnMenuItemClickListener onMenuItemClickListener) { - this.mOnMenuItemClickListener = onMenuItemClickListener; - } - - public void setOnSwipeListener(OnSwipeListener onSwipeListener) { - this.mOnSwipeListener = onSwipeListener; - } - - public void setOnMenuStateChangeListener(OnMenuStateChangeListener onMenuStateChangeListener) { - mOnMenuStateChangeListener = onMenuStateChangeListener; - } - - public static interface OnMenuItemClickListener { - boolean onMenuItemClick(int position, SwipeMenu menu, int index); - } - - public static interface OnSwipeListener { - void onSwipeStart(int position); - - void onSwipeEnd(int position); - } - - public static interface OnMenuStateChangeListener { - void onMenuOpen(int position); - - void onMenuClose(int position); - } - - public void setSwipeDirection(int direction) { - mDirection = direction; - } - - /** - * 判断点击事件是否在某个view内 - * - * @param view - * @param ev - * @return - */ - public static boolean inRangeOfView(View view, MotionEvent ev) { - int[] location = new int[2]; - view.getLocationOnScreen(location); - int x = location[0]; - int y = location[1]; - if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuView.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuView.java deleted file mode 100644 index 6d9d1ea..0000000 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuView.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; - -import java.util.List; -import android.text.TextUtils; -import android.view.Gravity; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -/** - * Created by tariel on 18/06/16. - */ -public class SwipeMenuView extends LinearLayout implements OnClickListener { - - private SwipeMenuListView mListView; - private SwipeMenuLayout mLayout; - private SwipeMenu mMenu; - private OnSwipeItemClickListener onItemClickListener; - private int position; - - public int getPosition() { - return position; - } - - public void setPosition(int position) { - this.position = position; - } - - public SwipeMenuView(SwipeMenu menu, SwipeMenuListView listView) { - super(menu.getContext()); - mListView = listView; - mMenu = menu; - List items = menu.getMenuItems(); - int id = 0; - for (SwipeMenuItem item : items) { - addItem(item, id++); - } - } - - private void addItem(SwipeMenuItem item, int id) { - LayoutParams params = new LayoutParams(item.getWidth(), - LayoutParams.MATCH_PARENT); - LinearLayout parent = new LinearLayout(getContext()); - parent.setId(id); - parent.setGravity(Gravity.CENTER); - parent.setOrientation(LinearLayout.VERTICAL); - parent.setLayoutParams(params); - parent.setBackgroundDrawable(item.getBackground()); - parent.setOnClickListener(this); - addView(parent); - - if (item.getIcon() != null) { - parent.addView(createIcon(item)); - } - if (!TextUtils.isEmpty(item.getTitle())) { - parent.addView(createTitle(item)); - } - - } - - private ImageView createIcon(SwipeMenuItem item) { - ImageView iv = new ImageView(getContext()); - iv.setImageDrawable(item.getIcon()); - return iv; - } - - private TextView createTitle(SwipeMenuItem item) { - TextView tv = new TextView(getContext()); - tv.setText(item.getTitle()); - tv.setGravity(Gravity.CENTER); - tv.setTextSize(item.getTitleSize()); - tv.setTextColor(item.getTitleColor()); - return tv; - } - - @Override - public void onClick(View v) { - if (onItemClickListener != null && mLayout.isOpen()) { - onItemClickListener.onItemClick(this, mMenu, v.getId()); - } - } - - public OnSwipeItemClickListener getOnSwipeItemClickListener() { - return onItemClickListener; - } - - public void setOnSwipeItemClickListener(OnSwipeItemClickListener onItemClickListener) { - this.onItemClickListener = onItemClickListener; - } - - public void setLayout(SwipeMenuLayout mLayout) { - this.mLayout = mLayout; - } - - public static interface OnSwipeItemClickListener { - void onItemClick(SwipeMenuView view, SwipeMenu menu, int index); - } -} diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuLayout.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipableElement.java similarity index 68% rename from app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuLayout.java rename to app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipableElement.java index 479e8f1..07b1ff1 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuLayout.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipableElement.java @@ -1,41 +1,42 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; +package com.hikapro.backpack.presenter.adapters.helper.items.swipe2; import android.content.Context; +import android.graphics.Rect; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.widget.ScrollerCompat; import android.util.AttributeSet; -import android.util.Log; import android.util.TypedValue; import android.view.GestureDetector.OnGestureListener; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; -import android.widget.AbsListView; -import android.widget.FrameLayout; +import android.widget.LinearLayout; /** * Created by tariel on 18/06/16. */ -public class SwipeMenuLayout extends FrameLayout { +public class SwipableElement extends LinearLayout { + + public static final int DIRECTION_LEFT = 1; + public static final int DIRECTION_RIGHT = -1; private static final int CONTENT_VIEW_ID = 1; private static final int MENU_VIEW_ID = 2; private static final int STATE_CLOSE = 0; private static final int STATE_OPEN = 1; - private int mSwipeDirection; private View mContentView; - private SwipeMenuView mMenuView; + private SwipeMenuLayout mMenuView; private int mDownX; private int state = STATE_CLOSE; private GestureDetectorCompat mGestureDetector; private OnGestureListener mGestureListener; private boolean isFling; private int MIN_FLING = dp2px(15); - private int MAX_VELOCITYX = -dp2px(500); + private int MAX_VELOCITY_X = -dp2px(500); private ScrollerCompat mOpenScroller; private ScrollerCompat mCloseScroller; private int mBaseX; @@ -43,52 +44,39 @@ public class SwipeMenuLayout extends FrameLayout { private Interpolator mCloseInterpolator; private Interpolator mOpenInterpolator; - private boolean mSwipEnable = true; + private boolean mSwipeEnable = true; - public SwipeMenuLayout(View contentView, SwipeMenuView menuView) { - this(contentView, menuView, null, null); + public SwipableElement(Context context, View contentView, SwipeMenuLayout menuView) { + this(context, contentView, menuView, null, null); } - public SwipeMenuLayout(View contentView, SwipeMenuView menuView, + public SwipableElement(Context context, View contentView, SwipeMenuLayout menuView, Interpolator closeInterpolator, Interpolator openInterpolator) { - super(contentView.getContext()); + super(context); + mCloseInterpolator = closeInterpolator; mOpenInterpolator = openInterpolator; mContentView = contentView; mMenuView = menuView; - mMenuView.setLayout(this); - init(); + + doSomething(); } - // private SwipeMenuLayout(Context context, AttributeSet attrs, int - // defStyle) { - // super(context, attrs, defStyle); - // } - - private SwipeMenuLayout(Context context, AttributeSet attrs) { + private SwipableElement(Context context, AttributeSet attrs) { super(context, attrs); } - private SwipeMenuLayout(Context context) { + private SwipableElement(Context context) { super(context); } - public int getPosition() { - return position; - } - - public void setPosition(int position) { - this.position = position; - mMenuView.setPosition(position); - } public void setSwipeDirection(int swipeDirection) { mSwipeDirection = swipeDirection; } - private void init() { - setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.WRAP_CONTENT)); + private void doSomething() { + setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 56)); mGestureListener = new SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { @@ -99,20 +87,17 @@ public class SwipeMenuLayout extends FrameLayout { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - // TODO - if (Math.abs(e1.getX() - e2.getX()) > MIN_FLING - && velocityX < MAX_VELOCITYX) { - isFling = true; + if (e1 != null && e2 != null) { + if (Math.abs(e1.getX() - e2.getX()) > MIN_FLING + && velocityX < MAX_VELOCITY_X) { + isFling = true; + } } - // Log.i("byz", MAX_VELOCITYX + ", velocityX = " + velocityX); return super.onFling(e1, e2, velocityX, velocityY); } }; - mGestureDetector = new GestureDetectorCompat(getContext(), - mGestureListener); + mGestureDetector = new GestureDetectorCompat(getContext(), mGestureListener); - // mScroller = ScrollerCompat.create(getContext(), new - // BounceInterpolator()); if (mCloseInterpolator != null) { mCloseScroller = ScrollerCompat.create(getContext(), mCloseInterpolator); @@ -126,35 +111,17 @@ public class SwipeMenuLayout extends FrameLayout { mOpenScroller = ScrollerCompat.create(getContext()); } - LayoutParams contentParams = new LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); + LayoutParams contentParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); mContentView.setLayoutParams(contentParams); if (mContentView.getId() < 1) { mContentView.setId(CONTENT_VIEW_ID); } - - mMenuView.setId(MENU_VIEW_ID); - mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT)); + if (mMenuView.getId() < 1) + mMenuView.setId(MENU_VIEW_ID); + mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); addView(mContentView); addView(mMenuView); - - // if (mContentView.getBackground() == null) { - // mContentView.setBackgroundColor(Color.WHITE); - // } - - // in android 2.x, MenuView height is MATCH_PARENT is not work. - // getViewTreeObserver().addOnGlobalLayoutListener( - // new OnGlobalLayoutListener() { - // @Override - // public void onGlobalLayout() { - // setMenuHeight(mContentView.getHeight()); - // // getViewTreeObserver() - // // .removeGlobalOnLayoutListener(this); - // } - // }); - } @Override @@ -170,25 +137,25 @@ public class SwipeMenuLayout extends FrameLayout { public boolean onSwipe(MotionEvent event) { mGestureDetector.onTouchEvent(event); switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: mDownX = (int) event.getX(); isFling = false; break; + case MotionEvent.ACTION_MOVE: - // Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX()); int dis = (int) (mDownX - event.getX()); if (state == STATE_OPEN) { - dis += mMenuView.getWidth()*mSwipeDirection;; + dis += mMenuView.getWidth() * mSwipeDirection; } swipe(dis); break; + case MotionEvent.ACTION_UP: - if ((isFling || Math.abs(mDownX - event.getX()) > (mMenuView.getWidth() / 2)) && + if ((isFling || Math.abs(mDownX - event.getX()) > (mMenuView.getWidth() / 4)) && Math.signum(mDownX - event.getX()) == mSwipeDirection) { - // open smoothOpenMenu(); } else { - // close smoothCloseMenu(); return false; } @@ -201,25 +168,20 @@ public class SwipeMenuLayout extends FrameLayout { return state == STATE_OPEN; } - @Override - public boolean onTouchEvent(MotionEvent event) { - return super.onTouchEvent(event); - } - private void swipe(int dis) { - if(!mSwipEnable){ + if (!mSwipeEnable){ return ; } if (Math.signum(dis) != mSwipeDirection) { dis = 0; - } else if (Math.abs(dis) > mMenuView.getWidth()) { + } else if (mMenuView.getWidth() > 0 && Math.abs(dis) > mMenuView.getWidth()) { dis = mMenuView.getWidth()*mSwipeDirection; } mContentView.layout(-dis, mContentView.getTop(), mContentView.getWidth() -dis, getMeasuredHeight()); - if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) { + if (mSwipeDirection == SwipableRecycler.DIRECTION_LEFT) { mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(), mContentView.getWidth() + mMenuView.getWidth() - dis, @@ -247,7 +209,7 @@ public class SwipeMenuLayout extends FrameLayout { public void smoothCloseMenu() { state = STATE_CLOSE; - if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) { + if (mSwipeDirection == SwipableRecycler.DIRECTION_LEFT) { mBaseX = -mContentView.getLeft(); mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350); } else { @@ -258,11 +220,11 @@ public class SwipeMenuLayout extends FrameLayout { } public void smoothOpenMenu() { - if(!mSwipEnable){ + if(!mSwipeEnable){ return ; } state = STATE_OPEN; - if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) { + if (mSwipeDirection == SwipableRecycler.DIRECTION_LEFT) { mOpenScroller.startScroll(-mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350); } else { mOpenScroller.startScroll(mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350); @@ -281,7 +243,7 @@ public class SwipeMenuLayout extends FrameLayout { } public void openMenu() { - if(!mSwipEnable){ + if(!mSwipeEnable){ return ; } if (state == STATE_CLOSE) { @@ -294,7 +256,7 @@ public class SwipeMenuLayout extends FrameLayout { return mContentView; } - public SwipeMenuView getMenuView() { + public SwipeMenuLayout getMenuView() { return mMenuView; } @@ -306,16 +268,28 @@ public class SwipeMenuLayout extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - mMenuView.measure(MeasureSpec.makeMeasureSpec(0, - MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec( - getMeasuredHeight(), MeasureSpec.EXACTLY)); + + int width = getMeasuredWidth(); + int height = getMeasuredHeight(); + int childWidthMeasureSpec; + int childHeightMeasureSpec; + + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + + mContentView.measure(childWidthMeasureSpec, childHeightMeasureSpec); + + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + + mMenuView.measure(childWidthMeasureSpec, childHeightMeasureSpec); + } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { - mContentView.layout(0, 0, getMeasuredWidth(), - mContentView.getMeasuredHeight()); - if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) { + mContentView.layout(0, 0, getMeasuredWidth(),mContentView.getMeasuredHeight()); + if (mSwipeDirection == DIRECTION_LEFT) { mMenuView.layout(getMeasuredWidth(), 0, getMeasuredWidth() + mMenuView.getMeasuredWidth(), mContentView.getMeasuredHeight()); @@ -326,7 +300,6 @@ public class SwipeMenuLayout extends FrameLayout { } public void setMenuHeight(int measuredHeight) { - Log.i("byz", "pos = " + position + ", height = " + measuredHeight); LayoutParams params = (LayoutParams) mMenuView.getLayoutParams(); if (params.height != measuredHeight) { params.height = measuredHeight; @@ -334,11 +307,21 @@ public class SwipeMenuLayout extends FrameLayout { } } - public void setSwipEnable(boolean swipEnable){ - mSwipEnable = swipEnable; + public void setSwipeEnable(boolean swipeEnable){ + mSwipeEnable = swipeEnable; } - public boolean getSwipEnable(){ - return mSwipEnable; + public boolean getSwipeEnable(){ + return mSwipeEnable; + } + + public boolean isMenuVisible() { + Rect bounds = new Rect(); + this.getHitRect(bounds); + if (mMenuView.getLocalVisibleRect(bounds)) { + return true; + } else { + return false; + } } } diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipableRecycler.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipableRecycler.java new file mode 100644 index 0000000..77a2339 --- /dev/null +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipableRecycler.java @@ -0,0 +1,199 @@ +package com.hikapro.backpack.presenter.adapters.helper.items.swipe2; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.MotionEvent; +import android.view.View; + +/** + * Created by tariel on 06/07/16. + */ +public class SwipableRecycler extends RecyclerView { + + private static final int TOUCH_ACTION_START = 1; + private static final int TOUCH_ACTION_MOVE_X = 2; + private static final int TOUCH_ACTION_MOVE_Y = 3; + + public static final int DIRECTION_LEFT = 1; + public static final int DIRECTION_RIGHT = -1; + private int mDirection = 1; // swipe from right to left by default + + private int MAX_Y = 5; + private int MAX_X = 3; + private float mDownX; + private float mDownY; + private int mTouchState; + private SwipableElement lastTouchedElement; + + public SwipableRecycler(Context context) { + super(context); + init(); + } + + public SwipableRecycler(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(); + } + + public SwipableRecycler(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent e) { + View buf; + int action = e.getAction(); + + switch (action) { + case MotionEvent.ACTION_DOWN: + boolean handled = false; + mDownX = e.getX(); + mDownY = e.getY(); + handled = super.onInterceptTouchEvent(e); + mTouchState = TOUCH_ACTION_START; + buf = findChildViewUnder(mDownX, mDownY); + if (buf instanceof SwipableElement) { + + if (lastTouchedElement != null && lastTouchedElement.isOpen() && !inRangeOfView(lastTouchedElement.getMenuView(), e)) { + return true; + } + lastTouchedElement = (SwipableElement) buf; + lastTouchedElement.setSwipeDirection(mDirection); + } + if (lastTouchedElement != null && lastTouchedElement.isOpen() && lastTouchedElement != buf) { + handled = true; + } + if (lastTouchedElement != null && lastTouchedElement.isOpen() && inRangeOfView(lastTouchedElement.getMenuView(), e)) { + lastTouchedElement.getMenuView().notifyOnClick(e.getRawX(), e.getRawY()); + } + if (lastTouchedElement != null) + lastTouchedElement.onSwipe(e); + return handled; + + case MotionEvent.ACTION_MOVE: + float dy = Math.abs((e.getY() - mDownY)); + float dx = Math.abs((e.getX() - mDownX)); + + if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) { + if (mTouchState == TOUCH_ACTION_START) { + if (Math.abs(dy) > MAX_Y) { + mTouchState = TOUCH_ACTION_MOVE_Y; + } else if (dx > MAX_X) { + mTouchState = TOUCH_ACTION_MOVE_X; + } + } + return true; + } + } + return super.onInterceptTouchEvent(e); + } + + @Override + public boolean onTouchEvent(MotionEvent e) { + View buf; + int action = e.getAction(); + if (action != MotionEvent.ACTION_DOWN && lastTouchedElement == null) + return super.onTouchEvent(e); + + switch (action) { + case MotionEvent.ACTION_DOWN: + SwipableElement test = null; + mDownX = e.getX(); + mDownY = e.getY(); + mTouchState = TOUCH_ACTION_START; + + buf = findChildViewUnder(e.getX(), e.getY()); + + if (buf instanceof SwipableElement) + test = (SwipableElement) buf; + + if (lastTouchedElement != null && lastTouchedElement == test + && lastTouchedElement.isOpen()) { + mTouchState = TOUCH_ACTION_MOVE_X; + lastTouchedElement.onSwipe(e); + return true; + } + if (lastTouchedElement != null && lastTouchedElement.isOpen()) { + lastTouchedElement.smoothCloseMenu(); + lastTouchedElement = null; + // try to cancel the touch event + MotionEvent cancelEvent = MotionEvent.obtain(e); + cancelEvent.setAction(MotionEvent.ACTION_CANCEL); + super.onTouchEvent(cancelEvent); + return true; + } + if (buf instanceof SwipableElement) { + lastTouchedElement = (SwipableElement) buf; + lastTouchedElement.setSwipeDirection(mDirection); + } + if (lastTouchedElement != null) { + lastTouchedElement.onSwipe(e); + } + break; + + case MotionEvent.ACTION_MOVE: + float dy = Math.abs((e.getY() - mDownY)); + float dx = Math.abs((e.getX() - mDownX)); + + if (mTouchState == TOUCH_ACTION_MOVE_X) { + if (lastTouchedElement != null) { + lastTouchedElement.onSwipe(e); + } + e.setAction(MotionEvent.ACTION_CANCEL); + super.onTouchEvent(e); + return true; + } else if (mTouchState == TOUCH_ACTION_START) { + if (Math.abs(dy) > MAX_Y) { + mTouchState = TOUCH_ACTION_MOVE_Y; + } else if (dx > MAX_X) { + mTouchState = TOUCH_ACTION_MOVE_X; + } + } + break; + + case MotionEvent.ACTION_UP: + if (mTouchState == TOUCH_ACTION_MOVE_X) { + if (lastTouchedElement != null) { + boolean isBeforeOpen = lastTouchedElement.isOpen(); + lastTouchedElement.onSwipe(e); + boolean isAfterOpen = lastTouchedElement.isOpen(); + + if (!isAfterOpen) { + lastTouchedElement = null; + } + } + e.setAction(MotionEvent.ACTION_CANCEL); + super.onTouchEvent(e); + return true; + } + break; + } + return super.onTouchEvent(e); + } + + public static boolean inRangeOfView(View view, MotionEvent ev) { + int[] location = new int[2]; + view.getLocationOnScreen(location); + int x = location[0]; + int y = location[1]; + if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) { + return false; + } + return true; + } + + private void init() { + MAX_X = dp2px(MAX_X); + MAX_Y = dp2px(MAX_Y); + mTouchState = TOUCH_ACTION_START; + } + + private int dp2px(int dp) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, + getContext().getResources().getDisplayMetrics()); + } +} diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenu.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenu.java similarity index 99% rename from app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenu.java rename to app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenu.java index d647ffc..000d5c2 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenu.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenu.java @@ -1,4 +1,4 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; +package com.hikapro.backpack.presenter.adapters.helper.items.swipe2; import android.content.Context; diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuItem.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenuItem.java similarity index 99% rename from app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuItem.java rename to app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenuItem.java index ca9630d..256663c 100644 --- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuItem.java +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenuItem.java @@ -1,4 +1,4 @@ -package com.hikapro.backpack.presenter.adapters.helper.items.swipe; +package com.hikapro.backpack.presenter.adapters.helper.items.swipe2; import android.content.Context; import android.graphics.drawable.Drawable; diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenuLayout.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenuLayout.java new file mode 100644 index 0000000..561a63f --- /dev/null +++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe2/SwipeMenuLayout.java @@ -0,0 +1,123 @@ +package com.hikapro.backpack.presenter.adapters.helper.items.swipe2; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.List; + +/** + * Created by tariel on 18/06/16. + */ +public class SwipeMenuLayout extends LinearLayout { + + private SwipeMenu swipeMenu; + + private OnMenuItemClickListener menuItemClickListener; + + public OnMenuItemClickListener getMenuItemClickListener() { + return menuItemClickListener; + } + + public void setMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { + this.menuItemClickListener = menuItemClickListener; + } + + public SwipeMenuLayout(Context context) { + super(context); + } + + public SwipeMenuLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SwipeMenuLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public void addMenu(SwipeMenu menu) { + swipeMenu = menu; + List items = menu.getMenuItems(); + int id = 0; + for (SwipeMenuItem item : items) { + addItem(item, item.getId() == 0 ? ++id : item.getId()); + } + } + + + private void addItem(SwipeMenuItem item, int id) { + + LayoutParams params = new LayoutParams(item.getWidth(),LayoutParams.MATCH_PARENT); + LinearLayout parent = new LinearLayout(getContext()); + parent.setId(id); + parent.setGravity(Gravity.CENTER); + parent.setOrientation(LinearLayout.VERTICAL); + parent.setLayoutParams(params); + parent.setBackgroundDrawable(item.getBackground()); + addView(parent); + + if (item.getIcon() != null) { + parent.addView(createIcon(item)); + } + if (!TextUtils.isEmpty(item.getTitle())) { + parent.addView(createTitle(item)); + } + } + + private ImageView createIcon(SwipeMenuItem item) { + ImageView iv = new ImageView(getContext()); + iv.setImageDrawable(item.getIcon()); + return iv; + } + + private TextView createTitle(SwipeMenuItem item) { + TextView tv = new TextView(getContext()); + tv.setText(item.getTitle()); + tv.setGravity(Gravity.CENTER); + tv.setTextSize(item.getTitleSize()); + tv.setTextColor(item.getTitleColor()); + return tv; + } + // should be raw coordinates + public void notifyOnClick(float x, float y) { + View menuItem = findViewAtPoint(x, y); + if (menuItem != null) { + if (menuItemClickListener != null) + menuItemClickListener.onMenuItemClick(menuItem); + } + } + + public interface OnMenuItemClickListener { + void onMenuItemClick(View v); + } + + private View findViewAtPoint(float x, float y) { + View ret = null; + View buf; + for (int i = 0; i < this.getChildCount(); ++i) { + buf = getChildAt(i); + if (isPointInsideView(x, y, buf)) { + ret = buf; + break; + } + } + return ret; + } + + private boolean isPointInsideView(float x, float y, View view) { + int location[] = new int[2]; + view.getLocationOnScreen(location); + int viewX = location[0]; + int viewY = location[1]; + + // point is inside view bounds + return ((x > viewX && x < (viewX + view.getWidth())) && + (y > viewY && y < (viewY + view.getHeight()))); + } + +} diff --git a/app/src/main/java/com/hikapro/backpack/test/ScreenSlidePageFrag.java b/app/src/main/java/com/hikapro/backpack/test/ScreenSlidePageFrag.java new file mode 100644 index 0000000..9703b97 --- /dev/null +++ b/app/src/main/java/com/hikapro/backpack/test/ScreenSlidePageFrag.java @@ -0,0 +1,9 @@ +package com.hikapro.backpack.test; + +import android.app.Fragment; + +/** + * Created by tariel on 16/07/16. + */ +public class ScreenSlidePageFrag extends Fragment { +} diff --git a/app/src/main/java/com/hikapro/backpack/view/View.java b/app/src/main/java/com/hikapro/backpack/view/View.java index a29536b..fb6cf53 100644 --- a/app/src/main/java/com/hikapro/backpack/view/View.java +++ b/app/src/main/java/com/hikapro/backpack/view/View.java @@ -25,7 +25,7 @@ public interface View { } interface ItemList extends Base { - void showItemDetail(Item item); + void showItemDetail(Item item, int setId); void showPackedItems(Set set); void setPresenter(Presenter.ItemList presenter); Set getSet(); @@ -33,6 +33,7 @@ public interface View { interface ItemDetail extends Base { void setPresenter(Presenter.ItemDetail presenter); Item getItem(); + int getSetId(); } interface Share extends Base { @@ -49,7 +50,7 @@ public interface View { void startSetListFragment(); void startItemListFragment(Set set); void startPackedListFragment(Set set); - void startItemDetailFragment(Item item); + void startItemDetailFragment(Item item, int setId); void startShareFragment(int setId); void startAddFragment(Set set); diff --git a/app/src/main/java/com/hikapro/backpack/view/fragments/ItemDetailFragment.java b/app/src/main/java/com/hikapro/backpack/view/fragments/ItemDetailFragment.java index 94249e0..87800b7 100644 --- a/app/src/main/java/com/hikapro/backpack/view/fragments/ItemDetailFragment.java +++ b/app/src/main/java/com/hikapro/backpack/view/fragments/ItemDetailFragment.java @@ -7,9 +7,13 @@ import android.os.Bundle; import android.app.Fragment; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import com.hikapro.backpack.R; import com.hikapro.backpack.model.entities.Item; import com.hikapro.backpack.presenter.Presenter; @@ -19,6 +23,7 @@ import com.hikapro.backpack.presenter.Presenter; public class ItemDetailFragment extends Fragment implements com.hikapro.backpack.view.View.ItemDetail { private static final String BUNDLE_ITEM_KEY = "BUNDLE_ITEM_KEY"; + private static final String BUNDLE_SET_KEY = "BUNDLE_SET_KEY"; private Presenter.ItemDetail presenter; private com.hikapro.backpack.view.View.ActivityCallback activityCallback; @@ -32,10 +37,11 @@ public class ItemDetailFragment extends Fragment implements com.hikapro.backpack return new ItemDetailFragment(); } - public static ItemDetailFragment newFromItem(Item item) { + public static ItemDetailFragment newInstance(Item item, int setId) { ItemDetailFragment ret = ItemDetailFragment.construct(); Bundle args = new Bundle(); args.putSerializable(BUNDLE_ITEM_KEY, item); + args.putInt(BUNDLE_SET_KEY, setId); ret.setArguments(args); return ret; } @@ -142,4 +148,11 @@ public class ItemDetailFragment extends Fragment implements com.hikapro.backpack Item item = (Item) args.getSerializable(BUNDLE_ITEM_KEY); return item; } + + @Override + public int getSetId() { + Bundle args = getArguments(); + int setId = args.getInt(BUNDLE_SET_KEY); + return setId; + } } diff --git a/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java b/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java index 7a8b305..004c146 100644 --- a/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java +++ b/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java @@ -71,11 +71,9 @@ public class ItemListFragment extends Fragment implements com.hikapro.backpack.v @Override public boolean onOptionsItemSelected(MenuItem item) { boolean ret; + switch (item.getItemId()) { - case android.R.id.home: - this.getFragmentManager().popBackStack(); - ret = true; - break; + case R.id.action_share : activityCallback.startShareFragment(getSet().getId()); ret = true; @@ -117,13 +115,13 @@ public class ItemListFragment extends Fragment implements com.hikapro.backpack.v throw new ClassCastException(activity.toString() + " must implement activityCallback"); } - Log.i(this.toString(), " onAttach"); + Log.i(this.getClass().getName(), " onAttach"); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); - Log.i(this.toString(), " onCreate"); + Log.i(this.getClass().getName(), " onCreate"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -131,58 +129,58 @@ public class ItemListFragment extends Fragment implements com.hikapro.backpack.v // Inflate the layout for this fragment presenter.setView(this); View view = presenter.onCreateView(inflater, container, savedInstanceState); - Log.i(this.toString(), " onCreateView"); + Log.i(this.getClass().getName(), " onCreateView"); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Log.i(this.toString(), " onActivityCreated"); + Log.i(this.getClass().getName(), " onActivityCreated"); } @Override public void onStart() { super.onStart(); - Log.i(this.toString(), " onStart"); + Log.i(this.getClass().getName(), " onStart"); } @Override public void onResume() { super.onResume(); - Log.i(this.toString(), " onResume"); + Log.i(this.getClass().getName(), " onResume"); } @Override public void onStop() { super.onStop(); - Log.i(this.toString(), " onStop"); + Log.i(this.getClass().getName(), " onStop"); } @Override public void onDestroyView() { super.onDestroyView(); presenter.onDestroy(true); // TODO isChangingConfigurations - Log.i(this.toString(), " onDestroyView"); + Log.i(this.getClass().getName(), " onDestroyView"); } @Override public void onDestroy() { super.onDestroy(); presenter.onDestroy(false); // TODO isChangingConfigurations - Log.i(this.toString(), " onDestroy"); + Log.i(this.getClass().getName(), " onDestroy"); } @Override public void onDetach() { super.onDetach(); - Log.i(this.toString(), " onDetach"); + Log.i(this.getClass().getName(), " onDetach"); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); presenter.onSaveInstanceState(outState); - Log.i(this.toString(), " onSaveInstanceState"); + Log.i(this.getClass().getName(), " onSaveInstanceState"); } // life cycle <-- @Override - public void showItemDetail(Item item) { - activityCallback.startItemDetailFragment(item); + public void showItemDetail(Item item, int setId) { + activityCallback.startItemDetailFragment(item, setId); }//TODO del? @Override diff --git a/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java b/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java index d851e0f..40e6a50 100644 --- a/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java +++ b/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java @@ -6,8 +6,10 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.ImageButton; +import android.widget.TextView; import com.hikapro.backpack.R; +import com.hikapro.backpack.presenter.adapters.helper.items.swipe2.SwipableElement; /** @@ -15,12 +17,10 @@ import com.hikapro.backpack.R; */ public class ItemViewHolder extends RecyclerView.ViewHolder { - public int id; - public CheckBox checkBox; - public Button leaveAtHomeButton; - public Button deleteButton; - public ImageButton infoButton; - public ViewGroup swipeGroup; + public CheckBox cb_item; + public TextView tv_text; + public ImageButton im_info; + public ViewGroup menu; public ItemViewHolder(View v) { super(v); @@ -28,11 +28,10 @@ public class ItemViewHolder extends RecyclerView.ViewHolder { } private void setupViews(View view) { - infoButton = (ImageButton) view.findViewById(R.id.info_button); - checkBox = (CheckBox) view.findViewById(R.id.item_checkbox); - leaveAtHomeButton = (Button) view.findViewById(R.id.leave_at_home_button); - deleteButton = (Button) view.findViewById(R.id.delete_button); - swipeGroup = (ViewGroup) view.findViewById((R.id.swipe_container)); - } + cb_item = (CheckBox) view.findViewById(R.id.item_checkbox); + tv_text = (TextView) view.findViewById(R.id.item_text); + im_info = (ImageButton) view.findViewById(R.id.item_info_button); + menu = (ViewGroup) view.findViewById(R.id.menu); + } } diff --git a/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolderCopy.java b/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolderCopy.java new file mode 100644 index 0000000..929d95d --- /dev/null +++ b/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolderCopy.java @@ -0,0 +1,38 @@ +package com.hikapro.backpack.view.recycler; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ImageButton; + +import com.hikapro.backpack.R; + + +/** + * Created by tariel on 01/05/16. + */ +public class ItemViewHolderCopy extends RecyclerView.ViewHolder { + + public int id; + public CheckBox checkBox; + public Button leaveAtHomeButton; + public Button deleteButton; + public ImageButton infoButton; + public ViewGroup swipeGroup; + + public ItemViewHolderCopy(View v) { + super(v); + setupViews(v); + } + + private void setupViews(View view) { + infoButton = (ImageButton) view.findViewById(R.id.info_button); + checkBox = (CheckBox) view.findViewById(R.id.item_checkbox); + leaveAtHomeButton = (Button) view.findViewById(R.id.leave_at_home_button); + deleteButton = (Button) view.findViewById(R.id.delete_button); + swipeGroup = (ViewGroup) view.findViewById((R.id.swipe_container)); + } + +} diff --git a/app/src/main/res/layout/fragment_item_detail.xml b/app/src/main/res/layout/fragment_item_detail.xml index 8ed0fe2..ce063c5 100644 --- a/app/src/main/res/layout/fragment_item_detail.xml +++ b/app/src/main/res/layout/fragment_item_detail.xml @@ -1,15 +1,58 @@ - + android:animateLayoutChanges="true" + android:background="@color/colorUiMainbackground2"> - + + + + - - + android:scrollbars="vertical" + android:scrollIndicators="none"/> + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_item_list.xml b/app/src/main/res/layout/fragment_item_list.xml index f4da14b..093b85b 100644 --- a/app/src/main/res/layout/fragment_item_list.xml +++ b/app/src/main/res/layout/fragment_item_list.xml @@ -1,8 +1,8 @@ - + android:scrollIndicators="none"/> - + android:scrollbars="vertical"/> diff --git a/app/src/main/res/layout/item_detail.xml b/app/src/main/res/layout/item_detail.xml index 567d66f..a6f7cfc 100644 --- a/app/src/main/res/layout/item_detail.xml +++ b/app/src/main/res/layout/item_detail.xml @@ -1,37 +1,29 @@ - + android:orientation="vertical"> - + + android:textColor="@color/colorUiMainFont" /> - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_detail_copy.xml b/app/src/main/res/layout/item_detail_copy.xml new file mode 100644 index 0000000..567d66f --- /dev/null +++ b/app/src/main/res/layout/item_detail_copy.xml @@ -0,0 +1,37 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_element.xml b/app/src/main/res/layout/item_element.xml new file mode 100644 index 0000000..433c599 --- /dev/null +++ b/app/src/main/res/layout/item_element.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/app/src/main/res/values/colors_background.xml b/app/src/main/res/values/colors_background.xml index 9afa84f..9f4c327 100644 --- a/app/src/main/res/values/colors_background.xml +++ b/app/src/main/res/values/colors_background.xml @@ -7,4 +7,8 @@ #76EE00 #001F3F #76EE00 + #F93F25 + #C9C9CE + #76EE00 + #C9C9CE \ No newline at end of file diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml new file mode 100644 index 0000000..097452c --- /dev/null +++ b/app/src/main/res/values/ids.xml @@ -0,0 +1,4 @@ + + + + \ 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 46334d7..10ae603 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,12 +9,16 @@ Choose item category: Continue with my packing ↑ Already in List + WHAT IS IT? + More about this item ❭ UNPACK MY BAG Share undo - delete - leave at home + DELETE + LEAVE AT HOME + ADD TO BAG + RETURN TO LIST SAVE CANCEL OKAY