Merge branch 'tag_my_list_frag' into dev

This commit is contained in:
Tariel Hlontsi 2016-05-15 16:58:39 +03:00
commit 963cd5e5db
52 changed files with 1514 additions and 278 deletions

View File

@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" /> <ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" /> <ConfirmationsSetting value="0" id="Remove" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@ -10,7 +10,7 @@ android {
} }
*/ */
defaultConfig { defaultConfig {
applicationId "hikapro.com.backpack" applicationId "com.hikapro.backpack"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 23 targetSdkVersion 23
versionCode 1 versionCode 1
@ -28,12 +28,12 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
compile 'com.google.code.gson:gson:2.6.2' compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.1' compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1' compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp:logging-interceptor:2.7.0' compile 'com.squareup.okhttp:logging-interceptor:2.7.0'
compile 'com.android.support:support-v4:23.3.0' compile 'com.android.support:support-v4:23.3.0'
compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0' compile 'com.android.support:design:23.3.0'

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hikapro.com.backpack"> package="hikapro.com.backpack">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:name=".App" android:name=".App"

View File

@ -9,15 +9,19 @@ import android.util.Log;
import hikapro.com.backpack.model.DetailModel; import hikapro.com.backpack.model.DetailModel;
import hikapro.com.backpack.model.ItemModel; import hikapro.com.backpack.model.ItemModel;
import hikapro.com.backpack.model.PackedModel;
import hikapro.com.backpack.model.SetModel; import hikapro.com.backpack.model.SetModel;
import hikapro.com.backpack.model.entities.Item; import hikapro.com.backpack.model.entities.Item;
import hikapro.com.backpack.model.entities.Set; import hikapro.com.backpack.model.entities.Set;
import hikapro.com.backpack.presenter.ItemDetailPresenter; import hikapro.com.backpack.presenter.ItemDetailPresenter;
import hikapro.com.backpack.presenter.ItemListPresenter; import hikapro.com.backpack.presenter.ItemListPresenter;
import hikapro.com.backpack.presenter.PackedListPresenter;
import hikapro.com.backpack.presenter.Presenter;
import hikapro.com.backpack.presenter.SetListPresenter; import hikapro.com.backpack.presenter.SetListPresenter;
import hikapro.com.backpack.view.View; import hikapro.com.backpack.view.View;
import hikapro.com.backpack.view.fragments.ItemDetailFragment; import hikapro.com.backpack.view.fragments.ItemDetailFragment;
import hikapro.com.backpack.view.fragments.ItemListFragment; import hikapro.com.backpack.view.fragments.ItemListFragment;
import hikapro.com.backpack.view.fragments.PackedListFragment;
import hikapro.com.backpack.view.fragments.SetListFragment; import hikapro.com.backpack.view.fragments.SetListFragment;
public class MainActivity extends Activity implements View.ActivityCallback { public class MainActivity extends Activity implements View.ActivityCallback {
@ -73,6 +77,17 @@ public class MainActivity extends Activity implements View.ActivityCallback {
ItemDetailPresenter presenter = stateMaintainer.get(ItemDetailPresenter.class.getName()); ItemDetailPresenter presenter = stateMaintainer.get(ItemDetailPresenter.class.getName());
DetailModel model = stateMaintainer.get(DetailModel.class.getName()); DetailModel model = stateMaintainer.get(DetailModel.class.getName());
view.setPresenter(presenter);
presenter.setView(view);
presenter.setModel(model);
model.setPresenter(presenter);
}
fragment = fragmentManager.findFragmentByTag(PackedListFragment.class.getName());
if (fragment != null) {
PackedListFragment view = (PackedListFragment) fragment;
PackedListPresenter presenter = stateMaintainer.get(PackedListPresenter.class.getName());
PackedModel model = stateMaintainer.get(PackedModel.class.getName());
view.setPresenter(presenter); view.setPresenter(presenter);
presenter.setView(view); presenter.setView(view);
presenter.setModel(model); presenter.setModel(model);
@ -132,7 +147,8 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model); presenter.setModel(model);
model.setPresenter(presenter); model.setPresenter(presenter);
replaceFragment(view, false, SetListFragment.class.getName()); //replaceFragment(view, false, SetListFragment.class.getName(), false, false);
replaceFragment(view, SetListFragment.class.getName(), 0);
stateMaintainer.put(presenter); stateMaintainer.put(presenter);
stateMaintainer.put(model); stateMaintainer.put(model);
@ -150,12 +166,40 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model); presenter.setModel(model);
model.setPresenter(presenter); model.setPresenter(presenter);
replaceFragment(view, true, ItemListFragment.class.getName()); //replaceFragment(view, true, ItemListFragment.class.getName(), true, true);
replaceFragment(view, ItemListFragment.class.getName(),
Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_X);
stateMaintainer.put(presenter); stateMaintainer.put(presenter);
stateMaintainer.put(model); stateMaintainer.put(model);
} }
@Override
public void startPackedListFragment(Set set) {
PackedListFragment view = PackedListFragment.newFromSet(set);
PackedListPresenter presenter = new PackedListPresenter();
PackedModel model;
if (stateMaintainer.hasKey(PackedModel.class.getName())) {
model = stateMaintainer.get(PackedModel.class.getName());
} else {
model = new PackedModel();
}
view.setPresenter(presenter);
presenter.setView(view);
presenter.setModel(model);
model.setPresenter(presenter);
//replaceFragment(view, true, ItemListFragment.class.getName(), true, true);
replaceFragment(view, PackedListFragment.class.getName(),
Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_Y);
stateMaintainer.put(presenter);
stateMaintainer.put(model);
}
@Override @Override
public void startItemDetailFragment(Item item) { public void startItemDetailFragment(Item item) {
@ -168,18 +212,49 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model); presenter.setModel(model);
model.setPresenter(presenter); model.setPresenter(presenter);
replaceFragment(view, true, ItemDetailFragment.class.getName()); //replaceFragment(view, true, ItemDetailFragment.class.getName(), true, true);
replaceFragment(view, ItemDetailFragment.class.getName(),
Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_X);
stateMaintainer.put(presenter); stateMaintainer.put(presenter);
stateMaintainer.put(model); stateMaintainer.put(model);
} }
private void replaceFragment(Fragment fragment, boolean addBackStack, String tag) { private void replaceFragment(Fragment fragment, boolean addBackStack, String tag,
boolean transition, boolean x) {
FragmentTransaction transaction = fragmentManager.beginTransaction(); FragmentTransaction transaction = fragmentManager.beginTransaction();
if (transition) {
if (x)
transaction.setCustomAnimations(R.animator.slide_in_left_x, R.animator.slide_out_right_x,
R.animator.slide_in_right_x, R.animator.slide_out_left_x);
}
transaction.replace(R.id.container, fragment, tag); transaction.replace(R.id.container, fragment, tag);
if (addBackStack) if (addBackStack)
transaction.addToBackStack(null); transaction.addToBackStack(null);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit(); transaction.commit();
} }
private void replaceFragment(Fragment fragment, String tag, int flags) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
if ((flags & Presenter.TRANSITION_X) == Presenter.TRANSITION_X) {
transaction.setCustomAnimations(R.animator.slide_in_left_x, R.animator.slide_out_right_x,
R.animator.slide_in_right_x, R.animator.slide_out_left_x);
}
if ((flags & Presenter.TRANSITION_Y) == Presenter.TRANSITION_Y) {
transaction.setCustomAnimations(R.animator.slide_in_top_y, R.animator.slide_out_bottom_y,
R.animator.slide_in_bottom_y, R.animator.slide_out_top_y);
}
transaction.replace(R.id.container, fragment, tag);
if ((flags & Presenter.ADD_TO_BACKSTACK) == Presenter.ADD_TO_BACKSTACK) {
transaction.addToBackStack(null);
}
//transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
}
} }

View File

@ -1,8 +1,15 @@
package hikapro.com.backpack.model; package hikapro.com.backpack.model;
import android.graphics.Bitmap;
import android.os.Message; import android.os.Message;
import java.util.List;
import hikapro.com.backpack.model.dao.Command;
import hikapro.com.backpack.model.dao.DAO;
import hikapro.com.backpack.model.dao.Event;
import hikapro.com.backpack.model.entities.Item; import hikapro.com.backpack.model.entities.Item;
import hikapro.com.backpack.model.entities.Set;
import hikapro.com.backpack.presenter.Presenter; import hikapro.com.backpack.presenter.Presenter;
/** /**
@ -12,9 +19,12 @@ public class DetailModel implements Model.Detail {
private Presenter.ItemDetail presenter; private Presenter.ItemDetail presenter;
private Item item; private Item item;
private DAO dao;
private Bitmap pic;
public DetailModel() { public DetailModel() {
this.dao = DAO.getInstance();
dao.registerObserver(this);
} }
// detail --> // detail -->
@ -28,6 +38,10 @@ public class DetailModel implements Model.Detail {
return item; return item;
} }
@Override
public Bitmap getPicture() {
return pic;
}
// detail <-- // detail <--
// events --> // events -->
@ -52,7 +66,14 @@ public class DetailModel implements Model.Detail {
// process --> // process -->
@Override @Override
public void executeQuery() { public void executeQuery() {
notifyDataSetChanged(); notifyDataSetChanged();
Message command;
command = Message.obtain();
command.what = Command.ITEM_GET_IMAGE;
command.arg1 = item.getId();
dao.executeCommand(command);
} }
// process <-- // process <--
@ -61,7 +82,6 @@ public class DetailModel implements Model.Detail {
public void setPresenter(Presenter.ItemDetail presenter) { public void setPresenter(Presenter.ItemDetail presenter) {
this.presenter = presenter; this.presenter = presenter;
this.item = presenter.getCurrentItem(); this.item = presenter.getCurrentItem();
} }
@Override @Override
@ -72,5 +92,14 @@ public class DetailModel implements Model.Detail {
@Override @Override
public void onEvent(Message event) { public void onEvent(Message event) {
switch (event.what) {
case Event.ITEM_IMAGE_LOAD_ERROR :
break;
case Event.ITEM_IMAGE_LOAD_COMPLETED :
pic = (Bitmap) event.obj;
notifyDataSetChanged();
break;
}
} }
} }

View File

@ -21,19 +21,21 @@ import hikapro.com.backpack.presenter.Presenter;
*/ */
public class ItemModel implements Model.Item { public class ItemModel implements Model.Item {
private Presenter.ItemList presenter; protected Presenter.ItemList presenter;
private List<Category> rawCategories; private List<Category> rawCategories;
private List<Category> sortedCategories; private List<Category> sortedCategories;
private List<Item> rawItems; private List<Item> rawItems;
private DAO dao; protected DAO dao;
private int currentSet; protected int currentSet;
private Hashtable<Integer, Category> categoriesCache; protected int currentSetActiveItemsQty;
protected int packedQty;
protected Hashtable<Integer, Category> categoriesCache;
private List<Item> itemsCache; private List<Item> itemsCache;
private List<Item> itemsDiscardCache; private List<Item> itemsDiscardCache;
private Hashtable<Category, List<Item>> items; private Hashtable<Category, List<Item>> items;
private Hashtable<Integer, List<Item>> cache; protected Hashtable<Integer, List<Item>> cache;
public ItemModel() { public ItemModel() {
this.rawCategories = new ArrayList<>(); this.rawCategories = new ArrayList<>();
@ -42,6 +44,8 @@ public class ItemModel implements Model.Item {
this.categoriesCache = new Hashtable<>(20, 0.9f); this.categoriesCache = new Hashtable<>(20, 0.9f);
this.packedQty = -1;
this.itemsCache = new ArrayList<>(); this.itemsCache = new ArrayList<>();
this.itemsDiscardCache = new ArrayList<>(); this.itemsDiscardCache = new ArrayList<>();
this.cache = new Hashtable<>(12, 0.9f); this.cache = new Hashtable<>(12, 0.9f);
@ -59,7 +63,6 @@ public class ItemModel implements Model.Item {
return ret; return ret;
} }
// categories <-- // categories <--
// items --> // items -->
@ -70,6 +73,7 @@ public class ItemModel implements Model.Item {
iList.add(item); iList.add(item);
Collections.sort(iList); Collections.sort(iList);
cache.put(currentSet, iList); cache.put(currentSet, iList);
++currentSetActiveItemsQty;
// TODO write to database // TODO write to database
return 0; return 0;
} }
@ -78,6 +82,7 @@ public class ItemModel implements Model.Item {
if (isPendingRemoval(item)) if (isPendingRemoval(item))
itemsDiscardCache.remove(item); itemsDiscardCache.remove(item);
cache.get(currentSet).remove(item); cache.get(currentSet).remove(item);
--currentSetActiveItemsQty;
//TODO write to ds //TODO write to ds
return false; return false;
@ -168,6 +173,15 @@ public class ItemModel implements Model.Item {
return is ? cache.get(currentSet).size() : 0; return is ? cache.get(currentSet).size() : 0;
} }
@Override
public int getActiveItemsCount() {
return currentSetActiveItemsQty;
}
@Override
public int getPackedQty() {
return packedQty;
}
// items <-- // items <--
// events --> // events -->
@ -192,6 +206,29 @@ public class ItemModel implements Model.Item {
// process --> // 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);
}
@Override
public void unpackItem(int itemId) {
// nothing
}
@Override
public void unpackSet(int setId) {
// nothing
}
@Override @Override
public void executeQuery() { public void executeQuery() {
Message command; Message command;
@ -208,14 +245,20 @@ public class ItemModel implements Model.Item {
command.what = Command.SET_GET_ITEMS; command.what = Command.SET_GET_ITEMS;
command.arg1 = presenter.getCurrentSet().getId(); command.arg1 = presenter.getCurrentSet().getId();
dao.executeCommand(command); dao.executeCommand(command);
} }
} }
@Override @Override
public void onEvent(Message event) { public void onEvent(Message event) {
switch (event.what) { switch (event.what) {
case Event.SET_ITEMS_LOAD_ERROR : 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; break;
case Event.ITEM_FROM_SET_ERROR : case Event.ITEM_FROM_SET_ERROR :
break; break;
@ -233,6 +276,17 @@ public class ItemModel implements Model.Item {
List<Item> res = (List<Item>) event.obj; List<Item> res = (List<Item>) event.obj;
cache.put(event.arg1, res); cache.put(event.arg1, res);
notifyDataSetChanged(); 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; break;
case Event.ITEM_CATEGORY_LOAD_COMPLETED : case Event.ITEM_CATEGORY_LOAD_COMPLETED :
categoriesCache = (Hashtable<Integer, Category>)event.obj; categoriesCache = (Hashtable<Integer, Category>)event.obj;
@ -242,8 +296,17 @@ public class ItemModel implements Model.Item {
case Event.ITEM_DELETED : case Event.ITEM_DELETED :
break; break;
case Event.ITEM_PACKED : case Event.ITEM_PACKED :
//TODO something
++packedQty;
if (presenter != null) {
presenter.notifyItemPackStatusChanged();
}
break; break;
case Event.ITEM_UNPACKED : case Event.ITEM_UNPACKED :
--packedQty;
if (presenter != null) {
presenter.notifyItemPackStatusChanged();
}
break; break;
case Event.ITEM_INSERTED : case Event.ITEM_INSERTED :
break; break;
@ -257,8 +320,9 @@ public class ItemModel implements Model.Item {
@Override @Override
public void setPresenter(Presenter.ItemList presenter) { public void setPresenter(Presenter.ItemList presenter) {
this.presenter = presenter; this.presenter = presenter;
this.currentSet = presenter.getCurrentSet().getId(); this.currentSet = presenter.getCurrentSet().getId();
this.currentSetActiveItemsQty = presenter.getCurrentSet().getActiveQty();
} }
@Override @Override
@ -266,45 +330,6 @@ public class ItemModel implements Model.Item {
return presenter; return presenter;
} }
private void initData() {
List<Integer> ids = presenter.getCurrentSet().getItems();
List<Item> sortedItems = new ArrayList<>(ids.size());
Category category;
for (Item item : rawItems) {
if (ids.contains(item.getId())) {
sortedItems.add(item);
}
}
Collections.sort(sortedItems);
items = new Hashtable<>(sortedItems.size());
for (Item item : sortedItems) {
category = findCategory(item.getCategory());
if (category != null) {
if (items.containsKey(category)) {
items.get(category).add(item);
} else {
List<Item> innerList = new ArrayList<>(20);
innerList.add(item);
items.put(category, innerList);
}
}
}
Category[] array = items.keySet().toArray(new Category[items.size()]);
sortedCategories = Arrays.asList(array);
notifyDataSetChanged();
}
private Category findSortedCategory(int categoryId) {
Category category = null;
for (Category c : sortedCategories) {
if (c.getId() == categoryId) {
category = c;
break;
}
}
return category;
}
private Category findCategory(int categoryId) { private Category findCategory(int categoryId) {
Category category = null; Category category = null;

View File

@ -1,5 +1,6 @@
package hikapro.com.backpack.model; package hikapro.com.backpack.model;
import android.graphics.Bitmap;
import android.os.Message; import android.os.Message;
import java.util.List; import java.util.List;
@ -43,6 +44,8 @@ public interface Model {
void pendingRemove(hikapro.com.backpack.model.entities.Item item); void pendingRemove(hikapro.com.backpack.model.entities.Item item);
void pendingRemoveCancel(hikapro.com.backpack.model.entities.Item item); void pendingRemoveCancel(hikapro.com.backpack.model.entities.Item item);
int getItemsCount(); int getItemsCount();
int getActiveItemsCount();
int getPackedQty();
hikapro.com.backpack.model.entities.Item findItem(int id); hikapro.com.backpack.model.entities.Item findItem(int id);
hikapro.com.backpack.model.entities.Item getItemByPosition(int position); hikapro.com.backpack.model.entities.Item getItemByPosition(int position);
@ -50,13 +53,20 @@ public interface Model {
hikapro.com.backpack.model.entities.Category getCategoryByPosition(int position); hikapro.com.backpack.model.entities.Category getCategoryByPosition(int position);
void setPresenter(Presenter.ItemList presenter); void setPresenter(Presenter.ItemList presenter);
Presenter.ItemList getPresenter(); Presenter.ItemList getPresenter();
void packItem(int itemId);
void unpackItem(int itemId);
void unpackSet(int setId);
} }
interface Detail extends Base { interface Detail extends Base {
int getCount(); int getCount();
hikapro.com.backpack.model.entities.Item findItem(int id); hikapro.com.backpack.model.entities.Item findItem(int id);
Bitmap getPicture();
void setPresenter(Presenter.ItemDetail presenter); void setPresenter(Presenter.ItemDetail presenter);
Presenter.ItemDetail getPresenter(); Presenter.ItemDetail getPresenter();
} }
} }

View File

@ -0,0 +1,121 @@
package hikapro.com.backpack.model;
import android.os.Message;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import hikapro.com.backpack.model.dao.Command;
import hikapro.com.backpack.model.dao.DAO;
import hikapro.com.backpack.model.dao.Event;
import hikapro.com.backpack.model.entities.Category;
import hikapro.com.backpack.model.entities.Item;
import hikapro.com.backpack.presenter.Presenter;
/**
* Created by tariel on 12/05/16.
*/
public class PackedModel extends ItemModel {
public PackedModel() {
super();
}
@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_PACKED_ITEMS;
command.arg1 = presenter.getCurrentSet().getId();
dao.executeCommand(command);
}
}
@Override
public void onEvent(Message event) {
switch (event.what) {
case Event.SET_PACKED_LOAD_ERROR :
break;
case Event.SET_UNPACK_ERROR :
break;
case Event.ITEM_CATEGORY_LOAD_ERROR :
break;
case Event.ITEM_PACK_ERROR :
break;
case Event.ITEM_UNPACK_ERROR :
break;
case Event.SET_PACKED_LOAD_COMPLETED :
List<Item> res = (List<Item>) event.obj;
cache.put(event.arg1, res);
notifyDataSetChanged();
packedQty = res.size();
if (presenter != null) {
presenter.notifyItemPackStatusChanged();
}
break;
case Event.SET_UNPACK_COMPLETED :
packedQty = 0;
cache.get(event.arg2).clear();
if (presenter != null) {
presenter.notifyItemPackStatusChanged();
}
break;
case Event.ITEM_CATEGORY_LOAD_COMPLETED :
categoriesCache = (Hashtable<Integer, Category>)event.obj;
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;
}
}
@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);
}
@Override
public void packItem(int itemId) {
// nothing
}
@Override
public void unpackSet(int setId) {
Message command;
command = Message.obtain();
command.what = Command.SET_UNPACK_ITEMS;
command.arg1 = setId;
dao.executeCommand(command);
}
}

View File

@ -13,12 +13,15 @@ public interface Command {
int SET_GET_ALL = 0x64; int SET_GET_ALL = 0x64;
int SET_REORDER = 0x65; int SET_REORDER = 0x65;
int SET_GET_ITEMS = 0x66; int SET_GET_ITEMS = 0x66;
int SET_GET_PACKED_ITEMS = 0x67;
int SET_UNPACK_ITEMS = 0x68;
int ITEM_DELETE_FROM_SET = 0x78; int ITEM_DELETE_FROM_SET = 0x78;
int ITEM_INSERT = 0x79; int ITEM_INSERT = 0x79;
int ITEM_PACK = 0x7A; int ITEM_PACK = 0x7A;
int ITEM_UNPACK = 0x7B; int ITEM_UNPACK = 0x7B;
int ITEM_GET_CATEGORIES = 0x7C; int ITEM_GET_CATEGORIES = 0x7C;
int ITEM_GET_IMAGE = 0x7D;
int MY_LIST_POST = 0x8C; int MY_LIST_POST = 0x8C;
int MY_LIST_ITEM_ADD = 0x8D; int MY_LIST_ITEM_ADD = 0x8D;

View File

@ -5,6 +5,8 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
@ -108,6 +110,7 @@ public class DAO {
SetTask setTask; SetTask setTask;
ItemTask itemTask; ItemTask itemTask;
ImageProviderTask imageProviderTask;
if (command != null) { if (command != null) {
switch (command.what) { switch (command.what) {
@ -132,6 +135,19 @@ public class DAO {
threadPool.execute(setTask); threadPool.execute(setTask);
break; break;
case Command.SET_GET_PACKED_ITEMS :
setTask = new SetTask(Command.SET_GET_PACKED_ITEMS,
Process.THREAD_PRIORITY_MORE_FAVORABLE);
setTask.setId = command.arg1;
threadPool.execute(setTask);
break;
case Command.SET_UNPACK_ITEMS :
setTask = new SetTask(Command.SET_UNPACK_ITEMS,
Process.THREAD_PRIORITY_DEFAULT);
setTask.setId = command.arg1;
threadPool.execute(setTask);
case Command.ITEM_GET_CATEGORIES : case Command.ITEM_GET_CATEGORIES :
itemTask = new ItemTask(Command.ITEM_GET_CATEGORIES, itemTask = new ItemTask(Command.ITEM_GET_CATEGORIES,
Process.THREAD_PRIORITY_MORE_FAVORABLE); Process.THREAD_PRIORITY_MORE_FAVORABLE);
@ -170,6 +186,16 @@ public class DAO {
threadPool.execute(itemTask); threadPool.execute(itemTask);
break; break;
case Command.ITEM_GET_IMAGE :
Item item = findItem(command.arg1);
if (item != null) {
imageProviderTask = new ImageProviderTask(Command.ITEM_GET_IMAGE,
Process.THREAD_PRIORITY_DEFAULT);
imageProviderTask.item = item;
threadPool.execute(imageProviderTask);
}
break;
case Command.MY_LIST_ITEM_ADD : case Command.MY_LIST_ITEM_ADD :
break; break;
@ -320,20 +346,56 @@ public class DAO {
db.close(); db.close();
return ret; return ret;
} }
private List<Item> readItems(int setId) {
private Item findItem(int id) {
Item ret = null;
Cursor cursor = null;
SQLiteDatabase db = null;
try {
db = getReadDB();
String query = String.format("SELECT * FROM %s a WHERE a.%s = %d LIMIT 1",
Db.ItemsTable.TABLE_NAME, Db.ItemsTable.COLUMN_ID, id);
cursor = db.rawQuery(query, null);
if (cursor.moveToNext()) {
ret = Db.ItemsTable.parseCursor(cursor);
}
} catch (Exception e) {
//TODO write to log here
} finally {
if (cursor != null)
cursor.close();
if (db != null)
db.close();
}
return ret;
}
private List<Item> readItems(int setId, boolean packed) {
List<Item> ret = new ArrayList<>(256); List<Item> ret = new ArrayList<>(256);
Cursor cursor = null; Cursor cursor = null;
SQLiteDatabase db = null; SQLiteDatabase db = null;
Item item; Item item;
String query = String.format( String query = String.format(
"SELECT * FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s <> 1 AND b.%s <> 1", "SELECT 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",
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.TABLE_NAME, Db.ItemsTable.TABLE_NAME,
Db.SetItemsTable.TABLE_NAME, Db.SetItemsTable.TABLE_NAME,
Db.ItemsTable.COLUMN_ID, Db.ItemsTable.COLUMN_ID,
Db.SetItemsTable.COLUMN_ITEM, Db.SetItemsTable.COLUMN_ITEM,
Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_SET,
Db.SetItemsTable.COLUMN_DELETED, Db.SetItemsTable.COLUMN_DELETED,
Db.SetItemsTable.COLUMN_PACKED); Db.SetItemsTable.COLUMN_PACKED,
packed ? "=" : "<>");
try { try {
db = getReadDB(); db = getReadDB();
cursor = db.rawQuery(query, new String[]{String.valueOf(setId)}); cursor = db.rawQuery(query, new String[]{String.valueOf(setId)});
@ -382,6 +444,20 @@ public class DAO {
} }
return ret; return ret;
} }
private Set readSet(SQLiteDatabase db, int setId) {
Set ret = null;
Cursor cursor;
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);
if (cursor != null)
cursor.close();
return ret;
}
private List<Set> readSets() { private List<Set> readSets() {
List<Set> ret = new ArrayList<>(12); List<Set> ret = new ArrayList<>(12);
Cursor cursor = null; Cursor cursor = null;
@ -389,19 +465,8 @@ public class DAO {
Set set; Set set;
try { try {
db = getReadDB(); db = getReadDB();
cursor = db.query(Db.SetsTable.TABLE_NAME, String query = String.format("SELECT * FROM %s", Db.SetsTable.TABLE_NAME);
new String[]{Db.SetsTable.COLUMN_ID, cursor = db.rawQuery(query, null);
Db.SetsTable.COLUMN_ITEMS,
Db.SetsTable.COLUMN_LINE_NUMBER,
Db.SetsTable.COLUMN_NAME,
Db.SetsTable.COLUMN_PHOTO_LOCAL,
Db.SetsTable.COLUMN_PHOTO_THUMB_LOCAL,
Db.SetsTable.COLUMN_PHOTO_THUMB_URL,
Db.SetsTable.COLUMN_PHOTO_THUMBNAIL_LOCAL,
Db.SetsTable.COLUMN_PHOTO_THUMBNAIL_URL,
Db.SetsTable.COLUMN_PHOTO_URL},
null,null,null,null,
Db.SetsTable.COLUMN_LINE_NUMBER);
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
set = Db.SetsTable.parseCursor(cursor); set = Db.SetsTable.parseCursor(cursor);
ret.add(set); ret.add(set);
@ -421,6 +486,32 @@ public class DAO {
return ret; return ret;
} }
// updates // updates
private int updateItemLocalPic(int id, String path) {
int ret = 0;
SQLiteDatabase db = null;
ContentValues values;
try {
db = getWriteDB();
db.beginTransaction();
values = new ContentValues();
values.put(Db.ItemsTable.COLUMN_PHOTO_LOCAL, path);
ret = db.update(Db.ItemsTable.TABLE_NAME, values, "_id = ?",
new String[]{String.valueOf(id)});
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 updateSetsOrder(List<Set> reorderedSet) { private int updateSetsOrder(List<Set> reorderedSet) {
int ret = 0; int ret = 0;
SQLiteDatabase db = null; SQLiteDatabase db = null;
@ -475,10 +566,59 @@ public class DAO {
} }
return ret; return ret;
} }
private int updateSetItemsPacked(int setId, boolean pack) {
int ret = 0;
SQLiteDatabase db = null;
ContentValues values;
Set set;
try {
db = getWriteDB();
db.beginTransaction();
/*
String query = String.format("UPDATE %s SET %s = %d where %s = %d",
Db.SetItemsTable.TABLE_NAME,
Db.SetItemsTable.COLUMN_PACKED,
pack,
Db.SetItemsTable.COLUMN_SET,
setId);
Cursor cursor = db.rawQuery(query, null);*/
values = new ContentValues();
values.put(Db.SetItemsTable.COLUMN_PACKED, pack);
ret = db.update(Db.SetItemsTable.TABLE_NAME, values, String.format("%s = ?",
Db.SetItemsTable.COLUMN_SET),
new String[]{String.valueOf(setId)});
set = readSet(db, setId);
if (set != null) {
values = new ContentValues();
values.put(Db.SetsTable.COLUMN_PACKED_QTY, pack ? set.getActiveQty() : 0);
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 updateSetItemPacked(int setId, int itemId, boolean pack) { private int updateSetItemPacked(int setId, int itemId, boolean pack) {
int ret = 0; int ret = 0;
SQLiteDatabase db = null; SQLiteDatabase db = null;
ContentValues values; ContentValues values;
Set set;
try { try {
db = getWriteDB(); db = getWriteDB();
db.beginTransaction(); db.beginTransaction();
@ -489,13 +629,13 @@ public class DAO {
Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ), Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ),
new String[]{String.valueOf(setId), String.valueOf(itemId)}); new String[]{String.valueOf(setId), String.valueOf(itemId)});
if (pack) { set = readSet(db, setId);
values = Db.SetItemsTable.toContentValues(MY_LIST_ID, itemId); if (set != null) {
db.insert(Db.SetItemsTable.TABLE_NAME, null, values); values = new ContentValues();
} else { values.put(Db.SetsTable.COLUMN_PACKED_QTY, pack ? set.getPackedQty() + 1 : set.getPackedQty() - 1);
db.delete(Db.SetItemsTable.TABLE_NAME, String.format("%s = ? AND %s = ?", ret += db.update(Db.SetsTable.TABLE_NAME, values, String.format("%s = ?",
Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_ITEM ), Db.SetsTable.COLUMN_ID),
new String[]{String.valueOf(MY_LIST_ID), String.valueOf(itemId) }); new String[]{String.valueOf(setId)});
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();
} catch (SQLiteException e) { } catch (SQLiteException e) {
@ -616,6 +756,7 @@ public class DAO {
int priority; int priority;
int setId; int setId;
List<Set> setsToUpdate; List<Set> setsToUpdate;
List<Item> items;
public SetTask(int command, int priority) { public SetTask(int command, int priority) {
this.currentCommand = command; this.currentCommand = command;
@ -641,7 +782,7 @@ public class DAO {
break; break;
case Command.SET_GET_ITEMS : case Command.SET_GET_ITEMS :
List<Item> items = readItems(setId); items = readItems(setId, false);
if (items.isEmpty()) if (items.isEmpty())
message.what = Event.SET_ITEMS_LOAD_ERROR; message.what = Event.SET_ITEMS_LOAD_ERROR;
else { else {
@ -659,6 +800,27 @@ public class DAO {
else else
message.what = Event.SET_REORDER_ERROR; message.what = Event.SET_REORDER_ERROR;
break; break;
case Command.SET_GET_PACKED_ITEMS :
items = readItems(setId, true);
if (items.isEmpty())
message.what = Event.SET_PACKED_LOAD_ERROR;
else {
Collections.sort(items);
message.what = Event.SET_PACKED_LOAD_COMPLETED;
message.obj = items;
message.arg1 = setId;
}
break;
case Command.SET_UNPACK_ITEMS :
message.arg1 = updateSetItemsPacked(setId, false);
message.arg2 = setId;
if (message.arg1 > 0)
message.what = Event.SET_UNPACK_COMPLETED;
else
message.what = Event.SET_UNPACK_ERROR;
break;
} }
handler.sendMessage(message); handler.sendMessage(message);
} }
@ -738,7 +900,67 @@ public class DAO {
} }
} }
} }
// IMAGE PROVIDER CLASS
private class ImageProviderTask implements Runnable {
int currentCommand;
int priority;
Item item;
public ImageProviderTask(int command, int priority) {
this.currentCommand = command;
this.priority = priority;
}
@Override
public void run() {
android.os.Process.setThreadPriority(priority);
Message message = Message.obtain();
switch (currentCommand) {
case Command.ITEM_GET_IMAGE :
try {
Bitmap bitmap = loadItemImage(item);
if (bitmap != null) {
message.what = Event.ITEM_IMAGE_LOAD_COMPLETED;
message.obj = bitmap;
}
else
message.what = Event.ITEM_IMAGE_LOAD_ERROR;
} catch (Exception e) {
message.what = Event.ITEM_IMAGE_LOAD_ERROR;
}
break;
}
handler.sendMessage(message);
}
}
//endregion //endregion
private Bitmap loadItemImage(Item item){
ImageDownloadHelper downloadHelper = new ImageDownloadHelper();
Bitmap bitmap = null;
String filename = null;
if (item != null) {
bitmap = BitmapFactory.decodeFile(item.getPhotoLocal());
// cannot retrieve, download and save then
if (bitmap == null) { // return it
bitmap = downloadHelper.loadImage(item.getPhotoUrl());
if (bitmap != null) {
if (downloadHelper.isExternalStorageWritable()) {
filename = downloadHelper.saveImageExternal(
downloadHelper.generateFileName(item.getPhotoUrl()), bitmap);
} else {
filename = downloadHelper.saveImageInternal(
downloadHelper.generateFileName(item.getPhotoUrl()), bitmap);
}
updateItemLocalPic(item.getId(), filename);
}
}
}
return bitmap;
}
} }

View File

@ -96,8 +96,9 @@ public class Db {
values.put(COLUMN_PHOTO_URL, item.getPhotoUrl()); values.put(COLUMN_PHOTO_URL, item.getPhotoUrl());
if (item.getPhotoThumbUrl() != null) if (item.getPhotoThumbUrl() != null)
values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl()); values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl());
if (item.getPhotoLocal() != null)
values.put(COLUMN_PHOTO_LOCAL, item.getPhotoLocal());
/* /*
values.put(COLUMN_PHOTO_LOCAL, );
values.put(COLUMN_PHOTO_THUMB_LOCAL, item.getName()); values.put(COLUMN_PHOTO_THUMB_LOCAL, item.getName());
*/ */
return values; return values;
@ -120,6 +121,7 @@ public class Db {
} }
item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL))); item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL))); item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
item.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL)));
return item; return item;
} }
@ -138,6 +140,8 @@ public class Db {
public static final String COLUMN_PHOTO_THUMBNAIL_URL = "photo_thumbnail_url"; public static final String COLUMN_PHOTO_THUMBNAIL_URL = "photo_thumbnail_url";
public static final String COLUMN_PHOTO_THUMBNAIL_LOCAL = "photo_thumbnail_local"; public static final String COLUMN_PHOTO_THUMBNAIL_LOCAL = "photo_thumbnail_local";
public static final String COLUMN_LINE_NUMBER = "line_num"; public static final String COLUMN_LINE_NUMBER = "line_num";
public static final String COLUMN_PACKED_QTY = "packed_qty";
public static final String COLUMN_ACTIVE_QTY = "active_qty";
public static final String CREATE = public static final String CREATE =
@ -151,6 +155,8 @@ public class Db {
COLUMN_PHOTO_THUMB_LOCAL + " TEXT, " + COLUMN_PHOTO_THUMB_LOCAL + " TEXT, " +
COLUMN_PHOTO_THUMBNAIL_URL + " TEXT, " + COLUMN_PHOTO_THUMBNAIL_URL + " TEXT, " +
COLUMN_LINE_NUMBER + " INTEGER, " + COLUMN_LINE_NUMBER + " INTEGER, " +
COLUMN_PACKED_QTY + " INTEGER, " +
COLUMN_ACTIVE_QTY + " INTEGER, " +
COLUMN_PHOTO_THUMBNAIL_LOCAL + " TEXT" + COLUMN_PHOTO_THUMBNAIL_LOCAL + " TEXT" +
" ); "; " ); ";
@ -170,6 +176,7 @@ public class Db {
values.put(COLUMN_PHOTO_THUMB_URL, set.getPhotoThumb()); values.put(COLUMN_PHOTO_THUMB_URL, set.getPhotoThumb());
values.put(COLUMN_PHOTO_THUMBNAIL_URL, set.getPhotoThumbnail()); values.put(COLUMN_PHOTO_THUMBNAIL_URL, set.getPhotoThumbnail());
values.put(COLUMN_LINE_NUMBER, lineNumber); values.put(COLUMN_LINE_NUMBER, lineNumber);
values.put(COLUMN_ACTIVE_QTY, items.size());
/* /*
values.put(COLUMN_PHOTO_LOCAL, ""); values.put(COLUMN_PHOTO_LOCAL, "");
values.put(COLUMN_PHOTO_THUMB_LOCAL, ""); values.put(COLUMN_PHOTO_THUMB_LOCAL, "");
@ -194,6 +201,8 @@ public class Db {
set.setPhotoThumb(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL))); set.setPhotoThumb(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
set.setPhotoThumbnail(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMBNAIL_URL))); set.setPhotoThumbnail(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMBNAIL_URL)));
set.setLineNumber(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_LINE_NUMBER))); set.setLineNumber(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_LINE_NUMBER)));
set.setPackedQty(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_PACKED_QTY)));
set.setActiveQty(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ACTIVE_QTY)));
return set; return set;
} }

View File

@ -12,11 +12,15 @@ public interface Event {
int SET_LOAD_ERROR = -0x1; int SET_LOAD_ERROR = -0x1;
int SET_REORDER_ERROR = -0x2; int SET_REORDER_ERROR = -0x2;
int SET_ITEMS_LOAD_ERROR = -0x3; int SET_ITEMS_LOAD_ERROR = -0x3;
int SET_PACKED_LOAD_ERROR = -0x4;
int SET_UNPACK_ERROR = -0x5;
int SET_LOAD_COMPLETED = 0x1; int SET_LOAD_COMPLETED = 0x1;
int SET_REORDER_COMPLETED = 0x2; int SET_REORDER_COMPLETED = 0x2;
int SET_ITEMS_LOAD_COMPLETED = 0x3; int SET_ITEMS_LOAD_COMPLETED = 0x3;
int SET_PACKED_LOAD_COMPLETED = 0x4;
int SET_UNPACK_COMPLETED = 0x5;
int ITEM_FROM_SET_ERROR = -0x14; int ITEM_FROM_SET_ERROR = -0x14;
@ -25,6 +29,7 @@ public interface Event {
int ITEM_PACK_ERROR = -0x17; int ITEM_PACK_ERROR = -0x17;
int ITEM_UNPACK_ERROR = -0x18; int ITEM_UNPACK_ERROR = -0x18;
int ITEM_CATEGORY_LOAD_ERROR = -0x19; int ITEM_CATEGORY_LOAD_ERROR = -0x19;
int ITEM_IMAGE_LOAD_ERROR = -0x1A;
int ITEM_FROM_SET_DELETED = 0x14; int ITEM_FROM_SET_DELETED = 0x14;
int ITEM_INSERTED = 0x15; int ITEM_INSERTED = 0x15;
@ -32,6 +37,8 @@ public interface Event {
int ITEM_PACKED = 0x17; int ITEM_PACKED = 0x17;
int ITEM_UNPACKED = 0x18; int ITEM_UNPACKED = 0x18;
int ITEM_CATEGORY_LOAD_COMPLETED = 0x19; int ITEM_CATEGORY_LOAD_COMPLETED = 0x19;
int ITEM_IMAGE_LOAD_COMPLETED = 0x1A;
int MY_LIST_POST_ERROR = -0x28; int MY_LIST_POST_ERROR = -0x28;
int MY_LIST_ITEM_ADD_ERROR = -0x29; int MY_LIST_ITEM_ADD_ERROR = -0x29;

View File

@ -0,0 +1,145 @@
package hikapro.com.backpack.model.dao;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import hikapro.com.backpack.App;
/**
* Created by tariel on 04/05/16.
*/
public class ImageDownloadHelper {
public static final String ITEMS_TAG = "items";
private Context context;
public ImageDownloadHelper() {
this.context = App.getAppContext();
}
public Bitmap loadImage(String netPath) {
Bitmap bitmap = null;
try {
URL url = new URL(netPath);
URLConnection conn = url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
} catch (Exception ex) {
Log.e(ITEMS_TAG, " File cannot be downloaded");
}
return bitmap;
}
public boolean existsExternal(String filename) {
boolean ret = false;
if (isExternalStorageReadable()) {
File directory = getDir();
File file = new File(directory.getAbsoluteFile(), filename);
ret = file.exists();
}
return ret;
}
public boolean existsInternal(String filename) {
boolean ret = false;
File file = createTempFile(filename);
if (file != null) {
ret = file.exists();
}
return ret;
}
private File createTempFile(String fileName) {
File file = null;
try {
file = File.createTempFile(fileName, null, context.getCacheDir());
} catch (IOException e) {
Log.e(ITEMS_TAG, " Cannot obtain temp file");
}
return file;
}
public String generateFileName(String netPath) {
String ret = "";
if (netPath != null && !netPath.isEmpty()) {
ret = Uri.parse(netPath).getLastPathSegment();
}
return ret;
}
public String saveImageInternal(String filename, Bitmap bitmap) {
File file = null;
FileOutputStream outputStream;
if (bitmap != null && !filename.isEmpty()) {
file = createTempFile(filename);
if (file != null) {
try {
outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
Log.e(ITEMS_TAG, " File cannot be saved");
}
}
}
return file != null ? file.getAbsolutePath() : null;
}
public String saveImageExternal(String filename, Bitmap bitmap) {
File file = null;
FileOutputStream outputStream;
if (isExternalStorageWritable()) {
if (bitmap != null && !filename.isEmpty()) {
File directory = getDir();
file = new File(directory.getAbsoluteFile(), filename);
try {
outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
Log.e(ITEMS_TAG, " File cannot be saved");
}
}
}
return file != null ? file.getAbsolutePath() : null;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
private File getDir() {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), ITEMS_TAG);
if (!file.mkdirs()) {
Log.e(ITEMS_TAG, " Directory not created");
}
return file;
}
}

View File

@ -34,6 +34,8 @@ public class Item implements Comparable<Item>, Serializable {
@Expose @Expose
private String photoThumbUrl; private String photoThumbUrl;
private String photoLocal;
public Item() { public Item() {
} }
@ -104,6 +106,14 @@ public class Item implements Comparable<Item>, Serializable {
this.photoThumbUrl = photoThumbUrl; this.photoThumbUrl = photoThumbUrl;
} }
public String getPhotoLocal() {
return photoLocal;
}
public void setPhotoLocal(String photoLocal) {
this.photoLocal = photoLocal;
}
@Override @Override
public int hashCode() { public int hashCode() {
int result = name != null ? name.hashCode() : 0; int result = name != null ? name.hashCode() : 0;

View File

@ -32,6 +32,8 @@ public class Set implements Comparable<Set>, Serializable {
private String photoThumbnail; private String photoThumbnail;
private int lineNumber; private int lineNumber;
private int packedQty;
private int activeQty;
public Set() { public Set() {
} }
@ -101,6 +103,22 @@ public class Set implements Comparable<Set>, Serializable {
this.lineNumber = lineNumber; this.lineNumber = lineNumber;
} }
public int getPackedQty() {
return packedQty;
}
public void setPackedQty(int packedQty) {
this.packedQty = packedQty;
}
public int getActiveQty() {
return activeQty;
}
public void setActiveQty(int activeQty) {
this.activeQty = activeQty;
}
@Override @Override
public int hashCode() { public int hashCode() {
int result = name != null ? name.hashCode() : 0; int result = name != null ? name.hashCode() : 0;

View File

@ -1,6 +1,7 @@
package hikapro.com.backpack.presenter; package hikapro.com.backpack.presenter;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
@ -60,35 +61,6 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
} }
// life cycle <-- // life cycle <--
// recycler -->
@Override
public int getItemsCount() {
return model.getCount();
}
@Override
public void bindViewHolder(DetailViewHolder holder, int position) {
hikapro.com.backpack.model.entities.Item item = model.findItem(position);
holder.title.setText(item.getName());
holder.description.setText(item.getDescription());
holder.title.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View view) {
showMessage("On detail click");
}
});
}
@Override
public DetailViewHolder createViewHolder(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);
return viewHolder;
}
// recycler <--
// process --> // process -->
@Override @Override
@ -110,6 +82,11 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
this.model = model; this.model = model;
} }
@Override
public Model.Detail getModel() {
return model;
}
@Override @Override
public Item getCurrentItem() { public Item getCurrentItem() {
return item; return item;
@ -136,6 +113,11 @@ public class ItemDetailPresenter implements Presenter.ItemDetail {
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show(); Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
} }
@Override
public void displayPicture(Bitmap bitmap) {
}
// other impl <-- // other impl <--
private View.ItemDetail getView() throws NullPointerException { private View.ItemDetail getView() throws NullPointerException {

View File

@ -1,5 +1,7 @@
package hikapro.com.backpack.presenter; package hikapro.com.backpack.presenter;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
@ -7,6 +9,8 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper; import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -26,13 +30,17 @@ import hikapro.com.backpack.view.View;
*/ */
public class ItemListPresenter implements Presenter.ItemList { public class ItemListPresenter implements Presenter.ItemList {
private static final String BUNDLE_SET_LIST_KEY = "BUNDLE_SET_LIST_KEY"; protected static final String BUNDLE_SET_LIST_KEY = "BUNDLE_SET_LIST_KEY";
private WeakReference<View.ItemList> view; protected WeakReference<View.ItemList> view;
private Model.Item model; protected Model.Item model;
private Set set; protected Set set;
private ItemListAdapter adapter; protected ItemListAdapter adapter;
RecyclerView recycler; protected RecyclerView recycler;
private LinearLayout footer;
private TextView showPacked;
protected TextView packedCount;
public ItemListPresenter() { public ItemListPresenter() {
this.adapter = new ItemListAdapter(this); this.adapter = new ItemListAdapter(this);
@ -51,9 +59,11 @@ public class ItemListPresenter implements Presenter.ItemList {
} }
@Override @Override
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/*
if (savedInstanceState != null) if (savedInstanceState != null)
set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY);*/ set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY);
else
set = getView().getSet();
android.view.View view = inflater.inflate(R.layout.fragment_item_list, container, false); android.view.View view = inflater.inflate(R.layout.fragment_item_list, container, false);
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext()); LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
recycler = (RecyclerView) view.findViewById(R.id.items_recycler); recycler = (RecyclerView) view.findViewById(R.id.items_recycler);
@ -76,6 +86,32 @@ public class ItemListPresenter implements Presenter.ItemList {
adapter.setUndoOn(true); adapter.setUndoOn(true);
model.executeQuery(); model.executeQuery();
footer = (LinearLayout) view.findViewById(R.id.item_list_footer);
packedCount = (TextView) footer.findViewById(R.id.footer_packed_count);
showPacked = (TextView) footer.findViewById(R.id.open_packed);
showPacked.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View v) {
showPackedItems();
}
});
Activity activity = (Activity) getActivityContext();
if (activity != null) {
ActionBar actionBar = activity.getActionBar();
if (actionBar != null) {
actionBar.show();
actionBar.setTitle(set.getName());
}
}
/*
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; return view;
} }
@Override @Override
@ -94,12 +130,45 @@ public class ItemListPresenter implements Presenter.ItemList {
} }
@Override @Override
public void clickItem(int itemId) { public void notifyItemPackStatusChanged() {
setVisibility();
Context context = getActivityContext();
if (context != null) {
String str = String.format("%s %d / %d",
context.getResources().getString(R.string.packed),
model.getPackedQty(),
model.getActiveItemsCount());
packedCount.setText(str);
}
}
@Override
public void setVisibility() {
if (model.getPackedQty() == model.getActiveItemsCount()) {
footer.setVisibility(android.view.View.VISIBLE);
} else if ( model.getPackedQty() > 0) {
footer.setVisibility(android.view.View.VISIBLE);
} else {
footer.setVisibility(android.view.View.GONE);
}
}
private void showPackedItems () {
getView().showPackedItems(set);
}
@Override
public void showDetails(int itemId) {
Item item = model.findItem(itemId); Item item = model.findItem(itemId);
if (item != null) if (item != null)
getView().showItemDetail(item); getView().showItemDetail(item);
else else
showMessage(String.format("Item with Id %d is not found.", itemId)); showMessage(String.format("Item with Id %d is not found.", itemId));
} }
// process <-- // process <--
@ -143,7 +212,7 @@ public class ItemListPresenter implements Presenter.ItemList {
// other impl <-- // other impl <--
private View.ItemList getView() throws NullPointerException { protected View.ItemList getView() throws NullPointerException {
if ( view != null ) if ( view != null )
return view.get(); return view.get();
else else

View File

@ -0,0 +1,123 @@
package hikapro.com.backpack.presenter;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import hikapro.com.backpack.R;
import hikapro.com.backpack.model.entities.Set;
import hikapro.com.backpack.presenter.adapters.PackedListAdapter;
import hikapro.com.backpack.presenter.adapters.helper.items.DividerDecoration;
import hikapro.com.backpack.presenter.adapters.helper.items.ItemSwipeCallback;
import hikapro.com.backpack.presenter.adapters.helper.items.StickyHeaderDecoration;
/**
* Created by tariel on 13/05/16.
*/
public class PackedListPresenter extends ItemListPresenter {
private TextView backToList;
private Button unpackButton;
public PackedListPresenter() {
this.adapter = new PackedListAdapter(this);
adapter.setHasStableIds(true);
adapter.setCheckAll(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null)
set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY);
else
set = getView().getSet();
android.view.View view = inflater.inflate(R.layout.fragment_packed_list, container, false);
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
recycler = (RecyclerView) view.findViewById(R.id.items_recycler);
recycler.setLayoutManager(llm);
recycler.setAdapter(adapter);
final StickyHeaderDecoration decoration = new StickyHeaderDecoration(adapter);
recycler.addItemDecoration(decoration);
recycler.addItemDecoration(new DividerDecoration(getActivityContext()));
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
decoration.invalidateHeaders();
}
});
ItemSwipeCallback itemSwipeCallback = new ItemSwipeCallback(0, ItemTouchHelper.LEFT, adapter, getActivityContext());
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemSwipeCallback);
itemTouchHelper.attachToRecyclerView(recycler);
adapter.setUndoOn(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);
unpackButton.setVisibility(View.VISIBLE);
} else {
backToList.setVisibility(View.VISIBLE);
packedCount.setVisibility(View.VISIBLE);
unpackButton.setVisibility(View.INVISIBLE);
}
unpackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
model.unpackSet(set.getId());
}
});
backToList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment fragment = (Fragment) getView();
if (fragment != null)
fragment.getFragmentManager().popBackStack();
}
});
/*
String str = String.format("%s %d / %d",
getActivityContext().getResources().getString(R.string.packed),
model.getPackedQty(), model.getActiveItemsCount());
packedCount.setText(str);
*/
return view;
}
@Override
public void setVisibility() {
if (model.getPackedQty() == 0) {
packedCount.setVisibility(View.GONE);
unpackButton.setVisibility(View.GONE);
backToList.setVisibility(View.VISIBLE);
} else if (model.getPackedQty() == model.getActiveItemsCount()) {
packedCount.setVisibility(View.GONE);
unpackButton.setVisibility(View.VISIBLE);
backToList.setVisibility(View.GONE);
} else {
packedCount.setVisibility(View.VISIBLE);
unpackButton.setVisibility(View.GONE);
backToList.setVisibility(View.VISIBLE);
}
}
}

View File

@ -1,6 +1,7 @@
package hikapro.com.backpack.presenter; package hikapro.com.backpack.presenter;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -18,20 +19,22 @@ import hikapro.com.backpack.view.recycler.SetViewHolder;
*/ */
public interface Presenter { public interface Presenter {
int ADD_TO_BACKSTACK = 0b0001;
int TRANSITION_X = 0b0010;
int TRANSITION_Y = 0b0100;
interface Base { interface Base {
Context getAppContext(); Context getAppContext();
Context getActivityContext(); Context getActivityContext();
} }
interface SetList extends Base { interface SetList extends Base {
SetViewHolder createViewHolder(ViewGroup parent, int viewType); void showItemList(Set set);
void bindViewHolder(SetViewHolder holder, int position);
int getSetsCount();
void clickSet(int setId);
void onDestroy(boolean isChangingConfiguration); void onDestroy(boolean isChangingConfiguration);
android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
void setView(hikapro.com.backpack.view.View.SetList view); void setView(hikapro.com.backpack.view.View.SetList view);
void setModel(Model.Set model); void setModel(Model.Set model);
Model.Set getModel();
void notifyDataSetChanged(); void notifyDataSetChanged();
void showMessage(String message); void showMessage(String message);
@ -49,28 +52,28 @@ public interface Presenter {
void setModel(Model.Item model); void setModel(Model.Item model);
Model.Item getModel(); Model.Item getModel();
void notifyDataSetChanged(); void notifyDataSetChanged();
void notifyItemPackStatusChanged();
void setVisibility();
Set getCurrentSet(); Set getCurrentSet();
void showMessage(String message); void showMessage(String message);
void onSaveInstanceState(Bundle outState); void onSaveInstanceState(Bundle outState);
void clickItem(int itemId); void showDetails(int itemId);
void filter(String query); void filter(String query);
} }
interface ItemDetail extends Base { interface ItemDetail extends Base {
void setView(hikapro.com.backpack.view.View.ItemDetail view); void setView(hikapro.com.backpack.view.View.ItemDetail view);
void setModel(Model.Detail model); void setModel(Model.Detail model);
Model.Detail getModel();
void notifyDataSetChanged(); void notifyDataSetChanged();
void showMessage(String message); void showMessage(String message);
int getItemsCount();
void bindViewHolder(DetailViewHolder holder, int position);
DetailViewHolder createViewHolder(ViewGroup parent, int viewType);
void onDestroy(boolean isChangingConfiguration); void onDestroy(boolean isChangingConfiguration);
android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
void onSaveInstanceState(Bundle outState); void onSaveInstanceState(Bundle outState);
Item getCurrentItem(); Item getCurrentItem();
void displayPicture(Bitmap bitmap);
} }
} }

View File

@ -1,5 +1,6 @@
package hikapro.com.backpack.presenter; package hikapro.com.backpack.presenter;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.DefaultItemAnimator;
@ -82,66 +83,17 @@ public class SetListPresenter implements Presenter.SetList {
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter);
mItemTouchHelper = new ItemTouchHelper(callback); mItemTouchHelper = new ItemTouchHelper(callback);
mItemTouchHelper.attachToRecyclerView(setRecycler); mItemTouchHelper.attachToRecyclerView(setRecycler);
Activity activity = (Activity) getActivityContext();
if (activity != null)
activity.getActionBar().hide();
return view; return view;
} }
// life cycle <-- // life cycle <--
// recycler -->
@Override
public SetViewHolder createViewHolder(ViewGroup parent, int viewType) {
SetViewHolder viewHolder;
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.set_card,
parent, false);
viewHolder = new SetViewHolder(v);
return viewHolder;
}
@Override
public void bindViewHolder(final SetViewHolder holder, int position) {
final hikapro.com.backpack.model.entities.Set set = model.getSetByPosition(position);
holder.textView.setText(set.getName());
holder.cardView.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View v) {
if (getView() != null)
getView().showItemList(set);
else
showMessage("There is no view in presenter");
}
});
//GLM_add_resources_SetList
holder.cardView.setOnLongClickListener(new android.view.View.OnLongClickListener() {
@Override
public boolean onLongClick(android.view.View v) {
mDragStartListener.onStartDrag(holder);
return false;
}
});
}
@Override
public int getSetsCount() {
return model.getSetsCount();
}
// recycler <--
// process --> // process -->
@Override
public void clickSet(int setId) {
Set set = model.findSet(setId);
if (set != null) {
getView().showItemList(set);
} else {
showMessage("Set not found!");
}
}
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
@ -176,6 +128,12 @@ public class SetListPresenter implements Presenter.SetList {
public void setModel(Model.Set model) { public void setModel(Model.Set model) {
this.model = model; this.model = model;
} }
@Override
public Model.Set getModel() {
return model;
}
@Override @Override
public void showMessage(String message) { public void showMessage(String message) {
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show(); Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
@ -195,4 +153,15 @@ public class SetListPresenter implements Presenter.SetList {
public void onStartDrag(RecyclerView.ViewHolder viewHolder) { public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
mItemTouchHelper.startDrag(viewHolder); mItemTouchHelper.startDrag(viewHolder);
} }
public void showItemList(Set set) {
if (getView() != null)
getView().showItemList(set);
else
showMessage("There is no view in presenter");
}
public void onLongClick(SetViewHolder holder) {
mDragStartListener.onStartDrag(holder);
}
} }

View File

@ -1,8 +1,12 @@
package hikapro.com.backpack.presenter.adapters; package hikapro.com.backpack.presenter.adapters;
import android.graphics.Bitmap;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import hikapro.com.backpack.R;
import hikapro.com.backpack.model.Model;
import hikapro.com.backpack.presenter.Presenter; import hikapro.com.backpack.presenter.Presenter;
import hikapro.com.backpack.view.recycler.DetailViewHolder; import hikapro.com.backpack.view.recycler.DetailViewHolder;
@ -12,7 +16,6 @@ import hikapro.com.backpack.view.recycler.DetailViewHolder;
public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> { public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
private Presenter.ItemDetail presenter; private Presenter.ItemDetail presenter;
private int itemId;
public ItemDetailAdapter(Presenter.ItemDetail presenter) { public ItemDetailAdapter(Presenter.ItemDetail presenter) {
this.presenter = presenter; this.presenter = presenter;
@ -20,21 +23,33 @@ public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
@Override @Override
public int getItemCount() { public int getItemCount() {
return presenter.getItemsCount(); return presenter.getModel().getCount();
} }
@Override @Override
public void onBindViewHolder(DetailViewHolder holder, int position) { public void onBindViewHolder(DetailViewHolder holder, int position) {
presenter.bindViewHolder(holder, position); hikapro.com.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() {
@Override
public void onClick(android.view.View view) {
presenter.showMessage("On detail click");
}
});
} }
@Override @Override
public DetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public DetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return presenter.createViewHolder(parent, viewType); DetailViewHolder viewHolder;
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail,
parent, false);
viewHolder = new DetailViewHolder(v);
return viewHolder;
} }
public void setItemId(int id) {
this.itemId = id;
}
} }

View File

@ -10,10 +10,8 @@ import android.view.ViewGroup;
import java.util.HashMap; import java.util.HashMap;
import hikapro.com.backpack.R; import hikapro.com.backpack.R;
import hikapro.com.backpack.model.Model;
import hikapro.com.backpack.model.entities.Category; import hikapro.com.backpack.model.entities.Category;
import hikapro.com.backpack.model.entities.Item; import hikapro.com.backpack.model.entities.Item;
import hikapro.com.backpack.presenter.ItemListPresenter;
import hikapro.com.backpack.presenter.Presenter; import hikapro.com.backpack.presenter.Presenter;
import hikapro.com.backpack.presenter.adapters.helper.items.StickyHeaderAdapter; import hikapro.com.backpack.presenter.adapters.helper.items.StickyHeaderAdapter;
import hikapro.com.backpack.view.recycler.HeaderViewHolder; import hikapro.com.backpack.view.recycler.HeaderViewHolder;
@ -30,6 +28,7 @@ public class ItemListAdapter extends RecyclerView.Adapter<ItemViewHolder> implem
private Handler handler = new Handler(); // hanlder for running delayed runnables private Handler handler = new Handler(); // hanlder for running delayed runnables
HashMap<Item, Runnable> pendingRunables = new HashMap<>(); // map of items to pending runnables, so we can cancel a removal if need be HashMap<Item, Runnable> pendingRunables = new HashMap<>(); // map of items to pending runnables, so we can cancel a removal if need be
private Presenter.ItemList presenter; private Presenter.ItemList presenter;
private boolean checkAll;
public ItemListAdapter(Presenter.ItemList presenter) { public ItemListAdapter(Presenter.ItemList presenter) {
this.presenter = presenter; this.presenter = presenter;
@ -43,7 +42,8 @@ public class ItemListAdapter extends RecyclerView.Adapter<ItemViewHolder> implem
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
return presenter.getModel().getItemByPosition(position).getId(); long ret = presenter.getModel().getItemId(position);
return ret;
} }
@Override @Override
@ -53,7 +53,7 @@ public class ItemListAdapter extends RecyclerView.Adapter<ItemViewHolder> implem
if (presenter.getModel().isPendingRemoval(item)) { if (presenter.getModel().isPendingRemoval(item)) {
// we need to show the "undo" state of the row // we need to show the "undo" state of the row
holder.itemView.setBackgroundColor(Color.RED); holder.itemView.setBackgroundColor(Color.RED);
holder.title.setVisibility(View.GONE); holder.checkBox.setVisibility(View.GONE);
holder.undoButton.setVisibility(View.VISIBLE); holder.undoButton.setVisibility(View.VISIBLE);
holder.undoButton.setOnClickListener(new View.OnClickListener() { holder.undoButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -68,16 +68,28 @@ public class ItemListAdapter extends RecyclerView.Adapter<ItemViewHolder> implem
} }
}); });
} else { } else {
holder.title.setVisibility(View.VISIBLE); holder.checkBox.setVisibility(View.VISIBLE);
holder.title.setText(item.getName()); holder.checkBox.setChecked(checkAll);
holder.checkBox.setText(item.getName() + " " + item.getId() + " pos " + position);//TODO del
holder.id = item.getId(); holder.id = item.getId();
holder.title.setOnClickListener(new android.view.View.OnClickListener() { holder.checkBox.setOnClickListener(new android.view.View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
presenter.clickItem(holder.id); 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.categoryId = item.getCategory();
holder.itemView.setBackgroundColor(0x33FF99); holder.itemView.setBackgroundColor(0x33FF99);
holder.undoButton.setVisibility(View.GONE); holder.undoButton.setVisibility(View.GONE);
holder.undoButton.setOnClickListener(null); holder.undoButton.setOnClickListener(null);
@ -118,11 +130,6 @@ public class ItemListAdapter extends RecyclerView.Adapter<ItemViewHolder> implem
notifyDataSetChanged(); notifyDataSetChanged();
} }
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
@Override @Override
public long getHeaderId(int position) { public long getHeaderId(int position) {
/*if (position == 0) { /*if (position == 0) {
@ -184,4 +191,26 @@ public class ItemListAdapter extends RecyclerView.Adapter<ItemViewHolder> implem
return presenter.getModel().isPendingRemoval(item); return presenter.getModel().isPendingRemoval(item);
} }
public void pack(int itemId, int position) {
presenter.getModel().packItem(itemId);
notifyDataSetChanged();
/*
notifyItemRemoved(position);
notifyItemRangeRemoved(position, getItemCount());
*/
}
public void unpack(int itemId, int position) {
presenter.getModel().unpackItem(itemId);
//notifyItemRemoved(position);
notifyDataSetChanged();
}
public void unpackAll() {
}
public void setCheckAll(boolean checkAll) {
this.checkAll = checkAll;
}
} }

View File

@ -0,0 +1,14 @@
package hikapro.com.backpack.presenter.adapters;
import hikapro.com.backpack.presenter.Presenter;
import hikapro.com.backpack.presenter.adapters.ItemListAdapter;
/**
* Created by tariel on 12/05/16.
*/
public class PackedListAdapter extends ItemListAdapter {
public PackedListAdapter(Presenter.ItemList presenter) {
super(presenter);
}
}

View File

@ -1,8 +1,11 @@
package hikapro.com.backpack.presenter.adapters; package hikapro.com.backpack.presenter.adapters;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import hikapro.com.backpack.R;
import hikapro.com.backpack.presenter.SetListPresenter; import hikapro.com.backpack.presenter.SetListPresenter;
import hikapro.com.backpack.presenter.adapters.helper.sets.ItemTouchHelperAdapter; import hikapro.com.backpack.presenter.adapters.helper.sets.ItemTouchHelperAdapter;
import hikapro.com.backpack.view.recycler.SetViewHolder; import hikapro.com.backpack.view.recycler.SetViewHolder;
@ -13,24 +16,59 @@ import hikapro.com.backpack.view.recycler.SetViewHolder;
public class SetListAdapter extends RecyclerView.Adapter<SetViewHolder> implements ItemTouchHelperAdapter{ public class SetListAdapter extends RecyclerView.Adapter<SetViewHolder> implements ItemTouchHelperAdapter{
private SetListPresenter presenter; private SetListPresenter presenter;
private String rightBracket;
public SetListAdapter(SetListPresenter presenter) { public SetListAdapter(SetListPresenter presenter) {
this.presenter = presenter; this.presenter = presenter;
} }
@Override @Override
public void onBindViewHolder(SetViewHolder holder, int position) { public void onBindViewHolder(final SetViewHolder holder, int position) {
presenter.bindViewHolder(holder, position);
final hikapro.com.backpack.model.entities.Set set = presenter.getModel().getSetByPosition(position);
if (rightBracket == null || rightBracket.isEmpty()) {
if (presenter.getActivityContext() != null)
this.rightBracket = presenter.getActivityContext().getResources().
getString(R.string.right_angle_bracket);
else
this.rightBracket = "";
}
holder.textView.setText(set.getName() + " " + rightBracket);
String info = String.format("%s %d / %d",
presenter.getActivityContext().getResources().getString(R.string.packed),
set.getPackedQty(),
set.getActiveQty());
holder.setInfo.setText(info);
holder.cardView.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(android.view.View v) {
presenter.showItemList(set);
}
});
holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
presenter.onLongClick(holder);
return false;
}
});
} }
@Override @Override
public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return presenter.createViewHolder(parent, viewType); SetViewHolder viewHolder;
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.set_card,
parent, false);
viewHolder = new SetViewHolder(v);
return viewHolder;
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return presenter.getSetsCount(); return presenter.getModel().getSetsCount();
} }
//GLM_add_resources_SetList //GLM_add_resources_SetList

View File

@ -26,6 +26,7 @@ public interface View {
interface ItemList extends Base { interface ItemList extends Base {
void showItemDetail(Item item); void showItemDetail(Item item);
void showPackedItems(Set set);
void setPresenter(Presenter.ItemList presenter); void setPresenter(Presenter.ItemList presenter);
Set getSet(); Set getSet();
} }
@ -33,9 +34,11 @@ public interface View {
void setPresenter(Presenter.ItemDetail presenter); void setPresenter(Presenter.ItemDetail presenter);
Item getItem(); Item getItem();
} }
interface ActivityCallback { interface ActivityCallback {
void startSetListFragment(); void startSetListFragment();
void startItemListFragment(Set set); void startItemListFragment(Set set);
void startPackedListFragment(Set set);
void startItemDetailFragment(Item item); void startItemDetailFragment(Item item);
} }

View File

@ -71,52 +71,52 @@ public class ItemDetailFragment extends Fragment implements hikapro.com.backpack
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View view = presenter.onCreateView(inflater, container, savedInstanceState);
presenter.setView(this); presenter.setView(this);
Log.i(this.toString(), "onCreateView"); View view = presenter.onCreateView(inflater, container, savedInstanceState);
Log.i(this.toString(), " onCreateView");
return view; return view;
} }
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
Log.i(this.toString(), "onActivityCreated"); Log.i(this.toString(), " onActivityCreated");
} }
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
Log.i(this.toString(), "onStart"); Log.i(this.toString(), " onStart");
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
Log.i(this.toString(), "onResume"); Log.i(this.toString(), " onResume");
} }
@Override @Override
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
Log.i(this.toString(), "onStop"); Log.i(this.toString(), " onStop");
} }
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
presenter.onDestroy(true); // TODO isChangingConfigurations presenter.onDestroy(true); // TODO isChangingConfigurations
Log.i(this.toString(), "onDestroyView"); Log.i(this.toString(), " onDestroyView");
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
presenter.onDestroy(false); // TODO isChangingConfigurations presenter.onDestroy(false); // TODO isChangingConfigurations
Log.i(this.toString(), "onDestroy"); Log.i(this.toString(), " onDestroy");
} }
@Override @Override
public void onDetach() { public void onDetach() {
super.onDetach(); super.onDetach();
Log.i(this.toString(), "onDetach"); Log.i(this.toString(), " onDetach");
} }
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Log.i(this.toString(), "onSaveInstanceState"); Log.i(this.toString(), " onSaveInstanceState");
} }
// life cycle <-- // life cycle <--

View File

@ -25,7 +25,7 @@ import hikapro.com.backpack.presenter.Presenter;
public class ItemListFragment extends Fragment implements hikapro.com.backpack.view.View.ItemList, public class ItemListFragment extends Fragment implements hikapro.com.backpack.view.View.ItemList,
SearchView.OnQueryTextListener { SearchView.OnQueryTextListener {
private static final String BUNDLE_SET_KEY = "BUNDLE_SET_KEY"; protected static final String BUNDLE_SET_KEY = "BUNDLE_SET_KEY";
private hikapro.com.backpack.view.View.ActivityCallback activityCallback; private hikapro.com.backpack.view.View.ActivityCallback activityCallback;
private Presenter.ItemList presenter; private Presenter.ItemList presenter;
@ -33,7 +33,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
// Required empty public constructor // Required empty public constructor
} }
protected static ItemListFragment construct() { private static ItemListFragment construct() {
return new ItemListFragment(); return new ItemListFragment();
} }
@ -70,7 +70,24 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item); boolean ret;
switch (item.getItemId()) {
case R.id.action_share :
Toast.makeText(getActivityContext(), "Share", Toast.LENGTH_SHORT).show();
ret = true;
break;
case R.id.action_unpack_my_bag :
Toast.makeText(getActivityContext(), "Unpack my bag", Toast.LENGTH_SHORT).show();
ret = true;
break;
case R.id.action_restore_to_default :
Toast.makeText(getActivityContext(), "Restore to default", Toast.LENGTH_SHORT).show();
ret = true;
break;
default:
ret = super.onOptionsItemSelected(item);
}
return ret;
} }
// life cycle --> // life cycle -->
@ -93,13 +110,13 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
throw new ClassCastException(activity.toString() throw new ClassCastException(activity.toString()
+ " must implement activityCallback"); + " must implement activityCallback");
} }
Log.i(this.toString(), "onAttach"); Log.i(this.toString(), " onAttach");
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(true); setHasOptionsMenu(true);
Log.i(this.toString(), "onCreate"); Log.i(this.toString(), " onCreate");
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -107,50 +124,51 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
// Inflate the layout for this fragment // Inflate the layout for this fragment
presenter.setView(this); presenter.setView(this);
View view = presenter.onCreateView(inflater, container, savedInstanceState); View view = presenter.onCreateView(inflater, container, savedInstanceState);
Log.i(this.toString(), "onCreateView"); Log.i(this.toString(), " onCreateView");
return view; return view;
} }
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
Log.i(this.toString(), "onActivityCreated"); Log.i(this.toString(), " onActivityCreated");
} }
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
Log.i(this.toString(), "onStart"); Log.i(this.toString(), " onStart");
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
Log.i(this.toString(), "onResume"); Log.i(this.toString(), " onResume");
} }
@Override @Override
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
Log.i(this.toString(), "onStop"); Log.i(this.toString(), " onStop");
} }
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
presenter.onDestroy(true); // TODO isChangingConfigurations presenter.onDestroy(true); // TODO isChangingConfigurations
Log.i(this.toString(), "onDestroyView"); Log.i(this.toString(), " onDestroyView");
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
presenter.onDestroy(false); // TODO isChangingConfigurations presenter.onDestroy(false); // TODO isChangingConfigurations
Log.i(this.toString(), "onDestroy"); Log.i(this.toString(), " onDestroy");
} }
@Override @Override
public void onDetach() { public void onDetach() {
super.onDetach(); super.onDetach();
Log.i(this.toString(), "onDetach"); Log.i(this.toString(), " onDetach");
} }
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
Log.i(this.toString(), "onSaveInstanceState"); presenter.onSaveInstanceState(outState);
Log.i(this.toString(), " onSaveInstanceState");
} }
// life cycle <-- // life cycle <--
@ -160,6 +178,11 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
activityCallback.startItemDetailFragment(item); activityCallback.startItemDetailFragment(item);
} }
@Override
public void showPackedItems(Set set) {
activityCallback.startPackedListFragment(set);
}
@Override @Override
public void setPresenter(Presenter.ItemList presenter) { public void setPresenter(Presenter.ItemList presenter) {
this.presenter = presenter; this.presenter = presenter;

View File

@ -0,0 +1,27 @@
package hikapro.com.backpack.view.fragments;
import android.os.Bundle;
import hikapro.com.backpack.model.entities.Set;
/**
* Created by tariel on 12/05/16.
*/
public class PackedListFragment extends ItemListFragment {
public PackedListFragment() {
}
private static PackedListFragment construct() {
return new PackedListFragment();
}
public static PackedListFragment newFromSet(Set set) {
PackedListFragment ret = PackedListFragment.construct();
Bundle args = new Bundle();
args.putSerializable(BUNDLE_SET_KEY, set);
ret.setArguments(args);
return ret;
}
}

View File

@ -3,6 +3,8 @@ package hikapro.com.backpack.view.recycler;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import hikapro.com.backpack.R; import hikapro.com.backpack.R;
@ -14,9 +16,9 @@ import hikapro.com.backpack.R;
public class ItemViewHolder extends RecyclerView.ViewHolder { public class ItemViewHolder extends RecyclerView.ViewHolder {
public int id; public int id;
public int categoryId; public CheckBox checkBox;
public TextView title; public Button undoButton;
public Button undoButton; public ImageButton infoButton;
public ItemViewHolder(View v) { public ItemViewHolder(View v) {
super(v); super(v);
@ -24,7 +26,9 @@ public class ItemViewHolder extends RecyclerView.ViewHolder {
} }
private void setupViews(View view) { private void setupViews(View view) {
title = (TextView) view.findViewById(R.id.item_txt); infoButton = (ImageButton) view.findViewById(R.id.info_button);
checkBox = (CheckBox) view.findViewById(R.id.item_checkbox);
undoButton = (Button) view.findViewById(R.id.undo_button); undoButton = (Button) view.findViewById(R.id.undo_button);
} }
} }

View File

@ -17,6 +17,7 @@ public class SetViewHolder extends RecyclerView.ViewHolder implements ItemTouchH
public CardView cardView; public CardView cardView;
public TextView textView; public TextView textView;
public TextView setInfo;
//GLM_add_resources_SetList //GLM_add_resources_SetList
private View view; private View view;
@ -24,16 +25,13 @@ public class SetViewHolder extends RecyclerView.ViewHolder implements ItemTouchH
public SetViewHolder(View v) { public SetViewHolder(View v) {
super(v); super(v);
//
this.view = v;
//
setupViews(v); setupViews(v);
} }
private void setupViews(View view) { private void setupViews(View view) {
cardView = (CardView) view.findViewById(R.id.card_view_set); cardView = (CardView) view.findViewById(R.id.card_view_set);
textView = (TextView) view.findViewById(R.id.set_text); textView = (TextView) view.findViewById(R.id.set_text);
setInfo = (TextView) view.findViewById(R.id.set_info);
this.view = view; this.view = view;
drawable = view.getBackground(); drawable = view.getBackground();

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="y"
android:valueFrom="-1000"
android:valueTo="0"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="1000"
android:valueTo="0"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="-1000"
android:valueTo="0"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="y"
android:valueFrom="1000"
android:valueTo="0"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="y"
android:valueFrom="0"
android:valueTo="-1000"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="0"
android:valueTo="1000"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="0"
android:valueTo="-1000"
android:valueType="floatType" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="y"
android:valueFrom="0"
android:valueTo="1000"
android:valueType="floatType" />
</set>

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true"
android:id="@+id/item_list_footer"
android:background="#33D3D3D3"
android:layout_gravity="bottom"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Packed 8/106"
android:id="@+id/footer_packed_count"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="What is in my bag"
android:id="@+id/open_packed"/>
</LinearLayout>

View File

@ -1,14 +1,48 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="hikapro.com.backpack.view.fragments.ItemListFragment" tools:context="hikapro.com.backpack.view.fragments.ItemListFragment"
android:orientation="vertical"> android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:animateLayoutChanges="true">
<android.support.v7.widget.RecyclerView <LinearLayout
android:id="@+id/items_recycler" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/items_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scrollbars="vertical" android:orientation="vertical"
/> android:id="@+id/item_list_footer"
</LinearLayout> android:layout_gravity="bottom"
android:visibility="gone"
android:background="#80968AA7">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="Packed"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#00FF7F"
android:id="@+id/footer_packed_count"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#00FF7F"
android:text="Show what's in my bag &#x2193;"
android:id="@+id/open_packed"/>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:animateLayoutChanges="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/item_list_header"
android:layout_gravity="top"
android:gravity="center"
android:visibility="visible"
android:layout_alignParentTop="true"
android:animateLayoutChanges="true"
android:background="#80968AA7">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="Packed"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#00FF7F"
android:id="@+id/header_packed_count"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#00FF7F"
android:text="Continue with my packing &#x2191;"
android:id="@+id/back_to_list"/>
<Button
android:id="@+id/unpack_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UNPACK MY BAG"
android:textSize="18sp"
android:textAlignment="center"
android:background="#76EE00"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:layout_below="@id/item_list_header">
<android.support.v7.widget.RecyclerView
android:id="@+id/items_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
/>
</LinearLayout>
</RelativeLayout>

View File

@ -13,9 +13,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"/>
android:text="@string/hello_blank_fragment" />
<ImageView <ImageView
android:id="@+id/item_photo" android:id="@+id/item_photo"
@ -32,7 +30,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/item_photo" android:layout_below="@id/item_photo"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_marginTop="25dp" android:layout_marginTop="25dp" />
android:text="@string/hello_blank_fragment" />
</RelativeLayout> </RelativeLayout>

View File

@ -18,7 +18,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="5dp" android:layout_marginLeft="5dp"
android:layout_marginBottom="5dp"/> android:layout_marginBottom="5dp"
android:textSize="26sp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold"
android:typeface="serif"/>
<TextView
android:id="@+id/set_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</LinearLayout> </LinearLayout>

View File

@ -2,22 +2,37 @@
<FrameLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
> >
<TextView <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:clickable="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:padding="8dp" <CheckBox
android:textSize="14sp" android:layout_width="match_parent"
tools:text="Aardvark" android:layout_height="wrap_content"
android:id="@+id/item_txt" android:padding="8dp"
tools:context=".MainActivity"/> android:textSize="14sp"
android:id="@+id/item_checkbox"
android:layout_alignParentLeft="true"
android:layout_marginLeft="16dp"
tools:context=".MainActivity"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/info_button"
android:src="@drawable/ic_info_black_24dp"
android:background="@null"
android:layout_alignParentRight="true"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
/>
</RelativeLayout>
<Button <Button
android:id="@+id/undo_button" android:id="@+id/undo_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -2,11 +2,26 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"> tools:context=".MainActivity">
<item <item
android:id="@+id/action_settings" android:id="@+id/action_share"
android:orderInCategory="1" android:orderInCategory="1"
android:title="Settings" android:title="Share"
android:showAsAction="never" /> android:showAsAction="never"
app:showAsAction="never" />
<item
android:id="@+id/action_unpack_my_bag"
android:orderInCategory="2"
android:title="Unpack my bag"
android:showAsAction="never"
app:showAsAction="never" />
<item
android:id="@+id/action_restore_to_default"
android:orderInCategory="3"
android:title="Restore to default"
android:showAsAction="never"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
android:id="@+id/action_search" android:id="@+id/action_search"
@ -16,5 +31,12 @@
android:actionViewClass="android.widget.SearchView" android:actionViewClass="android.widget.SearchView"
android:visible="true" android:visible="true"
android:title="Search"/> android:title="Search"/>
<item
android:id="@+id/action_add"
android:icon="@drawable/ic_add_white_36dp"
android:showAsAction="always|collapseActionView"
app:showAsAction="always|collapseActionView"
android:visible="true"
android:title="Add"/>
</menu> </menu>

View File

@ -1,6 +1,5 @@
<resources> <resources>
<string name="app_name">BackPack</string> <string name="app_name">Back Pack</string>
<string name="packed">Packed</string>
<!-- TODO: Remove or change this placeholder text --> <string name="right_angle_bracket">&#x276D;</string>
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources> </resources>