diff --git a/.idea/misc.xml b/.idea/misc.xml
index 5d19981..fbb6828 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -37,7 +37,7 @@
-
+
diff --git a/app/build.gradle b/app/build.gradle
index b8a8cf2..324d086 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -24,11 +24,16 @@ android {
}
}
+repositories {
+ mavenCentral()
+}
+
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
+
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
@@ -38,4 +43,5 @@ dependencies {
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:cardview-v7:23.3.0'
+ compile 'com.facebook.android:facebook-android-sdk:4.11.0'
}
diff --git a/app/libs/socialauth-4.4.jar b/app/libs/socialauth-4.4.jar
new file mode 100644
index 0000000..ed8ecf6
Binary files /dev/null and b/app/libs/socialauth-4.4.jar differ
diff --git a/app/libs/socialauth-android-3.2.jar b/app/libs/socialauth-android-3.2.jar
new file mode 100644
index 0000000..04cc9d3
Binary files /dev/null and b/app/libs/socialauth-android-3.2.jar differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 64e5780..dc7c65f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,8 @@
package="com.hikapro.backpack">
+
+
+
@@ -18,6 +21,13 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/fonts/Ubuntu-B.ttf b/app/src/main/assets/fonts/Ubuntu-B.ttf
new file mode 100644
index 0000000..c0142fe
Binary files /dev/null and b/app/src/main/assets/fonts/Ubuntu-B.ttf differ
diff --git a/app/src/main/assets/fonts/Ubuntu-M.ttf b/app/src/main/assets/fonts/Ubuntu-M.ttf
new file mode 100644
index 0000000..4a776d3
Binary files /dev/null and b/app/src/main/assets/fonts/Ubuntu-M.ttf differ
diff --git a/app/src/main/java/com/hikapro/backpack/FlowLayout.java b/app/src/main/java/com/hikapro/backpack/FlowLayout.java
new file mode 100644
index 0000000..7846c87
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/FlowLayout.java
@@ -0,0 +1,108 @@
+package com.hikapro.backpack;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Created by tariel on 22/05/16.
+ */
+public class FlowLayout extends ViewGroup {
+
+ private int PADDING_X;
+ private int PADDING_Y;
+ private int mHeight;
+
+ public FlowLayout(Context context) {
+ super(context);
+ setPaddings(0,0);
+ }
+
+ protected void setPaddings(int V, int H){
+ PADDING_X = H;
+ PADDING_Y = V;
+ }
+
+ protected void setPaddings(Context ctx, AttributeSet attrs){
+ TypedArray a = ctx
+ .obtainStyledAttributes(attrs, R.styleable.FlowLayout);
+ String H = a.getString(R.styleable.FlowLayout_paddingX);
+ String V = a.getString(R.styleable.FlowLayout_paddingY);
+ if (H == null || V == null)
+ setPaddings(V == null ? 0 : Integer.parseInt(V), H == null ? 0 :Integer.parseInt(H));
+ else {
+ setPaddings(Integer.parseInt(V), Integer.parseInt(H));
+ a.recycle();
+ }
+
+ }
+
+ public FlowLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setPaddings(context,attrs);
+ }
+
+ public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setPaddings(context,attrs);
+ }
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);
+ final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
+ int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
+ final int count = getChildCount();
+ int xpos = getPaddingLeft();
+ int ypos = getPaddingTop();
+ int childHeightMeasureSpec;
+ if(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST)
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
+ else
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ mHeight = 0;
+ for(int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if(child.getVisibility() != GONE) {
+ child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec);
+ final int childw = child.getMeasuredWidth();
+ mHeight = Math.max(mHeight, child.getMeasuredHeight() + PADDING_Y);
+ if(xpos + childw > width) {
+ xpos = getPaddingLeft();
+ ypos += mHeight;
+ }
+ xpos += childw + PADDING_X;
+ }
+ }
+ if(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
+ height = ypos + mHeight;
+ } else if(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
+ if(ypos + mHeight < height) {
+ height = ypos + mHeight;
+ }
+ }
+ height += 5; // Fudge to avoid clipping bottom of last row.
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int width = r - l;
+ int xpos = getPaddingLeft();
+ int ypos = getPaddingTop();
+ for(int i = 0; i < getChildCount(); i++) {
+ final View child = getChildAt(i);
+ if(child.getVisibility() != GONE) {
+ final int childw = child.getMeasuredWidth();
+ final int childh = child.getMeasuredHeight();
+ if(xpos + childw > width) {
+ xpos = getPaddingLeft();
+ ypos += mHeight;
+ }
+ child.layout(xpos, ypos, xpos + childw, ypos + childh);
+ xpos += childw + PADDING_X;
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/MainActivity.java b/app/src/main/java/com/hikapro/backpack/MainActivity.java
index f22a430..9282095 100644
--- a/app/src/main/java/com/hikapro/backpack/MainActivity.java
+++ b/app/src/main/java/com/hikapro/backpack/MainActivity.java
@@ -7,22 +7,28 @@ import android.app.FragmentTransaction;
import android.os.Bundle;
import android.util.Log;
+import com.hikapro.backpack.model.AddModel;
import com.hikapro.backpack.model.DetailModel;
import com.hikapro.backpack.model.ItemModel;
import com.hikapro.backpack.model.PackedModel;
import com.hikapro.backpack.model.SetModel;
+import com.hikapro.backpack.model.ShareModel;
import com.hikapro.backpack.model.entities.Item;
import com.hikapro.backpack.model.entities.Set;
+import com.hikapro.backpack.presenter.AddPresenter;
import com.hikapro.backpack.presenter.ItemDetailPresenter;
import com.hikapro.backpack.presenter.ItemListPresenter;
import com.hikapro.backpack.presenter.PackedListPresenter;
import com.hikapro.backpack.presenter.Presenter;
import com.hikapro.backpack.presenter.SetListPresenter;
+import com.hikapro.backpack.presenter.SharePresenter;
import com.hikapro.backpack.view.View;
+import com.hikapro.backpack.view.fragments.AddFragment;
import com.hikapro.backpack.view.fragments.ItemDetailFragment;
import com.hikapro.backpack.view.fragments.ItemListFragment;
import com.hikapro.backpack.view.fragments.PackedListFragment;
import com.hikapro.backpack.view.fragments.SetListFragment;
+import com.hikapro.backpack.view.fragments.ShareFragment;
public class MainActivity extends Activity implements View.ActivityCallback {
@@ -82,6 +88,7 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
}
+
fragment = fragmentManager.findFragmentByTag(PackedListFragment.class.getName());
if (fragment != null) {
PackedListFragment view = (PackedListFragment) fragment;
@@ -93,6 +100,30 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
}
+
+ fragment = fragmentManager.findFragmentByTag(ShareFragment.class.getName());
+ if (fragment != null) {
+ ShareFragment view = (ShareFragment) fragment;
+ SharePresenter presenter = stateMaintainer.get(SharePresenter.class.getName());
+ ShareModel model = stateMaintainer.get(ShareModel.class.getName());
+
+ view.setPresenter(presenter);
+ presenter.setView(view);
+ presenter.setModel(model);
+ model.setPresenter(presenter);
+ }
+
+ fragment = fragmentManager.findFragmentByTag(AddFragment.class.getName());
+ if (fragment != null) {
+ AddFragment view = (AddFragment) fragment;
+ AddPresenter presenter = stateMaintainer.get(AddPresenter.class.getName());
+ AddModel model = stateMaintainer.get(AddModel.class.getName());
+
+ view.setPresenter(presenter);
+ presenter.setView(view);
+ presenter.setModel(model);
+ model.setPresenter(presenter);
+ }
}
Log.i("On create", "Activity");
}
@@ -147,7 +178,6 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
- //replaceFragment(view, false, SetListFragment.class.getName(), false, false);
replaceFragment(view, SetListFragment.class.getName(), 0);
stateMaintainer.put(presenter);
stateMaintainer.put(model);
@@ -166,7 +196,6 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
- //replaceFragment(view, true, ItemListFragment.class.getName(), true, true);
replaceFragment(view, ItemListFragment.class.getName(),
Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_X);
@@ -191,7 +220,6 @@ public class MainActivity extends Activity implements View.ActivityCallback {
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);
@@ -212,7 +240,6 @@ public class MainActivity extends Activity implements View.ActivityCallback {
presenter.setModel(model);
model.setPresenter(presenter);
- //replaceFragment(view, true, ItemDetailFragment.class.getName(), true, true);
replaceFragment(view, ItemDetailFragment.class.getName(),
Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_X);
@@ -220,20 +247,41 @@ public class MainActivity extends Activity implements View.ActivityCallback {
stateMaintainer.put(model);
}
- private void replaceFragment(Fragment fragment, boolean addBackStack, String tag,
- boolean transition, boolean x) {
- 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);
- }
+ @Override
+ public void startShareFragment(int setId) {
- transaction.replace(R.id.container, fragment, tag);
- if (addBackStack)
- transaction.addToBackStack(null);
- transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
- transaction.commit();
+ ShareFragment view = ShareFragment.construct();
+ SharePresenter presenter = new SharePresenter();
+ ShareModel model = new ShareModel();
+
+ view.setPresenter(presenter);
+ presenter.setView(view);
+ presenter.setModel(model);
+ model.setPresenter(presenter);
+
+ replaceFragment(view, ShareFragment.class.getName(),
+ Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_X);
+
+ stateMaintainer.put(presenter);
+ stateMaintainer.put(model);
+ }
+
+ @Override
+ public void startAddFragment(Set set) {
+ AddFragment view = AddFragment.newFromSet(set);
+ AddPresenter presenter = new AddPresenter();
+ AddModel model = new AddModel();
+
+ view.setPresenter(presenter);
+ presenter.setView(view);
+ presenter.setModel(model);
+ model.setPresenter(presenter);
+
+ replaceFragment(view, AddFragment.class.getName(),
+ Presenter.ADD_TO_BACKSTACK | Presenter.TRANSITION_X);
+
+ stateMaintainer.put(presenter);
+ stateMaintainer.put(model);
}
private void replaceFragment(Fragment fragment, String tag, int flags) {
diff --git a/app/src/main/java/com/hikapro/backpack/model/AddModel.java b/app/src/main/java/com/hikapro/backpack/model/AddModel.java
new file mode 100644
index 0000000..48d61ce
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/model/AddModel.java
@@ -0,0 +1,154 @@
+package com.hikapro.backpack.model;
+
+import android.os.Message;
+import android.widget.Toast;
+
+import com.hikapro.backpack.App;
+import com.hikapro.backpack.model.dao.Command;
+import com.hikapro.backpack.model.dao.DAO;
+import com.hikapro.backpack.model.dao.Event;
+import com.hikapro.backpack.model.entities.Category;
+import com.hikapro.backpack.model.entities.Item;
+import com.hikapro.backpack.presenter.Presenter;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * Created by tariel on 18/05/16.
+ */
+public class AddModel implements Model.Add {
+
+ private Presenter.Add presenter;
+ private DAO dao;
+ private List- filteredItems;
+ private List categoriesCache;
+
+ public AddModel() {
+ this.filteredItems = new ArrayList<>(256);
+ this.categoriesCache = new ArrayList<>(20);
+ this.dao = DAO.getInstance();
+ dao.registerObserver(this);
+ }
+
+ @Override
+ public void onEvent(Message event) {
+
+ switch (event.what) {
+
+ case Event.ITEM_LIKE_LOAD_ERROR :
+ if (!filteredItems.isEmpty()) {
+ filteredItems.clear();
+ }
+ notifyDataSetChanged();
+ break;
+
+ case Event.ITEM_CATEGORY_LOAD_ERROR :
+ break;
+
+ case Event.ITEM_INSERT_ERROR :
+ Toast.makeText(App.getAppContext(), "Item not inserted!", Toast.LENGTH_SHORT).show();
+ break;
+
+ case Event.ITEM_LIKE_LOAD_COMPLETED :
+ filteredItems = (List
- ) event.obj;
+ notifyDataSetChanged();
+ break;
+
+ case Event.ITEM_CATEGORY_LOAD_COMPLETED :
+ Hashtable res = (Hashtable)event.obj;
+ categoriesCache = new ArrayList<>(res.values()); // TODO check utilization
+ break;
+
+ case Event.ITEM_INSERTED :
+ Toast.makeText(App.getAppContext(), "New item inserted", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+
+ @Override
+ public void onDestroy(boolean isConfigurationChanging) {
+ if ( !isConfigurationChanging ) {
+ presenter = null;
+ }
+ }
+
+ @Override
+ public void executeQuery() {
+ Message command;
+ if (categoriesCache.isEmpty()) {
+ command = Message.obtain();
+ command.what = Command.ITEM_GET_CATEGORIES;
+ dao.executeCommand(command);
+ }
+ }
+
+ @Override
+ public void add(Item item, int setId) {
+ Message command;
+ command = Message.obtain();
+ command.what = Command.ITEM_INSERT;
+ command.obj = item;
+ command.arg1 = setId;
+ dao.executeCommand(command);
+ }
+
+ @Override
+ public void filter(String query, int checkThisSet) {
+
+ if (!query.isEmpty()) {
+ Message command = Message.obtain();
+ command.what = Command.ITEM_GET_LIKE;
+ command.arg1 = checkThisSet;
+ query = query.toLowerCase();
+ command.obj = query;
+ dao.executeCommand(command);
+ }
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ boolean res = !filteredItems.isEmpty();
+ presenter.notifyDataSetChanged(res);
+ }
+
+ @Override
+ public int getItemsCount() {
+ return filteredItems.size();
+ }
+
+ @Override
+ public Item getItemByPosition(int position) {
+ return filteredItems.get(position);
+ }
+
+ @Override
+ public int getCategoriesCount() {
+ return categoriesCache.size();
+ }
+
+ @Override
+ public Category getCategoryByPosition(int position) {
+ return categoriesCache.get(position);
+ }
+
+ @Override
+ public Category getCategoryById(int id) {
+ for (Category category : categoriesCache) {
+ if (category.getId() == id)
+ return category;
+ }
+ return null;
+ }
+
+ @Override
+ public void setPresenter(Presenter.Add presenter) {
+ this.presenter = presenter;
+ }
+
+ @Override
+ public Presenter.Add getPresenter() {
+ return presenter;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/model/Api.java b/app/src/main/java/com/hikapro/backpack/model/Api.java
index 2cd2d68..218f39d 100644
--- a/app/src/main/java/com/hikapro/backpack/model/Api.java
+++ b/app/src/main/java/com/hikapro/backpack/model/Api.java
@@ -18,13 +18,13 @@ import retrofit2.http.Query;
public interface Api {
@GET("api/v1/backpack/items")
- Call
> getItems();
+ Call> getItems(@Query("locale") String locale);
@GET("api/v1/backpack/item_categories")
- Call> getItemCategories();
+ Call> getItemCategories(@Query("locale") String locale);
@GET("api/v1/backpack/sets")
- Call> getSets();
+ Call> getSets(@Query("locale") String locale);
@GET("api/v1/backpack/updates/timestamp")
Call getTimestamp();
diff --git a/app/src/main/java/com/hikapro/backpack/model/ItemModel.java b/app/src/main/java/com/hikapro/backpack/model/ItemModel.java
index c6e6c3b..4d2120e 100644
--- a/app/src/main/java/com/hikapro/backpack/model/ItemModel.java
+++ b/app/src/main/java/com/hikapro/backpack/model/ItemModel.java
@@ -2,12 +2,14 @@ package com.hikapro.backpack.model;
import android.os.Message;
+import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
+import com.hikapro.backpack.App;
import com.hikapro.backpack.model.dao.Command;
import com.hikapro.backpack.model.dao.DAO;
import com.hikapro.backpack.model.dao.Event;
@@ -228,6 +230,15 @@ public class ItemModel implements Model.Item {
// nothing
}
+ @Override
+ public void restoreSet(int setId) {
+ Message command;
+ command = Message.obtain();
+ command.what = Command.SET_RESTORE_DEFAULT;
+ command.arg1 = presenter.getCurrentSet().getId();
+ dao.executeCommand(command);
+ }
+
@Override
public void executeQuery() {
Message command;
@@ -259,6 +270,8 @@ public class ItemModel implements Model.Item {
break;
case Event.SET_UNPACK_ERROR :
break;
+ case Event.SET_RESTORE_ERROR :
+ break;
case Event.ITEM_FROM_SET_ERROR :
break;
case Event.ITEM_DELETE_ERROR :
@@ -309,6 +322,12 @@ public class ItemModel implements Model.Item {
break;
case Event.ITEM_INSERTED :
break;
+ case Event.SET_RESTORE_COMPLETED :
+ if (presenter != null) {
+ presenter.notifyDataSetChanged();
+ }
+ Toast.makeText(App.getAppContext(), "Restore completed", Toast.LENGTH_SHORT).show();
+ break;
}
}
diff --git a/app/src/main/java/com/hikapro/backpack/model/Model.java b/app/src/main/java/com/hikapro/backpack/model/Model.java
index 277a77f..f5920bc 100644
--- a/app/src/main/java/com/hikapro/backpack/model/Model.java
+++ b/app/src/main/java/com/hikapro/backpack/model/Model.java
@@ -5,6 +5,8 @@ import android.os.Message;
import java.util.List;
+import com.hikapro.backpack.model.entities.Category;
+import com.hikapro.backpack.model.entities.Item;
import com.hikapro.backpack.presenter.Presenter;
/**
@@ -27,6 +29,7 @@ public interface Model {
Presenter.SetList getPresenter();
//GLM
List getSets(); // tag renamed
+
void setsReorderNotify();
}
@@ -54,6 +57,7 @@ public interface Model {
void packItem(int itemId);
void unpackItem(int itemId);
void unpackSet(int setId);
+ void restoreSet(int setId);
}
interface Detail extends Base {
@@ -64,6 +68,24 @@ public interface Model {
Presenter.ItemDetail getPresenter();
}
+ interface Share extends Base {
+ void setPresenter(Presenter.Share presenter);
+ Presenter.Share getPresenter();
+
+ }
+
+ interface Add extends Base {
+ void setPresenter(Presenter.Add presenter);
+ Presenter.Add getPresenter();
+ void filter(String query, int checkThisSet);
+ int getItemsCount();
+ com.hikapro.backpack.model.entities.Item getItemByPosition(int position);
+ int getCategoriesCount();
+ Category getCategoryByPosition(int position);
+ Category getCategoryById(int id);
+ void add(com.hikapro.backpack.model.entities.Item item, int setId);
+ }
+
}
diff --git a/app/src/main/java/com/hikapro/backpack/model/NetworkUtil.java b/app/src/main/java/com/hikapro/backpack/model/NetworkUtil.java
new file mode 100644
index 0000000..10d2728
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/model/NetworkUtil.java
@@ -0,0 +1,43 @@
+package com.hikapro.backpack.model;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+import java.net.InetAddress;
+
+/**
+ * Created by tariel on 29/05/16.
+ */
+public class NetworkUtil {
+
+ public static boolean isConnectedToNetwork(Context context) {
+ ConnectivityManager cm =
+ (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ boolean isConnected = activeNetwork != null &&
+ activeNetwork.isConnectedOrConnecting();
+ return isConnected;
+ }
+
+ public static boolean isInternetAvailable() {
+ boolean ret;
+ try {
+ InetAddress ipAddr = InetAddress.getByName("hikapro.com");
+ ret = ipAddr.equals("") ? false : true;
+ } catch (Exception e) {
+ ret = false;
+ }
+ return ret;
+ }
+
+ public static int getConnectionType(Context context) {
+ ConnectivityManager cm =
+ (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ return activeNetwork.getType();
+ //ConnectivityManager.TYPE_WIFI;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/model/RestClient.java b/app/src/main/java/com/hikapro/backpack/model/RestClient.java
index 83c0466..f3874d7 100644
--- a/app/src/main/java/com/hikapro/backpack/model/RestClient.java
+++ b/app/src/main/java/com/hikapro/backpack/model/RestClient.java
@@ -11,7 +11,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
*/
public class RestClient {
- public static final String BASE_URL = "http://hikapro.hikapro/";
+ public static final String BASE_URL = "http://hikapro.com/";
public static Api getApi() {
diff --git a/app/src/main/java/com/hikapro/backpack/model/SetModel.java b/app/src/main/java/com/hikapro/backpack/model/SetModel.java
index 000681f..aadb3eb 100644
--- a/app/src/main/java/com/hikapro/backpack/model/SetModel.java
+++ b/app/src/main/java/com/hikapro/backpack/model/SetModel.java
@@ -1,10 +1,13 @@
package com.hikapro.backpack.model;
import android.os.Message;
+import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
+import com.hikapro.backpack.App;
+import com.hikapro.backpack.R;
import com.hikapro.backpack.model.dao.Command;
import com.hikapro.backpack.model.dao.DAO;
import com.hikapro.backpack.model.dao.Event;
@@ -67,18 +70,16 @@ public class SetModel implements Model.Set {
}
- private void sendMessage(String message) {
- presenter.showMessage(message);
- }
-
//endregion
//region process
@Override
public void executeQuery() {
+ if (presenter != null)
+ presenter.startProgress();
Message command = Message.obtain();
- command.what = Command.SYNC_IF_NOT_EXISTS;
+ command.what = Command.SYNC;
dao.executeCommand(command);
command = Message.obtain();
command.what = Command.SET_GET_ALL;
@@ -88,13 +89,27 @@ public class SetModel implements Model.Set {
@Override
public void onEvent(Message event) {
switch (event.what) {
+ case Event.SYNC_NO_CONNECTION :
+ if (presenter != null)
+ presenter.stopProgress();
+ Toast.makeText(App.getAppContext(), R.string.no_connection, Toast.LENGTH_SHORT).show();
+ break;
+ case Event.SYNC_FAILED :
+ if (presenter != null)
+ presenter.stopProgress();
+ Toast.makeText(App.getAppContext(), "SYNC FAILED", Toast.LENGTH_SHORT).show();
+ break;
case Event.SET_LOAD_ERROR :
+ if (presenter != null)
+ presenter.stopProgress();
break;
case Event.SET_ITEMS_LOAD_ERROR :
break;
case Event.SET_REORDER_ERROR :
break;
case Event.SET_LOAD_COMPLETED :
+ if (presenter != null)
+ presenter.stopProgress();
cache = (List) event.obj;
notifyDataSetChanged();
break;
diff --git a/app/src/main/java/com/hikapro/backpack/model/ShareModel.java b/app/src/main/java/com/hikapro/backpack/model/ShareModel.java
new file mode 100644
index 0000000..4ba48fd
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/model/ShareModel.java
@@ -0,0 +1,50 @@
+package com.hikapro.backpack.model;
+
+import android.os.Message;
+
+import com.hikapro.backpack.model.dao.DAO;
+import com.hikapro.backpack.presenter.Presenter;
+
+/**
+ * Created by tariel on 16/05/16.
+ */
+public class ShareModel implements Model.Share {
+
+ private Presenter.Share presenter;
+ private DAO dao;
+
+ public ShareModel() {
+ this.dao = DAO.getInstance();
+ dao.registerObserver(this);
+ }
+
+ @Override
+ public void onDestroy(boolean isConfigurationChanging) {
+
+ }
+
+ @Override
+ public void executeQuery() {
+
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+
+ }
+
+ @Override
+ public void onEvent(Message event) {
+
+ }
+
+ @Override
+ public void setPresenter(Presenter.Share presenter) {
+ this.presenter = presenter;
+ }
+
+ @Override
+ public Presenter.Share getPresenter() {
+ return presenter;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/Command.java b/app/src/main/java/com/hikapro/backpack/model/dao/Command.java
index baaa42a..5aa6f89 100644
--- a/app/src/main/java/com/hikapro/backpack/model/dao/Command.java
+++ b/app/src/main/java/com/hikapro/backpack/model/dao/Command.java
@@ -15,6 +15,7 @@ public interface Command {
int SET_GET_ITEMS = 0x66;
int SET_GET_PACKED_ITEMS = 0x67;
int SET_UNPACK_ITEMS = 0x68;
+ int SET_RESTORE_DEFAULT = 0x69;
int ITEM_DELETE_FROM_SET = 0x78;
int ITEM_INSERT = 0x79;
@@ -22,6 +23,7 @@ public interface Command {
int ITEM_UNPACK = 0x7B;
int ITEM_GET_CATEGORIES = 0x7C;
int ITEM_GET_IMAGE = 0x7D;
+ int ITEM_GET_LIKE = 0x7E;
int MY_LIST_POST = 0x8C;
int MY_LIST_ITEM_ADD = 0x8D;
diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java b/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java
index b3dab3f..1c407c8 100644
--- a/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java
+++ b/app/src/main/java/com/hikapro/backpack/model/dao/DAO.java
@@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -27,14 +28,15 @@ import java.util.concurrent.TimeUnit;
import com.hikapro.backpack.App;
import com.hikapro.backpack.model.Api;
import com.hikapro.backpack.model.Model;
+import com.hikapro.backpack.model.NetworkUtil;
import com.hikapro.backpack.model.RestClient;
import com.hikapro.backpack.model.SetModel;
import com.hikapro.backpack.model.entities.Category;
import com.hikapro.backpack.model.entities.Item;
import com.hikapro.backpack.model.entities.Set;
import com.hikapro.backpack.model.entities.Timestamp;
-import retrofit2.Call;
-import retrofit2.Callback;
+import com.hikapro.backpack.model.entities.UpdateLog;
+
import retrofit2.Response;
/**
@@ -147,6 +149,14 @@ public class DAO {
Process.THREAD_PRIORITY_DEFAULT);
setTask.setId = command.arg1;
threadPool.execute(setTask);
+ break;
+
+ case Command.SET_RESTORE_DEFAULT :
+ setTask = new SetTask(Command.SET_RESTORE_DEFAULT,
+ Process.THREAD_PRIORITY_DEFAULT);
+ setTask.setId = command.arg1;
+ threadPool.execute(setTask);
+ break;
case Command.ITEM_GET_CATEGORIES :
itemTask = new ItemTask(Command.ITEM_GET_CATEGORIES,
@@ -196,6 +206,14 @@ public class DAO {
}
break;
+ case Command.ITEM_GET_LIKE :
+ itemTask = new ItemTask(Command.ITEM_GET_LIKE,
+ Process.THREAD_PRIORITY_MORE_FAVORABLE);
+ itemTask.query = (String) command.obj;
+ itemTask.setId = command.arg1;
+ threadPool.execute(itemTask);
+ break;
+
case Command.MY_LIST_ITEM_ADD :
break;
@@ -248,6 +266,7 @@ public class DAO {
}
}
}
+
private void insertItems(List- items) {
if (items != null && !items.isEmpty()) {
ContentValues values;
@@ -265,6 +284,55 @@ public class DAO {
}
}
}
+
+ private long insertItem(Item item) {
+ long ret = 0;
+ SQLiteDatabase db = null;
+ ContentValues values;
+ Cursor cursor = null;
+ if (item != null) {
+ try {
+ if (item.getId() < 0) {
+ db = getWriteDB();
+ db.beginTransaction();
+ String query = String.format("SELECT %s FROM %s WHERE %s = 1 ORDER BY %s DESC LIMIT 1",
+ Db.ItemsTable.COLUMN_ID,
+ Db.ItemsTable.TABLE_NAME,
+ Db.ItemsTable.COLUMN_USER_DEFINED,
+ Db.ItemsTable.COLUMN_ID);
+ cursor = db.rawQuery(query, null);
+
+ if (cursor.moveToNext()) {
+ int id = cursor.getInt(0);
+ item.setId(id + 1);
+ } else {
+ query = String.format("SELECT max(%s) FROM %s",
+ Db.ItemsTable.COLUMN_ID,
+ Db.ItemsTable.TABLE_NAME);
+ cursor = db.rawQuery(query, null);
+ if (cursor.moveToNext()) {
+ int maxId = cursor.getInt(0);
+ item.setId(maxId + 0x400);
+ }
+ }
+ values = Db.ItemsTable.toContentValues(item);
+ ret = db.insert(Db.ItemsTable.TABLE_NAME, null, values);
+ db.setTransactionSuccessful();
+ } else {
+ ret = item.getId();
+ }
+ } finally {
+ if (cursor != null)
+ cursor.close();
+ if (db != null) {
+ db.endTransaction();
+ db.close();
+ }
+ }
+ }
+ return ret;
+ }
+
private void insertCategories(List categories) {
if (categories != null && !categories.isEmpty()) {
@@ -283,6 +351,7 @@ public class DAO {
}
}
}
+
private void insertSets(List sets) {
if (sets != null && !sets.isEmpty()) {
@@ -304,6 +373,7 @@ public class DAO {
}
}
}
+
private void insertSetItems(Set set, SQLiteDatabase db) {
if (set != null && db != null) {
if (!set.getItems().isEmpty()) {
@@ -322,12 +392,13 @@ public class DAO {
}
}
}
- private void insertSetItem(int setId, int itemId) {
+
+ private void insertSetItem(int setId, int itemId, boolean userDefined) {
ContentValues values;
SQLiteDatabase db = getWriteDB();
try {
db.beginTransaction();
- values = Db.SetItemsTable.toContentValues(setId, itemId);
+ values = Db.SetItemsTable.toContentValues(setId, itemId, userDefined);
db.insert(Db.SetItemsTable.TABLE_NAME, null, values);
db.setTransactionSuccessful();
} finally {
@@ -335,8 +406,9 @@ public class DAO {
db.close();
}
}
+
// reads
- private boolean LogExist() {
+ private boolean logExist() {
boolean ret;
SQLiteDatabase db = getReadDB();
Cursor cursor = db.query(Db.LogTable.TABLE_NAME,
@@ -347,6 +419,26 @@ public class DAO {
return ret;
}
+ private UpdateLog readLastLog() {
+ UpdateLog ret = null;
+ SQLiteDatabase db = null;
+ Cursor cursor = null;
+ try {
+ db = getReadDB();
+ String q = String.format("SELECT * FROM %s ORDER BY %s DESC LIMIT 1",
+ Db.LogTable.TABLE_NAME, Db.LogTable.COLUMN_ID);
+ cursor = db.rawQuery(q,null);
+ if (cursor.moveToNext())
+ ret = Db.LogTable.parseCursor(cursor);
+ } finally {
+ if (cursor != null)
+ cursor.close();
+ if (db != null)
+ db.close();
+ }
+ return ret;
+ }
+
private Item findItem(int id) {
Item ret = null;
Cursor cursor = null;
@@ -376,7 +468,7 @@ public class DAO {
SQLiteDatabase db = null;
Item item;
String query = String.format(
- "SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s FROM %s a INNER JOIN %s b ON a.%s = b.%s WHERE b.%s = ? AND b.%s <> 1 AND b.%s %s 1",
+ "SELECT a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s, a.%s 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,
@@ -387,6 +479,7 @@ public class DAO {
Db.ItemsTable.COLUMN_PHOTO_THUMB_URL,
Db.ItemsTable.COLUMN_PHOTO_LOCAL,
Db.ItemsTable.COLUMN_PHOTO_THUMB_LOCAL,
+ Db.ItemsTable.COLUMN_USER_DEFINED,
Db.ItemsTable.TABLE_NAME,
Db.SetItemsTable.TABLE_NAME,
@@ -407,6 +500,8 @@ public class DAO {
//TODO write to log here
} catch (Exception e) {
+ int i = 0;
+ String s = null;
//TODO write to log here
} finally {
if (cursor != null)
@@ -416,6 +511,81 @@ public class DAO {
}
return ret;
}
+
+ private List
- readItemsLike(String like) {
+ List
- ret = new ArrayList<>(256);
+ Cursor cursor = null;
+ SQLiteDatabase db = null;
+ Item item;
+ String query = String.format("SELECT * FROM %s WHERE %s LIKE %s",
+ Db.ItemsTable.TABLE_NAME,
+ Db.ItemsTable.COLUMN_NAME,
+ '\''+like+'%'+'\'');
+ try {
+ db = getReadDB();
+ cursor = db.rawQuery(query, null);
+ while (cursor.moveToNext()) {
+ item = Db.ItemsTable.parseCursor(cursor);
+ ret.add(item);
+ }
+ } catch (SQLiteException e) {
+ e.toString();
+ //TODO write to log here
+
+ } catch (Exception e) {
+ //TODO write to log here
+ } finally {
+ if (cursor != null)
+ cursor.close();
+ if (db != null)
+ db.close();
+ }
+ return ret;
+ }
+
+ private List
- readItemsLike(String like, int checkThisSet) {
+ List
- ret = new ArrayList<>(256);
+ Cursor cursor = null;
+ Cursor cursor2 = null;
+ SQLiteDatabase db = null;
+ Item item;
+ String query = String.format("SELECT * FROM %s WHERE %s LIKE %s",
+ Db.ItemsTable.TABLE_NAME,
+ Db.ItemsTable.COLUMN_NAME,
+ '\''+like+'%'+'\'');
+ try {
+ db = getReadDB();
+ cursor = db.rawQuery(query, null);
+ while (cursor.moveToNext()) {
+ item = Db.ItemsTable.parseCursor(cursor);
+ query = String.format("SELECT * FROM %s WHERE %s = %d AND %s = %d LIMIT 1",
+ Db.SetItemsTable.TABLE_NAME,
+ Db.SetItemsTable.COLUMN_ITEM,
+ item.getId(),
+ Db.SetItemsTable.COLUMN_SET,
+ checkThisSet
+ );
+ cursor2 = db.rawQuery(query, null);
+ if (cursor2.moveToNext())
+ item.InList = true;
+ ret.add(item);
+ }
+ } catch (SQLiteException e) {
+ e.toString();
+ //TODO write to log here
+ } catch (Exception e) {
+ //TODO write to log here
+ } finally {
+ if (cursor != null)
+ cursor.close();
+ if (cursor2 != null)
+ cursor2.close();
+ if (db != null)
+ db.close();
+ }
+ return ret;
+ }
+
private Hashtable readCategories() {
Hashtable ret = new Hashtable<>(20, 0.9f);
Cursor cursor = null;
@@ -485,6 +655,7 @@ public class DAO {
}
return ret;
}
+
// updates
private int updateItemLocalPic(int id, String path) {
int ret = 0;
@@ -540,6 +711,7 @@ public class DAO {
}
return ret;
}
+
private int updateSetItemDeleted(int setId, int itemId, boolean del) {
int ret = 0;
SQLiteDatabase db = null;
@@ -575,16 +747,6 @@ public class DAO {
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 = ?",
@@ -651,6 +813,171 @@ public class DAO {
}
return ret;
}
+
+ private int updateSetRestoreDefault(int setId) {
+ int ret = 0;
+ SQLiteDatabase db = null;
+ ContentValues values;
+ Set set;
+ try {
+ db = getWriteDB();
+ db.beginTransaction();
+ values = new ContentValues();
+ values.put(Db.SetItemsTable.COLUMN_PACKED, false);
+ values.put(Db.SetItemsTable.COLUMN_DELETED, false);
+ 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, 0);
+ ret += db.update(Db.SetsTable.TABLE_NAME, values, String.format("%s = ?",
+ Db.SetsTable.COLUMN_ID),
+ new String[]{String.valueOf(setId)});
+ }
+ ret += db.delete(Db.SetItemsTable.TABLE_NAME,
+ String.format("%s = ? AND %s = ?", Db.SetItemsTable.COLUMN_SET, Db.SetItemsTable.COLUMN_USER_DEFINED),
+ new String[]{String.valueOf(setId), String.valueOf(1)});
+ 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 updateSetNames(List sets) {
+ int ret = 0;
+ SQLiteDatabase db = null;
+ ContentValues values;
+
+ try {
+ db = getWriteDB();
+ db.beginTransaction();
+ for (Set set : sets) {
+ values = new ContentValues();
+ values.put(Db.SetsTable.COLUMN_NAME, set.getName());
+ ret += db.update(Db.SetsTable.TABLE_NAME, values, String.format("%s = ?",
+ Db.SetsTable.COLUMN_ID),
+ new String[]{String.valueOf(set.getId())});
+ }
+ 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 updateCategoryNames(List categories) {
+ int ret = 0;
+ SQLiteDatabase db = null;
+ ContentValues values;
+
+ try {
+ db = getWriteDB();
+ db.beginTransaction();
+ for (Category category : categories) {
+ values = new ContentValues();
+ values.put(Db.CategoriesTable.COLUMN_NAME, category.getName());
+ ret += db.update(Db.CategoriesTable.TABLE_NAME, values, String.format("%s = ?",
+ Db.CategoriesTable.COLUMN_ID),
+ new String[]{String.valueOf(category.getId())});
+ }
+ 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 updateItemNames(List
- items) {
+ int ret = 0;
+ SQLiteDatabase db = null;
+ ContentValues values;
+
+ try {
+ db = getWriteDB();
+ db.beginTransaction();
+ for (Item item : items) {
+ values = new ContentValues();
+ values.put(Db.ItemsTable.COLUMN_NAME, item.getName());
+ values.put(Db.ItemsTable.COLUMN_DESCRIPTION, item.getDescription());
+ ret += db.update(Db.ItemsTable.TABLE_NAME, values, String.format("%s = ?",
+ Db.ItemsTable.COLUMN_ID),
+ new String[]{String.valueOf(item.getId())});
+ }
+ 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 updateLogLocale(int id, String newLocale) {
+ int ret = 0;
+ SQLiteDatabase db = null;
+ ContentValues values;
+
+ try {
+ db = getWriteDB();
+ db.beginTransaction();
+
+ values = new ContentValues();
+ values.put(Db.LogTable.COLUMN_LOCALE, newLocale);
+
+ ret = db.update(Db.LogTable.TABLE_NAME, values, String.format("%s = ?",
+ Db.ItemsTable.COLUMN_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;
+ }
//endregion
/////////////////////// TASK CLASSES //////////////////
@@ -685,6 +1012,7 @@ public class DAO {
int setId;
int itemId;
Item item;
+ String query;
public ItemTask(int command, int priority) {
this.currentCommand = command;
@@ -708,16 +1036,13 @@ public class DAO {
break;
case Command.ITEM_INSERT :
- List
- items = new ArrayList<>();
- items.add(item);
- if (items.isEmpty())
- message.what = Event.ITEM_INSERT_ERROR;
- else {
- insertItems(items);
- insertSetItem(setId, item.getId());
+ if (insertItem(item) > 0) {
+ insertSetItem(setId, item.getId(), item.isUserDefined());
message.what = Event.ITEM_INSERTED;
message.arg1 = setId;
message.arg2 = item.getId();
+ } else {
+ message.what = Event.ITEM_INSERT_ERROR;
}
break;
@@ -746,6 +1071,16 @@ public class DAO {
message.obj = res;
}
break;
+
+ case Command.ITEM_GET_LIKE :
+ List
- itemsLike = readItemsLike(query, setId);
+ if (itemsLike.isEmpty()) {
+ message.what = Event.ITEM_LIKE_LOAD_ERROR;
+ } else {
+ message.what = Event.ITEM_LIKE_LOAD_COMPLETED;
+ message.obj = itemsLike;
+ }
+ break;
}
handler.sendMessage(message);
}
@@ -821,6 +1156,14 @@ public class DAO {
else
message.what = Event.SET_UNPACK_ERROR;
break;
+
+ case Command.SET_RESTORE_DEFAULT :
+ message.arg1 = updateSetRestoreDefault(setId);
+ if (message.arg1 > 0)
+ message.what = Event.SET_RESTORE_COMPLETED;
+ else
+ message.what = Event.SET_RESTORE_ERROR;
+ break;
}
handler.sendMessage(message);
}
@@ -830,10 +1173,12 @@ public class DAO {
int currentCommand;
int priority;
int statusCode;
+ String locale;
public SyncTask(int command, int priority) {
this.currentCommand = command;
this.priority = priority;
+ this.locale = Locale.getDefault().getLanguage();
}
@Override
@@ -844,22 +1189,47 @@ public class DAO {
switch (currentCommand) {
case Command.SYNC:
try {
- Call
> call = api.getSets();
- call.enqueue(new Callback>() {
- @Override
- public void onResponse(Call> call, Response> response) {
- statusCode = response.code();
- // TODO
- // check if first time
- // if not check for updates else
- // insert into database here
- insertSets(response.body());
+ UpdateLog log = readLastLog();
+ if (log != null) {
+ if (log.getLocale().equals(locale))
+ message.what = Event.SYNC_COMPLETED;
+ else {
+ if (!NetworkUtil.isInternetAvailable()) {
+ message.what = Event.SYNC_FAILED;
+ } else {
+ Response> response0 = api.getSets(locale).execute();
+ updateSetNames(response0.body());
+ statusCode = response0.code();
+ Response> response1 = api.getItemCategories(locale).execute();
+ updateCategoryNames(response1.body());
+ statusCode = response1.code();
+ Response> response2 = api.getItems(locale).execute();
+ updateItemNames(response2.body());
+ statusCode = response2.code();
+ updateLogLocale(log.getId(), locale);
+ message.what = Event.SYNC_COMPLETED;
+ }
}
- @Override
- public void onFailure(Call> call, Throwable t) {
+
+ } else {
+ if (!NetworkUtil.isInternetAvailable()) {
+ message.what = Event.SYNC_NO_CONNECTION;
+ } else {
+ Response> response0 = api.getSets(locale).execute();
+ insertSets(response0.body());
+ statusCode = response0.code();
+ Response> response1 = api.getItemCategories(locale).execute();
+ insertCategories(response1.body());
+ statusCode = response1.code();
+ Response> response2 = api.getItems(locale).execute();
+ insertItems(response2.body());
+ statusCode = response2.code();
+ Response response3 = api.getTimestamp().execute();
+ insertTimestamp(response3.body());
+ statusCode = response3.code();
+ message.what = Event.SYNC_COMPLETED;
}
- });
- message.what = Event.SYNC_COMPLETED;
+ }
} catch (Exception e) {
message.what = Event.SYNC_FAILED;
@@ -871,24 +1241,27 @@ public class DAO {
break;
case Command.SYNC_IF_NOT_EXISTS:
- if (LogExist()) {
+ if (logExist()) {
message.what = Event.SYNC_COMPLETED;
} else {
-
try {
- Response> response0 = api.getSets().execute();
- insertSets(response0.body());
- statusCode = response0.code();
- Response> response1 = api.getItemCategories().execute();
- insertCategories(response1.body());
- statusCode = response1.code();
- Response> response2 = api.getItems().execute();
- insertItems(response2.body());
- statusCode = response2.code();
- Response response3 = api.getTimestamp().execute();
- insertTimestamp(response3.body());
- statusCode = response3.code();
- message.what = Event.SYNC_COMPLETED;
+ if (!NetworkUtil.isInternetAvailable()) {
+ message.what = Event.SYNC_NO_CONNECTION;
+ } else {
+ Response> response0 = api.getSets(locale).execute();
+ insertSets(response0.body());
+ statusCode = response0.code();
+ Response> response1 = api.getItemCategories(locale).execute();
+ insertCategories(response1.body());
+ statusCode = response1.code();
+ Response> response2 = api.getItems(locale).execute();
+ insertItems(response2.body());
+ statusCode = response2.code();
+ Response response3 = api.getTimestamp().execute();
+ insertTimestamp(response3.body());
+ statusCode = response3.code();
+ message.what = Event.SYNC_COMPLETED;
+ }
} catch (IOException e ){
message.what = Event.SYNC_FAILED;
} finally {
diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/Db.java b/app/src/main/java/com/hikapro/backpack/model/dao/Db.java
index 44d583a..c70216b 100644
--- a/app/src/main/java/com/hikapro/backpack/model/dao/Db.java
+++ b/app/src/main/java/com/hikapro/backpack/model/dao/Db.java
@@ -8,6 +8,7 @@ import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
+import java.util.Locale;
import com.hikapro.backpack.model.entities.Category;
import com.hikapro.backpack.model.entities.Item;
@@ -64,6 +65,7 @@ public class Db {
public static final String COLUMN_PHOTO_THUMB_URL = "photo_thumb_url";
public static final String COLUMN_PHOTO_LOCAL = "photo_local";
public static final String COLUMN_PHOTO_THUMB_LOCAL = "photo_thumb_local";
+ public static final String COLUMN_USER_DEFINED = "user_defined";
public static final String CREATE =
@@ -76,6 +78,7 @@ public class Db {
COLUMN_PHOTO_URL + " TEXT, " +
COLUMN_PHOTO_THUMB_URL + " TEXT, " +
COLUMN_PHOTO_LOCAL + " TEXT, " +
+ COLUMN_USER_DEFINED + " NUMERIC, " +
COLUMN_PHOTO_THUMB_LOCAL + " TEXT" +
" ); ";
@@ -98,6 +101,8 @@ public class Db {
values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl());
if (item.getPhotoLocal() != null)
values.put(COLUMN_PHOTO_LOCAL, item.getPhotoLocal());
+
+ values.put(COLUMN_USER_DEFINED, item.isUserDefined());
/*
values.put(COLUMN_PHOTO_THUMB_LOCAL, item.getName());
*/
@@ -122,6 +127,8 @@ public class Db {
item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
item.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL)));
+ short ud = cursor.getShort(cursor.getColumnIndexOrThrow(COLUMN_USER_DEFINED));
+ item.setUserDefined(ud != 0);
return item;
}
@@ -215,11 +222,13 @@ public class Db {
public static final String COLUMN_ID = "_id";
public static final String COLUMN_MODIFIED_DATETIME = "modified_datetime";
public static final String COLUMN_TIMESTAMP = "timestamp";
+ public static final String COLUMN_LOCALE = "locale";
public static final String CREATE =
"CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_TIMESTAMP + " INTEGER NOT NULL, " +
+ COLUMN_LOCALE + " TEXT, " +
COLUMN_MODIFIED_DATETIME + " INTEGER NOT NULL DEFAULT current_timestamp" +
" ); ";
@@ -227,13 +236,16 @@ public class Db {
ContentValues values = new ContentValues();
values.put(COLUMN_TIMESTAMP, timestamp.timestamp);
+ values.put(COLUMN_LOCALE, Locale.getDefault().getLanguage());
return values;
}
public static UpdateLog parseCursor(Cursor cursor) {
UpdateLog log = new UpdateLog();
+ log.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID)));
log.setTimestamp(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_TIMESTAMP)));
log.setModifiedDatetime(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_MODIFIED_DATETIME)));
+ log.setLocale(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_LOCALE)));
return log;
}
}
@@ -247,6 +259,7 @@ public class Db {
public static final String COLUMN_ITEM = "itemId";
public static final String COLUMN_DELETED = "deleted";
public static final String COLUMN_PACKED = "packed";
+ public static final String COLUMN_USER_DEFINED = "user_defined";
public static final String CREATE =
"CREATE TABLE " + TABLE_NAME + " (" +
@@ -254,6 +267,7 @@ public class Db {
COLUMN_SET + " INTEGER NOT NULL, " +
COLUMN_DELETED + " NUMERIC, " +
COLUMN_PACKED + " NUMERIC, " +
+ COLUMN_USER_DEFINED + " NUMERIC, " +
COLUMN_ITEM + " INTEGER NOT NULL" +
" ); ";
@@ -263,6 +277,17 @@ public class Db {
values.put(COLUMN_ITEM, itemId);
values.put(COLUMN_DELETED, 0);
values.put(COLUMN_PACKED, 0);
+ values.put(COLUMN_USER_DEFINED, 0);
+ return values;
+ }
+
+ public static ContentValues toContentValues(int setId, int itemId, boolean userDefined) {
+ ContentValues values = new ContentValues();
+ values.put(COLUMN_SET, setId);
+ values.put(COLUMN_ITEM, itemId);
+ values.put(COLUMN_DELETED, 0);
+ values.put(COLUMN_PACKED, 0);
+ values.put(COLUMN_USER_DEFINED, userDefined);
return values;
}
}
diff --git a/app/src/main/java/com/hikapro/backpack/model/dao/Event.java b/app/src/main/java/com/hikapro/backpack/model/dao/Event.java
index ffd4a74..ea03d07 100644
--- a/app/src/main/java/com/hikapro/backpack/model/dao/Event.java
+++ b/app/src/main/java/com/hikapro/backpack/model/dao/Event.java
@@ -14,6 +14,7 @@ public interface Event {
int SET_ITEMS_LOAD_ERROR = -0x3;
int SET_PACKED_LOAD_ERROR = -0x4;
int SET_UNPACK_ERROR = -0x5;
+ int SET_RESTORE_ERROR = -0x6;
int SET_LOAD_COMPLETED = 0x1;
@@ -21,6 +22,7 @@ public interface Event {
int SET_ITEMS_LOAD_COMPLETED = 0x3;
int SET_PACKED_LOAD_COMPLETED = 0x4;
int SET_UNPACK_COMPLETED = 0x5;
+ int SET_RESTORE_COMPLETED = 0x6;
int ITEM_FROM_SET_ERROR = -0x14;
@@ -30,6 +32,7 @@ public interface Event {
int ITEM_UNPACK_ERROR = -0x18;
int ITEM_CATEGORY_LOAD_ERROR = -0x19;
int ITEM_IMAGE_LOAD_ERROR = -0x1A;
+ int ITEM_LIKE_LOAD_ERROR = -0x1B;
int ITEM_FROM_SET_DELETED = 0x14;
int ITEM_INSERTED = 0x15;
@@ -38,6 +41,7 @@ public interface Event {
int ITEM_UNPACKED = 0x18;
int ITEM_CATEGORY_LOAD_COMPLETED = 0x19;
int ITEM_IMAGE_LOAD_COMPLETED = 0x1A;
+ int ITEM_LIKE_LOAD_COMPLETED = 0x1B;
int MY_LIST_POST_ERROR = -0x28;
@@ -51,6 +55,7 @@ public interface Event {
int MY_LIST_CLEARED = 0x2B;
int SYNC_FAILED = -0x3C;
+ int SYNC_NO_CONNECTION = -0x3D;
int SYNC_COMPLETED = 0x3C;
int NOT_IMPLEMENTED = 0x50;
diff --git a/app/src/main/java/com/hikapro/backpack/model/entities/Item.java b/app/src/main/java/com/hikapro/backpack/model/entities/Item.java
index 7293ab6..ca53163 100644
--- a/app/src/main/java/com/hikapro/backpack/model/entities/Item.java
+++ b/app/src/main/java/com/hikapro/backpack/model/entities/Item.java
@@ -36,9 +36,19 @@ public class Item implements Comparable- , Serializable {
private String photoLocal;
+ private boolean userDefined;
+
+ public boolean InList;
+
public Item() {
}
+ public Item(String name, int category) {
+ this.id = -1;
+ this.name = name;
+ this.category = category;
+ }
+
public Item(int id, String name, int category, String description, List buyUrls,
String photoUrl, String photoThumbUrl) {
this.id = id;
@@ -114,6 +124,14 @@ public class Item implements Comparable
- , Serializable {
this.photoLocal = photoLocal;
}
+ public boolean isUserDefined() {
+ return userDefined;
+ }
+
+ public void setUserDefined(boolean userDefined) {
+ this.userDefined = userDefined;
+ }
+
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
diff --git a/app/src/main/java/com/hikapro/backpack/model/entities/UpdateLog.java b/app/src/main/java/com/hikapro/backpack/model/entities/UpdateLog.java
index 5507436..ee33e54 100644
--- a/app/src/main/java/com/hikapro/backpack/model/entities/UpdateLog.java
+++ b/app/src/main/java/com/hikapro/backpack/model/entities/UpdateLog.java
@@ -5,12 +5,22 @@ package com.hikapro.backpack.model.entities;
*/
public class UpdateLog {
+ private int id;
private long timestamp;
private long modifiedDatetime;
+ private String locale;
public UpdateLog() {
}
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
public long getTimestamp() {
return timestamp;
}
@@ -26,4 +36,12 @@ public class UpdateLog {
public void setModifiedDatetime(long modifiedDatetime) {
this.modifiedDatetime = modifiedDatetime;
}
+
+ public String getLocale() {
+ return locale;
+ }
+
+ public void setLocale(String locale) {
+ this.locale = locale;
+ }
}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/AddPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/AddPresenter.java
new file mode 100644
index 0000000..0db093d
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/AddPresenter.java
@@ -0,0 +1,328 @@
+package com.hikapro.backpack.presenter;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.SearchView;
+import android.widget.Toast;
+
+import com.hikapro.backpack.R;
+import com.hikapro.backpack.model.Model;
+import com.hikapro.backpack.model.entities.Category;
+import com.hikapro.backpack.model.entities.Item;
+import com.hikapro.backpack.presenter.adapters.AddListAdapter;
+import com.hikapro.backpack.presenter.adapters.helper.items.DividerDecoration;
+import com.hikapro.backpack.view.View;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Created by tariel on 18/05/16.
+ */
+public class AddPresenter implements Presenter.Add {
+
+ private WeakReference view;
+ private Model.Add model;
+
+ private AddListAdapter adapter;
+ private RecyclerView recycler;
+ private ViewGroup categoryContainer;
+ private ViewGroup categoryContainerMain;
+ private boolean isContainerAlreadyInitialised;
+ private Item newItem;
+ private Item selectedItem;
+ private Button currentCategoryButton;
+ private Button cancelButton;
+ private Button saveButton;
+ private SearchView searchView;
+ private boolean canSave;
+
+
+ public AddPresenter() {
+ this.adapter = new AddListAdapter(this);
+ }
+
+ @Override
+ public void setView(View.Add view) {
+ this.view = new WeakReference<>(view);
+ }
+
+ @Override
+ public void setModel(Model.Add model) {
+ this.model = model;
+
+ }
+
+ @Override
+ public Model.Add getModel() {
+ return model;
+ }
+
+ @Override
+ public void onDestroy(boolean isChangingConfiguration) {
+ view = null;
+ model.onDestroy(isChangingConfiguration);
+ if ( !isChangingConfiguration ) {
+ model = null;
+ }
+ isContainerAlreadyInitialised = false;
+ }
+
+ @Override
+ public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ android.view.View view = inflater.inflate(R.layout.fragment_add, container, false);
+ model.executeQuery();
+ LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
+ recycler = (RecyclerView) view.findViewById(R.id.add_item_recycler);
+ recycler.setLayoutManager(llm);
+ recycler.setAdapter(adapter);
+ recycler.setItemAnimator(new DefaultItemAnimator());
+ recycler.addItemDecoration(new DividerDecoration(getActivityContext()));
+ categoryContainer = (ViewGroup) view.findViewById(R.id.add_item_category_flow);
+ categoryContainerMain = (ViewGroup) view.findViewById(R.id.add_item_category_container);
+ categoryContainerMain.setVisibility(android.view.View.GONE);
+ recycler.setVisibility(android.view.View.GONE);
+
+ Activity activity = (Activity) getActivityContext();
+ if (activity != null) {
+ ActionBar actionBar = activity.getActionBar();
+ if (actionBar != null) {
+ ViewGroup custActionBarView = (ViewGroup) inflater.inflate(R.layout.add_cust_actionbar, null);
+ actionBar.setDisplayShowHomeEnabled(false);
+ actionBar.setDisplayShowTitleEnabled(false);
+ actionBar.setDisplayShowCustomEnabled(true);
+ actionBar.setDisplayHomeAsUpEnabled(false);
+ actionBar.setCustomView(custActionBarView);
+
+ cancelButton = (Button) custActionBarView.findViewById(R.id.action_add_cancel);
+ saveButton = (Button) custActionBarView.findViewById(R.id.action_add_save);
+ cancelButton.setOnClickListener(new ActionBarButtonClickListener());
+ saveButton.setOnClickListener(new ActionBarButtonClickListener());
+ }
+ }
+
+ searchView = (SearchView) view.findViewById(R.id.add_search);
+ searchView.setIconified(false);
+ searchView.setIconifiedByDefault(false);
+ searchView.setQueryHint("Enter a new item name");
+ searchView.setSubmitButtonEnabled(false);
+ searchView.setBottom(20);
+ /*
+ Drawable d = getActivityContext().getResources().getDrawable( R.drawable.search_divider );
+ searchView.setDividerDrawable(d);*/
+
+ int magId = searchView.getContext().getResources().getIdentifier("android:id/search_mag_icon", null, null);
+ ImageView magImage = (ImageView) searchView.findViewById(magId);
+ magImage.setLayoutParams(new LinearLayout.LayoutParams(0, 0));
+ searchView.setMinimumHeight(40);
+ searchView.setOnQueryTextListener(new SearchTextListener());
+/*
+ int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
+ // Getting the 'search_plate' LinearLayout.
+ android.view.View searchPlate = searchView.findViewById(searchPlateId);
+ // Setting background of 'search_plate' to earlier defined drawable.
+ searchPlate.setBackgroundResource(R.drawable.search_divider);
+
+*/
+
+ return view;
+ }
+
+ @Override
+ public Context getAppContext() {
+ try {
+ return getView().getAppContext();
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public Context getActivityContext() {
+ try {
+ return getView().getActivityContext();
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public void notifyDataSetChanged(boolean found) {
+ adapter.notifyDataSetChanged();
+ if (found) {
+ categoryContainerMain.setVisibility(android.view.View.GONE);
+ recycler.setVisibility(android.view.View.VISIBLE);
+ currentCategoryButton = null;
+ } else {
+ categoryContainerMain.setVisibility(android.view.View.VISIBLE);
+ recycler.setVisibility(android.view.View.GONE);
+ initSelectCategoryContainer();
+ }
+ }
+
+ @Override
+ public void onAddItemClick(Item item) {
+ searchView.setQuery(item.getName(), false);
+ if (!item.InList)
+ selectedItem = item;
+ setSaveButtonAccess();
+ }
+
+ private void setSaveButtonAccess() {
+
+ if (searchView.getQuery().length() > 0 && currentCategoryButton != null
+ || selectedItem != null)
+ canSave = true;
+ else
+ canSave = false;
+
+ if (canSave)
+ saveButton.setTextColor(saveButton.getResources().getColor(R.color.save_green));
+ else
+ saveButton.setTextColor(saveButton.getResources().getColor(R.color.white));
+ }
+
+ private boolean checkUserInput() {
+ if (!canSave) {
+ if (searchView.getQuery().length() == 0)
+ Toast.makeText(getActivityContext(), "Please, enter a name", Toast.LENGTH_SHORT).show();
+ else if (categoryContainerMain.getVisibility() == android.view.View.VISIBLE)
+ Toast.makeText(getActivityContext(), "Please, select a category", Toast.LENGTH_SHORT).show();
+ else
+ Toast.makeText(getActivityContext(), "Already in List!", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ return true;
+ }
+
+ private void initSelectCategoryContainer() {
+ Button button;
+ Category category;
+ if (! isContainerAlreadyInitialised) {
+
+ for (int i = 0; i < model.getCategoriesCount(); ++i) {
+ category = model.getCategoryByPosition(i);
+ button = (Button) LayoutInflater.from(getActivityContext()).inflate(
+ R.layout.category_button, null);
+ button.setId(category.getId());
+ button.setText(category.getName());
+ button.setOnClickListener(new CategoryButtonClickListener());
+ categoryContainer.addView(button);
+
+ if (currentCategoryButton != null) {
+ if (button.getId() == currentCategoryButton.getId()) {
+ currentCategoryButton = button;
+ Drawable d = currentCategoryButton.getBackground();
+ PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP);
+ d.setColorFilter(filter);
+ }
+ }
+ }
+ setSaveButtonAccess();
+ isContainerAlreadyInitialised = true;
+ }
+ }
+
+ private View.Add getView() throws NullPointerException {
+ if ( view != null )
+ return view.get();
+ else
+ throw new NullPointerException("View is unavailable");
+ }
+
+ private class CategoryButtonClickListener implements android.view.View.OnClickListener {
+ @Override
+ public void onClick(android.view.View v) {
+
+ Drawable d = v.getBackground();
+ PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP);
+ d.setColorFilter(filter);
+
+ if (currentCategoryButton != null) {
+ d = currentCategoryButton.getBackground();
+ currentCategoryButton.invalidateDrawable(d);
+ d.clearColorFilter();
+ }
+
+ currentCategoryButton = (Button) v;
+ Toast.makeText(getActivityContext(), "Id " + currentCategoryButton.getId(), Toast.LENGTH_SHORT).show();
+ setSaveButtonAccess();
+ }
+ }
+
+ private class ActionBarButtonClickListener implements android.view.View.OnClickListener {
+ @Override
+ public void onClick(android.view.View v) {
+ Fragment fragment = (Fragment) getView();
+ switch (v.getId())
+ {
+ case R.id.action_add_cancel :
+ Toast.makeText(getActivityContext(), "Cancel", Toast.LENGTH_SHORT).show();
+ searchView.clearFocus();
+ if (fragment != null)
+ fragment.getFragmentManager().popBackStack();
+ break;
+
+ case R.id.action_add_save :
+ if (checkUserInput()) {
+ if (selectedItem != null) {
+ model.add(selectedItem, getView().getSet().getId());
+ } else {
+ newItem = new Item(searchView.getQuery().toString(), currentCategoryButton.getId());
+ newItem.setUserDefined(true);
+ model.add(newItem, getView().getSet().getId());
+ }
+ searchView.clearFocus();
+ if (fragment != null)
+ fragment.getFragmentManager().popBackStack();
+ }
+ break;
+ }
+ }
+ }
+
+ private class SearchTextListener implements SearchView.OnQueryTextListener {
+
+ public SearchTextListener() {
+ super();
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ model.filter(newText, getView().getSet().getId());
+ if (newText.isEmpty()) {
+ if (currentCategoryButton != null) {
+ Drawable d = currentCategoryButton.getBackground();
+ currentCategoryButton.invalidateDrawable(d);
+ d.clearColorFilter();
+ currentCategoryButton = null;
+ }
+ }
+ selectedItem = null;
+ setSaveButtonAccess();
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java
index f190732..2000ed0 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/ItemListPresenter.java
@@ -2,7 +2,9 @@ package com.hikapro.backpack.presenter;
import android.app.ActionBar;
import android.app.Activity;
+import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
@@ -97,10 +99,15 @@ public class ItemListPresenter implements Presenter.ItemList {
});
Activity activity = (Activity) getActivityContext();
if (activity != null) {
+ activity.invalidateOptionsMenu();
ActionBar actionBar = activity.getActionBar();
if (actionBar != null) {
actionBar.show();
actionBar.setTitle(set.getName());
+ actionBar.setDisplayShowHomeEnabled(false);
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setDisplayShowCustomEnabled(false);
+ actionBar.setDisplayHomeAsUpEnabled(true);
}
}
/*
@@ -229,4 +236,45 @@ public class ItemListPresenter implements Presenter.ItemList {
public Set getCurrentSet() {
return set;
}
+
+ @Override
+ public void unpack(int setId) {
+ model.unpackSet(setId);
+ }
+
+ @Override
+ public void restore(final int setId) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivityContext(), AlertDialog.THEME_HOLO_DARK);
+
+ builder.setMessage(R.string.dlg_restore_txt)
+ .setTitle(R.string.dlg_restore_header);
+
+ builder.setPositiveButton(R.string.ok_button, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ model.restoreSet(setId);
+ }
+ });
+ builder.setNegativeButton(R.string.cancel_button, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ AlertDialog dialog = builder.create();
+ dialog.show();
+
+ //Button button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ //button.setBackgroundColor(Color.GREEN);
+ /*
+ Drawable d = button.getBackground();
+ PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP);
+ d.setColorFilter(filter);*/
+ //button = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+ //button.setBackgroundColor(Color.GRAY);
+ /*
+ d = button.getBackground();
+ filter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP);
+ d.setColorFilter(filter);*/
+
+
+ }
}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java
index 04942f7..eab29ac 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/PackedListPresenter.java
@@ -1,5 +1,7 @@
package com.hikapro.backpack.presenter;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
@@ -99,6 +101,19 @@ public class PackedListPresenter extends ItemListPresenter {
model.getPackedQty(), model.getActiveItemsCount());
packedCount.setText(str);
*/
+ Activity activity = (Activity) getActivityContext();
+ if (activity != null) {
+ activity.invalidateOptionsMenu();
+ ActionBar actionBar = activity.getActionBar();
+ if (actionBar != null) {
+ actionBar.show();
+ actionBar.setTitle(set.getName());
+ actionBar.setDisplayShowHomeEnabled(false);
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setDisplayShowCustomEnabled(false);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ }
+ }
return view;
}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java b/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java
index ad7e968..13f0d57 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/Presenter.java
@@ -10,6 +10,7 @@ import android.view.ViewGroup;
import com.hikapro.backpack.model.Model;
import com.hikapro.backpack.model.entities.Item;
import com.hikapro.backpack.model.entities.Set;
+import com.hikapro.backpack.view.View;
/**
* Created by tariel on 19/04/16.
@@ -33,7 +34,8 @@ public interface Presenter {
void setModel(Model.Set model);
Model.Set getModel();
void notifyDataSetChanged();
- void showMessage(String message);
+ void startProgress();
+ void stopProgress();
//GLM_add_resources_SetList
void onItemDismiss(int position);
@@ -56,6 +58,8 @@ public interface Presenter {
void onSaveInstanceState(Bundle outState);
void showDetails(int itemId);
void filter(String query);
+ void unpack(int setId);
+ void restore(int setId);
}
interface ItemDetail extends Base {
@@ -71,6 +75,25 @@ public interface Presenter {
void displayPicture(Bitmap bitmap);
}
+ interface Share extends Base {
+ void setView(View.Share view);
+ void setModel(Model.Share model);
+ Model.Share getModel();
+ void onDestroy(boolean isChangingConfiguration);
+ android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
+
+ }
+
+ interface Add extends Base {
+ void setView(View.Add view);
+ void setModel(Model.Add model);
+ Model.Add getModel();
+ void onDestroy(boolean isChangingConfiguration);
+ android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
+ void notifyDataSetChanged(boolean found);
+ void onAddItemClick(Item item);
+ }
+
}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/SetListPresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/SetListPresenter.java
index 23a3d80..482560e 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/SetListPresenter.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/SetListPresenter.java
@@ -9,6 +9,7 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.ViewGroup;
+import android.widget.ProgressBar;
import android.widget.Toast;
import java.lang.ref.WeakReference;
@@ -31,6 +32,9 @@ public class SetListPresenter implements Presenter.SetList {
private WeakReference view;
private Model.Set model;
private SetListAdapter adapter;
+ private ViewGroup progressBarContainer;
+ private ProgressBar progressBar;
+ private RecyclerView setRecycler;
//GLM_add_resources_SetList
@@ -72,8 +76,12 @@ public class SetListPresenter implements Presenter.SetList {
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
android.view.View view = inflater.inflate(R.layout.fragment_set_list, container, false);
+
+ progressBarContainer = (ViewGroup) view.findViewById(R.id.set_progress_container);
+ progressBar = (ProgressBar) progressBarContainer.findViewById(R.id.set_progress);
+
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
- RecyclerView setRecycler = (RecyclerView) view.findViewById(R.id.set_recycler);
+ setRecycler = (RecyclerView) view.findViewById(R.id.set_recycler);
setRecycler.setLayoutManager(llm);
setRecycler.setAdapter(adapter);
setRecycler.setItemAnimator(new DefaultItemAnimator());
@@ -134,11 +142,6 @@ public class SetListPresenter implements Presenter.SetList {
return model;
}
- @Override
- public void showMessage(String message) {
- Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
- }
-
// other impl <--
private View.SetList getView() throws NullPointerException {
@@ -148,6 +151,18 @@ public class SetListPresenter implements Presenter.SetList {
throw new NullPointerException("View is unavailable");
}
+ @Override
+ public void startProgress() {
+ setRecycler.setVisibility(android.view.View.GONE);
+ progressBarContainer.setVisibility(android.view.View.VISIBLE);
+ }
+
+ @Override
+ public void stopProgress() {
+ setRecycler.setVisibility(android.view.View.VISIBLE);
+ progressBarContainer.setVisibility(android.view.View.GONE);
+ }
+
//GLM_add_resources_SetList
@Override
public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
@@ -158,7 +173,7 @@ public class SetListPresenter implements Presenter.SetList {
if (getView() != null)
getView().showItemList(set);
else
- showMessage("There is no view in presenter");
+ Toast.makeText(getActivityContext(), "There is no view in presenter", Toast.LENGTH_SHORT).show();
}
public void onLongClick(SetViewHolder holder) {
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/SharePresenter.java b/app/src/main/java/com/hikapro/backpack/presenter/SharePresenter.java
new file mode 100644
index 0000000..4c9268e
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/SharePresenter.java
@@ -0,0 +1,134 @@
+package com.hikapro.backpack.presenter;
+
+import android.app.Activity;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import com.facebook.CallbackManager;
+import com.facebook.FacebookCallback;
+import com.facebook.FacebookException;
+import com.facebook.FacebookSdk;
+import com.facebook.appevents.AppEventsLogger;
+import com.facebook.share.Sharer;
+import com.facebook.share.model.ShareHashtag;
+import com.facebook.share.model.ShareLinkContent;
+import com.facebook.share.widget.ShareDialog;
+import com.hikapro.backpack.R;
+import com.hikapro.backpack.model.Model;
+import com.hikapro.backpack.view.View;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Created by tariel on 16/05/16.
+ */
+public class SharePresenter implements Presenter.Share {
+
+ private ShareDialog shareDialog;
+ private CallbackManager callbackManager;
+
+ private Button facebookButton;
+ private Button twitterButton;
+
+ private WeakReference view;
+ private Model.Share model;
+
+ @Override
+ public Context getAppContext() {
+ try {
+ return getView().getAppContext();
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public Context getActivityContext() {
+ try {
+ return getView().getActivityContext();
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public void setView(View.Share view) {
+ this.view = new WeakReference<>(view);
+
+ }
+
+ @Override
+ public void setModel(Model.Share model) {
+ this.model = model;
+ }
+
+ @Override
+ public Model.Share getModel() {
+ return model;
+ }
+
+ @Override
+ public void onDestroy(boolean isChangingConfiguration) {
+ view = null;
+ model.onDestroy(isChangingConfiguration);
+ if ( !isChangingConfiguration ) {
+ model = null;
+ }
+ }
+
+ @Override
+ public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ android.view.View v = inflater.inflate(R.layout.fragment_share, container, false);
+
+ FacebookSdk.sdkInitialize(getAppContext());
+ //AppEventsLogger.activateApp(getActivityContext());
+ callbackManager = CallbackManager.Factory.create();
+ shareDialog = new ShareDialog((Activity) getActivityContext());
+ facebookButton = (Button) v.findViewById(R.id.facebook_share_button);
+ twitterButton = (Button) v.findViewById(R.id.twitter_share_button);
+ shareDialog.registerCallback(callbackManager, new
+
+ FacebookCallback() {
+ @Override
+ public void onSuccess(Sharer.Result result) {}
+
+ @Override
+ public void onCancel() {}
+
+ @Override
+ public void onError(FacebookException error) {}
+ });
+ facebookButton.setOnClickListener(new android.view.View.OnClickListener() {
+ @Override
+ public void onClick(android.view.View v) {
+ if (ShareDialog.canShow(ShareLinkContent.class)) {
+
+
+ ShareLinkContent linkContent = new ShareLinkContent.Builder()
+ .setContentTitle("Test Pack With Me app")
+ .setContentDescription("Test of facebook integration")
+ .setContentUrl(Uri.parse("http://developers.facebook.com/android"))
+ .setShareHashtag(new ShareHashtag.Builder()
+ .setHashtag("#PackWithMe")
+ .build())
+ .build();
+
+ shareDialog.show(linkContent);
+ }
+ }
+ });
+ return v;
+ }
+
+ private View.Share getView() throws NullPointerException {
+ if ( view != null )
+ return view.get();
+ else
+ throw new NullPointerException("View is unavailable");
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/AddListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/AddListAdapter.java
new file mode 100644
index 0000000..8b45761
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/AddListAdapter.java
@@ -0,0 +1,53 @@
+package com.hikapro.backpack.presenter.adapters;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import com.hikapro.backpack.R;
+import com.hikapro.backpack.model.entities.Item;
+import com.hikapro.backpack.presenter.Presenter;
+import com.hikapro.backpack.view.recycler.AddItemViewHolder;
+import com.hikapro.backpack.view.recycler.ItemViewHolder;
+
+/**
+ * Created by tariel on 18/05/16.
+ */
+public class AddListAdapter extends RecyclerView.Adapter {
+
+ private Presenter.Add presenter;
+
+ public AddListAdapter(Presenter.Add presenter) {
+ this.presenter = presenter;
+ }
+
+ @Override
+ public int getItemCount() {
+ return presenter.getModel().getItemsCount();
+ }
+
+ @Override
+ public void onBindViewHolder(AddItemViewHolder holder, int position) {
+ final Item item = presenter.getModel().getItemByPosition(position);
+ holder.name.setText(item.getName());
+ holder.category.setText(presenter.getModel().getCategoryById(item.getCategory()).getName());
+ holder.alreadyInList.setVisibility(item.InList ? View.VISIBLE : View.GONE);
+ holder.item.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ presenter.onAddItemClick(item);
+ }
+ });
+ }
+
+ @Override
+ public AddItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ AddItemViewHolder viewHolder;
+ View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_add,
+ parent, false);
+ viewHolder = new AddItemViewHolder(v);
+ return viewHolder;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java
index 83289ee..ce2b6fc 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/ItemListAdapter.java
@@ -1,6 +1,7 @@
package com.hikapro.backpack.presenter.adapters;
import android.graphics.Color;
+import android.graphics.Typeface;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -29,6 +30,7 @@ public class ItemListAdapter extends RecyclerView.Adapter implem
HashMap
- pendingRunables = new HashMap<>(); // map of items to pending runnables, so we can cancel a removal if need be
private Presenter.ItemList presenter;
private boolean checkAll;
+ private Typeface mainFace;
public ItemListAdapter(Presenter.ItemList presenter) {
this.presenter = presenter;
@@ -54,8 +56,8 @@ public class ItemListAdapter extends RecyclerView.Adapter implem
// we need to show the "undo" state of the row
holder.itemView.setBackgroundColor(Color.RED);
holder.checkBox.setVisibility(View.GONE);
- holder.undoButton.setVisibility(View.VISIBLE);
- holder.undoButton.setOnClickListener(new View.OnClickListener() {
+ holder.swipeGroup.setVisibility(View.VISIBLE);
+ holder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// user wants to undo the removal, let's cancel the pending task
@@ -68,9 +70,16 @@ public class ItemListAdapter extends RecyclerView.Adapter implem
}
});
} else {
+ /*
+ if (mainFace == null)
+ mainFace = Typeface.createFromAsset(presenter.getAppContext().getAssets(),
+ "fonts/Ubuntu-B.ttf");*/
+
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setChecked(checkAll);
holder.checkBox.setText(item.getName() + " " + item.getId() + " pos " + position);//TODO del
+ holder.checkBox.setTypeface(mainFace);
+ holder.swipeGroup.setVisibility(View.GONE);
holder.id = item.getId();
holder.checkBox.setOnClickListener(new android.view.View.OnClickListener() {
@Override
@@ -91,8 +100,7 @@ public class ItemListAdapter extends RecyclerView.Adapter implem
}
});
holder.itemView.setBackgroundColor(0x33FF99);
- holder.undoButton.setVisibility(View.GONE);
- holder.undoButton.setOnClickListener(null);
+ holder.deleteButton.setOnClickListener(null);
}
}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/SetListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/SetListAdapter.java
index 5a3ef18..bfa7f9d 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/SetListAdapter.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/SetListAdapter.java
@@ -1,5 +1,6 @@
package com.hikapro.backpack.presenter.adapters;
+import android.graphics.Typeface;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@@ -17,6 +18,7 @@ public class SetListAdapter extends RecyclerView.Adapter impleme
private SetListPresenter presenter;
private String rightBracket;
+ private Typeface mainFace;
public SetListAdapter(SetListPresenter presenter) {
this.presenter = presenter;
@@ -36,7 +38,13 @@ public class SetListAdapter extends RecyclerView.Adapter impleme
this.rightBracket = "";
}
+ if (mainFace == null) {
+ mainFace = Typeface.createFromAsset(presenter.getAppContext().getAssets(),
+ "fonts/Ubuntu-B.ttf");
+ }
+
holder.textView.setText(set.getName() + " " + rightBracket);
+ holder.textView.setTypeface(mainFace);
String info = String.format("%s %d / %d",
presenter.getActivityContext().getResources().getString(R.string.packed),
set.getPackedQty(),
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java
index 21aa37d..7feeccf 100644
--- a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/ItemSwipeCallback.java
@@ -10,6 +10,7 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
+import android.view.ViewGroup;
import com.hikapro.backpack.R;
import com.hikapro.backpack.presenter.adapters.ItemListAdapter;
@@ -21,6 +22,7 @@ public class ItemSwipeCallback extends ItemTouchHelper.SimpleCallback {
// we want to cache these and not allocate anything repeatedly in the onChildDraw method
Drawable background;
+ ViewGroup viewGroup;
Drawable xMark;
int xMarkMargin;
boolean initiated;
@@ -82,11 +84,21 @@ public class ItemSwipeCallback extends ItemTouchHelper.SimpleCallback {
init();
}
+ if (-(c.getWidth() * 0.6) > dX) {
+ this.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, false);
+ return;
+ }
+
// draw red background
- background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
- background.draw(c);
+ //viewGroup.setLeft(itemView.getRight() + (int) dX);
+ //if ((itemView.getRight() + (int)dX) >= c.getWidth() * 0.6) {
+ background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
+ background.draw(c);
+ //viewGroup.draw(c);
+ //}
// draw x mark
+
int itemHeight = itemView.getBottom() - itemView.getTop();
int intrinsicWidth = xMark.getIntrinsicWidth();
int intrinsicHeight = xMark.getIntrinsicWidth();
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/BaseSwipeListAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/BaseSwipeListAdapter.java
new file mode 100644
index 0000000..387f381
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/BaseSwipeListAdapter.java
@@ -0,0 +1,13 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import android.widget.BaseAdapter;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public abstract class BaseSwipeListAdapter extends BaseAdapter {
+
+ public boolean getSwipeEnableByPosition(int position) {
+ return true;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenu.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenu.java
new file mode 100644
index 0000000..d647ffc
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenu.java
@@ -0,0 +1,49 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public class SwipeMenu {
+
+ private Context mContext;
+ private List mItems;
+ private int mViewType;
+
+ public SwipeMenu(Context context) {
+ mContext = context;
+ mItems = new ArrayList();
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public void addMenuItem(SwipeMenuItem item) {
+ mItems.add(item);
+ }
+
+ public void removeMenuItem(SwipeMenuItem item) {
+ mItems.remove(item);
+ }
+
+ public List getMenuItems() {
+ return mItems;
+ }
+
+ public SwipeMenuItem getMenuItem(int index) {
+ return mItems.get(index);
+ }
+
+ public int getViewType() {
+ return mViewType;
+ }
+
+ public void setViewType(int viewType) {
+ this.mViewType = viewType;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuAdapter.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuAdapter.java
new file mode 100644
index 0000000..9e6c9c2
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuAdapter.java
@@ -0,0 +1,144 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListAdapter;
+import android.widget.WrapperListAdapter;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public class SwipeMenuAdapter implements WrapperListAdapter,
+ SwipeMenuView.OnSwipeItemClickListener {
+
+ private ListAdapter mAdapter;
+ private Context mContext;
+ private SwipeMenuListView.OnMenuItemClickListener onMenuItemClickListener;
+
+ public SwipeMenuAdapter(Context context, ListAdapter adapter) {
+ mAdapter = adapter;
+ mContext = context;
+ }
+
+ @Override
+ public int getCount() {
+ return mAdapter.getCount();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mAdapter.getItem(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mAdapter.getItemId(position);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ SwipeMenuLayout layout = null;
+ if (convertView == null) {
+ View contentView = mAdapter.getView(position, convertView, parent);
+ SwipeMenu menu = new SwipeMenu(mContext);
+ menu.setViewType(getItemViewType(position));
+ createMenu(menu);
+ SwipeMenuView menuView = new SwipeMenuView(menu,
+ (SwipeMenuListView) parent);
+ menuView.setOnSwipeItemClickListener(this);
+ SwipeMenuListView listView = (SwipeMenuListView) parent;
+ layout = new SwipeMenuLayout(contentView, menuView,
+ listView.getCloseInterpolator(),
+ listView.getOpenInterpolator());
+ layout.setPosition(position);
+ } else {
+ layout = (SwipeMenuLayout) convertView;
+ layout.closeMenu();
+ layout.setPosition(position);
+ View view = mAdapter.getView(position, layout.getContentView(),
+ parent);
+ }
+ if (mAdapter instanceof BaseSwipeListAdapter) {
+ boolean swipEnable = (((BaseSwipeListAdapter) mAdapter).getSwipeEnableByPosition(position));
+ layout.setSwipEnable(swipEnable);
+ }
+ return layout;
+ }
+
+ public void createMenu(SwipeMenu menu) {
+ // Test Code
+ SwipeMenuItem item = new SwipeMenuItem(mContext);
+ item.setTitle("Item 1");
+ item.setBackground(new ColorDrawable(Color.GRAY));
+ item.setWidth(300);
+ menu.addMenuItem(item);
+
+ item = new SwipeMenuItem(mContext);
+ item.setTitle("Item 2");
+ item.setBackground(new ColorDrawable(Color.RED));
+ item.setWidth(300);
+ menu.addMenuItem(item);
+ }
+
+ @Override
+ public void onItemClick(SwipeMenuView view, SwipeMenu menu, int index) {
+ if (onMenuItemClickListener != null) {
+ onMenuItemClickListener.onMenuItemClick(view.getPosition(), menu,
+ index);
+ }
+ }
+
+ public void setOnSwipeItemClickListener(
+ SwipeMenuListView.OnMenuItemClickListener onMenuItemClickListener) {
+ this.onMenuItemClickListener = onMenuItemClickListener;
+ }
+
+ @Override
+ public void registerDataSetObserver(DataSetObserver observer) {
+ mAdapter.registerDataSetObserver(observer);
+ }
+
+ @Override
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ mAdapter.unregisterDataSetObserver(observer);
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return mAdapter.areAllItemsEnabled();
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return mAdapter.isEnabled(position);
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return mAdapter.hasStableIds();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return mAdapter.getItemViewType(position);
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return mAdapter.getViewTypeCount();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return mAdapter.isEmpty();
+ }
+
+ @Override
+ public ListAdapter getWrappedAdapter() {
+ return mAdapter;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuCreator.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuCreator.java
new file mode 100644
index 0000000..5b6b3f6
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuCreator.java
@@ -0,0 +1,8 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public interface SwipeMenuCreator {
+ void create(SwipeMenu menu);
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuItem.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuItem.java
new file mode 100644
index 0000000..ca9630d
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuItem.java
@@ -0,0 +1,91 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public class SwipeMenuItem {
+
+ private int id;
+ private Context mContext;
+ private String title;
+ private Drawable icon;
+ private Drawable background;
+ private int titleColor;
+ private int titleSize;
+ private int width;
+
+ public SwipeMenuItem(Context context) {
+ mContext = context;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getTitleColor() {
+ return titleColor;
+ }
+
+ public int getTitleSize() {
+ return titleSize;
+ }
+
+ public void setTitleSize(int titleSize) {
+ this.titleSize = titleSize;
+ }
+
+ public void setTitleColor(int titleColor) {
+ this.titleColor = titleColor;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void setTitle(int resId) {
+ setTitle(mContext.getString(resId));
+ }
+
+ public Drawable getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Drawable icon) {
+ this.icon = icon;
+ }
+
+ public void setIcon(int resId) {
+ this.icon = mContext.getResources().getDrawable(resId);
+ }
+
+ public Drawable getBackground() {
+ return background;
+ }
+
+ public void setBackground(Drawable background) {
+ this.background = background;
+ }
+
+ public void setBackground(int resId) {
+ this.background = mContext.getResources().getDrawable(resId);
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuLayout.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuLayout.java
new file mode 100644
index 0000000..479e8f1
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuLayout.java
@@ -0,0 +1,344 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import android.content.Context;
+import android.support.v4.view.GestureDetectorCompat;
+import android.support.v4.widget.ScrollerCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.GestureDetector.OnGestureListener;
+import android.view.GestureDetector.SimpleOnGestureListener;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.widget.AbsListView;
+import android.widget.FrameLayout;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public class SwipeMenuLayout extends FrameLayout {
+
+ private static final int CONTENT_VIEW_ID = 1;
+ private static final int MENU_VIEW_ID = 2;
+
+ private static final int STATE_CLOSE = 0;
+ private static final int STATE_OPEN = 1;
+
+ private int mSwipeDirection;
+
+ private View mContentView;
+ private SwipeMenuView mMenuView;
+ private int mDownX;
+ private int state = STATE_CLOSE;
+ private GestureDetectorCompat mGestureDetector;
+ private OnGestureListener mGestureListener;
+ private boolean isFling;
+ private int MIN_FLING = dp2px(15);
+ private int MAX_VELOCITYX = -dp2px(500);
+ private ScrollerCompat mOpenScroller;
+ private ScrollerCompat mCloseScroller;
+ private int mBaseX;
+ private int position;
+ private Interpolator mCloseInterpolator;
+ private Interpolator mOpenInterpolator;
+
+ private boolean mSwipEnable = true;
+
+ public SwipeMenuLayout(View contentView, SwipeMenuView menuView) {
+ this(contentView, menuView, null, null);
+ }
+
+ public SwipeMenuLayout(View contentView, SwipeMenuView menuView,
+ Interpolator closeInterpolator, Interpolator openInterpolator) {
+ super(contentView.getContext());
+ mCloseInterpolator = closeInterpolator;
+ mOpenInterpolator = openInterpolator;
+ mContentView = contentView;
+ mMenuView = menuView;
+ mMenuView.setLayout(this);
+ init();
+ }
+
+ // private SwipeMenuLayout(Context context, AttributeSet attrs, int
+ // defStyle) {
+ // super(context, attrs, defStyle);
+ // }
+
+ private SwipeMenuLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ private SwipeMenuLayout(Context context) {
+ super(context);
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(int position) {
+ this.position = position;
+ mMenuView.setPosition(position);
+ }
+
+ public void setSwipeDirection(int swipeDirection) {
+ mSwipeDirection = swipeDirection;
+ }
+
+ private void init() {
+ setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.WRAP_CONTENT));
+ mGestureListener = new SimpleOnGestureListener() {
+ @Override
+ public boolean onDown(MotionEvent e) {
+ isFling = false;
+ return true;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2,
+ float velocityX, float velocityY) {
+ // TODO
+ if (Math.abs(e1.getX() - e2.getX()) > MIN_FLING
+ && velocityX < MAX_VELOCITYX) {
+ isFling = true;
+ }
+ // Log.i("byz", MAX_VELOCITYX + ", velocityX = " + velocityX);
+ return super.onFling(e1, e2, velocityX, velocityY);
+ }
+ };
+ mGestureDetector = new GestureDetectorCompat(getContext(),
+ mGestureListener);
+
+ // mScroller = ScrollerCompat.create(getContext(), new
+ // BounceInterpolator());
+ if (mCloseInterpolator != null) {
+ mCloseScroller = ScrollerCompat.create(getContext(),
+ mCloseInterpolator);
+ } else {
+ mCloseScroller = ScrollerCompat.create(getContext());
+ }
+ if (mOpenInterpolator != null) {
+ mOpenScroller = ScrollerCompat.create(getContext(),
+ mOpenInterpolator);
+ } else {
+ mOpenScroller = ScrollerCompat.create(getContext());
+ }
+
+ LayoutParams contentParams = new LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ mContentView.setLayoutParams(contentParams);
+ if (mContentView.getId() < 1) {
+ mContentView.setId(CONTENT_VIEW_ID);
+ }
+
+ mMenuView.setId(MENU_VIEW_ID);
+ mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+
+ addView(mContentView);
+ addView(mMenuView);
+
+ // if (mContentView.getBackground() == null) {
+ // mContentView.setBackgroundColor(Color.WHITE);
+ // }
+
+ // in android 2.x, MenuView height is MATCH_PARENT is not work.
+ // getViewTreeObserver().addOnGlobalLayoutListener(
+ // new OnGlobalLayoutListener() {
+ // @Override
+ // public void onGlobalLayout() {
+ // setMenuHeight(mContentView.getHeight());
+ // // getViewTreeObserver()
+ // // .removeGlobalOnLayoutListener(this);
+ // }
+ // });
+
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ }
+
+ public boolean onSwipe(MotionEvent event) {
+ mGestureDetector.onTouchEvent(event);
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mDownX = (int) event.getX();
+ isFling = false;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ // Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX());
+ int dis = (int) (mDownX - event.getX());
+ if (state == STATE_OPEN) {
+ dis += mMenuView.getWidth()*mSwipeDirection;;
+ }
+ swipe(dis);
+ break;
+ case MotionEvent.ACTION_UP:
+ if ((isFling || Math.abs(mDownX - event.getX()) > (mMenuView.getWidth() / 2)) &&
+ Math.signum(mDownX - event.getX()) == mSwipeDirection) {
+ // open
+ smoothOpenMenu();
+ } else {
+ // close
+ smoothCloseMenu();
+ return false;
+ }
+ break;
+ }
+ return true;
+ }
+
+ public boolean isOpen() {
+ return state == STATE_OPEN;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return super.onTouchEvent(event);
+ }
+
+ private void swipe(int dis) {
+ if(!mSwipEnable){
+ return ;
+ }
+ if (Math.signum(dis) != mSwipeDirection) {
+ dis = 0;
+ } else if (Math.abs(dis) > mMenuView.getWidth()) {
+ dis = mMenuView.getWidth()*mSwipeDirection;
+ }
+
+ mContentView.layout(-dis, mContentView.getTop(),
+ mContentView.getWidth() -dis, getMeasuredHeight());
+
+ if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+
+ mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
+ mContentView.getWidth() + mMenuView.getWidth() - dis,
+ mMenuView.getBottom());
+ } else {
+ mMenuView.layout(-mMenuView.getWidth() - dis, mMenuView.getTop(),
+ - dis, mMenuView.getBottom());
+ }
+ }
+
+ @Override
+ public void computeScroll() {
+ if (state == STATE_OPEN) {
+ if (mOpenScroller.computeScrollOffset()) {
+ swipe(mOpenScroller.getCurrX()*mSwipeDirection);
+ postInvalidate();
+ }
+ } else {
+ if (mCloseScroller.computeScrollOffset()) {
+ swipe((mBaseX - mCloseScroller.getCurrX())*mSwipeDirection);
+ postInvalidate();
+ }
+ }
+ }
+
+ public void smoothCloseMenu() {
+ state = STATE_CLOSE;
+ if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+ mBaseX = -mContentView.getLeft();
+ mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350);
+ } else {
+ mBaseX = mMenuView.getRight();
+ mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350);
+ }
+ postInvalidate();
+ }
+
+ public void smoothOpenMenu() {
+ if(!mSwipEnable){
+ return ;
+ }
+ state = STATE_OPEN;
+ if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+ mOpenScroller.startScroll(-mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350);
+ } else {
+ mOpenScroller.startScroll(mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350);
+ }
+ postInvalidate();
+ }
+
+ public void closeMenu() {
+ if (mCloseScroller.computeScrollOffset()) {
+ mCloseScroller.abortAnimation();
+ }
+ if (state == STATE_OPEN) {
+ state = STATE_CLOSE;
+ swipe(0);
+ }
+ }
+
+ public void openMenu() {
+ if(!mSwipEnable){
+ return ;
+ }
+ if (state == STATE_CLOSE) {
+ state = STATE_OPEN;
+ swipe(mMenuView.getWidth() * mSwipeDirection);
+ }
+ }
+
+ public View getContentView() {
+ return mContentView;
+ }
+
+ public SwipeMenuView getMenuView() {
+ return mMenuView;
+ }
+
+ private int dp2px(int dp) {
+ return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+ getContext().getResources().getDisplayMetrics());
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mMenuView.measure(MeasureSpec.makeMeasureSpec(0,
+ MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(
+ getMeasuredHeight(), MeasureSpec.EXACTLY));
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ mContentView.layout(0, 0, getMeasuredWidth(),
+ mContentView.getMeasuredHeight());
+ if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+ mMenuView.layout(getMeasuredWidth(), 0,
+ getMeasuredWidth() + mMenuView.getMeasuredWidth(),
+ mContentView.getMeasuredHeight());
+ } else {
+ mMenuView.layout(-mMenuView.getMeasuredWidth(), 0,
+ 0, mContentView.getMeasuredHeight());
+ }
+ }
+
+ public void setMenuHeight(int measuredHeight) {
+ Log.i("byz", "pos = " + position + ", height = " + measuredHeight);
+ LayoutParams params = (LayoutParams) mMenuView.getLayoutParams();
+ if (params.height != measuredHeight) {
+ params.height = measuredHeight;
+ mMenuView.setLayoutParams(mMenuView.getLayoutParams());
+ }
+ }
+
+ public void setSwipEnable(boolean swipEnable){
+ mSwipEnable = swipEnable;
+ }
+
+ public boolean getSwipEnable(){
+ return mSwipEnable;
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuListView.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuListView.java
new file mode 100644
index 0000000..41f1be2
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuListView.java
@@ -0,0 +1,339 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import android.content.Context;
+import android.support.v4.view.MotionEventCompat;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public class SwipeMenuListView extends ListView {
+
+ private static final int TOUCH_STATE_NONE = 0;
+ private static final int TOUCH_STATE_X = 1;
+ private static final int TOUCH_STATE_Y = 2;
+
+ public static final int DIRECTION_LEFT = 1;
+ public static final int DIRECTION_RIGHT = -1;
+ private int mDirection = 1;//swipe from right to left by default
+
+ private int MAX_Y = 5;
+ private int MAX_X = 3;
+ private float mDownX;
+ private float mDownY;
+ private int mTouchState;
+ private int mTouchPosition;
+ private SwipeMenuLayout mTouchView;
+ private OnSwipeListener mOnSwipeListener;
+
+ private SwipeMenuCreator mMenuCreator;
+ private OnMenuItemClickListener mOnMenuItemClickListener;
+ private OnMenuStateChangeListener mOnMenuStateChangeListener;
+ private Interpolator mCloseInterpolator;
+ private Interpolator mOpenInterpolator;
+
+ public SwipeMenuListView(Context context) {
+ super(context);
+ init();
+ }
+
+ public SwipeMenuListView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ public SwipeMenuListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+ MAX_X = dp2px(MAX_X);
+ MAX_Y = dp2px(MAX_Y);
+ mTouchState = TOUCH_STATE_NONE;
+ }
+
+ @Override
+ public void setAdapter(ListAdapter adapter) {
+ super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) {
+ @Override
+ public void createMenu(SwipeMenu menu) {
+ if (mMenuCreator != null) {
+ mMenuCreator.create(menu);
+ }
+ }
+
+ @Override
+ public void onItemClick(SwipeMenuView view, SwipeMenu menu,
+ int index) {
+ boolean flag = false;
+ if (mOnMenuItemClickListener != null) {
+ flag = mOnMenuItemClickListener.onMenuItemClick(
+ view.getPosition(), menu, index);
+ }
+ if (mTouchView != null && !flag) {
+ mTouchView.smoothCloseMenu();
+ }
+ }
+ });
+ }
+
+ public void setCloseInterpolator(Interpolator interpolator) {
+ mCloseInterpolator = interpolator;
+ }
+
+ public void setOpenInterpolator(Interpolator interpolator) {
+ mOpenInterpolator = interpolator;
+ }
+
+ public Interpolator getOpenInterpolator() {
+ return mOpenInterpolator;
+ }
+
+ public Interpolator getCloseInterpolator() {
+ return mCloseInterpolator;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ //在拦截处处理,在滑动设置了点击事件的地方也能swip,点击时又不能影响原来的点击事件
+ int action = ev.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mDownX = ev.getX();
+ mDownY = ev.getY();
+ boolean handled = super.onInterceptTouchEvent(ev);
+ mTouchState = TOUCH_STATE_NONE;
+ mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
+ View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
+
+ //只在空的时候赋值 以免每次触摸都赋值,会有多个open状态
+ if (view instanceof SwipeMenuLayout) {
+ //如果有打开了 就拦截.
+ if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
+ return true;
+ }
+ mTouchView = (SwipeMenuLayout) view;
+ mTouchView.setSwipeDirection(mDirection);
+ }
+ //如果摸在另外个view
+ if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
+ handled = true;
+ }
+
+ if (mTouchView != null) {
+ mTouchView.onSwipe(ev);
+ }
+ return handled;
+ case MotionEvent.ACTION_MOVE:
+ float dy = Math.abs((ev.getY() - mDownY));
+ float dx = Math.abs((ev.getX() - mDownX));
+ if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
+ //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
+ if (mTouchState == TOUCH_STATE_NONE) {
+ if (Math.abs(dy) > MAX_Y) {
+ mTouchState = TOUCH_STATE_Y;
+ } else if (dx > MAX_X) {
+ mTouchState = TOUCH_STATE_X;
+ if (mOnSwipeListener != null) {
+ mOnSwipeListener.onSwipeStart(mTouchPosition);
+ }
+ }
+ }
+ return true;
+ }
+ }
+ return super.onInterceptTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
+ return super.onTouchEvent(ev);
+ int action = ev.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ int oldPos = mTouchPosition;
+ mDownX = ev.getX();
+ mDownY = ev.getY();
+ mTouchState = TOUCH_STATE_NONE;
+
+ mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
+
+ if (mTouchPosition == oldPos && mTouchView != null
+ && mTouchView.isOpen()) {
+ mTouchState = TOUCH_STATE_X;
+ mTouchView.onSwipe(ev);
+ return true;
+ }
+
+ View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
+
+ if (mTouchView != null && mTouchView.isOpen()) {
+ mTouchView.smoothCloseMenu();
+ mTouchView = null;
+ // return super.onTouchEvent(ev);
+ // try to cancel the touch event
+ MotionEvent cancelEvent = MotionEvent.obtain(ev);
+ cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
+ onTouchEvent(cancelEvent);
+ if (mOnMenuStateChangeListener != null) {
+ mOnMenuStateChangeListener.onMenuClose(oldPos);
+ }
+ return true;
+ }
+ if (view instanceof SwipeMenuLayout) {
+ mTouchView = (SwipeMenuLayout) view;
+ mTouchView.setSwipeDirection(mDirection);
+ }
+ if (mTouchView != null) {
+ mTouchView.onSwipe(ev);
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ //有些可能有header,要减去header再判断
+ mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount();
+ //如果滑动了一下没完全展现,就收回去,这时候mTouchView已经赋值,再滑动另外一个不可以swip的view
+ //会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view
+ if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) {
+ break;
+ }
+ float dy = Math.abs((ev.getY() - mDownY));
+ float dx = Math.abs((ev.getX() - mDownX));
+ if (mTouchState == TOUCH_STATE_X) {
+ if (mTouchView != null) {
+ mTouchView.onSwipe(ev);
+ }
+ getSelector().setState(new int[]{0});
+ ev.setAction(MotionEvent.ACTION_CANCEL);
+ super.onTouchEvent(ev);
+ return true;
+ } else if (mTouchState == TOUCH_STATE_NONE) {
+ if (Math.abs(dy) > MAX_Y) {
+ mTouchState = TOUCH_STATE_Y;
+ } else if (dx > MAX_X) {
+ mTouchState = TOUCH_STATE_X;
+ if (mOnSwipeListener != null) {
+ mOnSwipeListener.onSwipeStart(mTouchPosition);
+ }
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mTouchState == TOUCH_STATE_X) {
+ if (mTouchView != null) {
+ boolean isBeforeOpen = mTouchView.isOpen();
+ mTouchView.onSwipe(ev);
+ boolean isAfterOpen = mTouchView.isOpen();
+ if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) {
+ if (isAfterOpen) {
+ mOnMenuStateChangeListener.onMenuOpen(mTouchPosition);
+ } else {
+ mOnMenuStateChangeListener.onMenuClose(mTouchPosition);
+ }
+ }
+ if (!isAfterOpen) {
+ mTouchPosition = -1;
+ mTouchView = null;
+ }
+ }
+ if (mOnSwipeListener != null) {
+ mOnSwipeListener.onSwipeEnd(mTouchPosition);
+ }
+ ev.setAction(MotionEvent.ACTION_CANCEL);
+ super.onTouchEvent(ev);
+ return true;
+ }
+ break;
+ }
+ return super.onTouchEvent(ev);
+ }
+
+ public void smoothOpenMenu(int position) {
+ if (position >= getFirstVisiblePosition()
+ && position <= getLastVisiblePosition()) {
+ View view = getChildAt(position - getFirstVisiblePosition());
+ if (view instanceof SwipeMenuLayout) {
+ mTouchPosition = position;
+ if (mTouchView != null && mTouchView.isOpen()) {
+ mTouchView.smoothCloseMenu();
+ }
+ mTouchView = (SwipeMenuLayout) view;
+ mTouchView.setSwipeDirection(mDirection);
+ mTouchView.smoothOpenMenu();
+ }
+ }
+ }
+
+ public void smoothCloseMenu(){
+ if (mTouchView != null && mTouchView.isOpen()) {
+ mTouchView.smoothCloseMenu();
+ }
+ }
+
+ private int dp2px(int dp) {
+ return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+ getContext().getResources().getDisplayMetrics());
+ }
+
+ public void setMenuCreator(SwipeMenuCreator menuCreator) {
+ this.mMenuCreator = menuCreator;
+ }
+
+ public void setOnMenuItemClickListener(
+ OnMenuItemClickListener onMenuItemClickListener) {
+ this.mOnMenuItemClickListener = onMenuItemClickListener;
+ }
+
+ public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
+ this.mOnSwipeListener = onSwipeListener;
+ }
+
+ public void setOnMenuStateChangeListener(OnMenuStateChangeListener onMenuStateChangeListener) {
+ mOnMenuStateChangeListener = onMenuStateChangeListener;
+ }
+
+ public static interface OnMenuItemClickListener {
+ boolean onMenuItemClick(int position, SwipeMenu menu, int index);
+ }
+
+ public static interface OnSwipeListener {
+ void onSwipeStart(int position);
+
+ void onSwipeEnd(int position);
+ }
+
+ public static interface OnMenuStateChangeListener {
+ void onMenuOpen(int position);
+
+ void onMenuClose(int position);
+ }
+
+ public void setSwipeDirection(int direction) {
+ mDirection = direction;
+ }
+
+ /**
+ * 判断点击事件是否在某个view内
+ *
+ * @param view
+ * @param ev
+ * @return
+ */
+ public static boolean inRangeOfView(View view, MotionEvent ev) {
+ int[] location = new int[2];
+ view.getLocationOnScreen(location);
+ int x = location[0];
+ int y = location[1];
+ if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) {
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuView.java b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuView.java
new file mode 100644
index 0000000..6d9d1ea
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/presenter/adapters/helper/items/swipe/SwipeMenuView.java
@@ -0,0 +1,100 @@
+package com.hikapro.backpack.presenter.adapters.helper.items.swipe;
+
+import java.util.List;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Created by tariel on 18/06/16.
+ */
+public class SwipeMenuView extends LinearLayout implements OnClickListener {
+
+ private SwipeMenuListView mListView;
+ private SwipeMenuLayout mLayout;
+ private SwipeMenu mMenu;
+ private OnSwipeItemClickListener onItemClickListener;
+ private int position;
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(int position) {
+ this.position = position;
+ }
+
+ public SwipeMenuView(SwipeMenu menu, SwipeMenuListView listView) {
+ super(menu.getContext());
+ mListView = listView;
+ mMenu = menu;
+ List items = menu.getMenuItems();
+ int id = 0;
+ for (SwipeMenuItem item : items) {
+ addItem(item, id++);
+ }
+ }
+
+ private void addItem(SwipeMenuItem item, int id) {
+ LayoutParams params = new LayoutParams(item.getWidth(),
+ LayoutParams.MATCH_PARENT);
+ LinearLayout parent = new LinearLayout(getContext());
+ parent.setId(id);
+ parent.setGravity(Gravity.CENTER);
+ parent.setOrientation(LinearLayout.VERTICAL);
+ parent.setLayoutParams(params);
+ parent.setBackgroundDrawable(item.getBackground());
+ parent.setOnClickListener(this);
+ addView(parent);
+
+ if (item.getIcon() != null) {
+ parent.addView(createIcon(item));
+ }
+ if (!TextUtils.isEmpty(item.getTitle())) {
+ parent.addView(createTitle(item));
+ }
+
+ }
+
+ private ImageView createIcon(SwipeMenuItem item) {
+ ImageView iv = new ImageView(getContext());
+ iv.setImageDrawable(item.getIcon());
+ return iv;
+ }
+
+ private TextView createTitle(SwipeMenuItem item) {
+ TextView tv = new TextView(getContext());
+ tv.setText(item.getTitle());
+ tv.setGravity(Gravity.CENTER);
+ tv.setTextSize(item.getTitleSize());
+ tv.setTextColor(item.getTitleColor());
+ return tv;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (onItemClickListener != null && mLayout.isOpen()) {
+ onItemClickListener.onItemClick(this, mMenu, v.getId());
+ }
+ }
+
+ public OnSwipeItemClickListener getOnSwipeItemClickListener() {
+ return onItemClickListener;
+ }
+
+ public void setOnSwipeItemClickListener(OnSwipeItemClickListener onItemClickListener) {
+ this.onItemClickListener = onItemClickListener;
+ }
+
+ public void setLayout(SwipeMenuLayout mLayout) {
+ this.mLayout = mLayout;
+ }
+
+ public static interface OnSwipeItemClickListener {
+ void onItemClick(SwipeMenuView view, SwipeMenu menu, int index);
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/view/View.java b/app/src/main/java/com/hikapro/backpack/view/View.java
index fae4e55..a29536b 100644
--- a/app/src/main/java/com/hikapro/backpack/view/View.java
+++ b/app/src/main/java/com/hikapro/backpack/view/View.java
@@ -35,11 +35,23 @@ public interface View {
Item getItem();
}
+ interface Share extends Base {
+ void setPresenter(Presenter.Share presenter);
+ }
+
+ interface Add extends Base {
+ void setPresenter(Presenter.Add presenter);
+ void setNewItem(Item item);
+ Set getSet();
+ }
+
interface ActivityCallback {
void startSetListFragment();
void startItemListFragment(Set set);
void startPackedListFragment(Set set);
void startItemDetailFragment(Item item);
+ void startShareFragment(int setId);
+ void startAddFragment(Set set);
}
}
diff --git a/app/src/main/java/com/hikapro/backpack/view/fragments/AddFragment.java b/app/src/main/java/com/hikapro/backpack/view/fragments/AddFragment.java
new file mode 100644
index 0000000..8d79497
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/view/fragments/AddFragment.java
@@ -0,0 +1,160 @@
+package com.hikapro.backpack.view.fragments;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.SearchView;
+
+import com.hikapro.backpack.R;
+import com.hikapro.backpack.model.entities.Item;
+import com.hikapro.backpack.model.entities.Set;
+import com.hikapro.backpack.presenter.Presenter;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class AddFragment extends Fragment implements com.hikapro.backpack.view.View.Add {
+
+ protected static final String BUNDLE_SET_KEY = "BUNDLE_SET_KEY";
+ private Presenter.Add presenter;
+ private com.hikapro.backpack.view.View.ActivityCallback activityCallback;
+
+ public static AddFragment construct() {
+ return new AddFragment();
+ }
+
+ public static AddFragment newFromSet(Set set) {
+ AddFragment ret = AddFragment.construct();
+ Bundle args = new Bundle();
+ args.putSerializable(BUNDLE_SET_KEY, set);
+ ret.setArguments(args);
+ return ret;
+ }
+
+
+ public AddFragment() {
+ // Required empty public constructor
+ }
+
+ // life cycle -->
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ try {
+ activityCallback = (com.hikapro.backpack.view.View.ActivityCallback) context;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(context.toString()
+ + " must implement activityCallback");
+ }
+ }
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ activityCallback = (com.hikapro.backpack.view.View.ActivityCallback) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString()
+ + " must implement activityCallback");
+ }
+ Log.i(this.toString(), " onAttach");
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // setHasOptionsMenu(true);
+ Log.i(this.toString(), " onCreate");
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ presenter.setView(this);
+ View view = presenter.onCreateView(inflater, container, savedInstanceState);
+ Log.i(this.toString(), " onCreateView");
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ Log.i(this.toString(), " onActivityCreated");
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ Log.i(this.toString(), " onStart");
+ }
+ @Override
+ public void onResume() {
+ super.onResume();
+ Log.i(this.toString(), " onResume");
+ }
+ @Override
+ public void onStop() {
+ super.onStop();
+ Log.i(this.toString(), " onStop");
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ presenter.onDestroy(true); // TODO isChangingConfigurations
+ Log.i(this.toString(), " onDestroyView");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ presenter.onDestroy(false); // TODO isChangingConfigurations
+ Log.i(this.toString(), " onDestroy");
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ Log.i(this.toString(), " onDetach");
+ }
+
+ @Override
+ public Context getAppContext() {
+ return this.getActivity().getApplicationContext();
+ }
+
+ @Override
+ public Context getActivityContext() {
+ return this.getActivity();
+ }
+
+ @Override
+ public void setPresenter(Presenter.Add presenter) {
+ this.presenter = presenter;
+ }
+
+ @Override
+ public void setNewItem(Item item) {
+
+ }
+
+ public Set getSet() {
+ return (Set) getArguments().getSerializable(BUNDLE_SET_KEY);
+ }
+/*
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.menu_add, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+*/
+}
diff --git a/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java b/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java
index 1ebd3f4..7a8b305 100644
--- a/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java
+++ b/app/src/main/java/com/hikapro/backpack/view/fragments/ItemListFragment.java
@@ -5,6 +5,7 @@ import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
+import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -71,18 +72,25 @@ public class ItemListFragment extends Fragment implements com.hikapro.backpack.v
public boolean onOptionsItemSelected(MenuItem item) {
boolean ret;
switch (item.getItemId()) {
+ case android.R.id.home:
+ this.getFragmentManager().popBackStack();
+ ret = true;
+ break;
case R.id.action_share :
- Toast.makeText(getActivityContext(), "Share", Toast.LENGTH_SHORT).show();
+ activityCallback.startShareFragment(getSet().getId());
ret = true;
break;
case R.id.action_unpack_my_bag :
- Toast.makeText(getActivityContext(), "Unpack my bag", Toast.LENGTH_SHORT).show();
+ presenter.unpack(getSet().getId());
ret = true;
break;
case R.id.action_restore_to_default :
- Toast.makeText(getActivityContext(), "Restore to default", Toast.LENGTH_SHORT).show();
+ presenter.restore(getSet().getId());
ret = true;
break;
+ case R.id.action_add :
+ activityCallback.startAddFragment(getSet());
+ ret = true;
default:
ret = super.onOptionsItemSelected(item);
}
@@ -175,7 +183,7 @@ public class ItemListFragment extends Fragment implements com.hikapro.backpack.v
@Override
public void showItemDetail(Item item) {
activityCallback.startItemDetailFragment(item);
- }
+ }//TODO del?
@Override
public void showPackedItems(Set set) {
diff --git a/app/src/main/java/com/hikapro/backpack/view/fragments/ShareFragment.java b/app/src/main/java/com/hikapro/backpack/view/fragments/ShareFragment.java
new file mode 100644
index 0000000..4d59cbb
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/view/fragments/ShareFragment.java
@@ -0,0 +1,79 @@
+package com.hikapro.backpack.view.fragments;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.hikapro.backpack.R;
+import com.hikapro.backpack.presenter.Presenter;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class ShareFragment extends Fragment implements com.hikapro.backpack.view.View.Share {
+
+ private Presenter.Share presenter;
+ private com.hikapro.backpack.view.View.ActivityCallback activityCallback;
+
+
+ public ShareFragment() {
+ // Required empty public constructor
+ }
+
+ public static ShareFragment construct() {
+ ShareFragment ret = new ShareFragment();
+ return ret;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ try {
+ activityCallback = (com.hikapro.backpack.view.View.ActivityCallback) context;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(context.toString()
+ + " must implement activityCallback");
+ }
+ }
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ activityCallback = (com.hikapro.backpack.view.View.ActivityCallback) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString()
+ + " must implement activityCallback");
+ }
+ Log.i(this.toString(), "onAttach");
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ presenter.setView(this);
+ View v = presenter.onCreateView(inflater, container, savedInstanceState);
+ return v;
+ }
+
+ @Override
+ public void setPresenter(Presenter.Share presenter) {
+ this.presenter = presenter;
+ }
+
+ @Override
+ public Context getAppContext() {
+ return this.getActivity().getApplicationContext();
+ }
+
+ @Override
+ public Context getActivityContext() {
+ return this.getActivity();
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/view/recycler/AddItemViewHolder.java b/app/src/main/java/com/hikapro/backpack/view/recycler/AddItemViewHolder.java
new file mode 100644
index 0000000..a36abe5
--- /dev/null
+++ b/app/src/main/java/com/hikapro/backpack/view/recycler/AddItemViewHolder.java
@@ -0,0 +1,32 @@
+package com.hikapro.backpack.view.recycler;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.hikapro.backpack.R;
+
+/**
+ * Created by tariel on 18/05/16.
+ */
+public class AddItemViewHolder extends RecyclerView.ViewHolder {
+
+ public TextView name;
+ public TextView category;
+ public TextView alreadyInList;
+ public RelativeLayout item;
+
+ public AddItemViewHolder(View itemView) {
+ super(itemView);
+ setupViews(itemView);
+ }
+
+ private void setupViews(View view) {
+ item = (RelativeLayout) view.findViewById(R.id.add_item_item);
+ name = (TextView) item.findViewById(R.id.add_item_name);
+ category = (TextView) item.findViewById(R.id.add_item_category);
+ alreadyInList = (TextView) item.findViewById(R.id.add_already_in_list);
+ }
+}
diff --git a/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java b/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java
index 3b1cb90..d851e0f 100644
--- a/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java
+++ b/app/src/main/java/com/hikapro/backpack/view/recycler/ItemViewHolder.java
@@ -2,6 +2,7 @@ package com.hikapro.backpack.view.recycler;
import android.support.v7.widget.RecyclerView;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
@@ -16,8 +17,10 @@ public class ItemViewHolder extends RecyclerView.ViewHolder {
public int id;
public CheckBox checkBox;
- public Button undoButton;
+ public Button leaveAtHomeButton;
+ public Button deleteButton;
public ImageButton infoButton;
+ public ViewGroup swipeGroup;
public ItemViewHolder(View v) {
super(v);
@@ -25,9 +28,11 @@ public class ItemViewHolder extends RecyclerView.ViewHolder {
}
private void setupViews(View view) {
- infoButton = (ImageButton) view.findViewById(R.id.info_button);
- checkBox = (CheckBox) view.findViewById(R.id.item_checkbox);
- undoButton = (Button) view.findViewById(R.id.undo_button);
+ infoButton = (ImageButton) view.findViewById(R.id.info_button);
+ checkBox = (CheckBox) view.findViewById(R.id.item_checkbox);
+ leaveAtHomeButton = (Button) view.findViewById(R.id.leave_at_home_button);
+ deleteButton = (Button) view.findViewById(R.id.delete_button);
+ swipeGroup = (ViewGroup) view.findViewById((R.id.swipe_container));
}
}
diff --git a/app/src/main/res/drawable/facebook_48.png b/app/src/main/res/drawable/facebook_48.png
new file mode 100644
index 0000000..eb0a202
Binary files /dev/null and b/app/src/main/res/drawable/facebook_48.png differ
diff --git a/app/src/main/res/drawable/pic.png b/app/src/main/res/drawable/pic.png
new file mode 100644
index 0000000..7ab8b3a
Binary files /dev/null and b/app/src/main/res/drawable/pic.png differ
diff --git a/app/src/main/res/drawable/search_divider.xml b/app/src/main/res/drawable/search_divider.xml
new file mode 100644
index 0000000..d70309e
--- /dev/null
+++ b/app/src/main/res/drawable/search_divider.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/twitter_48.png b/app/src/main/res/drawable/twitter_48.png
new file mode 100644
index 0000000..c3e985b
Binary files /dev/null and b/app/src/main/res/drawable/twitter_48.png differ
diff --git a/app/src/main/res/layout/add_cust_actionbar.xml b/app/src/main/res/layout/add_cust_actionbar.xml
new file mode 100644
index 0000000..2f6a61e
--- /dev/null
+++ b/app/src/main/res/layout/add_cust_actionbar.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/category_button.xml b/app/src/main/res/layout/category_button.xml
new file mode 100644
index 0000000..28f89e2
--- /dev/null
+++ b/app/src/main/res/layout/category_button.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/divider.xml b/app/src/main/res/layout/divider.xml
new file mode 100644
index 0000000..3509b84
--- /dev/null
+++ b/app/src/main/res/layout/divider.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/footer.xml b/app/src/main/res/layout/footer.xml
index d9885a0..24b5c5a 100644
--- a/app/src/main/res/layout/footer.xml
+++ b/app/src/main/res/layout/footer.xml
@@ -6,21 +6,19 @@
android:orientation="vertical"
android:animateLayoutChanges="true"
android:id="@+id/item_list_footer"
- android:background="#33D3D3D3"
+ android:background="@color/colorFooterbackground"
android:layout_gravity="bottom"
>
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_add.xml b/app/src/main/res/layout/fragment_add.xml
new file mode 100644
index 0000000..93cd3a5
--- /dev/null
+++ b/app/src/main/res/layout/fragment_add.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_item_detail.xml b/app/src/main/res/layout/fragment_item_detail.xml
index 7c72fe6..8ed0fe2 100644
--- a/app/src/main/res/layout/fragment_item_detail.xml
+++ b/app/src/main/res/layout/fragment_item_detail.xml
@@ -3,7 +3,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context="com.hikapro.backpack.view.fragments.ItemDetailFragment">
+ tools:context="com.hikapro.backpack.view.fragments.ItemDetailFragment"
+ android:background="@color/colorUiMainbackground">
-
-
-
diff --git a/app/src/main/res/layout/fragment_item_list.xml b/app/src/main/res/layout/fragment_item_list.xml
index 87c0787..f4da14b 100644
--- a/app/src/main/res/layout/fragment_item_list.xml
+++ b/app/src/main/res/layout/fragment_item_list.xml
@@ -8,7 +8,8 @@
+ android:orientation="vertical"
+ android:background="@color/colorUiMainbackground2">
+ android:background="@color/colorFooterbackground">
diff --git a/app/src/main/res/layout/fragment_packed_list.xml b/app/src/main/res/layout/fragment_packed_list.xml
index f238f47..fc10ed7 100644
--- a/app/src/main/res/layout/fragment_packed_list.xml
+++ b/app/src/main/res/layout/fragment_packed_list.xml
@@ -12,37 +12,36 @@
android:visibility="visible"
android:layout_alignParentTop="true"
android:animateLayoutChanges="true"
- android:background="#80968AA7">
+ android:background="@color/colorFooterbackground">
@@ -51,7 +50,8 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_alignParentBottom="true"
- android:layout_below="@id/item_list_header">
+ android:layout_below="@id/item_list_header"
+ android:background="@color/colorUiMainbackground2">
-
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_share.xml b/app/src/main/res/layout/fragment_share.xml
new file mode 100644
index 0000000..60c2b67
--- /dev/null
+++ b/app/src/main/res/layout/fragment_share.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_add.xml b/app/src/main/res/layout/item_add.xml
new file mode 100644
index 0000000..d5ff6d9
--- /dev/null
+++ b/app/src/main/res/layout/item_add.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_detail.xml b/app/src/main/res/layout/item_detail.xml
index d2a2002..567d66f 100644
--- a/app/src/main/res/layout/item_detail.xml
+++ b/app/src/main/res/layout/item_detail.xml
@@ -3,26 +3,27 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingBottom="16dp"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingTop="16dp">
+ android:paddingBottom="@dimen/margin_standard"
+ android:paddingLeft="@dimen/margin_standard"
+ android:paddingRight="@dimen/margin_standard"
+ android:paddingTop="@dimen/margin_standard">
+ android:layout_centerHorizontal="true"
+ android:textColor="@color/colorUiMainFont"/>
+ android:contentDescription="@string/cd_item_image"/>
+ android:textColor="@color/colorUiMainFont"
+ android:layout_marginTop="@dimen/margin_standard_plus_plus" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/set_card.xml b/app/src/main/res/layout/set_card.xml
index cb1b49a..bbfaf68 100644
--- a/app/src/main/res/layout/set_card.xml
+++ b/app/src/main/res/layout/set_card.xml
@@ -4,30 +4,32 @@
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view_set"
android:layout_width="match_parent"
- android:layout_height="200dp"
- android:layout_margin="5dp"
- card_view:cardCornerRadius="4dp">
+ android:layout_height="@dimen/card_height"
+ android:layout_margin="@dimen/margin_min"
+ card_view:cardCornerRadius="@dimen/card_corner_radius">
+ android:orientation="vertical"
+ android:background="@color/colorUiMainbackground2">
+ android:textColor="@color/colorUiMainFont"/>
+ android:layout_centerInParent="true"
+ android:textColor="@color/colorUiMainFont"/>
diff --git a/app/src/main/res/layout/test.xml b/app/src/main/res/layout/test.xml
new file mode 100644
index 0000000..c51b945
--- /dev/null
+++ b/app/src/main/res/layout/test.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/test_actionbar.xml b/app/src/main/res/layout/test_actionbar.xml
new file mode 100644
index 0000000..550f9e7
--- /dev/null
+++ b/app/src/main/res/layout/test_actionbar.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/test_actionbar2.xml b/app/src/main/res/layout/test_actionbar2.xml
new file mode 100644
index 0000000..c47b681
--- /dev/null
+++ b/app/src/main/res/layout/test_actionbar2.xml
@@ -0,0 +1,25 @@
+
+
+ >
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_header.xml b/app/src/main/res/layout/view_header.xml
index 115b9c6..f2d9673 100644
--- a/app/src/main/res/layout/view_header.xml
+++ b/app/src/main/res/layout/view_header.xml
@@ -7,10 +7,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
- android:background="#001F3F"
- android:textSize="28sp"
+ android:background="@color/colorStickyHeaderBackground"
+ android:textSize="@dimen/size_sticky_header"
android:textStyle="bold"
android:textColor="@android:color/white"
- tools:text="Animals starting with A"
android:id="@+id/header"
tools:context=".MainActivity"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_item.xml b/app/src/main/res/layout/view_item.xml
index 7c734d4..e591439 100644
--- a/app/src/main/res/layout/view_item.xml
+++ b/app/src/main/res/layout/view_item.xml
@@ -5,7 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="56dp"
+ android:layout_height="@dimen/item_height"
>
-
-
+ android:layout_height="match_parent"
+ android:layout_gravity="end|center_vertical">
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_add.xml b/app/src/main/res/menu/menu_add.xml
new file mode 100644
index 0000000..cba5472
--- /dev/null
+++ b/app/src/main/res/menu/menu_add.xml
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index 76d6fac..f6ac70d 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -2,7 +2,17 @@
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 3ab3e9c..64e2d8f 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -3,4 +3,10 @@
#3F51B5
#303F9F
#FF4081
+
+ #ff0d0d0d
+ #ffffffff
+ #99ffffff
+ #ff5ae117
+
diff --git a/app/src/main/res/values/colors_background.xml b/app/src/main/res/values/colors_background.xml
new file mode 100644
index 0000000..9afa84f
--- /dev/null
+++ b/app/src/main/res/values/colors_background.xml
@@ -0,0 +1,10 @@
+
+
+ #323232
+ #7F7F7F
+ #33D3D3D3
+ #76EE00
+ #76EE00
+ #001F3F
+ #76EE00
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors_font.xml b/app/src/main/res/values/colors_font.xml
new file mode 100644
index 0000000..1cecbea
--- /dev/null
+++ b/app/src/main/res/values/colors_font.xml
@@ -0,0 +1,5 @@
+
+
+ #FFFFFF
+ #00FF00
+
\ No newline at end of file
diff --git a/app/src/main/res/values/custom.xml b/app/src/main/res/values/custom.xml
new file mode 100644
index 0000000..615bfd2
--- /dev/null
+++ b/app/src/main/res/values/custom.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 361540a..cb89298 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -3,4 +3,15 @@
16dp
16dp
16dp
+ 16dp
+ 20dp
+ 25dp
+ 10dp
+ 5dp
+ 4dp
+ 200dp
+ 56dp
+ 8dp
+
+ 5dp
diff --git a/app/src/main/res/values/dimens_text.xml b/app/src/main/res/values/dimens_text.xml
new file mode 100644
index 0000000..a675670
--- /dev/null
+++ b/app/src/main/res/values/dimens_text.xml
@@ -0,0 +1,16 @@
+
+
+ 26sp
+ 28sp
+ 10sp
+ 14sp
+ 18sp
+ 16sp
+ 18sp
+
+
+ 14sp
+ 16sp
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 37b90c6..46334d7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,4 +2,34 @@
Back Pack
Packed
❭
+
+ 117849588616149
+
+ Show what\'s in my bag ↓
+ Choose item category:
+ Continue with my packing ↑
+ Already in List
+
+ UNPACK MY BAG
+ Share
+ undo
+ delete
+ leave at home
+ SAVE
+ CANCEL
+ OKAY
+
+ Facebook
+ Twitter
+ Item photo
+
+ Facebook
+ Twitter
+
+ No internet connection
+ Loading...
+
+ Restore To Default
+ Do you want to restore this list? Items you have added will be removed, while deleted items will be added back
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index f927816..6cd08a5 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -8,4 +8,27 @@
- @color/colorAccent
+
+
+
+
+
+