diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
new file mode 100644
index 0000000..e64e3f9
--- /dev/null
+++ b/.idea/assetWizardSettings.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index 513b456..9c9d487 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/misc.xml b/.idea/misc.xml
index e0d5b93..b0c7b20 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/app/build.gradle b/app/build.gradle
index 06a8215..de6473e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,13 +10,17 @@ android {
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
- buildToolsVersion '27.0.3'
+ buildToolsVersion '28.0.3'
}
dependencies {
@@ -24,7 +28,9 @@ dependencies {
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'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.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.1.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
+ implementation 'com.android.support:recyclerview-v7:27.1.1'
}
diff --git a/app/src/androidTest/java/ru/volgorobot/vrcatalog/ExampleInstrumentedTest.java b/app/src/androidTest/java/ru/volgorobot/vrcatalog/ExampleInstrumentedTest.java
deleted file mode 100644
index e7b1127..0000000
--- a/app/src/androidTest/java/ru/volgorobot/vrcatalog/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package ru.volgorobot.vrcatalog;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("ru.volgorobot.vrcatalog", appContext.getPackageName());
- }
-}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 564beb7..1539b9a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,8 @@
+
+
@@ -19,8 +21,9 @@
-
-
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/MainActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/MainActivity.java
deleted file mode 100644
index fd07e6a..0000000
--- a/app/src/main/java/ru/volgorobot/vrcatalog/MainActivity.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package ru.volgorobot.vrcatalog;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.design.widget.NavigationView;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBarDrawerToggle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.MenuItem;
-import android.view.Menu;
-
-public class MainActivity extends AppCompatActivity
- implements NavigationView.OnNavigationItemSelectedListener {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Toolbar toolbar = findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
-
- DrawerLayout drawer = findViewById(R.id.drawer_layout);
- ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
- this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
- drawer.addDrawerListener(toggle);
- toggle.syncState();
-
- NavigationView navigationView = findViewById(R.id.nav_view);
- navigationView.setNavigationItemSelectedListener(this);
- }
-
- @Override
- public void onBackPressed() {
- DrawerLayout drawer = findViewById(R.id.drawer_layout);
- if (drawer.isDrawerOpen(GravityCompat.START)) {
- drawer.closeDrawer(GravityCompat.START);
- } else {
- super.onBackPressed();
- }
- }
-
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
-
- return super.onOptionsItemSelected(item);
- }
-
- @SuppressWarnings("StatementWithEmptyBody")
- @Override
- public boolean onNavigationItemSelected(MenuItem item) {
- // Handle navigation view item clicks here.
- int id = item.getItemId();
- NavigationView navView = findViewById(R.id.nav_view);
-
- if (id == R.id.nav_settings) {
- startActivity(new Intent(this, SettingsActivity.class));
-
- } else if (id == R.id.nav_about) {
- startActivity(new Intent(this, AboutActivity.class));
- }
-
- DrawerLayout drawer = findViewById(R.id.drawer_layout);
- drawer.closeDrawer(GravityCompat.START);
- return true;
- }
-}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java
new file mode 100644
index 0000000..89d94b6
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/MainContract.java
@@ -0,0 +1,47 @@
+package ru.volgorobot.vrcatalog;
+
+import android.content.Intent;
+
+import java.util.ArrayList;
+
+import me.texy.treeview.TreeNode;
+import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
+import ru.volgorobot.vrcatalog.model.CoreModel;
+import ru.volgorobot.vrcatalog.model.DetailModel;
+import ru.volgorobot.vrcatalog.model.FirstLevelModel;
+import ru.volgorobot.vrcatalog.model.SecondLevelModel;
+import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
+
+public interface MainContract {
+ interface MainActivityView {
+ void swipeLayoutSetRefreshing(boolean state);
+ void buildFirstLevelTree(ArrayList firstLevelModels);
+ void onFailureAnswer(int errorCode);
+ void refreshTree();
+ void startActivityByIntent(Intent intent);
+ }
+
+ interface Presenter {
+ void getFirstLevel();
+ CoreModel getCoreModel();
+ }
+
+ interface ViewBinderPresenter {
+ void fetchSecondLevel(FirstLevelModel firstLevelModel, TreeNode treeNode);
+ void fetchThirdLevel(SecondLevelModel secondLevelModel, TreeNode treeNode);
+ void fetchDetail(ThirdLevelModel thirdLevelModel);
+ }
+
+ interface ViewBinder {
+ void rotateImageView();
+ }
+
+ interface MainModel {
+ ArrayList fetchFirstLevel() throws NetworkErrorException, NullPointerException;
+ ArrayList fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
+ ArrayList fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
+ ArrayList fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException;
+ void reinitializeApi() throws IllegalStateException;
+ boolean getApiState();
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/MainPresenter.java b/app/src/main/java/ru/volgorobot/vrcatalog/MainPresenter.java
new file mode 100644
index 0000000..81a6f77
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/MainPresenter.java
@@ -0,0 +1,74 @@
+package ru.volgorobot.vrcatalog;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+import java.util.ArrayList;
+
+import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
+import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode;
+import ru.volgorobot.vrcatalog.model.CoreModel;
+import ru.volgorobot.vrcatalog.model.FirstLevelModel;
+
+public class MainPresenter implements MainContract.Presenter {
+ private MainContract.MainActivityView mView;
+ private CoreModel coreModel;
+
+ public MainPresenter(MainContract.MainActivityView mainActivityView, Context context) {
+ this.mView = mainActivityView;
+ this.coreModel = new CoreModel(context);
+ }
+
+ @Override
+ public void getFirstLevel() {
+ mView.swipeLayoutSetRefreshing(true);
+ try {
+ coreModel.reinitializeApi();
+ } catch (IllegalStateException e) {
+ mView.onFailureAnswer(3);
+ return;
+ }
+ new AsyncTask>>() {
+ @Override
+ protected ResultWithErrorCode> doInBackground(Void... voids) {
+ ArrayList firstLevelModels = null;
+ try {
+ firstLevelModels = coreModel.fetchFirstLevel();
+ } catch (NetworkErrorException networkErrorException) {
+ return new ResultWithErrorCode<>(firstLevelModels, networkErrorException.getErrorCode());
+ } catch (NullPointerException nullPointerException) {
+ return new ResultWithErrorCode<>(firstLevelModels, 3);
+ }
+ return new ResultWithErrorCode<>(firstLevelModels, 0);
+ }
+
+ @Override
+ protected void onPostExecute(ResultWithErrorCode> result) {
+ switch (result.getErrorCode()) {
+ case 0: {
+ mView.buildFirstLevelTree(result.getData());
+ break;
+ }
+ case 1: {
+ mView.onFailureAnswer(1);
+ break;
+ }
+ case 2: {
+ mView.onFailureAnswer(2);
+ break;
+ }
+ case 3: {
+ mView.onFailureAnswer(3);
+ break;
+ }
+ }
+ mView.swipeLayoutSetRefreshing(false);
+ }
+ }.execute();
+ }
+
+ @Override
+ public CoreModel getCoreModel() {
+ return this.coreModel;
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/ViewBinderPresenter.java b/app/src/main/java/ru/volgorobot/vrcatalog/ViewBinderPresenter.java
new file mode 100644
index 0000000..d633d53
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/ViewBinderPresenter.java
@@ -0,0 +1,205 @@
+package ru.volgorobot.vrcatalog;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+
+import java.util.ArrayList;
+
+import me.texy.treeview.TreeNode;
+import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
+import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode;
+import ru.volgorobot.vrcatalog.model.DetailModel;
+import ru.volgorobot.vrcatalog.model.FirstLevelModel;
+import ru.volgorobot.vrcatalog.model.SecondLevelModel;
+import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
+import ru.volgorobot.vrcatalog.view.DetailActivity;
+
+public class ViewBinderPresenter implements MainContract.ViewBinderPresenter {
+ private MainContract.MainActivityView mView;
+ private MainContract.MainModel coreModel;
+ private MainContract.ViewBinder viewBinder;
+ private Context context;
+
+ public ViewBinderPresenter(MainContract.MainActivityView mView, MainContract.MainModel coreModel, MainContract.ViewBinder viewBinder) {
+ this.mView = mView;
+ this.coreModel = coreModel;
+ this.viewBinder = viewBinder;
+ }
+
+ public ViewBinderPresenter(MainContract.MainActivityView mView, MainContract.MainModel coreModel, MainContract.ViewBinder viewBinder, Context context) {
+ this.mView = mView;
+ this.coreModel = coreModel;
+ this.viewBinder = viewBinder;
+ this.context = context;
+ }
+
+ @Override
+ public void fetchSecondLevel(FirstLevelModel firstLevelModel, TreeNode treeNode) {
+ new AsyncTask>>() {
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ mView.swipeLayoutSetRefreshing(true);
+ }
+
+ @Override
+ protected ResultWithErrorCode> doInBackground(FirstLevelModel... firstLevelModel) {
+ ArrayList secondLevelModels = null;
+ try {
+ secondLevelModels = coreModel.fetchSecondLevelByParentID(firstLevelModel[0].getID());
+ } catch (NetworkErrorException networkErrorException) {
+ return new ResultWithErrorCode<>(secondLevelModels, networkErrorException.getErrorCode());
+ } catch (NullPointerException nullPointerException) {
+ return new ResultWithErrorCode<>(secondLevelModels, 3);
+ }
+
+ return new ResultWithErrorCode<>(secondLevelModels, 0);
+ }
+
+ @Override
+ 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);
+ mView.refreshTree();
+ viewBinder.rotateImageView();
+ break;
+ }
+ case 1: {
+ mView.onFailureAnswer(1);
+ break;
+ }
+ case 2: {
+ mView.onFailureAnswer(2);
+ break;
+ }
+ case 3: {
+ mView.onFailureAnswer(3);
+ break;
+ }
+ }
+ mView.swipeLayoutSetRefreshing(false);
+ }
+ }.execute(firstLevelModel);
+ }
+
+ @Override
+ public void fetchThirdLevel(SecondLevelModel secondLevelModel, TreeNode treeNode) {
+ new AsyncTask>>() {
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ mView.swipeLayoutSetRefreshing(true);
+ }
+
+ @Override
+ protected ResultWithErrorCode> doInBackground(SecondLevelModel... secondLevelModel) {
+ ArrayList thirdLevelModels = null;
+ try {
+ thirdLevelModels = coreModel.fetchThirdLevelByParentID(secondLevelModel[0].getID());
+ } catch (NetworkErrorException networkErrorException) {
+ return new ResultWithErrorCode<>(thirdLevelModels, networkErrorException.getErrorCode());
+ } catch (NullPointerException nullPointerException) {
+ return new ResultWithErrorCode<>(thirdLevelModels, 3);
+ }
+ return new ResultWithErrorCode<>(thirdLevelModels, 0);
+ }
+
+ @Override
+ 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);
+ mView.refreshTree();
+ viewBinder.rotateImageView();
+ break;
+ }
+ case 1: {
+ mView.onFailureAnswer(1);
+ break;
+ }
+ case 2: {
+ mView.onFailureAnswer(2);
+ break;
+ }
+ case 3: {
+ mView.onFailureAnswer(3);
+ break;
+ }
+ }
+ mView.swipeLayoutSetRefreshing(false);
+ }
+ }.execute(secondLevelModel);
+ }
+
+ @Override
+ public void fetchDetail(ThirdLevelModel thirdLevelModel) {
+ new AsyncTask>() {
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ mView.swipeLayoutSetRefreshing(true);
+ }
+
+ @Override
+ protected ResultWithErrorCode doInBackground(ThirdLevelModel... thirdLevelModel) {
+ ArrayList detail = null;
+ try {
+ detail = coreModel.fetchDetailByID(thirdLevelModel[0].getID());
+ } catch (NetworkErrorException networkErrorException) {
+ return new ResultWithErrorCode<>(detail.get(0), networkErrorException.getErrorCode());
+ } catch (NullPointerException nullPointerException) {
+ return new ResultWithErrorCode<>(detail.get(0), 3);
+ }
+ return new ResultWithErrorCode<>(detail.get(0), 0);
+ }
+
+ @Override
+ protected void onPostExecute(ResultWithErrorCode result) {
+ super.onPostExecute(result);
+ switch (result.getErrorCode()) {
+ case 0: {
+ Intent intent = new Intent(context, DetailActivity.class);
+ intent.putExtra("detailName", result.getData().getName());
+ intent.putExtra("detailQuantity", result.getData().getNumber().toString());
+ intent.putExtra("detailPrice", result.getData().getPrice());
+ intent.putExtra("detailCountry", result.getData().getCountry());
+ intent.putExtra("detailAnalogue", result.getData().getAnalogue());
+ intent.putExtra("detailDatasheet", result.getData().getDocURL());
+ intent.putExtra("detailNotes", result.getData().getNotes());
+ mView.startActivityByIntent(intent);
+ break;
+ }
+ case 1: {
+ mView.onFailureAnswer(1);
+ break;
+ }
+ case 2: {
+ mView.onFailureAnswer(2);
+ break;
+ }
+ case 3: {
+ mView.onFailureAnswer(3);
+ break;
+ }
+ }
+ mView.swipeLayoutSetRefreshing(false);
+ }
+ }.execute(thirdLevelModel);
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java
new file mode 100644
index 0000000..cfd5368
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/AppCompatPreferenceActivity.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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 android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
+ * to be used with AppCompat.
+ *
+ * This technique can be used with an {@link android.app.Activity} class, not just
+ * {@link android.preference.PreferenceActivity}.
+ */
+
+public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
+ private AppCompatDelegate mDelegate;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ getDelegate().installViewFactory();
+ getDelegate().onCreate(savedInstanceState);
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ getDelegate().onPostCreate(savedInstanceState);
+ }
+
+ public ActionBar getSupportActionBar() {
+ return getDelegate().getSupportActionBar();
+ }
+
+ public void setSupportActionBar(@Nullable Toolbar toolbar) {
+ getDelegate().setSupportActionBar(toolbar);
+ }
+
+ @Override
+ public MenuInflater getMenuInflater() {
+ return getDelegate().getMenuInflater();
+ }
+
+ @Override
+ public void setContentView(@LayoutRes int layoutResID) {
+ getDelegate().setContentView(layoutResID);
+ }
+
+ @Override
+ public void setContentView(View view) {
+ getDelegate().setContentView(view);
+ }
+
+ @Override
+ public void setContentView(View view, ViewGroup.LayoutParams params) {
+ getDelegate().setContentView(view, params);
+ }
+
+ @Override
+ public void addContentView(View view, ViewGroup.LayoutParams params) {
+ getDelegate().addContentView(view, params);
+ }
+
+ @Override
+ protected void onPostResume() {
+ super.onPostResume();
+ getDelegate().onPostResume();
+ }
+
+ @Override
+ protected void onTitleChanged(CharSequence title, int color) {
+ super.onTitleChanged(title, color);
+ getDelegate().setTitle(title);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ getDelegate().onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ getDelegate().onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ getDelegate().onDestroy();
+ }
+
+ public void invalidateOptionsMenu() {
+ getDelegate().invalidateOptionsMenu();
+ }
+
+ private AppCompatDelegate getDelegate() {
+ if (mDelegate == null) {
+ mDelegate = AppCompatDelegate.create(this, null);
+ }
+ return mDelegate;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/NetworkErrorException.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/NetworkErrorException.java
new file mode 100644
index 0000000..ea9bf16
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/NetworkErrorException.java
@@ -0,0 +1,13 @@
+package ru.volgorobot.vrcatalog.additional;
+
+public class NetworkErrorException extends Exception {
+ private int errorCode;
+
+ public NetworkErrorException(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/NodeViewFactory.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/NodeViewFactory.java
new file mode 100644
index 0000000..6343fe4
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/NodeViewFactory.java
@@ -0,0 +1,38 @@
+package ru.volgorobot.vrcatalog.additional;
+
+import android.content.Context;
+import android.view.View;
+
+import me.texy.treeview.base.BaseNodeViewBinder;
+import me.texy.treeview.base.BaseNodeViewFactory;
+import ru.volgorobot.vrcatalog.MainContract;
+import ru.volgorobot.vrcatalog.model.CoreModel;
+import ru.volgorobot.vrcatalog.nodeViewBinders.FirstLevelNodeViewBinder;
+import ru.volgorobot.vrcatalog.nodeViewBinders.SecondLevelNodeViewBinder;
+import ru.volgorobot.vrcatalog.nodeViewBinders.ThirdLevelNodeViewBinder;
+
+public class NodeViewFactory extends BaseNodeViewFactory {
+ MainContract.MainActivityView mView;
+ CoreModel coreModel;
+ Context context;
+
+ public NodeViewFactory(Context context, MainContract.MainActivityView mView, CoreModel coreModel) {
+ this.mView = mView;
+ this.context = context;
+ this.coreModel = coreModel;
+ }
+
+ @Override
+ public BaseNodeViewBinder getNodeViewBinder(View view, int level) {
+ switch (level) {
+ case 0:
+ return new FirstLevelNodeViewBinder(view, context, mView, coreModel);
+ case 1:
+ return new SecondLevelNodeViewBinder(view, context, mView, coreModel);
+ case 2:
+ return new ThirdLevelNodeViewBinder(view, context, mView, coreModel);
+ default:
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/additional/ResultWithErrorCode.java b/app/src/main/java/ru/volgorobot/vrcatalog/additional/ResultWithErrorCode.java
new file mode 100644
index 0000000..6d20600
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/additional/ResultWithErrorCode.java
@@ -0,0 +1,28 @@
+package ru.volgorobot.vrcatalog.additional;
+
+
+public class ResultWithErrorCode {
+ private T data;
+ private int errorCode;
+
+ public ResultWithErrorCode(T data, int errorCode) {
+ this.data = data;
+ this.errorCode = errorCode;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/api/Controller.java b/app/src/main/java/ru/volgorobot/vrcatalog/api/Controller.java
new file mode 100644
index 0000000..3a1654a
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/api/Controller.java
@@ -0,0 +1,42 @@
+package ru.volgorobot.vrcatalog.api;
+
+import android.content.Context;
+import android.widget.Toast;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class Controller {
+ private static String baseURL;
+ private static Retrofit retrofit;
+ private static VRApi vrApi;
+
+
+ public static VRApi getApi(String baseURL1) throws IllegalStateException {
+ baseURL = baseURL1;
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+ try {
+ buildRetrofitObject(gson);
+ vrApi = retrofit.create(VRApi.class);
+ return vrApi;
+ } catch(IllegalStateException e) {
+ throw new IllegalStateException();
+ }
+ }
+
+ private static void buildRetrofitObject(Gson gson) throws IllegalStateException {
+ try {
+ retrofit = new Retrofit.Builder()
+ .baseUrl(baseURL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+ } catch(Exception e) {
+ throw new IllegalStateException();
+ }
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/api/VRApi.java b/app/src/main/java/ru/volgorobot/vrcatalog/api/VRApi.java
new file mode 100644
index 0000000..80e062d
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/api/VRApi.java
@@ -0,0 +1,26 @@
+package ru.volgorobot.vrcatalog.api;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.http.GET;
+import retrofit2.http.Query;
+import ru.volgorobot.vrcatalog.model.DetailModel;
+import ru.volgorobot.vrcatalog.model.FirstLevelModel;
+import ru.volgorobot.vrcatalog.model.SecondLevelModel;
+import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
+
+public interface VRApi {
+
+ @GET("/API/Api.php?action=getFirstLevel")
+ Call> getFirstLevel();
+
+ @GET("/API/Api.php?action=getSecondLevel")
+ Call> getSecondLevel(@Query("parentTypeID") int parentTypeID);
+
+ @GET("/API/Api.php?action=getDetailsByParentID")
+ Call> getDetails(@Query("parentID") int parentID);
+
+ @GET("/API/Api.php?action=getDetailByID")
+ Call> getDetailByID(@Query("detailID") int detailID);
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/CoreModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/CoreModel.java
new file mode 100644
index 0000000..ccbb53a
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/CoreModel.java
@@ -0,0 +1,128 @@
+package ru.volgorobot.vrcatalog.model;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import retrofit2.Response;
+import ru.volgorobot.vrcatalog.MainContract;
+import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
+import ru.volgorobot.vrcatalog.api.Controller;
+import ru.volgorobot.vrcatalog.api.VRApi;
+
+public class CoreModel implements MainContract.MainModel {
+ private Context context;
+ private VRApi vrApi;
+ private String baseURL;
+
+ public CoreModel(Context context) {
+ this.context = context;
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ this.baseURL = sharedPreferences.getString("addressOfServer", "");
+ try {
+ vrApi = Controller.getApi(baseURL);
+ } catch(IllegalStateException e) {
+ // Nothing
+ }
+ }
+
+ @Override
+ public ArrayList fetchFirstLevel() throws NetworkErrorException, NullPointerException {
+ if(vrApi == null) {
+ throw new NullPointerException();
+ }
+ final ArrayList firstLevelModels = new ArrayList<>();
+ try {
+ Response> response = vrApi.getFirstLevel().execute();
+ if(response.isSuccessful()) {
+ firstLevelModels.addAll(response.body());
+ } else {
+ throw new NetworkErrorException(2);
+ }
+ } catch (IOException e) {
+ throw new NetworkErrorException(1);
+ }
+ return firstLevelModels;
+ }
+
+ @Override
+ public ArrayList fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
+ if(vrApi == null) {
+ throw new NullPointerException();
+ }
+ final ArrayList secondLevelModels = new ArrayList<>();
+ try {
+ Response> response = vrApi.getSecondLevel(parentID).execute();
+ if(response.isSuccessful()) {
+ secondLevelModels.addAll(response.body());
+ } else {
+ throw new NetworkErrorException(2);
+ }
+ } catch (IOException e) {
+ throw new NetworkErrorException(1);
+ }
+ return secondLevelModels;
+ }
+
+ @Override
+ public ArrayList fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
+ if(vrApi == null) {
+ throw new NullPointerException();
+ }
+ final ArrayList thirdLevelModels = new ArrayList<>();
+ try {
+ Response> response = vrApi.getDetails(parentID).execute();
+ if(response.isSuccessful()) {
+ thirdLevelModels.addAll(response.body());
+ } else {
+ throw new NetworkErrorException(2);
+ }
+ } catch (IOException e) {
+ throw new NetworkErrorException(1);
+ }
+ return thirdLevelModels;
+ }
+
+ @Override
+ public ArrayList fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException {
+ if(vrApi == null) {
+ throw new NullPointerException();
+ }
+ ArrayList detail = new ArrayList<>();
+ try {
+ Response> response = vrApi.getDetailByID(detailID).execute();
+ if(response.isSuccessful()) {
+ detail.addAll(response.body());
+ } else {
+ throw new NetworkErrorException(2);
+ }
+ } catch (IOException e) {
+ throw new NetworkErrorException(1);
+ }
+ return detail;
+ }
+
+ @Override
+ public void reinitializeApi() throws IllegalStateException {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ this.baseURL = sharedPreferences.getString("addressOfServer", "");
+ try {
+ vrApi = Controller.getApi(baseURL);
+ } catch(IllegalStateException e) {
+ throw new IllegalStateException();
+ }
+ }
+
+ @Override
+ public boolean getApiState() {
+ if(vrApi != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/DetailModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/DetailModel.java
new file mode 100644
index 0000000..273be0f
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/DetailModel.java
@@ -0,0 +1,237 @@
+package ru.volgorobot.vrcatalog.model;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class DetailModel {
+
+ @SerializedName("ID")
+ @Expose
+ private Integer iD;
+
+ @SerializedName("DetalTypeId")
+ @Expose
+ private Integer detalTypeId;
+
+ @SerializedName("DetailSubTypeId")
+ @Expose
+ private Integer detailSubTypeId;
+
+ @SerializedName("Name")
+ @Expose
+ private String name;
+
+ @SerializedName("Number")
+ @Expose
+ private Integer number;
+
+ @SerializedName("Place")
+ @Expose
+ private String place;
+
+ @SerializedName("Price")
+ @Expose
+ private String price;
+
+ @SerializedName("ManufacturerId")
+ @Expose
+ private Integer manufacturerId;
+
+ @SerializedName("Country")
+ @Expose
+ private String country;
+
+ @SerializedName("IsBU")
+ @Expose
+ private Boolean isBU;
+
+ @SerializedName("BodyTypeId")
+ @Expose
+ private Integer bodyTypeId;
+
+ @SerializedName("analogue")
+ @Expose
+ private String analogue;
+
+ @SerializedName("docURL")
+ @Expose
+ private String docURL;
+
+ @SerializedName("EdIzmId")
+ @Expose
+ private Integer edIzmId;
+
+ @SerializedName("State")
+ @Expose
+ private String state;
+
+ @SerializedName("Notes")
+ @Expose
+ private String notes;
+
+ @SerializedName("ID_Shop")
+ @Expose
+ private Integer iDShop;
+
+ public DetailModel() {
+ // Empty constructor
+ }
+
+ public DetailModel(Integer iD, Integer detalTypeId, Integer detailSubTypeId, String name, Integer number, String place, String price, Integer manufacturerId, String country, Boolean isBU, Integer bodyTypeId, String analogue, String docURL, Integer edIzmId, String state, String notes, Integer iDShop) {
+ super();
+ this.iD = iD;
+ this.detalTypeId = detalTypeId;
+ this.detailSubTypeId = detailSubTypeId;
+ this.name = name;
+ this.number = number;
+ this.place = place;
+ this.price = price;
+ this.manufacturerId = manufacturerId;
+ this.country = country;
+ this.isBU = isBU;
+ this.bodyTypeId = bodyTypeId;
+ this.analogue = analogue;
+ this.docURL = docURL;
+ this.edIzmId = edIzmId;
+ this.state = state;
+ this.notes = notes;
+ this.iDShop = iDShop;
+ }
+
+ public Integer getID() {
+ return iD;
+ }
+
+ public void setID(Integer iD) {
+ this.iD = iD;
+ }
+
+ public Integer getDetalTypeId() {
+ return detalTypeId;
+ }
+
+ public void setDetalTypeId(Integer detalTypeId) {
+ this.detalTypeId = detalTypeId;
+ }
+
+ public Integer getDetailSubTypeId() {
+ return detailSubTypeId;
+ }
+
+ public void setDetailSubTypeId(Integer detailSubTypeId) {
+ this.detailSubTypeId = detailSubTypeId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getNumber() {
+ return number;
+ }
+
+ public void setNumber(Integer number) {
+ this.number = number;
+ }
+
+ public String getPlace() {
+ return place;
+ }
+
+ public void setPlace(String place) {
+ this.place = place;
+ }
+
+ public String getPrice() {
+ return price;
+ }
+
+ public void setPrice(String price) {
+ this.price = price;
+ }
+
+ public Integer getManufacturerId() {
+ return manufacturerId;
+ }
+
+ public void setManufacturerId(Integer manufacturerId) {
+ this.manufacturerId = manufacturerId;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public Boolean getIsBU() {
+ return isBU;
+ }
+
+ public void setIsBU(Boolean isBU) {
+ this.isBU = isBU;
+ }
+
+ public Integer getBodyTypeId() {
+ return bodyTypeId;
+ }
+
+ public void setBodyTypeId(Integer bodyTypeId) {
+ this.bodyTypeId = bodyTypeId;
+ }
+
+ public String getAnalogue() {
+ return analogue;
+ }
+
+ public void setAnalogue(String analogue) {
+ this.analogue = analogue;
+ }
+
+ public String getDocURL() {
+ return docURL;
+ }
+
+ public void setDocURL(String docURL) {
+ this.docURL = docURL;
+ }
+
+ public Integer getEdIzmId() {
+ return edIzmId;
+ }
+
+ public void setEdIzmId(Integer edIzmId) {
+ this.edIzmId = edIzmId;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public Integer getIDShop() {
+ return iDShop;
+ }
+
+ public void setIDShop(Integer iDShop) {
+ this.iDShop = iDShop;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/FirstLevelModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/FirstLevelModel.java
new file mode 100644
index 0000000..3b467f7
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/FirstLevelModel.java
@@ -0,0 +1,46 @@
+package ru.volgorobot.vrcatalog.model;
+
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class FirstLevelModel {
+
+ @SerializedName("Name")
+ @Expose
+ private String name;
+
+ @SerializedName("ID")
+ @Expose
+ private Integer iD;
+
+
+ public FirstLevelModel() {
+ // Empty constructor
+ }
+
+ public FirstLevelModel(String name, Integer iD) {
+ this.name = name;
+ this.iD = iD;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getID() {
+ return iD;
+ }
+
+ public void setID(Integer iD) {
+ this.iD = iD;
+ }
+
+ public String toString() {
+ return name;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/SecondLevelModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/SecondLevelModel.java
new file mode 100644
index 0000000..51cfb71
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/SecondLevelModel.java
@@ -0,0 +1,57 @@
+package ru.volgorobot.vrcatalog.model;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class SecondLevelModel {
+
+ @SerializedName("ID")
+ @Expose
+ private Integer iD;
+
+ @SerializedName("DetailTypeId")
+ @Expose
+ private Integer detailTypeId;
+
+ @SerializedName("Name")
+ @Expose
+ private String name;
+
+ public SecondLevelModel() {
+ // Empty constructor
+ }
+
+ public SecondLevelModel(Integer iD, Integer detailTypeId, String name) {
+ this.iD = iD;
+ this.detailTypeId = detailTypeId;
+ this.name = name;
+ }
+
+ public Integer getID() {
+ return iD;
+ }
+
+ public void setID(Integer iD) {
+ this.iD = iD;
+ }
+
+ public Integer getDetailTypeId() {
+ return detailTypeId;
+ }
+
+ public void setDetailTypeId(Integer detailTypeId) {
+ this.detailTypeId = detailTypeId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/model/ThirdLevelModel.java b/app/src/main/java/ru/volgorobot/vrcatalog/model/ThirdLevelModel.java
new file mode 100644
index 0000000..c8898de
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/model/ThirdLevelModel.java
@@ -0,0 +1,65 @@
+package ru.volgorobot.vrcatalog.model;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class ThirdLevelModel {
+
+ @SerializedName("ID")
+ @Expose
+ private Integer iD;
+ @SerializedName("DetailSubTypeId")
+ @Expose
+ private Integer detailSubTypeId;
+ @SerializedName("Name")
+ @Expose
+ private String name;
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public ThirdLevelModel() {
+ }
+
+ /**
+ *
+ * @param detailSubTypeId Parent category
+ * @param name Name of detail
+ * @param iD ID of detail
+ */
+ public ThirdLevelModel(Integer iD, Integer detailSubTypeId, String name) {
+ super();
+ this.iD = iD;
+ this.detailSubTypeId = detailSubTypeId;
+ this.name = name;
+ }
+
+ public Integer getID() {
+ return iD;
+ }
+
+ public void setID(Integer iD) {
+ this.iD = iD;
+ }
+
+ public Integer getDetailSubTypeId() {
+ return detailSubTypeId;
+ }
+
+ public void setDetailSubTypeId(Integer detailSubTypeId) {
+ this.detailSubTypeId = detailSubTypeId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java
new file mode 100644
index 0000000..78b6495
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/FirstLevelNodeViewBinder.java
@@ -0,0 +1,58 @@
+package ru.volgorobot.vrcatalog.nodeViewBinders;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import me.texy.treeview.TreeNode;
+import me.texy.treeview.base.BaseNodeViewBinder;
+import ru.volgorobot.vrcatalog.MainContract;
+import ru.volgorobot.vrcatalog.R;
+import ru.volgorobot.vrcatalog.ViewBinderPresenter;
+import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
+import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode;
+import ru.volgorobot.vrcatalog.model.CoreModel;
+import ru.volgorobot.vrcatalog.model.FirstLevelModel;
+import ru.volgorobot.vrcatalog.model.SecondLevelModel;
+
+public class FirstLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder {
+ TextView textView;
+ ImageView imageView;
+ ViewBinderPresenter viewBinderPresenter;
+
+ public FirstLevelNodeViewBinder(View itemView, Context context, MainContract.MainActivityView mView, MainContract.MainModel coreModel) {
+ super(itemView);
+ textView = (TextView) itemView.findViewById(R.id.node_name_view);
+ imageView = (ImageView) itemView.findViewById(R.id.arrow_img);
+ viewBinderPresenter = new ViewBinderPresenter(mView, coreModel, this);
+ }
+
+ @Override
+ public int getLayoutId() {
+ return R.layout.first_level_item;
+ }
+
+ @Override
+ public void bindView(TreeNode treeNode) {
+ textView.setText(treeNode.getValue().toString());
+ }
+
+ @Override
+ public void onNodeToggled(TreeNode treeNode, boolean expand) {
+ if(expand) {
+ FirstLevelModel firstLevelModel = (FirstLevelModel) treeNode.getValue();
+ viewBinderPresenter.fetchSecondLevel(firstLevelModel, treeNode);
+ } else {
+ imageView.animate().rotation(0).setDuration(200).start();
+ }
+ }
+
+ @Override
+ 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
new file mode 100644
index 0000000..fb561bb
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/SecondLevelNodeViewBinder.java
@@ -0,0 +1,60 @@
+package ru.volgorobot.vrcatalog.nodeViewBinders;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import me.texy.treeview.TreeNode;
+import me.texy.treeview.base.BaseNodeViewBinder;
+import ru.volgorobot.vrcatalog.MainContract;
+import ru.volgorobot.vrcatalog.R;
+import ru.volgorobot.vrcatalog.ViewBinderPresenter;
+import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
+import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode;
+import ru.volgorobot.vrcatalog.model.CoreModel;
+import ru.volgorobot.vrcatalog.model.SecondLevelModel;
+import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
+
+public class SecondLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder {
+ TextView textView;
+ ImageView imageView;
+ MainContract.ViewBinderPresenter viewBinderPresenter;
+
+
+ public SecondLevelNodeViewBinder(View itemView, Context context, MainContract.MainActivityView mView, CoreModel coreModel) {
+ super(itemView);
+ textView = (TextView) itemView.findViewById(R.id.node_name_view);
+ imageView = (ImageView) itemView.findViewById(R.id.arrow_img);
+ viewBinderPresenter = new ViewBinderPresenter(mView, coreModel, this);
+ }
+
+ @Override
+ public int getLayoutId() {
+ return R.layout.second_level_item;
+ }
+
+ @Override
+ public void bindView(final TreeNode treeNode) {
+ textView.setText(treeNode.getValue().toString());
+ imageView.setRotation(treeNode.isExpanded() ? 90 : 0);
+ }
+
+ @Override
+ public void onNodeToggled(TreeNode treeNode, boolean expand) {
+ if(expand) {
+ SecondLevelModel secondLevelModel = (SecondLevelModel) treeNode.getValue();
+ viewBinderPresenter.fetchThirdLevel(secondLevelModel, treeNode);
+ } else {
+ imageView.animate().rotation(0).setDuration(200).start();
+ }
+ }
+
+ @Override
+ public void rotateImageView() {
+ imageView.animate().rotation(90).setDuration(200).start();
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java
new file mode 100644
index 0000000..1545d46
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/nodeViewBinders/ThirdLevelNodeViewBinder.java
@@ -0,0 +1,54 @@
+package ru.volgorobot.vrcatalog.nodeViewBinders;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import me.texy.treeview.TreeNode;
+import me.texy.treeview.base.BaseNodeViewBinder;
+import ru.volgorobot.vrcatalog.MainContract;
+import ru.volgorobot.vrcatalog.R;
+import ru.volgorobot.vrcatalog.ViewBinderPresenter;
+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.ThirdLevelModel;
+import ru.volgorobot.vrcatalog.view.DetailActivity;
+
+public class ThirdLevelNodeViewBinder extends BaseNodeViewBinder implements MainContract.ViewBinder {
+ TextView textView;
+ MainContract.ViewBinderPresenter viewBinderPresenter;
+
+ public ThirdLevelNodeViewBinder(View itemView, Context context, MainContract.MainActivityView mView, CoreModel coreModel) {
+ super(itemView);
+ viewBinderPresenter = new ViewBinderPresenter(mView, coreModel, this, context);
+ textView = (TextView) itemView.findViewById(R.id.node_name_view);
+ }
+
+ @Override
+ public int getLayoutId() {
+ return R.layout.third_level_item;
+ }
+
+ @Override
+ public void bindView(final TreeNode treeNode) {
+ textView.setText(treeNode.getValue().toString());
+ }
+
+ @Override
+ public void onNodeToggled(TreeNode treeNode, boolean expand) {
+ super.onNodeToggled(treeNode, expand);
+ ThirdLevelModel thirdLevelModel = (ThirdLevelModel) treeNode.getValue();
+ viewBinderPresenter.fetchDetail(thirdLevelModel);
+ }
+
+ @Override
+ public void rotateImageView() {
+ // This is unnecessary.
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/AboutActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java
similarity index 92%
rename from app/src/main/java/ru/volgorobot/vrcatalog/AboutActivity.java
rename to app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java
index 817410f..a1496df 100644
--- a/app/src/main/java/ru/volgorobot/vrcatalog/AboutActivity.java
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/AboutActivity.java
@@ -1,10 +1,12 @@
-package ru.volgorobot.vrcatalog;
+package ru.volgorobot.vrcatalog.view;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
+import ru.volgorobot.vrcatalog.R;
+
public class AboutActivity extends AppCompatActivity {
@Override
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/DetailActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/DetailActivity.java
new file mode 100644
index 0000000..b478d3b
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/DetailActivity.java
@@ -0,0 +1,114 @@
+package ru.volgorobot.vrcatalog.view;
+
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.text.method.LinkMovementMethod;
+import android.view.MenuItem;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ru.volgorobot.vrcatalog.R;
+
+public class DetailActivity extends AppCompatActivity {
+ TextView nameView;
+ TextView quantityView;
+ TextView priceView;
+ TextView countryView;
+ TextView analogueView;
+ TextView datasheetView;
+ EditText notesView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_detail);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeButtonEnabled(true);
+ initializeViews();
+
+ Intent intent = getIntent();
+
+ HashMap extrasMap = getIntentExtras(intent);
+
+ nameView.setText(extrasMap.get("detailName"));
+ quantityView.setText(extrasMap.get("detailQuantity"));
+ priceView.setText(extrasMap.get("detailPrice"));
+ countryView.setText(extrasMap.get("detailCountry"));
+ analogueView.setText(extrasMap.get("detailAnalogue"));
+ datasheetView.setText(extrasMap.get("detailDatasheet"));
+ notesView.setText(extrasMap.get("detailNotes"));
+ }
+
+ void initializeViews() {
+ nameView = findViewById(R.id.name);
+ quantityView = findViewById(R.id.quantity);
+ priceView = findViewById(R.id.price);
+ notesView = findViewById(R.id.notes);
+ countryView = findViewById(R.id.country);
+ analogueView = findViewById(R.id.analogue);
+ datasheetView = findViewById(R.id.datasheet);
+ datasheetView.setMovementMethod(LinkMovementMethod.getInstance());
+ }
+
+ HashMap getIntentExtras(Intent intent) {
+ HashMap hashMap = new HashMap<>();
+ String tmp;
+
+ tmp = intent.getStringExtra("detailName");
+ hashMap.put("detailName", tmp);
+
+ tmp = intent.getStringExtra("detailQuantity");
+ if(tmp.equals("0")) {
+ tmp = "Под заказ";
+ }
+ hashMap.put("detailQuantity", tmp);
+
+ tmp = intent.getStringExtra("detailPrice");
+ if(tmp.equals("0")) {
+ tmp = "Уточните у продавца";
+ }
+ hashMap.put("detailPrice", tmp);
+
+ tmp = intent.getStringExtra("detailCountry");
+ if(tmp.equals("")) {
+ tmp = "Не указано";
+ }
+ hashMap.put("detailCountry", tmp);
+
+ tmp = intent.getStringExtra("detailAnalogue");
+ if(tmp.equals("")) {
+ tmp = "Нет аналогов";
+ }
+ hashMap.put("detailAnalogue", tmp);
+
+ tmp = intent.getStringExtra("detailDatasheet");
+ if(!tmp.matches("\\S")) {
+ tmp = "Не указано";
+ }
+ hashMap.put("detailDatasheet", tmp);
+
+ tmp = intent.getStringExtra("detailNotes");
+ if(tmp != null && tmp.equals("")) {
+ tmp = "Нет описания";
+ } else if (tmp == null){
+ tmp = "Нет описания";
+ }
+ hashMap.put("detailNotes", tmp);
+
+ return hashMap;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java
new file mode 100644
index 0000000..88a25af
--- /dev/null
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/MainActivity.java
@@ -0,0 +1,160 @@
+package ru.volgorobot.vrcatalog.view;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.design.widget.NavigationView;
+import android.support.v4.view.GravityCompat;
+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.Toolbar;
+import android.util.Log;
+import android.view.MenuItem;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+import me.texy.treeview.TreeNode;
+import me.texy.treeview.TreeView;
+import ru.volgorobot.vrcatalog.MainContract;
+import ru.volgorobot.vrcatalog.MainPresenter;
+import ru.volgorobot.vrcatalog.R;
+import ru.volgorobot.vrcatalog.additional.NodeViewFactory;
+import ru.volgorobot.vrcatalog.model.FirstLevelModel;
+
+public class MainActivity extends AppCompatActivity
+ implements NavigationView.OnNavigationItemSelectedListener, SwipeRefreshLayout.OnRefreshListener, MainContract.MainActivityView {
+
+ private MainContract.Presenter mPresenter;
+ private TreeView treeView;
+ private TreeNode rootNode = TreeNode.root();
+ private SwipeRefreshLayout mSwipeRefreshLayout;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ DrawerLayout drawer = findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+ drawer.addDrawerListener(toggle);
+ toggle.syncState();
+
+ NavigationView navigationView = findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+
+ mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
+ mSwipeRefreshLayout.setOnRefreshListener(MainActivity.this);
+ mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
+
+ mPresenter = new MainPresenter(this, MainActivity.this);
+
+ treeView = new TreeView(rootNode, MainActivity.this, new NodeViewFactory(MainActivity.this, this, this.mPresenter.getCoreModel()));
+ treeView.setItemAnimator(new DefaultItemAnimator());
+ ((ViewGroup) findViewById(R.id.treeViewContainer)).addView(treeView.getView());
+ mSwipeRefreshLayout.setRefreshing(true);
+ mPresenter.getFirstLevel();
+ }
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+ // Handle navigation view item clicks here.
+ int id = item.getItemId();
+ NavigationView navView = findViewById(R.id.nav_view);
+
+ if (id == R.id.nav_settings) {
+ startActivity(new Intent(this, SettingsActivity.class));
+
+ } else if (id == R.id.nav_about) {
+ startActivity(new Intent(this, AboutActivity.class));
+ }
+
+ DrawerLayout drawer = findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+ return true;
+ }
+
+
+ @Override
+ public void onRefresh() {
+ mPresenter.getFirstLevel();
+ }
+
+ public void onFailureAnswer(int errorCode) {
+ switch (errorCode) {
+ case 1: {
+ Toast.makeText(MainActivity.this, "Ошибка сети. Проверьте подключение к сети или данные подключения к API!", Toast.LENGTH_LONG).show();
+ Log.e("VRCatalog", "Network Error! Re-check your connection credentials or network settings! Technical info: null");
+ mSwipeRefreshLayout.setRefreshing(false);
+ break;
+ }
+ case 2: {
+ Toast.makeText(MainActivity.this, "Ответ от сервера неверен! Перепроверьте данные подключения!", Toast.LENGTH_LONG).show();
+ Log.e("VRCatalog", "Answer of server is wrong! Re-check your connection credentials! Technical info: null");
+ mSwipeRefreshLayout.setRefreshing(false);
+ break;
+ }
+ case 3: {
+ Toast.makeText(this, "Вы ввели неверный URL. Пример: http://example.ru", Toast.LENGTH_LONG).show();
+ mSwipeRefreshLayout.setRefreshing(false);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void swipeLayoutSetRefreshing(boolean state) {
+ mSwipeRefreshLayout.setRefreshing(state);
+ }
+
+ @Override
+ public void buildFirstLevelTree(ArrayList firstLevelModels) {
+ ArrayList treeNodes = new ArrayList<>();
+ for (int i = 0; i < firstLevelModels.size(); i++) {
+ TreeNode treeNode = new TreeNode(firstLevelModels.get(i));
+ treeNode.setLevel(0);
+ treeNodes.add(treeNode);
+ }
+ rootNode.setChildren(treeNodes);
+ treeView.refreshTreeView();
+ }
+
+ @Override
+ public void refreshTree() {
+ treeView.refreshTreeView();
+ }
+
+ @Override
+ public void startActivityByIntent(Intent intent) {
+ startActivity(intent);
+ }
+}
+
+
diff --git a/app/src/main/java/ru/volgorobot/vrcatalog/SettingsActivity.java b/app/src/main/java/ru/volgorobot/vrcatalog/view/SettingsActivity.java
similarity index 64%
rename from app/src/main/java/ru/volgorobot/vrcatalog/SettingsActivity.java
rename to app/src/main/java/ru/volgorobot/vrcatalog/view/SettingsActivity.java
index 928ab76..e4d5335 100644
--- a/app/src/main/java/ru/volgorobot/vrcatalog/SettingsActivity.java
+++ b/app/src/main/java/ru/volgorobot/vrcatalog/view/SettingsActivity.java
@@ -1,23 +1,21 @@
-package ru.volgorobot.vrcatalog;
+package ru.volgorobot.vrcatalog.view;
-import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
-import android.support.v7.app.AppCompatDelegate;
import android.view.Menu;
import android.view.MenuItem;
-import android.preference.PreferenceActivity;
-public class SettingsActivity extends PreferenceActivity {
+import ru.volgorobot.vrcatalog.R;
+import ru.volgorobot.vrcatalog.additional.AppCompatPreferenceActivity;
- private AppCompatDelegate mDelegate;
+public class SettingsActivity extends AppCompatPreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.activity_settings);
- //getActionBar().setDisplayHomeAsUpEnabled(true);
- //getActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeButtonEnabled(true);
}
@Override
diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml
new file mode 100644
index 0000000..a3d1622
--- /dev/null
+++ b/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml
index 4bc0a9c..f89d895 100644
--- a/app/src/main/res/layout/activity_about.xml
+++ b/app/src/main/res/layout/activity_about.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
- tools:context=".AboutActivity">
+ tools:context=".view.AboutActivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 1b78829..1916f82 100644
--- a/app/src/main/res/layout/app_bar_main.xml
+++ b/app/src/main/res/layout/app_bar_main.xml
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".MainActivity">
+ tools:context=".view.MainActivity">
-
+ tools:context=".view.MainActivity"
+ tools:showIn="@layout/app_bar_main"
+ android:orientation="horizontal"
+ android:id="@+id/swipeRefreshLayout">
-
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/first_level_item.xml b/app/src/main/res/layout/first_level_item.xml
new file mode 100644
index 0000000..68a0797
--- /dev/null
+++ b/app/src/main/res/layout/first_level_item.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/second_level_item.xml b/app/src/main/res/layout/second_level_item.xml
new file mode 100644
index 0000000..b1ede8e
--- /dev/null
+++ b/app/src/main/res/layout/second_level_item.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/third_level_item.xml b/app/src/main/res/layout/third_level_item.xml
new file mode 100644
index 0000000..2679be5
--- /dev/null
+++ b/app/src/main/res/layout/third_level_item.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/activity_settings.xml b/app/src/main/res/xml/activity_settings.xml
index 3609123..a97929d 100644
--- a/app/src/main/res/xml/activity_settings.xml
+++ b/app/src/main/res/xml/activity_settings.xml
@@ -2,6 +2,7 @@
+ android:title="Адрес API-сервера"
+ android:summary="API-сервер необходим для доступа к БД деталей"
+ android:defaultValue="http://example.com"/>
\ No newline at end of file
diff --git a/app/src/test/java/ru/volgorobot/vrcatalog/ExampleUnitTest.java b/app/src/test/java/ru/volgorobot/vrcatalog/ExampleUnitTest.java
deleted file mode 100644
index ac47aea..0000000
--- a/app/src/test/java/ru/volgorobot/vrcatalog/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package ru.volgorobot.vrcatalog;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 077cb2f..03de3f4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,9 +5,10 @@ buildscript {
repositories {
google()
jcenter()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
@@ -19,6 +20,7 @@ allprojects {
repositories {
google()
jcenter()
+ mavenCentral()
}
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4b3c7b5..3f0f9be 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Sat Sep 08 16:32:20 MSK 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip