Merge branch 'develop' into 'master'
Release version 0.3 See merge request ChronosX88/VRCatalog!5
This commit is contained in:
commit
b6200a39d9
6
.idea/assetWizardSettings.xml
generated
6
.idea/assetWizardSettings.xml
generated
@ -18,7 +18,7 @@
|
||||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="jar:file:/home/WORK/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_search_black_24dp.xml" />
|
||||
<entry key="url" value="jar:file:/home/chronosx/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B/bin/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/file/ic_cloud_off_black_24dp.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
@ -28,8 +28,8 @@
|
||||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="color" value="ffffff" />
|
||||
<entry key="outputName" value="ic_search_white_24dp" />
|
||||
<entry key="color" value="a9a9a9" />
|
||||
<entry key="outputName" value="ic_cloud_off_black_24dp" />
|
||||
<entry key="sourceFile" value="$USER_HOME$" />
|
||||
</map>
|
||||
</option>
|
||||
|
BIN
.idea/caches/gradle_models.ser
generated
Normal file
BIN
.idea/caches/gradle_models.ser
generated
Normal file
Binary file not shown.
6
.idea/render.experimental.xml
generated
Normal file
6
.idea/render.experimental.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RenderSettings">
|
||||
<option name="showDecorations" value="true" />
|
||||
</component>
|
||||
</project>
|
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@ -2,5 +2,6 @@
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -6,8 +6,8 @@ android {
|
||||
applicationId "ru.volgorobot.vrcatalog"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 27
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionCode 4
|
||||
versionName "0.3"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
compileOptions {
|
||||
@ -33,4 +33,5 @@ dependencies {
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
|
||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
||||
}
|
||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
}
|
@ -23,7 +23,9 @@
|
||||
</activity>
|
||||
<activity android:name=".view.SettingsActivity" />
|
||||
<activity android:name=".view.AboutActivity" />
|
||||
<activity android:name=".view.DetailActivity" />
|
||||
<activity
|
||||
android:name=".view.DetailActivity"
|
||||
android:theme="@style/ItemActivityTheme"/>
|
||||
<activity
|
||||
android:name=".view.SearchableActivity"
|
||||
android:label="Поиск"
|
||||
|
106
app/src/main/java/ru/volgorobot/vrcatalog/ItemPresenter.java
Normal file
106
app/src/main/java/ru/volgorobot/vrcatalog/ItemPresenter.java
Normal file
@ -0,0 +1,106 @@
|
||||
package ru.volgorobot.vrcatalog;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Base64;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
import ru.volgorobot.vrcatalog.additional.NetworkErrorException;
|
||||
import ru.volgorobot.vrcatalog.additional.ResultWithErrorCode;
|
||||
import ru.volgorobot.vrcatalog.model.CoreModel;
|
||||
import ru.volgorobot.vrcatalog.model.ImageItemModel;
|
||||
|
||||
public class ItemPresenter implements MainContract.ItemPresenter {
|
||||
|
||||
// TODO
|
||||
|
||||
private MainContract.ItemView mView;
|
||||
private Context context;
|
||||
private MainContract.MainModel coreModel;
|
||||
|
||||
public ItemPresenter(Context context, MainContract.ItemView itemView) {
|
||||
this.mView = itemView;
|
||||
this.context = context;
|
||||
this.coreModel = new CoreModel(context);
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
@Override
|
||||
public void getImagesByItemID(int id) {
|
||||
new AsyncTask<Void, Void, ResultWithErrorCode<ArrayList<ImageItemModel>>>() {
|
||||
@Override
|
||||
protected ResultWithErrorCode<ArrayList<ImageItemModel>> doInBackground(Void... voids) {
|
||||
ArrayList<ImageItemModel> images = null;
|
||||
try {
|
||||
images = coreModel.fetchImagesByItemID(id);
|
||||
} catch (NetworkErrorException networkErrorException) {
|
||||
return new ResultWithErrorCode<>(images, networkErrorException.getErrorCode());
|
||||
} catch (NullPointerException nullPointerException) {
|
||||
return new ResultWithErrorCode<>(images, 3);
|
||||
}
|
||||
return new ResultWithErrorCode<>(images, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(ResultWithErrorCode<ArrayList<ImageItemModel>> result) {
|
||||
super.onPostExecute(result);
|
||||
switch (result.getErrorCode()) {
|
||||
case 0: {
|
||||
//mView.setViewPagerContent(result.getData());
|
||||
ArrayList<Bitmap> bitmaps = new ArrayList<>();
|
||||
ArrayList<String> uriStrings = new ArrayList<>();
|
||||
for (ImageItemModel imageItem : result.getData()) {
|
||||
byte[] imageStream = Base64.decode(imageItem.getImage(), Base64.DEFAULT);
|
||||
bitmaps.add(BitmapFactory.decodeByteArray(imageStream, 0, imageStream.length));
|
||||
}
|
||||
for (int i = 0; i < bitmaps.size(); i++) {
|
||||
uriStrings.add(processImages(bitmaps.get(i)).toString());
|
||||
}
|
||||
String[] uriStringsArray = new String[uriStrings.size()];
|
||||
uriStrings.toArray(uriStringsArray);
|
||||
mView.setViewPagerContent(uriStringsArray);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
mView.onFailureAnswer(1);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
mView.onFailureAnswer(2);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
mView.onFailureAnswer(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private Uri processImages(Bitmap bitmap) {
|
||||
File cacheDir = context.getCacheDir();
|
||||
File cacheObject = new File(cacheDir, UUID.randomUUID().toString());
|
||||
try {
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(cacheObject);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Uri.fromFile(cacheObject);
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ 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.ImageItemModel;
|
||||
import ru.volgorobot.vrcatalog.model.SecondLevelModel;
|
||||
import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
|
||||
|
||||
@ -42,10 +43,11 @@ public interface MainContract {
|
||||
ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
|
||||
ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException;
|
||||
void reinitializeApi() throws IllegalStateException;
|
||||
boolean getApiState();
|
||||
boolean isApiNotNull();
|
||||
ArrayList<ThirdLevelModel> fetchDetailsByName(String name) throws NetworkErrorException, NullPointerException;
|
||||
ArrayList<FirstLevelModel> fetchCategoryByID(int id) throws NetworkErrorException, NullPointerException;
|
||||
ArrayList<SecondLevelModel> fetchSubCategoryByID(int id) throws NetworkErrorException, NullPointerException;
|
||||
ArrayList<ImageItemModel> fetchImagesByItemID(int id) throws NetworkErrorException, NullPointerException;
|
||||
}
|
||||
|
||||
interface SearchablePresenter {
|
||||
@ -57,4 +59,13 @@ public interface MainContract {
|
||||
void onFailureAnswer(int errorCode);
|
||||
void swipeLayoutSetRefreshing(boolean state);
|
||||
}
|
||||
|
||||
interface ItemPresenter {
|
||||
void getImagesByItemID(int id);
|
||||
}
|
||||
|
||||
interface ItemView {
|
||||
void onFailureAnswer(int errorCode);
|
||||
void setViewPagerContent(String[] uris);
|
||||
}
|
||||
}
|
||||
|
@ -170,6 +170,7 @@ public class ViewBinderPresenter implements MainContract.ViewBinderPresenter {
|
||||
switch (result.getErrorCode()) {
|
||||
case 0: {
|
||||
Intent intent = new Intent(context, DetailActivity.class);
|
||||
intent.putExtra("itemID", result.getData().getID().toString());
|
||||
intent.putExtra("detailName", result.getData().getName());
|
||||
intent.putExtra("detailQuantity", result.getData().getNumber().toString());
|
||||
intent.putExtra("detailPrice", result.getData().getPrice());
|
||||
|
@ -0,0 +1,76 @@
|
||||
package ru.volgorobot.vrcatalog.additional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ImagePagerAdapter extends PagerAdapter {
|
||||
/**
|
||||
* This class is designed to control the ViewPager (images of item) in the activity of viewing details of items.
|
||||
*/
|
||||
|
||||
private Context context;
|
||||
private String[] imageUris;
|
||||
|
||||
public ImagePagerAdapter(Context context, String[] imageUris) {
|
||||
this.context = context;
|
||||
this.imageUris = imageUris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return imageUris.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes a new image from a URI.
|
||||
* @return ImageView
|
||||
*/
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(@NonNull ViewGroup container, int position) {
|
||||
ImageView imageView = new ImageView(context);
|
||||
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(313, 313);
|
||||
imageView.setLayoutParams(params);
|
||||
Picasso.get()
|
||||
.load(imageUris[position])
|
||||
.resize(0, 313)
|
||||
.centerCrop()
|
||||
.into(imageView);
|
||||
container.addView(imageView);
|
||||
|
||||
return imageView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||
container.removeView((View) object);
|
||||
}
|
||||
|
||||
public Bitmap getBitmap(int position) {
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(imageUris[position]));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package ru.volgorobot.vrcatalog.additional;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import ru.volgorobot.vrcatalog.R;
|
||||
|
||||
public class PropertiesListAdapter extends BaseAdapter {
|
||||
private LinkedHashMap<String, String> mData;
|
||||
private String[] mKeys;
|
||||
|
||||
public PropertiesListAdapter(LinkedHashMap<String, String> data) {
|
||||
mData = data;
|
||||
mKeys = mData.keySet().toArray(new String[data.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mData.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return mData.get(mKeys[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
final View result;
|
||||
|
||||
if (convertView == null) {
|
||||
result = LayoutInflater.from(parent.getContext()).inflate(R.layout.properties_list_adapter, parent, false);
|
||||
} else {
|
||||
result = convertView;
|
||||
}
|
||||
|
||||
((TextView) result.findViewById(R.id.propertyNameView)).setText(mKeys[position]);
|
||||
((TextView) result.findViewById(R.id.propertyValueView)).setText(getItem(position).toString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ import me.texy.treeview.base.BaseNodeViewBinder;
|
||||
import me.texy.treeview.base.BaseNodeViewFactory;
|
||||
import ru.volgorobot.vrcatalog.MainContract;
|
||||
import ru.volgorobot.vrcatalog.nodeViewBinders.ThirdLevelNodeViewBinder;
|
||||
import ru.volgorobot.vrcatalog.searchNodeViewBinders.SecondLevelNodeViewBinder;
|
||||
import ru.volgorobot.vrcatalog.searchNodeViewBinders.FirstLevelNodeViewBinder;
|
||||
import ru.volgorobot.vrcatalog.searchNodeViewBinders.SecondLevelNodeViewBinder;
|
||||
|
||||
public class SearchableNodeViewFactory extends BaseNodeViewFactory {
|
||||
private Context context;
|
||||
|
@ -4,32 +4,37 @@ import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
import ru.volgorobot.vrcatalog.model.DetailModel;
|
||||
import ru.volgorobot.vrcatalog.model.FirstLevelModel;
|
||||
import ru.volgorobot.vrcatalog.model.ImageItemModel;
|
||||
import ru.volgorobot.vrcatalog.model.SecondLevelModel;
|
||||
import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
|
||||
|
||||
public interface VRApi {
|
||||
|
||||
@GET("/API/Api.php?action=getFirstLevel")
|
||||
@GET("/api/level/1")
|
||||
Call<List<FirstLevelModel>> getFirstLevel();
|
||||
|
||||
@GET("/API/Api.php?action=getSecondLevel")
|
||||
Call<List<SecondLevelModel>> getSecondLevel(@Query("parentTypeID") int parentTypeID);
|
||||
@GET("/api/level/2")
|
||||
Call<List<SecondLevelModel>> getSecondLevel(@Query("categoryID") int categoryID);
|
||||
|
||||
@GET("/API/Api.php?action=getDetailsByParentID")
|
||||
Call<List<ThirdLevelModel>> getDetails(@Query("parentID") int parentID);
|
||||
@GET("/api/level/3")
|
||||
Call<List<ThirdLevelModel>> getDetails(@Query("subcategoryID") int subcategoryID);
|
||||
|
||||
@GET("/API/Api.php?action=getDetailByID")
|
||||
Call<List<DetailModel>> getDetailByID(@Query("detailID") int detailID);
|
||||
@GET("/api/item/{id}")
|
||||
Call<List<DetailModel>> getDetailByID(@Path("id") int itemID);
|
||||
|
||||
@GET("/API/Api.php?action=getCategoryByID")
|
||||
Call<List<FirstLevelModel>> getCategoryByID(@Query("id") int id);
|
||||
@GET("/api/level/1/{id}")
|
||||
Call<List<FirstLevelModel>> getCategoryByID(@Path("id") int categoryID);
|
||||
|
||||
@GET("/API/Api.php?action=getSubCategoryByID")
|
||||
Call<List<SecondLevelModel>> getSubCategoryByID(@Query("id") int id);
|
||||
@GET("/api/level/2/{id}")
|
||||
Call<List<SecondLevelModel>> getSubCategoryByID(@Path("id") int subcategoryID);
|
||||
|
||||
@GET("/API/Api.php?action=getDetailsByName")
|
||||
@GET("/api/item")
|
||||
Call<List<ThirdLevelModel>> getDetailsByName(@Query("name") String name);
|
||||
|
||||
@GET("/api/item/{id}/images")
|
||||
Call<List<ImageItemModel>> getImagesByItemID(@Path("id") int itemID);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class CoreModel implements MainContract.MainModel {
|
||||
|
||||
@Override
|
||||
public ArrayList<FirstLevelModel> fetchFirstLevel() throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
|
||||
@ -51,7 +51,7 @@ public class CoreModel implements MainContract.MainModel {
|
||||
|
||||
@Override
|
||||
public ArrayList<SecondLevelModel> fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
|
||||
@ -70,7 +70,7 @@ public class CoreModel implements MainContract.MainModel {
|
||||
|
||||
@Override
|
||||
public ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
|
||||
@ -89,7 +89,7 @@ public class CoreModel implements MainContract.MainModel {
|
||||
|
||||
@Override
|
||||
public ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
ArrayList<DetailModel> detail = new ArrayList<>();
|
||||
@ -118,17 +118,13 @@ public class CoreModel implements MainContract.MainModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApiState() {
|
||||
if(vrApi != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public boolean isApiNotNull() {
|
||||
return vrApi != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<ThirdLevelModel> fetchDetailsByName(String name) throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
|
||||
@ -147,7 +143,7 @@ public class CoreModel implements MainContract.MainModel {
|
||||
|
||||
@Override
|
||||
public ArrayList<FirstLevelModel> fetchCategoryByID(int id) throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
|
||||
@ -166,7 +162,7 @@ public class CoreModel implements MainContract.MainModel {
|
||||
|
||||
@Override
|
||||
public ArrayList<SecondLevelModel> fetchSubCategoryByID(int id) throws NetworkErrorException, NullPointerException {
|
||||
if(vrApi == null) {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
|
||||
@ -182,4 +178,23 @@ public class CoreModel implements MainContract.MainModel {
|
||||
}
|
||||
return secondLevelModels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<ImageItemModel> fetchImagesByItemID(int id) throws NetworkErrorException, NullPointerException {
|
||||
if(!isApiNotNull()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final ArrayList<ImageItemModel> imageItemModels = new ArrayList<>();
|
||||
try {
|
||||
Response<List<ImageItemModel>> response = vrApi.getImagesByItemID(id).execute();
|
||||
if(response.isSuccessful()) {
|
||||
imageItemModels.addAll(response.body());
|
||||
} else {
|
||||
throw new NetworkErrorException(2);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new NetworkErrorException(1);
|
||||
}
|
||||
return imageItemModels;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package ru.volgorobot.vrcatalog.model;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class ImageItemModel {
|
||||
@SerializedName("DetailID")
|
||||
@Expose
|
||||
private Integer detailID;
|
||||
@SerializedName("image")
|
||||
@Expose
|
||||
private String image;
|
||||
@SerializedName("MD5")
|
||||
@Expose
|
||||
private String MD5;
|
||||
|
||||
public Integer getDetailID() {
|
||||
return detailID;
|
||||
}
|
||||
|
||||
public void setDetailID(Integer detailID) {
|
||||
this.detailID = detailID;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String getMD5() {
|
||||
return MD5;
|
||||
}
|
||||
|
||||
public void setMD5(String mD5) {
|
||||
this.MD5 = mD5;
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ 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;
|
||||
|
@ -1,94 +1,100 @@
|
||||
package ru.volgorobot.vrcatalog.view;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.EditText;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import ru.volgorobot.vrcatalog.ItemPresenter;
|
||||
import ru.volgorobot.vrcatalog.MainContract;
|
||||
import ru.volgorobot.vrcatalog.R;
|
||||
import ru.volgorobot.vrcatalog.additional.ImagePagerAdapter;
|
||||
import ru.volgorobot.vrcatalog.additional.PropertiesListAdapter;
|
||||
|
||||
public class DetailActivity extends AppCompatActivity {
|
||||
TextView nameView;
|
||||
TextView quantityView;
|
||||
TextView priceView;
|
||||
TextView countryView;
|
||||
TextView analogueView;
|
||||
TextView datasheetView;
|
||||
EditText notesView;
|
||||
public class DetailActivity extends AppCompatActivity implements MainContract.ItemView {
|
||||
private MainContract.ItemPresenter mPresenter;
|
||||
private ViewPager viewPager;
|
||||
private ListView propertiesList;
|
||||
private ImagePagerAdapter imagePagerAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_detail);
|
||||
Toolbar toolbar = findViewById(R.id.itemactivity_toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
initializeViews();
|
||||
|
||||
mPresenter = new ItemPresenter(DetailActivity.this, this);
|
||||
Intent intent = getIntent();
|
||||
|
||||
HashMap<String, String> extrasMap = getIntentExtras(intent);
|
||||
((TextView) findViewById(R.id.itemName)).setText(intent.getStringExtra("detailName"));
|
||||
String tmp = intent.getStringExtra("detailPrice");
|
||||
if(tmp.equals("0")) {
|
||||
tmp = "Уточните у продавца";
|
||||
} else {
|
||||
tmp = tmp + " \u20BD";
|
||||
}
|
||||
((TextView) findViewById(R.id.itemPrice)).setText(tmp);
|
||||
|
||||
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"));
|
||||
LinkedHashMap<String, String> extrasMap = getIntentExtras(intent);
|
||||
|
||||
propertiesList = findViewById(R.id.propertiesList);
|
||||
PropertiesListAdapter propertiesListAdapter = new PropertiesListAdapter(extrasMap);
|
||||
propertiesList.setAdapter(propertiesListAdapter);
|
||||
|
||||
mPresenter.getImagesByItemID(Integer.parseInt(intent.getStringExtra("itemID")));
|
||||
}
|
||||
|
||||
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());
|
||||
viewPager = findViewById(R.id.viewPager);
|
||||
}
|
||||
|
||||
HashMap<String, String> getIntentExtras(Intent intent) {
|
||||
HashMap<String, String> hashMap = new HashMap<>();
|
||||
LinkedHashMap<String, String> getIntentExtras(Intent intent) {
|
||||
LinkedHashMap<String, String> hashMap = new LinkedHashMap<>();
|
||||
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);
|
||||
hashMap.put("Количество", tmp);
|
||||
|
||||
tmp = intent.getStringExtra("detailCountry");
|
||||
if(tmp.equals("")) {
|
||||
tmp = "Не указано";
|
||||
}
|
||||
hashMap.put("detailCountry", tmp);
|
||||
hashMap.put("Страна изготовления", tmp);
|
||||
|
||||
tmp = intent.getStringExtra("detailAnalogue");
|
||||
if(tmp.equals("")) {
|
||||
tmp = "Нет аналогов";
|
||||
}
|
||||
hashMap.put("detailAnalogue", tmp);
|
||||
hashMap.put("Аналоги", tmp);
|
||||
|
||||
tmp = intent.getStringExtra("detailDatasheet");
|
||||
if(!tmp.matches("\\S")) {
|
||||
if(!(tmp.trim().length() > 0)) {
|
||||
tmp = "Не указано";
|
||||
}
|
||||
hashMap.put("detailDatasheet", tmp);
|
||||
hashMap.put("Техническая спецификация", tmp);
|
||||
|
||||
tmp = intent.getStringExtra("detailNotes");
|
||||
if(tmp != null && tmp.equals("")) {
|
||||
@ -96,7 +102,7 @@ public class DetailActivity extends AppCompatActivity {
|
||||
} else if (tmp == null){
|
||||
tmp = "Нет описания";
|
||||
}
|
||||
hashMap.put("detailNotes", tmp);
|
||||
hashMap.put("Описание", tmp);
|
||||
|
||||
return hashMap;
|
||||
}
|
||||
@ -110,4 +116,126 @@ public class DetailActivity extends AppCompatActivity {
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailureAnswer(int errorCode) {
|
||||
switch (errorCode) {
|
||||
case 1: {
|
||||
Toast.makeText(DetailActivity.this, "Ошибка сети. Проверьте подключение к сети или данные подключения к API!", Toast.LENGTH_LONG).show();
|
||||
Log.e("DetailActivity", "Network Error! Re-check your connection credentials or network settings!");
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
Toast.makeText(DetailActivity.this, "Ответ от сервера неверен! Перепроверьте данные подключения!", Toast.LENGTH_LONG).show();
|
||||
Log.e("DetailActivity", "Answer of server is wrong! Re-check your connection credentials!");
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
Toast.makeText(DetailActivity.this, "Вы ввели неверный URL. Пример: http://example.ru", Toast.LENGTH_LONG).show();
|
||||
Log.e("DetailActivity", "Invalid-formatted URL. Please, check URL (change his if it need) and try again.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewPagerContent(String[] uris) {
|
||||
imagePagerAdapter = new ImagePagerAdapter(DetailActivity.this, uris);
|
||||
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
|
||||
viewPager.setAdapter(imagePagerAdapter);
|
||||
setViewPagerScrollListener();
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
imagePagerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private int getImageAverageColor(Bitmap bitmap) {
|
||||
if (null == bitmap) return Color.TRANSPARENT;
|
||||
|
||||
int redBucket = 0;
|
||||
int greenBucket = 0;
|
||||
int blueBucket = 0;
|
||||
int alphaBucket = 0;
|
||||
|
||||
boolean hasAlpha = bitmap.hasAlpha();
|
||||
int pixelCount = bitmap.getWidth() * bitmap.getHeight();
|
||||
int[] pixels = new int[pixelCount];
|
||||
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
|
||||
for (int y = 0, h = bitmap.getHeight(); y < h; y++)
|
||||
{
|
||||
for (int x = 0, w = bitmap.getWidth(); x < w; x++)
|
||||
{
|
||||
int color = pixels[x + y * w]; // x + y * width
|
||||
redBucket += (color >> 16) & 0xFF; // Color.red
|
||||
greenBucket += (color >> 8) & 0xFF; // Color.greed
|
||||
blueBucket += (color & 0xFF); // Color.blue
|
||||
if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
|
||||
}
|
||||
}
|
||||
|
||||
return Color.argb(
|
||||
(hasAlpha) ? (alphaBucket / pixelCount) : 255,
|
||||
redBucket / pixelCount,
|
||||
greenBucket / pixelCount,
|
||||
blueBucket / pixelCount);
|
||||
}
|
||||
|
||||
private void setViewPagerScrollListener() {
|
||||
ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() {
|
||||
boolean firstImageProcessed = false;
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
if(position == 0 && !firstImageProcessed) {
|
||||
viewPager.setBackgroundColor(getImageAverageColor(imagePagerAdapter.getBitmap(position)));
|
||||
firstImageProcessed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if(firstImageProcessed) {
|
||||
viewPager.setBackgroundColor(getImageAverageColor(imagePagerAdapter.getBitmap(position)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
//
|
||||
}
|
||||
};
|
||||
viewPager.setOnPageChangeListener(listener);
|
||||
}
|
||||
|
||||
public static boolean setListViewHeightBasedOnItems(ListView listView) {
|
||||
|
||||
ListAdapter listAdapter = listView.getAdapter();
|
||||
if (listAdapter != null) {
|
||||
|
||||
int numberOfItems = listAdapter.getCount();
|
||||
|
||||
// Get total height of all items.
|
||||
int totalItemsHeight = 0;
|
||||
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
|
||||
View item = listAdapter.getView(itemPos, null, listView);
|
||||
item.measure(0, 0);
|
||||
totalItemsHeight += item.getMeasuredHeight();
|
||||
}
|
||||
|
||||
// Get total height of all item dividers.
|
||||
int totalDividersHeight = listView.getDividerHeight() *
|
||||
(numberOfItems - 1);
|
||||
|
||||
// Set list height.
|
||||
ViewGroup.LayoutParams params = listView.getLayoutParams();
|
||||
params.height = totalItemsHeight + totalDividersHeight;
|
||||
listView.setLayoutParams(params);
|
||||
listView.requestLayout();
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,10 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -39,6 +42,9 @@ public class MainActivity extends AppCompatActivity
|
||||
private TreeView treeView;
|
||||
private TreeNode rootNode = TreeNode.root();
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private ImageView mConnectionErrorImageView;
|
||||
private ViewGroup mTreeViewContainer;
|
||||
private TextView mErrorTextView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -56,19 +62,25 @@ public class MainActivity extends AppCompatActivity
|
||||
NavigationView navigationView = findViewById(R.id.nav_view);
|
||||
navigationView.setNavigationItemSelectedListener(this);
|
||||
|
||||
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
|
||||
mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(MainActivity.this);
|
||||
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
|
||||
|
||||
mErrorTextView = findViewById(R.id.errorTextView);
|
||||
mConnectionErrorImageView = findViewById(R.id.connectionErrorImageView);
|
||||
|
||||
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());
|
||||
mTreeViewContainer = findViewById(R.id.treeViewContainer);
|
||||
mTreeViewContainer.addView(treeView.getView());
|
||||
mSwipeRefreshLayout.setRefreshing(true);
|
||||
mPresenter.getFirstLevel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||
@ -111,26 +123,44 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mConnectionErrorImageView.setVisibility(View.INVISIBLE);
|
||||
mErrorTextView.setVisibility(View.INVISIBLE);
|
||||
mTreeViewContainer.setVisibility(View.VISIBLE);
|
||||
rootNode.setChildren(new ArrayList<TreeNode>());
|
||||
treeView.refreshTreeView();
|
||||
mPresenter.getFirstLevel();
|
||||
}
|
||||
|
||||
public void onFailureAnswer(int errorCode) {
|
||||
switch (errorCode) {
|
||||
case 1: {
|
||||
mErrorTextView.setText("Ошибка сети. Проверьте подключение к сети или данные подключения к API!");
|
||||
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");
|
||||
Log.e("MainActivity", "Network Error! Re-check your connection credentials or network settings!");
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mTreeViewContainer.setVisibility(View.GONE);
|
||||
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||
mErrorTextView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
mErrorTextView.setText("Ответ от сервера неверен! Перепроверьте данные подключения!");
|
||||
Toast.makeText(MainActivity.this, "Ответ от сервера неверен! Перепроверьте данные подключения!", Toast.LENGTH_LONG).show();
|
||||
Log.e("VRCatalog", "Answer of server is wrong! Re-check your connection credentials! Technical info: null");
|
||||
Log.e("MainActivity", "Answer of server is wrong! Re-check your connection credentials!");
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mTreeViewContainer.setVisibility(View.GONE);
|
||||
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||
mErrorTextView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
mErrorTextView.setText("Вы ввели неверный URL. Пример: http://example.ru");
|
||||
Toast.makeText(this, "Вы ввели неверный URL. Пример: http://example.ru", Toast.LENGTH_LONG).show();
|
||||
Log.e("MainActivity", "Invalid-formatted URL. Please, check URL (change his if it need) and try again.");
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mTreeViewContainer.setVisibility(View.GONE);
|
||||
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||
mErrorTextView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,17 @@ package ru.volgorobot.vrcatalog.view;
|
||||
|
||||
import android.app.SearchManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.widget.NestedScrollView;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -27,6 +30,9 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
||||
private String detailName;
|
||||
private TreeView treeView;
|
||||
private TreeNode rootNode = TreeNode.root();
|
||||
private ImageView mConnectionErrorImageView;
|
||||
private NestedScrollView mTreeViewContainer;
|
||||
private TextView mErrorTextView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -41,6 +47,10 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
||||
mSwipeRefreshLayout.setOnRefreshListener(SearchableActivity.this);
|
||||
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
|
||||
|
||||
mConnectionErrorImageView = findViewById(R.id.searchableConnectionErrorImageView);
|
||||
mTreeViewContainer = findViewById(R.id.searchableTreeViewContainer);
|
||||
mErrorTextView = findViewById(R.id.searchableErrorTextView);
|
||||
|
||||
treeView = new TreeView(rootNode, SearchableActivity.this, new SearchableNodeViewFactory(SearchableActivity.this, this));
|
||||
treeView.setItemAnimator(new DefaultItemAnimator());
|
||||
((ViewGroup) findViewById(R.id.searchableTreeViewContainer)).addView(treeView.getView());
|
||||
@ -62,20 +72,32 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
||||
public void onFailureAnswer(int errorCode) {
|
||||
switch (errorCode) {
|
||||
case 1: {
|
||||
Toast.makeText(SearchableActivity.this, "Ошибка сети. Проверьте подключение к сети или данные подключения к API!", Toast.LENGTH_LONG).show();
|
||||
mErrorTextView.setText("Ошибка сети. Проверьте подключение к сети или данные подключения к API!");
|
||||
//Toast.makeText(SearchableActivity.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);
|
||||
mTreeViewContainer.setVisibility(View.GONE);
|
||||
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||
mErrorTextView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
Toast.makeText(SearchableActivity.this, "Ответ от сервера неверен! Перепроверьте данные подключения!", Toast.LENGTH_LONG).show();
|
||||
mErrorTextView.setText("Ответ от сервера неверен! Перепроверьте данные подключения!");
|
||||
//Toast.makeText(SearchableActivity.this, "Ответ от сервера неверен! Перепроверьте данные подключения!", Toast.LENGTH_LONG).show();
|
||||
Log.e("VRCatalog", "Answer of server is wrong! Re-check your connection credentials! Technical info: null");
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mTreeViewContainer.setVisibility(View.GONE);
|
||||
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||
mErrorTextView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
Toast.makeText(SearchableActivity.this, "Вы ввели неверный URL. Пример: http://example.ru", Toast.LENGTH_LONG).show();
|
||||
mErrorTextView.setText("Вы ввели неверный URL. Пример: http://example.ru");
|
||||
//Toast.makeText(SearchableActivity.this, "Вы ввели неверный URL. Пример: http://example.ru", Toast.LENGTH_LONG).show();
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mTreeViewContainer.setVisibility(View.GONE);
|
||||
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||
mErrorTextView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -83,6 +105,11 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mConnectionErrorImageView.setVisibility(View.INVISIBLE);
|
||||
mErrorTextView.setVisibility(View.INVISIBLE);
|
||||
mTreeViewContainer.setVisibility(View.VISIBLE);
|
||||
rootNode.setChildren(new ArrayList<TreeNode>());
|
||||
treeView.refreshTreeView();
|
||||
searchablePresenter.fetchDetailsTreeByName(detailName);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package ru.volgorobot.vrcatalog.view;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import ru.volgorobot.vrcatalog.R;
|
||||
|
5
app/src/main/res/drawable/ic_cloud_off_gray_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_cloud_off_gray_24dp.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#A9A9A9"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4c-1.48,0 -2.85,0.43 -4.01,1.17l1.46,1.46C10.21,6.23 11.08,6 12,6c3.04,0 5.5,2.46 5.5,5.5v0.5H19c1.66,0 3,1.34 3,3 0,1.13 -0.64,2.11 -1.56,2.62l1.45,1.45C23.16,18.16 24,16.68 24,15c0,-2.64 -2.05,-4.78 -4.65,-4.96zM3,5.27l2.75,2.74C2.56,8.15 0,10.77 0,14c0,3.31 2.69,6 6,6h11.73l2,2L21,20.73 4.27,4 3,5.27zM7.73,10l8,8H6c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4h1.73z"/>
|
||||
</vector>
|
8
app/src/main/res/drawable/tab_indicator_default.xml
Normal file
8
app/src/main/res/drawable/tab_indicator_default.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:innerRadius="0dp"
|
||||
android:shape="ring"
|
||||
android:thickness="2dp"
|
||||
android:useLevel="false">
|
||||
<solid android:color="@android:color/darker_gray"/>
|
||||
</shape>
|
9
app/src/main/res/drawable/tab_indicator_selected.xml
Normal file
9
app/src/main/res/drawable/tab_indicator_selected.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
android:innerRadius="0dp"
|
||||
android:shape="ring"
|
||||
android:thickness="4dp"
|
||||
android:useLevel="false"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/colorAccent"/>
|
||||
</shape>
|
8
app/src/main/res/drawable/tab_selector.xml
Normal file
8
app/src/main/res/drawable/tab_selector.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/tab_indicator_selected"
|
||||
android:state_selected="true"/>
|
||||
|
||||
<item android:drawable="@drawable/tab_indicator_default"/>
|
||||
</selector>
|
@ -1,155 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.design.widget.CoordinatorLayout 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">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<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" />
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
<android.support.design.widget.CollapsingToolbarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_scrollFlags="scroll|enterAlways">
|
||||
|
||||
<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" />
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="311dp"
|
||||
app:layout_collapseMode="parallax" />
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabDots"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="62dp"
|
||||
android:layout_gravity="bottom"
|
||||
app:tabBackground="@drawable/tab_selector"
|
||||
app:tabGravity="center"
|
||||
app:tabIndicatorHeight="0dp" />
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/itemactivity_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_collapseMode="pin"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||
android:theme="@style/ItemActionBar"/>
|
||||
|
||||
<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" />
|
||||
</android.support.design.widget.CollapsingToolbarLayout>
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<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" />
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="619dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:fillViewport="true">
|
||||
|
||||
<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" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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">
|
||||
<TextView
|
||||
android:id="@+id/itemName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:text="Item Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textSize="30sp" />
|
||||
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
<TextView
|
||||
android:id="@+id/itemPrice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:text="Item Price"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<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>
|
||||
<ListView
|
||||
android:id="@+id/propertiesList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:nestedScrollingEnabled="false"/>
|
||||
</LinearLayout>
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
@ -10,12 +10,45 @@
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/searchableSwipeRefreshLayout">
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/searchableTreeViewContainer"
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true">
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/searchableTreeViewContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true">
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/searchableConnectionErrorImageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="70dp"
|
||||
android:layout_marginBottom="52dp"
|
||||
android:src="@drawable/ic_cloud_off_gray_24dp"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="@+id/searchableErrorTextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/searchableErrorTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="77dp"
|
||||
android:layout_marginStart="9dp"
|
||||
android:layout_marginEnd="9dp"
|
||||
android:layout_marginBottom="68dp"
|
||||
android:text=""
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchableConnectionErrorImageView" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
@ -10,12 +10,53 @@
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/swipeRefreshLayout">
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/treeViewContainer"
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/mainActivityConstraint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true">
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/treeViewContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="1.0">
|
||||
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/connectionErrorImageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="70dp"
|
||||
android:layout_marginBottom="52dp"
|
||||
android:src="@drawable/ic_cloud_off_gray_24dp"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="@+id/errorTextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errorTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="77dp"
|
||||
android:layout_marginStart="9dp"
|
||||
android:layout_marginEnd="9dp"
|
||||
android:layout_marginBottom="68dp"
|
||||
android:text=""
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectionErrorImageView" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
22
app/src/main/res/layout/properties_list_adapter.xml
Normal file
22
app/src/main/res/layout/properties_list_adapter.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/propertyNameView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Property Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginLeft="9dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/propertyValueView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Property Value"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:autoLink="web"/>
|
||||
</LinearLayout>
|
@ -5,4 +5,17 @@
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
<style name="ItemActivityTheme" parent="AppTheme">
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
<style name="MyActionBar" parent="Widget.AppCompat.ActionBar.Solid">
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
<item name="background">@android:color/transparent</item>
|
||||
</style>
|
||||
<style name="ItemActionBar" parent="ItemActivityTheme">
|
||||
<item name="android:textColorPrimary">@android:color/white</item>
|
||||
<item name="android:textColorSecondary">@android:color/white</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
@ -17,4 +17,8 @@
|
||||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<style name="ItemActivityTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -8,7 +8,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath 'com.android.tools.build:gradle:3.3.1'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
Loading…
Reference in New Issue
Block a user