From 798ceff79f607ef68b004bed199da702a65799b7 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 15:15:50 +0400 Subject: [PATCH 1/9] Added a dividing line between the rows, reduced the height of categories/subcategories in the TreeView. --- app/src/main/res/layout/first_level_item.xml | 6 +++++- app/src/main/res/layout/second_level_item.xml | 6 +++++- app/src/main/res/layout/third_level_item.xml | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/first_level_item.xml b/app/src/main/res/layout/first_level_item.xml index 1d2da0f..bac1b57 100644 --- a/app/src/main/res/layout/first_level_item.xml +++ b/app/src/main/res/layout/first_level_item.xml @@ -1,9 +1,13 @@ + + + + + + Date: Mon, 25 Feb 2019 16:29:52 +0400 Subject: [PATCH 2/9] Made multicolored rows (gray-white), the text in SearchView is now white. --- .../ru/volgorobot/vrcatalog/MainContract.java | 1 + .../FirstLevelNodeViewBinder.java | 16 ++++++++++++++++ .../SecondLevelNodeViewBinder.java | 13 +++++++++++++ .../ThirdLevelNodeViewBinder.java | 13 +++++++++++++ .../volgorobot/vrcatalog/view/MainActivity.java | 5 +++++ .../vrcatalog/view/SearchableActivity.java | 5 +++++ app/src/main/res/layout/app_bar_main.xml | 2 +- app/src/main/res/layout/first_level_item.xml | 1 + app/src/main/res/layout/second_level_item.xml | 1 + app/src/main/res/layout/third_level_item.xml | 1 + app/src/main/res/values-v21/styles.xml | 4 +++- app/src/main/res/values/styles.xml | 3 --- 12 files changed, 60 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java index 991ebef..14c60b6 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java @@ -20,6 +20,7 @@ public interface MainContract { void onFailureAnswer(int errorCode); void refreshTree(); void startActivityByIntent(Intent intent); + int incTreeNodeIndex(); } interface Presenter { diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java index b3ddcad..7f55e80 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java @@ -1,8 +1,11 @@ package ru.volgorobot.vrcatalog.nodeViewBinders; import android.content.Context; +import android.graphics.Color; +import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import me.texy.treeview.TreeNode; @@ -15,12 +18,16 @@ import ru.volgorobot.vrcatalog.model.FirstLevelModel; public class FirstLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder { TextView textView; ImageView imageView; + RelativeLayout layout; ViewBinderPresenter viewBinderPresenter; + private MainContract.MainActivityView mView; public FirstLevelNodeViewBinder(View itemView, MainContract.MainActivityView mView, Context context) { super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); + layout = itemView.findViewById(R.id.parent_node_container_1); + this.mView = mView; viewBinderPresenter = new ViewBinderPresenter(mView, this, context); } @@ -32,6 +39,14 @@ public class FirstLevelNodeViewBinder extends BaseNodeViewBinder implements Main @Override public void bindView(TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + int index = mView.incTreeNodeIndex(); + treeNode.setIndex(index); + if(index % 2 == 1) { + layout.setBackgroundColor(Color.parseColor("#FFFFFF")); + } else { + layout.setBackgroundColor(Color.parseColor("#BABABA")); + } } @Override @@ -48,4 +63,5 @@ public class FirstLevelNodeViewBinder extends BaseNodeViewBinder implements Main public void rotateImageView() { imageView.animate().rotation(90).setDuration(200).start(); } + } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java index 9dacb60..04c114f 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java @@ -1,8 +1,10 @@ package ru.volgorobot.vrcatalog.nodeViewBinders; import android.content.Context; +import android.graphics.Color; import android.view.View; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import me.texy.treeview.TreeNode; @@ -15,6 +17,8 @@ import ru.volgorobot.vrcatalog.model.SecondLevelModel; public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder { TextView textView; ImageView imageView; + RelativeLayout layout; + private MainContract.MainActivityView mView; MainContract.LevelLoaderPresenter viewBinderPresenter; @@ -22,6 +26,8 @@ public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements Mai super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); + layout = itemView.findViewById(R.id.parent_node_container_2); + this.mView = mView; viewBinderPresenter = new ViewBinderPresenter(mView, this, context); } @@ -34,6 +40,13 @@ public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements Mai public void bindView(final TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + int index = mView.incTreeNodeIndex(); + treeNode.setIndex(index); + if(index % 2 == 1) { + layout.setBackgroundColor(Color.parseColor("#FFFFFF")); + } else { + layout.setBackgroundColor(Color.parseColor("#BABABA")); + } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java index f18c3e6..6d39968 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java @@ -1,7 +1,9 @@ package ru.volgorobot.vrcatalog.nodeViewBinders; import android.content.Context; +import android.graphics.Color; import android.view.View; +import android.widget.RelativeLayout; import android.widget.TextView; import me.texy.treeview.TreeNode; @@ -13,12 +15,16 @@ import ru.volgorobot.vrcatalog.model.ThirdLevelModel; public class ThirdLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder { TextView textView; + RelativeLayout layout; + private MainContract.MainActivityView mView; MainContract.LevelLoaderPresenter viewBinderPresenter; public ThirdLevelNodeViewBinder(View itemView, Context context, MainContract.MainActivityView mView) { super(itemView); viewBinderPresenter = new ViewBinderPresenter(mView, this, context); textView = itemView.findViewById(R.id.node_name_view); + layout = itemView.findViewById(R.id.parent_node_container_3); + this.mView = mView; } @Override @@ -29,6 +35,13 @@ public class ThirdLevelNodeViewBinder extends BaseNodeViewBinder implements Main @Override public void bindView(final TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); + int index = mView.incTreeNodeIndex(); + treeNode.setIndex(index); + if(index % 2 == 1) { + layout.setBackgroundColor(Color.parseColor("#FFFFFF")); + } else { + layout.setBackgroundColor(Color.parseColor("#BABABA")); + } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java index 3be56e8..d97ed36 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java @@ -45,6 +45,7 @@ public class MainActivity extends AppCompatActivity private ImageView mConnectionErrorImageView; private ViewGroup mTreeViewContainer; private TextView mErrorTextView; + private int treeNodeIndex; @Override protected void onCreate(Bundle savedInstanceState) { @@ -206,6 +207,10 @@ public class MainActivity extends AppCompatActivity return true; } + @Override + public int incTreeNodeIndex() { + return treeNodeIndex++; + } } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java index f411fcd..b6846bb 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java @@ -147,4 +147,9 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac } return super.onOptionsItemSelected(item); } + + @Override + public int incTreeNodeIndex() { + return 0; + } } diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml index 45fe46a..b87ac6b 100644 --- a/app/src/main/res/layout/app_bar_main.xml +++ b/app/src/main/res/layout/app_bar_main.xml @@ -16,7 +16,7 @@ android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" - android:theme="@style/CustomSearchStyle" + android:theme="@style/MainActivity" app:titleTextColor="@android:color/white" app:popupTheme="@style/AppTheme.PopupOverlay" /> diff --git a/app/src/main/res/layout/first_level_item.xml b/app/src/main/res/layout/first_level_item.xml index bac1b57..15caa90 100644 --- a/app/src/main/res/layout/first_level_item.xml +++ b/app/src/main/res/layout/first_level_item.xml @@ -1,5 +1,6 @@ diff --git a/app/src/main/res/layout/second_level_item.xml b/app/src/main/res/layout/second_level_item.xml index 213ff48..66db43e 100644 --- a/app/src/main/res/layout/second_level_item.xml +++ b/app/src/main/res/layout/second_level_item.xml @@ -1,5 +1,6 @@ @android:color/black @android:color/black - - - From 4d331326b04e05e66d706b427c6650d1058f93cb Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 16:32:12 +0400 Subject: [PATCH 3/9] Added check for empty list when deleting item in FavoritesActivity --- .../java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java index 290b069..a622f29 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java @@ -87,6 +87,7 @@ public class FavoritesActivity extends AppCompatActivity implements MainContract FavoritesListModel model = (FavoritesListModel) listView.getItemAtPosition(info.position); db.removeItem(model.getID()); updateListView(); + checkForEmptyContent(); } } return true; From 06f3df407c8555bf6870ebf722c227b77c94ac26 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 16:44:57 +0400 Subject: [PATCH 4/9] Made multicolored rows (gray-white) in SearchableView --- .../ru/volgorobot/vrcatalog/MainContract.java | 2 ++ .../additional/SearchableNodeViewFactory.java | 4 ++-- .../FirstLevelNodeViewBinder.java | 17 ++++++++++++++++- .../SecondLevelNodeViewBinder.java | 17 ++++++++++++++++- .../volgorobot/vrcatalog/view/MainActivity.java | 1 + .../vrcatalog/view/SearchableActivity.java | 3 ++- 6 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java index 14c60b6..e7d3303 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java @@ -68,6 +68,8 @@ public interface MainContract { void setTreeViewChildren(ArrayList children); void onFailureAnswer(int errorCode); void swipeLayoutSetRefreshing(boolean state); + int incTreeNodeIndex(); + } interface ItemPresenter { diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/SearchableNodeViewFactory.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/SearchableNodeViewFactory.java index baca273..04aab56 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/additional/SearchableNodeViewFactory.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/SearchableNodeViewFactory.java @@ -23,9 +23,9 @@ public class SearchableNodeViewFactory extends BaseNodeViewFactory { public BaseNodeViewBinder getNodeViewBinder(View view, int level) { switch (level) { case 0: - return new FirstLevelNodeViewBinder(view); + return new FirstLevelNodeViewBinder(view, mView); case 1: - return new SecondLevelNodeViewBinder(view); + return new SecondLevelNodeViewBinder(view, mView); case 2: return new ThirdLevelNodeViewBinder(view, context, mView); default: diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java index 674cc54..2f4000c 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java @@ -1,21 +1,28 @@ package ru.volgorobot.vrcatalog.searchNodeViewBinders; +import android.graphics.Color; import android.view.View; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import me.texy.treeview.TreeNode; import me.texy.treeview.base.BaseNodeViewBinder; +import ru.volgorobot.vrcatalog.MainContract; import ru.volgorobot.vrcatalog.R; public class FirstLevelNodeViewBinder extends BaseNodeViewBinder { TextView textView; ImageView imageView; + RelativeLayout layout; + MainContract.MainActivityView mView; - public FirstLevelNodeViewBinder(View itemView) { + public FirstLevelNodeViewBinder(View itemView, MainContract.MainActivityView mView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); + layout = itemView.findViewById(R.id.parent_node_container_1); + this.mView = mView; } @Override @@ -26,6 +33,14 @@ public class FirstLevelNodeViewBinder extends BaseNodeViewBinder { @Override public void bindView(TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + int index = mView.incTreeNodeIndex(); + treeNode.setIndex(index); + if(index % 2 == 1) { + layout.setBackgroundColor(Color.parseColor("#FFFFFF")); + } else { + layout.setBackgroundColor(Color.parseColor("#BABABA")); + } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java index 8718470..ebdf541 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java @@ -1,21 +1,28 @@ package ru.volgorobot.vrcatalog.searchNodeViewBinders; +import android.graphics.Color; import android.view.View; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import me.texy.treeview.TreeNode; import me.texy.treeview.base.BaseNodeViewBinder; +import ru.volgorobot.vrcatalog.MainContract; import ru.volgorobot.vrcatalog.R; public class SecondLevelNodeViewBinder extends BaseNodeViewBinder { TextView textView; ImageView imageView; + RelativeLayout layout; + MainContract.MainActivityView mView; - public SecondLevelNodeViewBinder(View itemView) { + public SecondLevelNodeViewBinder(View itemView, MainContract.MainActivityView mView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); + layout = itemView.findViewById(R.id.parent_node_container_2); + this.mView = mView; } @Override @@ -26,6 +33,14 @@ public class SecondLevelNodeViewBinder extends BaseNodeViewBinder { @Override public void bindView(TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + int index = mView.incTreeNodeIndex(); + treeNode.setIndex(index); + if(index % 2 == 1) { + layout.setBackgroundColor(Color.parseColor("#FFFFFF")); + } else { + layout.setBackgroundColor(Color.parseColor("#BABABA")); + } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java index d97ed36..46e9c17 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java @@ -125,6 +125,7 @@ public class MainActivity extends AppCompatActivity @Override public void onRefresh() { + treeNodeIndex = 0; mConnectionErrorImageView.setVisibility(View.INVISIBLE); mErrorTextView.setVisibility(View.INVISIBLE); mTreeViewContainer.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java index b6846bb..d1c3697 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java @@ -35,6 +35,7 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac private ImageView mConnectionErrorImageView; private NestedScrollView mTreeViewContainer; private TextView mErrorTextView; + private int treeNodeIndex; @Override protected void onCreate(Bundle savedInstanceState) { @@ -150,6 +151,6 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac @Override public int incTreeNodeIndex() { - return 0; + return treeNodeIndex++; } } From f29121ac7c7e98e8997306bc24b283cec55e0984 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 18:20:18 +0400 Subject: [PATCH 5/9] Removed multicolored rows (as a result of testing, this is terrible) --- .../ru/volgorobot/vrcatalog/MainContract.java | 3 - .../FirstLevelNodeViewBinder.java | 11 ---- .../SecondLevelNodeViewBinder.java | 11 ---- .../ThirdLevelNodeViewBinder.java | 11 ---- .../presenters/ViewBinderPresenter.java | 55 ++++++++++--------- .../FirstLevelNodeViewBinder.java | 11 ---- .../SecondLevelNodeViewBinder.java | 11 ---- .../vrcatalog/view/MainActivity.java | 7 --- .../vrcatalog/view/SearchableActivity.java | 6 -- 9 files changed, 29 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java index e7d3303..991ebef 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java @@ -20,7 +20,6 @@ public interface MainContract { void onFailureAnswer(int errorCode); void refreshTree(); void startActivityByIntent(Intent intent); - int incTreeNodeIndex(); } interface Presenter { @@ -68,8 +67,6 @@ public interface MainContract { void setTreeViewChildren(ArrayList children); void onFailureAnswer(int errorCode); void swipeLayoutSetRefreshing(boolean state); - int incTreeNodeIndex(); - } interface ItemPresenter { diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java index 7f55e80..acad9cb 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java @@ -18,16 +18,12 @@ import ru.volgorobot.vrcatalog.model.FirstLevelModel; public class FirstLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder { TextView textView; ImageView imageView; - RelativeLayout layout; ViewBinderPresenter viewBinderPresenter; - private MainContract.MainActivityView mView; public FirstLevelNodeViewBinder(View itemView, MainContract.MainActivityView mView, Context context) { super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); - layout = itemView.findViewById(R.id.parent_node_container_1); - this.mView = mView; viewBinderPresenter = new ViewBinderPresenter(mView, this, context); } @@ -40,13 +36,6 @@ public class FirstLevelNodeViewBinder extends BaseNodeViewBinder implements Main public void bindView(TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); imageView.setRotation(treeNode.isExpanded() ? 90 : 0); - int index = mView.incTreeNodeIndex(); - treeNode.setIndex(index); - if(index % 2 == 1) { - layout.setBackgroundColor(Color.parseColor("#FFFFFF")); - } else { - layout.setBackgroundColor(Color.parseColor("#BABABA")); - } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java index 04c114f..026cf46 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java @@ -17,8 +17,6 @@ import ru.volgorobot.vrcatalog.model.SecondLevelModel; public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder { TextView textView; ImageView imageView; - RelativeLayout layout; - private MainContract.MainActivityView mView; MainContract.LevelLoaderPresenter viewBinderPresenter; @@ -26,8 +24,6 @@ public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements Mai super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); - layout = itemView.findViewById(R.id.parent_node_container_2); - this.mView = mView; viewBinderPresenter = new ViewBinderPresenter(mView, this, context); } @@ -40,13 +36,6 @@ public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements Mai public void bindView(final TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); imageView.setRotation(treeNode.isExpanded() ? 90 : 0); - int index = mView.incTreeNodeIndex(); - treeNode.setIndex(index); - if(index % 2 == 1) { - layout.setBackgroundColor(Color.parseColor("#FFFFFF")); - } else { - layout.setBackgroundColor(Color.parseColor("#BABABA")); - } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java index 6d39968..0c7529a 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java @@ -15,16 +15,12 @@ import ru.volgorobot.vrcatalog.model.ThirdLevelModel; public class ThirdLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder { TextView textView; - RelativeLayout layout; - private MainContract.MainActivityView mView; MainContract.LevelLoaderPresenter viewBinderPresenter; public ThirdLevelNodeViewBinder(View itemView, Context context, MainContract.MainActivityView mView) { super(itemView); viewBinderPresenter = new ViewBinderPresenter(mView, this, context); textView = itemView.findViewById(R.id.node_name_view); - layout = itemView.findViewById(R.id.parent_node_container_3); - this.mView = mView; } @Override @@ -35,13 +31,6 @@ public class ThirdLevelNodeViewBinder extends BaseNodeViewBinder implements Main @Override public void bindView(final TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); - int index = mView.incTreeNodeIndex(); - treeNode.setIndex(index); - if(index % 2 == 1) { - layout.setBackgroundColor(Color.parseColor("#FFFFFF")); - } else { - layout.setBackgroundColor(Color.parseColor("#BABABA")); - } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ViewBinderPresenter.java b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ViewBinderPresenter.java index 0c26546..a4a08e2 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ViewBinderPresenter.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ViewBinderPresenter.java @@ -32,7 +32,7 @@ public class ViewBinderPresenter implements MainContract.LevelLoaderPresenter { @Override public void fetchSecondLevel(FirstLevelModel firstLevelModel, TreeNode treeNode) { - new AsyncTask>>() { + new AsyncTask>>() { @Override protected void onPreExecute() { super.onPreExecute(); @@ -40,31 +40,32 @@ public class ViewBinderPresenter implements MainContract.LevelLoaderPresenter { } @Override - protected ResultWithErrorCode> doInBackground(FirstLevelModel... firstLevelModel) { + protected ResultWithErrorCode> doInBackground(FirstLevelModel... firstLevelModel) { ArrayList secondLevelModels = null; + ArrayList treeNodes = new ArrayList<>(); try { secondLevelModels = coreModel.fetchSecondLevelByParentID(firstLevelModel[0].getID()); } catch (NetworkErrorException networkErrorException) { - return new ResultWithErrorCode<>(secondLevelModels, networkErrorException.getErrorCode()); + return new ResultWithErrorCode<>(null, networkErrorException.getErrorCode()); } catch (NullPointerException nullPointerException) { - return new ResultWithErrorCode<>(secondLevelModels, 3); + return new ResultWithErrorCode<>(null, 3); } - return new ResultWithErrorCode<>(secondLevelModels, 0); + for (int i = 0; i < secondLevelModels.size(); i++) { + TreeNode treeNode = new TreeNode(secondLevelModels.get(i)); + treeNode.setLevel(1); + treeNodes.add(treeNode); + } + + return new ResultWithErrorCode<>(treeNodes, 0); } @Override - protected void onPostExecute(ResultWithErrorCode> result) { + protected void onPostExecute(ResultWithErrorCode> result) { super.onPostExecute(result); switch (result.getErrorCode()) { case 0: { - ArrayList treeNodes = new ArrayList<>(); - for (int i = 0; i < result.getData().size(); i++) { - TreeNode treeNode1 = new TreeNode(result.getData().get(i)); - treeNode1.setLevel(1); - treeNodes.add(treeNode1); - } - treeNode.setChildren(treeNodes); + treeNode.setChildren(result.getData()); mView.refreshTree(); viewBinder.rotateImageView(); break; @@ -89,7 +90,7 @@ public class ViewBinderPresenter implements MainContract.LevelLoaderPresenter { @Override public void fetchThirdLevel(SecondLevelModel secondLevelModel, TreeNode treeNode) { - new AsyncTask>>() { + new AsyncTask>>() { @Override protected void onPreExecute() { super.onPreExecute(); @@ -97,30 +98,32 @@ public class ViewBinderPresenter implements MainContract.LevelLoaderPresenter { } @Override - protected ResultWithErrorCode> doInBackground(SecondLevelModel... secondLevelModel) { + protected ResultWithErrorCode> doInBackground(SecondLevelModel... secondLevelModel) { ArrayList thirdLevelModels = null; + ArrayList treeNodes = new ArrayList<>(); try { thirdLevelModels = coreModel.fetchThirdLevelByParentID(secondLevelModel[0].getID()); } catch (NetworkErrorException networkErrorException) { - return new ResultWithErrorCode<>(thirdLevelModels, networkErrorException.getErrorCode()); + return new ResultWithErrorCode<>(null, networkErrorException.getErrorCode()); } catch (NullPointerException nullPointerException) { - return new ResultWithErrorCode<>(thirdLevelModels, 3); + return new ResultWithErrorCode<>(null, 3); } - return new ResultWithErrorCode<>(thirdLevelModels, 0); + + for (int i = 0; i < thirdLevelModels.size(); i++) { + TreeNode treeNode1 = new TreeNode(thirdLevelModels.get(i)); + treeNode1.setLevel(2); + treeNodes.add(treeNode1); + } + + return new ResultWithErrorCode<>(treeNodes, 0); } @Override - protected void onPostExecute(ResultWithErrorCode> result) { + protected void onPostExecute(ResultWithErrorCode> result) { super.onPostExecute(result); switch (result.getErrorCode()) { case 0: { - ArrayList treeNodes = new ArrayList<>(); - for (int i = 0; i < result.getData().size(); i++) { - TreeNode treeNode1 = new TreeNode(result.getData().get(i)); - treeNode1.setLevel(2); - treeNodes.add(treeNode1); - } - treeNode.setChildren(treeNodes); + treeNode.setChildren(result.getData()); mView.refreshTree(); viewBinder.rotateImageView(); break; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java index 2f4000c..86acbac 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/FirstLevelNodeViewBinder.java @@ -14,15 +14,11 @@ import ru.volgorobot.vrcatalog.R; public class FirstLevelNodeViewBinder extends BaseNodeViewBinder { TextView textView; ImageView imageView; - RelativeLayout layout; - MainContract.MainActivityView mView; public FirstLevelNodeViewBinder(View itemView, MainContract.MainActivityView mView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); - layout = itemView.findViewById(R.id.parent_node_container_1); - this.mView = mView; } @Override @@ -34,13 +30,6 @@ public class FirstLevelNodeViewBinder extends BaseNodeViewBinder { public void bindView(TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); imageView.setRotation(treeNode.isExpanded() ? 90 : 0); - int index = mView.incTreeNodeIndex(); - treeNode.setIndex(index); - if(index % 2 == 1) { - layout.setBackgroundColor(Color.parseColor("#FFFFFF")); - } else { - layout.setBackgroundColor(Color.parseColor("#BABABA")); - } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java index ebdf541..b474415 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/searchNodeViewBinders/SecondLevelNodeViewBinder.java @@ -14,15 +14,11 @@ import ru.volgorobot.vrcatalog.R; public class SecondLevelNodeViewBinder extends BaseNodeViewBinder { TextView textView; ImageView imageView; - RelativeLayout layout; - MainContract.MainActivityView mView; public SecondLevelNodeViewBinder(View itemView, MainContract.MainActivityView mView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.node_name_view); imageView = (ImageView) itemView.findViewById(R.id.arrow_img); - layout = itemView.findViewById(R.id.parent_node_container_2); - this.mView = mView; } @Override @@ -34,13 +30,6 @@ public class SecondLevelNodeViewBinder extends BaseNodeViewBinder { public void bindView(TreeNode treeNode) { textView.setText(treeNode.getValue().toString()); imageView.setRotation(treeNode.isExpanded() ? 90 : 0); - int index = mView.incTreeNodeIndex(); - treeNode.setIndex(index); - if(index % 2 == 1) { - layout.setBackgroundColor(Color.parseColor("#FFFFFF")); - } else { - layout.setBackgroundColor(Color.parseColor("#BABABA")); - } } @Override diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java index 46e9c17..6095e37 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java @@ -45,7 +45,6 @@ public class MainActivity extends AppCompatActivity private ImageView mConnectionErrorImageView; private ViewGroup mTreeViewContainer; private TextView mErrorTextView; - private int treeNodeIndex; @Override protected void onCreate(Bundle savedInstanceState) { @@ -125,7 +124,6 @@ public class MainActivity extends AppCompatActivity @Override public void onRefresh() { - treeNodeIndex = 0; mConnectionErrorImageView.setVisibility(View.INVISIBLE); mErrorTextView.setVisibility(View.INVISIBLE); mTreeViewContainer.setVisibility(View.VISIBLE); @@ -207,11 +205,6 @@ public class MainActivity extends AppCompatActivity search.setQueryHint("Имя детали"); return true; } - - @Override - public int incTreeNodeIndex() { - return treeNodeIndex++; - } } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java index d1c3697..f411fcd 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java @@ -35,7 +35,6 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac private ImageView mConnectionErrorImageView; private NestedScrollView mTreeViewContainer; private TextView mErrorTextView; - private int treeNodeIndex; @Override protected void onCreate(Bundle savedInstanceState) { @@ -148,9 +147,4 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac } return super.onOptionsItemSelected(item); } - - @Override - public int incTreeNodeIndex() { - return treeNodeIndex++; - } } From 72f37f454995915cda4cd8d55cc0ed4c5fb0ec93 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 18:46:43 +0400 Subject: [PATCH 6/9] Added empty screen when no search results. --- .idea/assetWizardSettings.xml | 5 ++-- .../vrcatalog/view/SearchableActivity.java | 21 ++++++++++++- .../main/res/drawable/ic_clear_gray_24dp.xml | 5 ++++ .../main/res/layout/activity_searchable.xml | 30 +++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/drawable/ic_clear_gray_24dp.xml diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml index 0f9fbd3..91edac6 100644 --- a/.idea/assetWizardSettings.xml +++ b/.idea/assetWizardSettings.xml @@ -147,7 +147,7 @@ @@ -157,7 +157,8 @@ diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java index f411fcd..814facc 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java @@ -35,6 +35,9 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac private ImageView mConnectionErrorImageView; private NestedScrollView mTreeViewContainer; private TextView mErrorTextView; + private ImageView mEmptySearchImageView; + private TextView mEmptySearchTextView; + private boolean isInErrorState = false; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,9 +56,12 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac mTreeViewContainer = findViewById(R.id.searchableTreeViewContainer); mErrorTextView = findViewById(R.id.searchableErrorTextView); + mEmptySearchImageView = findViewById(R.id.emptySearchImage); + mEmptySearchTextView = findViewById(R.id.emptySearchText); + treeView = new TreeView(rootNode, SearchableActivity.this, new SearchableNodeViewFactory(SearchableActivity.this, this)); treeView.setItemAnimator(new DefaultItemAnimator()); - ((ViewGroup) findViewById(R.id.searchableTreeViewContainer)).addView(treeView.getView()); + mTreeViewContainer.addView(treeView.getView()); Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { detailName = intent.getStringExtra(SearchManager.QUERY); @@ -72,6 +78,15 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac rootNode.setChildren(children); treeView.expandAll(); treeView.refreshTreeView(); + if(children.size() == 0 && !isInErrorState) { + mEmptySearchImageView.setVisibility(View.VISIBLE); + mEmptySearchTextView.setVisibility(View.VISIBLE); + mTreeViewContainer.setVisibility(View.GONE); + } else { + mEmptySearchImageView.setVisibility(View.INVISIBLE); + mEmptySearchTextView.setVisibility(View.INVISIBLE); + mTreeViewContainer.setVisibility(View.VISIBLE); + } } public void onFailureAnswer(int errorCode) { @@ -84,6 +99,7 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac mTreeViewContainer.setVisibility(View.GONE); mConnectionErrorImageView.setVisibility(View.VISIBLE); mErrorTextView.setVisibility(View.VISIBLE); + isInErrorState = true; break; } case 2: { @@ -94,6 +110,7 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac mTreeViewContainer.setVisibility(View.GONE); mConnectionErrorImageView.setVisibility(View.VISIBLE); mErrorTextView.setVisibility(View.VISIBLE); + isInErrorState = true; break; } case 3: { @@ -103,6 +120,7 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac mTreeViewContainer.setVisibility(View.GONE); mConnectionErrorImageView.setVisibility(View.VISIBLE); mErrorTextView.setVisibility(View.VISIBLE); + isInErrorState = true; break; } } @@ -116,6 +134,7 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac rootNode.setChildren(new ArrayList()); treeView.refreshTreeView(); searchablePresenter.fetchDetailsTreeByName(detailName); + isInErrorState = false; } @Override diff --git a/app/src/main/res/drawable/ic_clear_gray_24dp.xml b/app/src/main/res/drawable/ic_clear_gray_24dp.xml new file mode 100644 index 0000000..184f32a --- /dev/null +++ b/app/src/main/res/drawable/ic_clear_gray_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_searchable.xml b/app/src/main/res/layout/activity_searchable.xml index 4bdcf45..693b0bc 100644 --- a/app/src/main/res/layout/activity_searchable.xml +++ b/app/src/main/res/layout/activity_searchable.xml @@ -49,6 +49,36 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/searchableConnectionErrorImageView" /> + + + + \ 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 7b2619f..46dadf7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,4 +3,5 @@ Open navigation drawer Close navigation drawer Ваш список избранного пуст + По вашему запросу ничего не найдено. From 23044d78d2a9af78afe7884e1879a19b7ccc7aa1 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 18:48:42 +0400 Subject: [PATCH 7/9] Centered text in empty screen (network error) in SearchableActivity --- app/src/main/res/layout/activity_searchable.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/activity_searchable.xml b/app/src/main/res/layout/activity_searchable.xml index 693b0bc..3220750 100644 --- a/app/src/main/res/layout/activity_searchable.xml +++ b/app/src/main/res/layout/activity_searchable.xml @@ -44,6 +44,7 @@ android:text="" android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:visibility="invisible" + android:gravity="center" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" From 7ed5e7dd9a952b8e8aaa41990c0adead6d630b3d Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 25 Feb 2019 18:54:36 +0400 Subject: [PATCH 8/9] Fixed bug with zooming in viewpager (FullScreenActivity) (application crashed) --- .../vrcatalog/additional/HackyViewPager.java | 40 +++++++++++++++++++ .../res/layout/activity_fullscreenimage.xml | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java new file mode 100644 index 0000000..b68f824 --- /dev/null +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java @@ -0,0 +1,40 @@ +package ru.volgorobot.vrcatalog.additional; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +/** + * ViewPager fixer class (which fix bug with zooming) + */ + +public class HackyViewPager extends android.support.v4.view.ViewPager { + + public HackyViewPager(Context context) { + super(context); + } + + public HackyViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + try { + return super.onTouchEvent(ev); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + try { + return super.onInterceptTouchEvent(ev); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return false; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_fullscreenimage.xml b/app/src/main/res/layout/activity_fullscreenimage.xml index f09d840..4afd413 100644 --- a/app/src/main/res/layout/activity_fullscreenimage.xml +++ b/app/src/main/res/layout/activity_fullscreenimage.xml @@ -9,7 +9,7 @@ tools:context="ru.volgorobot.vrcatalog.view.FullScreenImageActivity" android:background="@android:color/black"> - From d20de8da99d01f00675507c18d8ad210470a1c58 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Wed, 27 Feb 2019 18:02:42 +0400 Subject: [PATCH 9/9] Migration to AndroidX and transfer of communication with the database from a low-level implementation to Room. --- .idea/caches/gradle_models.ser | Bin 111999 -> 171766 bytes .idea/vcs.xml | 1 - app/build.gradle | 20 +++-- .../1.json | 46 ++++++++++ .../1.json | 46 ++++++++++ app/src/main/AndroidManifest.xml | 7 +- .../java/ru/volgorobot/vrcatalog/App.java | 25 ++++++ .../ru/volgorobot/vrcatalog/MainContract.java | 11 ++- .../AppCompatPreferenceActivity.java | 10 +-- .../vrcatalog/additional/DatabaseHelper.java | 11 +++ .../vrcatalog/additional/HackyViewPager.java | 4 +- .../adapters/FavoritesListAdapter.java | 17 ++-- .../adapters/FullscreenImagePagerAdapter.java | 6 +- .../adapters/ImagePagerAdapter.java | 4 +- .../vrcatalog/model/FavoritesDaoModel.java | 22 +++++ ...itesListModel.java => FavoritesModel.java} | 24 ++--- .../FirstLevelNodeViewBinder.java | 3 - .../presenters/FavoritesDBPresenter.java | 83 ------------------ .../presenters/FavoritesPresenter.java | 31 +++++-- .../vrcatalog/presenters/ItemPresenter.java | 33 ++++++- .../vrcatalog/view/AboutActivity.java | 2 +- .../vrcatalog/view/FavoritesActivity.java | 37 ++++---- .../view/FullScreenImageActivity.java | 10 +-- .../vrcatalog/view/ItemActivity.java | 24 +++-- .../vrcatalog/view/MainActivity.java | 21 ++--- .../vrcatalog/view/SearchableActivity.java | 9 +- app/src/main/res/layout/activity_detail.xml | 22 ++--- .../main/res/layout/activity_favorites.xml | 4 +- .../res/layout/activity_fullscreenimage.xml | 2 +- app/src/main/res/layout/activity_main.xml | 6 +- .../main/res/layout/activity_searchable.xml | 12 +-- app/src/main/res/layout/app_bar_main.xml | 10 +-- app/src/main/res/layout/content_main.xml | 12 +-- app/src/main/res/menu/main.xml | 2 +- gradle.properties | 2 + 35 files changed, 353 insertions(+), 226 deletions(-) create mode 100644 app/schemas/ru.volgorobot.vrcatalog.additional.AppDatabase/1.json create mode 100644 app/schemas/ru.volgorobot.vrcatalog.additional.DatabaseHelper/1.json create mode 100644 app/src/main/java/ru/volgorobot/vrcatalog/App.java create mode 100644 app/src/main/java/ru/volgorobot/vrcatalog/additional/DatabaseHelper.java create mode 100644 app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesDaoModel.java rename app/src/main/java/ru/volgorobot/vrcatalog/model/{FavoritesListModel.java => FavoritesModel.java} (51%) delete mode 100644 app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesDBPresenter.java diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser index 6f945081fc2a273341b052981ba2c3d685c99c04..e7dee58f6f5800a2ded5ae4054885c1479b4992b 100644 GIT binary patch literal 171766 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®(K7P;59` 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 kaJsf|~!I^C#% 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 SlX$_}Bqx1MR?NcRP5nQmyeIbn diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 8306744..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,5 @@ - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 373dcf7..6d65097 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,14 +1,18 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 27 + compileSdkVersion 28 defaultConfig { applicationId "ru.volgorobot.vrcatalog" minSdkVersion 19 targetSdkVersion 27 versionCode 7 versionName "0.5.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] + } + } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -24,15 +28,19 @@ android { } dependencies { + def room_version = "2.1.0-alpha04" implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'com.android.support:appcompat-v7:27.1.1' - implementation 'com.android.support:design:27.1.1' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.2' implementation 'me.texy.treeview:treeview_lib:1.0.4' implementation 'com.google.code.gson:gson:2.8.2' implementation 'com.squareup.retrofit2:retrofit:2.4.0' implementation 'com.squareup.retrofit2:converter-gson:2.4.0' - implementation 'com.android.support:recyclerview-v7:27.1.1' + implementation 'androidx.recyclerview:recyclerview:1.0.0-beta01' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.github.chrisbanes:PhotoView:2.1.4' + + implementation "androidx.room:room-runtime:$room_version" + annotationProcessor "androidx.room:room-compiler:$room_version" } diff --git a/app/schemas/ru.volgorobot.vrcatalog.additional.AppDatabase/1.json b/app/schemas/ru.volgorobot.vrcatalog.additional.AppDatabase/1.json new file mode 100644 index 0000000..ef6580c --- /dev/null +++ b/app/schemas/ru.volgorobot.vrcatalog.additional.AppDatabase/1.json @@ -0,0 +1,46 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "b484b5731c959dea19f42d92a1fccfcd", + "entities": [ + { + "tableName": "favorites", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `itemID` INTEGER NOT NULL, `itemName` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "itemID", + "columnName": "itemID", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "itemName", + "columnName": "itemName", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"b484b5731c959dea19f42d92a1fccfcd\")" + ] + } +} \ No newline at end of file diff --git a/app/schemas/ru.volgorobot.vrcatalog.additional.DatabaseHelper/1.json b/app/schemas/ru.volgorobot.vrcatalog.additional.DatabaseHelper/1.json new file mode 100644 index 0000000..ef6580c --- /dev/null +++ b/app/schemas/ru.volgorobot.vrcatalog.additional.DatabaseHelper/1.json @@ -0,0 +1,46 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "b484b5731c959dea19f42d92a1fccfcd", + "entities": [ + { + "tableName": "favorites", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `itemID` INTEGER NOT NULL, `itemName` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "itemID", + "columnName": "itemID", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "itemName", + "columnName": "itemName", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"b484b5731c959dea19f42d92a1fccfcd\")" + ] + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c48cb8e..fabb0e8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,7 @@ - @@ -10,7 +12,8 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:name=".App"> data); } interface ViewBinder { @@ -71,6 +76,10 @@ public interface MainContract { interface ItemPresenter { void getImagesByItemID(int id); + boolean checkFavoriteListed(int itemID); + int getFavoriteID(int itemID); + void addToFavorites(int itemID, String itemName); + void removeFromFavorites(int favID); } interface ItemView { diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java index cfd5368..9410cb3 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java @@ -17,11 +17,11 @@ package ru.volgorobot.vrcatalog.additional; import android.content.res.Configuration; import android.os.Bundle; import android.preference.PreferenceActivity; -import android.support.annotation.LayoutRes; -import android.support.annotation.Nullable; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatDelegate; -import android.support.v7.widget.Toolbar; +import androidx.annotation.LayoutRes; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/DatabaseHelper.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/DatabaseHelper.java new file mode 100644 index 0000000..3f78ecc --- /dev/null +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/DatabaseHelper.java @@ -0,0 +1,11 @@ +package ru.volgorobot.vrcatalog.additional; + +import androidx.room.Database; +import androidx.room.RoomDatabase; +import ru.volgorobot.vrcatalog.model.FavoritesDaoModel; +import ru.volgorobot.vrcatalog.model.FavoritesModel; + +@Database(entities = {FavoritesModel.class}, version = 1) +public abstract class DatabaseHelper extends RoomDatabase { + public abstract FavoritesDaoModel getFavoritesDaoModel(); +} \ No newline at end of file diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java index b68f824..dd32227 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/HackyViewPager.java @@ -4,11 +4,13 @@ import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; +import androidx.viewpager.widget.ViewPager; + /** * ViewPager fixer class (which fix bug with zooming) */ -public class HackyViewPager extends android.support.v4.view.ViewPager { +public class HackyViewPager extends ViewPager { public HackyViewPager(Context context) { super(context); diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FavoritesListAdapter.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FavoritesListAdapter.java index 9216b1d..b2287fc 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FavoritesListAdapter.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FavoritesListAdapter.java @@ -3,25 +3,22 @@ package ru.volgorobot.vrcatalog.additional.adapters; import android.content.Context; import android.widget.ArrayAdapter; +import java.util.ArrayList; import java.util.List; -import ru.volgorobot.vrcatalog.model.FavoritesListModel; -import ru.volgorobot.vrcatalog.presenters.FavoritesDBPresenter; +import ru.volgorobot.vrcatalog.model.FavoritesModel; -public class FavoritesListAdapter extends ArrayAdapter { - private FavoritesDBPresenter db; - - public FavoritesListAdapter(Context context, int resource, List objects) { +public class FavoritesListAdapter extends ArrayAdapter { + public FavoritesListAdapter(Context context, int resource, List objects) { super(context, resource, objects); - db = new FavoritesDBPresenter(context); } - public void updateData() { + public void updateData(ArrayList data) { super.clear(); - super.addAll(db.selectAll()); + super.addAll(data); } public int getArraySize() { - return db.selectAll().size(); + return super.getCount(); } } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FullscreenImagePagerAdapter.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FullscreenImagePagerAdapter.java index 49e5aac..954f341 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FullscreenImagePagerAdapter.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/FullscreenImagePagerAdapter.java @@ -1,9 +1,9 @@ package ru.volgorobot.vrcatalog.additional.adapters; import android.content.Context; -import android.support.annotation.NonNull; -import android.support.v4.view.PagerAdapter; -import android.support.v7.widget.Toolbar; +import androidx.annotation.NonNull; +import androidx.viewpager.widget.PagerAdapter; +import androidx.appcompat.widget.Toolbar; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/ImagePagerAdapter.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/ImagePagerAdapter.java index 2f182f9..c38c275 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/ImagePagerAdapter.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/adapters/ImagePagerAdapter.java @@ -5,8 +5,8 @@ import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.provider.MediaStore; -import android.support.annotation.NonNull; -import android.support.v4.view.PagerAdapter; +import androidx.annotation.NonNull; +import androidx.viewpager.widget.PagerAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesDaoModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesDaoModel.java new file mode 100644 index 0000000..7f1ef46 --- /dev/null +++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesDaoModel.java @@ -0,0 +1,22 @@ +package ru.volgorobot.vrcatalog.model; + +import java.util.List; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; + +@Dao +public interface FavoritesDaoModel { + @Query("SELECT * FROM favorites") + List getAll(); + + @Query("SELECT * FROM favorites WHERE itemID = :itemID") + List getFavoriteByItemID(int itemID); + + @Insert + void add(FavoritesModel model); + + @Query("DELETE FROM favorites WHERE id = :id") + void remove(int id); +} diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesListModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesModel.java similarity index 51% rename from app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesListModel.java rename to app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesModel.java index 75cfb7b..8f1daa9 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesListModel.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/FavoritesModel.java @@ -1,17 +1,21 @@ package ru.volgorobot.vrcatalog.model; -public class FavoritesListModel { - private int id; - private int itemID; - private String itemName; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; - public FavoritesListModel(int itemID, String itemName) { - this.itemID = itemID; - this.itemName = itemName; - } +@Entity(tableName = "favorites") +public class FavoritesModel { + @PrimaryKey(autoGenerate = true) + public int id; - public FavoritesListModel(int id, int itemID, String itemName) { - this.id = id; + @ColumnInfo + public int itemID; + + @ColumnInfo + public String itemName; + + public FavoritesModel(int itemID, String itemName) { this.itemID = itemID; this.itemName = itemName; } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java index acad9cb..b275c2e 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java @@ -1,11 +1,8 @@ package ru.volgorobot.vrcatalog.nodeViewBinders; import android.content.Context; -import android.graphics.Color; -import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ImageView; -import android.widget.RelativeLayout; import android.widget.TextView; import me.texy.treeview.TreeNode; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesDBPresenter.java b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesDBPresenter.java deleted file mode 100644 index ba5e70c..0000000 --- a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesDBPresenter.java +++ /dev/null @@ -1,83 +0,0 @@ -package ru.volgorobot.vrcatalog.presenters; - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; - -import java.util.ArrayList; - -import ru.volgorobot.vrcatalog.additional.DatabaseProperties; -import ru.volgorobot.vrcatalog.additional.SqliteHelper; -import ru.volgorobot.vrcatalog.model.FavoritesListModel; - -public class FavoritesDBPresenter { - private SqliteHelper mHelper; - private SQLiteDatabase mDB; - - public FavoritesDBPresenter(Context context) { - this.mHelper = new SqliteHelper(context); - this.mDB = mHelper.getWritableDatabase(); - } - - public ArrayList selectAll() { - ArrayList models = new ArrayList<>(); - - String[] columns = { - DatabaseProperties.FAVORITES_COLUMN_ID, - DatabaseProperties.FAVORITES_COLUMN_ITEM_ID, - DatabaseProperties.FAVORITES_COLUMN_ITEM_NAME - }; - - Cursor cursor = mDB.query(DatabaseProperties.FAVORITES_TABLE_NAME, columns, null, null, null, null, null); - - if(cursor == null) - return new ArrayList<>(); - - while(cursor.moveToNext()) { - models.add(new FavoritesListModel( - cursor.getInt(cursor.getColumnIndex(DatabaseProperties.FAVORITES_COLUMN_ID)), - cursor.getInt(cursor.getColumnIndex(DatabaseProperties.FAVORITES_COLUMN_ITEM_ID)), - cursor.getString(cursor.getColumnIndex(DatabaseProperties.FAVORITES_COLUMN_ITEM_NAME)))); - } - - cursor.close(); - - return models; - } - - public void add(FavoritesListModel model) { - ContentValues contentValues = new ContentValues(); - contentValues.put(DatabaseProperties.FAVORITES_COLUMN_ITEM_ID, model.getItemID()); - contentValues.put(DatabaseProperties.FAVORITES_COLUMN_ITEM_NAME, model.getItemName()); - mDB.insert(DatabaseProperties.FAVORITES_TABLE_NAME, null, contentValues); - } - - public void removeItem(int id) { - mDB.delete(DatabaseProperties.FAVORITES_TABLE_NAME, "_id = " + id, null); - } - - public boolean inFavoritesList(int itemID) { - String[] columns = { DatabaseProperties.FAVORITES_COLUMN_ITEM_ID }; - String[] selectionArgs = { Integer.toString(itemID) }; - Cursor cursor = mDB.query(DatabaseProperties.FAVORITES_TABLE_NAME, columns, DatabaseProperties.FAVORITES_COLUMN_ITEM_ID + " = ?", selectionArgs, null, null, null); - while(cursor.moveToNext()) { - if(cursor.getInt(cursor.getColumnIndex(DatabaseProperties.FAVORITES_COLUMN_ITEM_ID)) == itemID) - return true; - } - cursor.close(); - - return false; - } - - public int getFavoriteID(int itemID) { - String[] columns = { DatabaseProperties.FAVORITES_COLUMN_ID, DatabaseProperties.FAVORITES_COLUMN_ITEM_ID }; - Cursor cursor = mDB.query(DatabaseProperties.FAVORITES_TABLE_NAME, columns, DatabaseProperties.FAVORITES_COLUMN_ITEM_ID + " = " + Integer.toString(itemID), null, null, null, null); - int id = 0; - if( cursor != null && cursor.moveToFirst() ){ - id = cursor.getInt(cursor.getColumnIndex(DatabaseProperties.FAVORITES_COLUMN_ID)); - cursor.close(); - } - return id; - } -} diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesPresenter.java b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesPresenter.java index d61fb58..dd98fab 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesPresenter.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/FavoritesPresenter.java @@ -1,16 +1,21 @@ package ru.volgorobot.vrcatalog.presenters; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import java.util.ArrayList; +import androidx.room.Room; +import ru.volgorobot.vrcatalog.App; import ru.volgorobot.vrcatalog.MainContract; +import ru.volgorobot.vrcatalog.additional.DatabaseHelper; import ru.volgorobot.vrcatalog.additional.NetworkErrorException; import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode; import ru.volgorobot.vrcatalog.model.CoreModel; import ru.volgorobot.vrcatalog.model.DetailModel; +import ru.volgorobot.vrcatalog.model.FavoritesModel; import ru.volgorobot.vrcatalog.view.FavoritesActivity; import ru.volgorobot.vrcatalog.view.ItemActivity; @@ -18,13 +23,16 @@ public class FavoritesPresenter implements MainContract.FavoritesPresenter { private Context mContext; private MainContract.MainModel mainModel; private MainContract.FavoritesActivityView mView; + private DatabaseHelper db; - public FavoritesPresenter(Context context, FavoritesActivity view) { - this.mContext = context; - this.mainModel = new CoreModel(context); + public FavoritesPresenter(FavoritesActivity view) { + this.mContext = App.getContext(); + this.mainModel = new CoreModel(mContext); this.mView = view; + this.db = App.getDatabaseInstance(); } + @SuppressLint("StaticFieldLeak") @Override public void fetchItem(int itemID) { new AsyncTask>() { @@ -59,19 +67,30 @@ public class FavoritesPresenter implements MainContract.FavoritesPresenter { break; } case 1: { - mView.onFailruleAnswer(1); + mView.onFailureAnswer(1); break; } case 2: { - mView.onFailruleAnswer(2); + mView.onFailureAnswer(2); break; } case 3: { - mView.onFailruleAnswer(3); + mView.onFailureAnswer(3); break; } } } }.execute(itemID); } + + @Override + public void getAllItems() { + mView.updateListView((ArrayList) db.getFavoritesDaoModel().getAll()); + } + + @Override + public void removeItem(int id) { + db.getFavoritesDaoModel().remove(id); + mView.updateListView((ArrayList) db.getFavoritesDaoModel().getAll()); + } } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ItemPresenter.java b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ItemPresenter.java index 8bcdb04..7c5f316 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ItemPresenter.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/presenters/ItemPresenter.java @@ -15,21 +15,27 @@ import java.io.IOException; import java.util.ArrayList; import java.util.UUID; +import androidx.room.Room; +import ru.volgorobot.vrcatalog.App; import ru.volgorobot.vrcatalog.MainContract; +import ru.volgorobot.vrcatalog.additional.DatabaseHelper; import ru.volgorobot.vrcatalog.additional.NetworkErrorException; import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode; import ru.volgorobot.vrcatalog.model.CoreModel; +import ru.volgorobot.vrcatalog.model.FavoritesModel; import ru.volgorobot.vrcatalog.model.ImageItemModel; public class ItemPresenter implements MainContract.ItemPresenter { private MainContract.ItemView mView; private Context context; private MainContract.MainModel coreModel; + private DatabaseHelper db; - public ItemPresenter(Context context, MainContract.ItemView itemView) { + public ItemPresenter(MainContract.ItemView itemView) { this.mView = itemView; - this.context = context; + this.context = App.getContext(); this.coreModel = new CoreModel(context); + this.db = App.getDatabaseInstance(); } @SuppressLint("StaticFieldLeak") @@ -101,4 +107,27 @@ public class ItemPresenter implements MainContract.ItemPresenter { } return Uri.fromFile(cacheObject); } + + @Override + public boolean checkFavoriteListed(int itemID) { + return db.getFavoritesDaoModel().getFavoriteByItemID(itemID).size() != 0; + } + + @Override + public int getFavoriteID(int itemID) { + ArrayList models = (ArrayList) db.getFavoritesDaoModel().getFavoriteByItemID(itemID); + if(models.size() != 0) + return models.get(0).getID(); + return 0; + } + + @Override + public void addToFavorites(int itemID, String itemName) { + db.getFavoritesDaoModel().add(new FavoritesModel(itemID, itemName)); + } + + @Override + public void removeFromFavorites(int favID) { + db.getFavoritesDaoModel().remove(favID); + } } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java index 6dc752c..9f3569e 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java @@ -1,7 +1,7 @@ package ru.volgorobot.vrcatalog.view; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.MenuItem; import ru.volgorobot.vrcatalog.R; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java index a622f29..372d09b 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/FavoritesActivity.java @@ -1,8 +1,8 @@ package ru.volgorobot.vrcatalog.view; import android.content.Intent; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; @@ -19,12 +19,10 @@ import java.util.ArrayList; import ru.volgorobot.vrcatalog.MainContract; import ru.volgorobot.vrcatalog.R; import ru.volgorobot.vrcatalog.additional.adapters.FavoritesListAdapter; -import ru.volgorobot.vrcatalog.model.FavoritesListModel; -import ru.volgorobot.vrcatalog.presenters.FavoritesDBPresenter; +import ru.volgorobot.vrcatalog.model.FavoritesModel; import ru.volgorobot.vrcatalog.presenters.FavoritesPresenter; public class FavoritesActivity extends AppCompatActivity implements MainContract.FavoritesActivityView { - private FavoritesDBPresenter db; private FavoritesListAdapter adapter; private MainContract.FavoritesPresenter mPresenter; @@ -37,15 +35,13 @@ public class FavoritesActivity extends AppCompatActivity implements MainContract super.onCreate(savedInstanceState); setContentView(R.layout.activity_favorites); - mPresenter = new FavoritesPresenter(FavoritesActivity.this, this); + mPresenter = new FavoritesPresenter(this); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); actionBar.setTitle("Избранное"); - db = new FavoritesDBPresenter(FavoritesActivity.this); - initViews(); } @@ -55,16 +51,14 @@ public class FavoritesActivity extends AppCompatActivity implements MainContract listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { - FavoritesListModel model = (FavoritesListModel) listView.getItemAtPosition(i); + FavoritesModel model = (FavoritesModel) listView.getItemAtPosition(i); mPresenter.fetchItem(model.getItemID()); } }); + adapter = new FavoritesListAdapter(FavoritesActivity.this, android.R.layout.simple_list_item_1, new ArrayList<>()); + listView.setAdapter(adapter); favoritesEmptyImage = findViewById(R.id.favorites_empty_image); favoritesEmptyText = findViewById(R.id.favorites_empty_text); - ArrayList models = db.selectAll(); - adapter = new FavoritesListAdapter(FavoritesActivity.this, android.R.layout.simple_list_item_1, models); - listView.setAdapter(adapter); - checkForEmptyContent(); } public void checkForEmptyContent() { @@ -84,18 +78,18 @@ public class FavoritesActivity extends AppCompatActivity implements MainContract AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case 0: { - FavoritesListModel model = (FavoritesListModel) listView.getItemAtPosition(info.position); - db.removeItem(model.getID()); - updateListView(); - checkForEmptyContent(); + FavoritesModel model = (FavoritesModel) listView.getItemAtPosition(info.position); + mPresenter.removeItem(model.getID()); } } return true; } - private void updateListView() { - adapter.updateData(); + @Override + public void updateListView(ArrayList data) { + adapter.updateData(data); adapter.notifyDataSetChanged(); + checkForEmptyContent(); } @Override @@ -116,7 +110,7 @@ public class FavoritesActivity extends AppCompatActivity implements MainContract } @Override - public void onFailruleAnswer(int errorCode) { + public void onFailureAnswer(int errorCode) { switch (errorCode) { case 1: { Toast.makeText(FavoritesActivity.this, "Ошибка сети. Проверьте подключение к сети или данные подключения к API!", Toast.LENGTH_LONG).show(); @@ -144,7 +138,6 @@ public class FavoritesActivity extends AppCompatActivity implements MainContract @Override protected void onResume() { super.onResume(); - updateListView(); - checkForEmptyContent(); + mPresenter.getAllItems(); } } diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/FullScreenImageActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/FullScreenImageActivity.java index a897e65..497e451 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/FullScreenImageActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/FullScreenImageActivity.java @@ -4,11 +4,11 @@ import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.viewpager.widget.ViewPager; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.view.MenuItem; import android.view.View; import android.view.Window; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/ItemActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/ItemActivity.java index c9154e5..e7b4740 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/ItemActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/ItemActivity.java @@ -4,10 +4,11 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Color; import android.os.Bundle; -import android.support.design.widget.TabLayout; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import com.google.android.material.tabs.TabLayout; + +import androidx.viewpager.widget.ViewPager; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -17,10 +18,7 @@ import android.widget.TextView; import android.widget.Toast; import java.util.LinkedHashMap; -import java.util.Map; -import ru.volgorobot.vrcatalog.model.FavoritesListModel; -import ru.volgorobot.vrcatalog.presenters.FavoritesDBPresenter; import ru.volgorobot.vrcatalog.presenters.ItemPresenter; import ru.volgorobot.vrcatalog.MainContract; import ru.volgorobot.vrcatalog.R; @@ -33,9 +31,9 @@ public class ItemActivity extends AppCompatActivity implements MainContract.Item private ListView propertiesList; private ImagePagerAdapter imagePagerAdapter; private boolean inFavorites; - private FavoritesDBPresenter db; private int itemID; private String itemName; + private int favoriteID; @Override protected void onCreate(Bundle savedInstanceState) { @@ -47,7 +45,7 @@ public class ItemActivity extends AppCompatActivity implements MainContract.Item getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayShowTitleEnabled(false); initializeViews(); - mPresenter = new ItemPresenter(ItemActivity.this, this); + mPresenter = new ItemPresenter(this); Intent intent = getIntent(); itemName = intent.getStringExtra("detailName"); @@ -63,7 +61,6 @@ public class ItemActivity extends AppCompatActivity implements MainContract.Item LinkedHashMap intentDataForListView = getIntentExtras(intent); itemID = Integer.parseInt(intent.getStringExtra("itemID")); intentDataForListView.get("detailName"); - db = new FavoritesDBPresenter(ItemActivity.this); propertiesList = findViewById(R.id.propertiesList); PropertiesListAdapter propertiesListAdapter = new PropertiesListAdapter(intentDataForListView); @@ -71,7 +68,8 @@ public class ItemActivity extends AppCompatActivity implements MainContract.Item mPresenter.getImagesByItemID(Integer.parseInt(intent.getStringExtra("itemID"))); - inFavorites = db.inFavoritesList(itemID); + inFavorites = mPresenter.checkFavoriteListed(itemID); + favoriteID = mPresenter.getFavoriteID(itemID); } void initializeViews() { @@ -229,13 +227,13 @@ public class ItemActivity extends AppCompatActivity implements MainContract.Item MenuItem deleteFromFavorites = menu.findItem(R.id.action_unfavorite); addToFavorites.setOnMenuItemClickListener((MenuItem menuItem) -> { - db.add(new FavoritesListModel(0, itemID, itemName)); + mPresenter.addToFavorites(itemID, itemName); inFavorites = true; this.invalidateOptionsMenu(); return true; }); deleteFromFavorites.setOnMenuItemClickListener((MenuItem menuItem) -> { - db.removeItem(db.getFavoriteID(itemID)); + mPresenter.removeFromFavorites(favoriteID); inFavorites = false; this.invalidateOptionsMenu(); return true; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java index 6095e37..63fd314 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java @@ -5,16 +5,15 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.support.design.widget.NavigationView; -import android.support.v4.view.GravityCompat; -import android.support.v4.view.MenuItemCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.ActionBarDrawerToggle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.DefaultItemAnimator; -import android.support.v7.widget.SearchView; -import android.support.v7.widget.Toolbar; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.core.view.GravityCompat; +import androidx.core.view.MenuItemCompat; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.DefaultItemAnimator; +import androidx.appcompat.widget.SearchView; +import androidx.appcompat.widget.Toolbar; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -25,6 +24,8 @@ import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; +import com.google.android.material.navigation.NavigationView; + import java.util.ArrayList; import me.texy.treeview.TreeNode; diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java index 814facc..a0190c2 100644 --- a/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java +++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/SearchableActivity.java @@ -4,14 +4,13 @@ import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.provider.SearchRecentSuggestions; -import android.support.v4.widget.NestedScrollView; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.DefaultItemAnimator; +import androidx.core.widget.NestedScrollView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.DefaultItemAnimator; import android.util.Log; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml index 05af980..0d398a8 100644 --- a/app/src/main/res/layout/activity_detail.xml +++ b/app/src/main/res/layout/activity_detail.xml @@ -1,25 +1,25 @@ - - - - - - - - + + - - - \ No newline at end of file + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/activity_favorites.xml index 798f0e0..4308b86 100644 --- a/app/src/main/res/layout/activity_favorites.xml +++ b/app/src/main/res/layout/activity_favorites.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_fullscreenimage.xml b/app/src/main/res/layout/activity_fullscreenimage.xml index 4afd413..f2ed594 100644 --- a/app/src/main/res/layout/activity_fullscreenimage.xml +++ b/app/src/main/res/layout/activity_fullscreenimage.xml @@ -14,7 +14,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - - - - + diff --git a/app/src/main/res/layout/activity_searchable.xml b/app/src/main/res/layout/activity_searchable.xml index 3220750..6ab6a13 100644 --- a/app/src/main/res/layout/activity_searchable.xml +++ b/app/src/main/res/layout/activity_searchable.xml @@ -1,5 +1,5 @@ - - - - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml index b87ac6b..a314d65 100644 --- a/app/src/main/res/layout/app_bar_main.xml +++ b/app/src/main/res/layout/app_bar_main.xml @@ -1,17 +1,17 @@ - - - - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index fb7d24c..b5ae086 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -1,5 +1,5 @@ - - - - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml index c4d297b..f59c587 100644 --- a/app/src/main/res/menu/main.xml +++ b/app/src/main/res/menu/main.xml @@ -5,6 +5,6 @@ android:id="@+id/action_search" android:icon="@drawable/ic_search_white_24dp" app:showAsAction="always|collapseActionView" - app:actionViewClass="android.support.v7.widget.SearchView" + app:actionViewClass="androidx.appcompat.widget.SearchView" android:title="Поиск"/> diff --git a/gradle.properties b/gradle.properties index fc63706..ac6eb9b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,8 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx512m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit