Merge branch 'develop' into 'master'

Release version 0.1.0

See merge request ChronosX88/VRCatalog!2
This commit is contained in:
ChronosX88 2019-01-11 21:00:09 +00:00
commit 2ed06e448f
40 changed files with 1925 additions and 144 deletions

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/home/chronosx/Документы/bin/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/hardware/ic_keyboard_arrow_right_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputName" value="ic_keyboard_arrow_right_black_24dp" />
<entry key="sourceFile" value="$USER_HOME$" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -29,7 +29,7 @@
</value> </value>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@ -10,13 +10,17 @@ android {
versionName "1.0" versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }
buildToolsVersion '27.0.3' buildToolsVersion '28.0.3'
} }
dependencies { dependencies {
@ -24,7 +28,9 @@ dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1' implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12' implementation 'me.texy.treeview:treeview_lib:1.0.4'
androidTestImplementation 'com.android.support.test:runner:1.0.2' implementation 'com.google.code.gson:gson:2.8.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.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'
} }

View File

@ -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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@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());
}
}

View File

@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.volgorobot.vrcatalog"> package="ru.volgorobot.vrcatalog">
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -10,7 +12,7 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:name=".MainActivity" android:name=".view.MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
@ -19,8 +21,9 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".SettingsActivity" /> <activity android:name=".view.SettingsActivity" />
<activity android:name=".AboutActivity"></activity> <activity android:name=".view.AboutActivity" />
<activity android:name=".view.DetailActivity"></activity>
</application> </application>
</manifest> </manifest>

View File

@ -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;
}
}

View File

@ -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<FirstLevelModel> 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<FirstLevelModel> fetchFirstLevel() throws NetworkErrorException, NullPointerException;
ArrayList<SecondLevelModel> fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException;
void reinitializeApi() throws IllegalStateException;
boolean getApiState();
}
}

View File

@ -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<Void, Void, ResultWithErrorCode<ArrayList<FirstLevelModel>>>() {
@Override
protected ResultWithErrorCode<ArrayList<FirstLevelModel>> doInBackground(Void... voids) {
ArrayList<FirstLevelModel> 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<ArrayList<FirstLevelModel>> 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;
}
}

View File

@ -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<FirstLevelModel, Void, ResultWithErrorCode<ArrayList<SecondLevelModel>>>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
mView.swipeLayoutSetRefreshing(true);
}
@Override
protected ResultWithErrorCode<ArrayList<SecondLevelModel>> doInBackground(FirstLevelModel... firstLevelModel) {
ArrayList<SecondLevelModel> 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<ArrayList<SecondLevelModel>> result) {
super.onPostExecute(result);
switch (result.getErrorCode()) {
case 0: {
ArrayList<TreeNode> 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<SecondLevelModel, Void, ResultWithErrorCode<ArrayList<ThirdLevelModel>>>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
mView.swipeLayoutSetRefreshing(true);
}
@Override
protected ResultWithErrorCode<ArrayList<ThirdLevelModel>> doInBackground(SecondLevelModel... secondLevelModel) {
ArrayList<ThirdLevelModel> 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<ArrayList<ThirdLevelModel>> result) {
super.onPostExecute(result);
switch (result.getErrorCode()) {
case 0: {
ArrayList<TreeNode> 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<ThirdLevelModel, Void, ResultWithErrorCode<DetailModel>>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
mView.swipeLayoutSetRefreshing(true);
}
@Override
protected ResultWithErrorCode<DetailModel> doInBackground(ThirdLevelModel... thirdLevelModel) {
ArrayList<DetailModel> 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<DetailModel> 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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,28 @@
package ru.volgorobot.vrcatalog.additional;
public class ResultWithErrorCode<T> {
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;
}
}

View File

@ -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();
}
}
}

View File

@ -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<List<FirstLevelModel>> getFirstLevel();
@GET("/API/Api.php?action=getSecondLevel")
Call<List<SecondLevelModel>> getSecondLevel(@Query("parentTypeID") int parentTypeID);
@GET("/API/Api.php?action=getDetailsByParentID")
Call<List<ThirdLevelModel>> getDetails(@Query("parentID") int parentID);
@GET("/API/Api.php?action=getDetailByID")
Call<List<DetailModel>> getDetailByID(@Query("detailID") int detailID);
}

View File

@ -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<FirstLevelModel> fetchFirstLevel() throws NetworkErrorException, NullPointerException {
if(vrApi == null) {
throw new NullPointerException();
}
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
try {
Response<List<FirstLevelModel>> 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<SecondLevelModel> fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
if(vrApi == null) {
throw new NullPointerException();
}
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
try {
Response<List<SecondLevelModel>> 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<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
if(vrApi == null) {
throw new NullPointerException();
}
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
try {
Response<List<ThirdLevelModel>> 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<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException {
if(vrApi == null) {
throw new NullPointerException();
}
ArrayList<DetailModel> detail = new ArrayList<>();
try {
Response<List<DetailModel>> 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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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.
}
}

View File

@ -1,10 +1,12 @@
package ru.volgorobot.vrcatalog; package ru.volgorobot.vrcatalog.view;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import ru.volgorobot.vrcatalog.R;
public class AboutActivity extends AppCompatActivity { public class AboutActivity extends AppCompatActivity {
@Override @Override

View File

@ -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<String, String> 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<String, String> getIntentExtras(Intent intent) {
HashMap<String, String> 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);
}
}

View File

@ -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<FirstLevelModel> firstLevelModels) {
ArrayList<TreeNode> 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);
}
}

View File

@ -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.os.Bundle;
import android.support.v7.app.AppCompatDelegate;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; 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 @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.activity_settings); addPreferencesFromResource(R.xml.activity_settings);
//getActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//getActionBar().setHomeButtonEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
} }
@Override @Override

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M8.59,16.34l4.58,-4.59 -4.58,-4.59L10,5.75l6,6 -6,6z"/>
</vector>

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center" android:gravity="center"
tools:context=".AboutActivity"> tools:context=".view.AboutActivity">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteY="81dp">
<TextView
android:id="@+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Название: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBaseline_toBaselineOf="@+id/name"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="@+id/name_text"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/notes_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="172dp"
android:text="Описание: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintStart_toStartOf="@+id/notes"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/quantity_text"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:text="Количество на складе: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBaseline_toBaselineOf="@+id/quantity"
app:layout_constraintStart_toStartOf="@+id/name_text" />
<TextView
android:id="@+id/quantity"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/price"
app:layout_constraintStart_toEndOf="@+id/quantity_text"
app:layout_constraintTop_toTopOf="@+id/name" />
<EditText
android:id="@+id/notes"
android:layout_width="0dp"
android:layout_height="99dp"
android:layout_marginStart="16dp"
android:layout_marginTop="18dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:focusable="false"
android:focusableInTouchMode="false"
android:inputType="textMultiLine"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/notes_text">
<requestFocus />
</EditText>
<TextView
android:id="@+id/price_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Цена: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBaseline_toBaselineOf="@+id/price"
app:layout_constraintStart_toStartOf="@+id/quantity_text" />
<TextView
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="11dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/country_text"
app:layout_constraintStart_toEndOf="@+id/price_text" />
<TextView
android:id="@+id/country_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Страна изготовления: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBaseline_toBaselineOf="@+id/country"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/country"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginTop="86dp"
android:layout_marginBottom="86dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/notes_text"
app:layout_constraintStart_toEndOf="@+id/country_text"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/analogue_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Аналоги: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBaseline_toBaselineOf="@+id/analogue"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/analogue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="@+id/analogue_text"
app:layout_constraintTop_toBottomOf="@+id/country_text" />
<TextView
android:id="@+id/datasheet_text"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginStart="16dp"
android:text="Техническая спецификация: "
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBaseline_toBaselineOf="@+id/datasheet"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/datasheet"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_marginTop="128dp"
android:layout_marginBottom="127dp"
android:autoLink="web"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/notes"
app:layout_constraintStart_toEndOf="@+id/datasheet_text"
app:layout_constraintTop_toTopOf="@+id/name" />
</android.support.constraint.ConstraintLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".view.MainActivity">
<android.support.design.widget.AppBarLayout <android.support.design.widget.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,11 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity" tools:context=".view.MainActivity"
tools:showIn="@layout/app_bar_main"> tools:showIn="@layout/app_bar_main"
android:orientation="horizontal"
android:id="@+id/swipeRefreshLayout">
</android.support.constraint.ConstraintLayout> <android.support.v4.widget.NestedScrollView
android:id="@+id/treeViewContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawVerticalTrack="true">
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp">
<LinearLayout
android:id="@+id/node_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/arrow_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_keyboard_arrow_right_black_24dp" />
<TextView
android:id="@+id/node_name_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Tree Node"
android:textAppearance="@style/TextAppearance.AppCompat"
android:textSize="18sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/node_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="60dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/arrow_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_keyboard_arrow_right_black_24dp" />
<TextView
android:id="@+id/node_name_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="monospace"
android:text="Tree Node"
android:textAppearance="@style/TextAppearance.AppCompat"
android:textSize="18sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/node_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="110dp"
android:orientation="horizontal">
<TextView
android:id="@+id/node_name_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="monospace"
android:text="Tree Node"
android:textAppearance="@style/TextAppearance.AppCompat"
android:textSize="18sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -2,6 +2,7 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference <EditTextPreference
android:key="addressOfServer" android:key="addressOfServer"
android:title="Адрес PHP скрипта-посредника" android:title="Адрес API-сервера"
android:summary="PHP скрипт-посредник необходим для доступа к БД деталей" /> android:summary="API-сервер необходим для доступа к БД деталей"
android:defaultValue="http://example.com"/>
</PreferenceScreen> </PreferenceScreen>

View File

@ -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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

View File

@ -5,9 +5,10 @@ buildscript {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
} }
dependencies { 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 // NOTE: Do not place your application dependencies here; they belong
@ -19,6 +20,7 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
} }
} }

View File

@ -1,6 +1,5 @@
#Sat Sep 08 16:32:20 MSK 2018
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists 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