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>
|
<PersistentState>
|
||||||
<option name="values">
|
<option name="values">
|
||||||
<map>
|
<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>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</PersistentState>
|
</PersistentState>
|
||||||
@ -28,8 +28,8 @@
|
|||||||
</option>
|
</option>
|
||||||
<option name="values">
|
<option name="values">
|
||||||
<map>
|
<map>
|
||||||
<entry key="color" value="ffffff" />
|
<entry key="color" value="a9a9a9" />
|
||||||
<entry key="outputName" value="ic_search_white_24dp" />
|
<entry key="outputName" value="ic_cloud_off_black_24dp" />
|
||||||
<entry key="sourceFile" value="$USER_HOME$" />
|
<entry key="sourceFile" value="$USER_HOME$" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</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">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -6,8 +6,8 @@ android {
|
|||||||
applicationId "ru.volgorobot.vrcatalog"
|
applicationId "ru.volgorobot.vrcatalog"
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 1
|
versionCode 4
|
||||||
versionName "1.0"
|
versionName "0.3"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@ -33,4 +33,5 @@ dependencies {
|
|||||||
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
|
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
|
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
|
||||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
||||||
}
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
|
}
|
@ -23,7 +23,9 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".view.SettingsActivity" />
|
<activity android:name=".view.SettingsActivity" />
|
||||||
<activity android:name=".view.AboutActivity" />
|
<activity android:name=".view.AboutActivity" />
|
||||||
<activity android:name=".view.DetailActivity" />
|
<activity
|
||||||
|
android:name=".view.DetailActivity"
|
||||||
|
android:theme="@style/ItemActivityTheme"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".view.SearchableActivity"
|
android:name=".view.SearchableActivity"
|
||||||
android:label="Поиск"
|
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.CoreModel;
|
||||||
import ru.volgorobot.vrcatalog.model.DetailModel;
|
import ru.volgorobot.vrcatalog.model.DetailModel;
|
||||||
import ru.volgorobot.vrcatalog.model.FirstLevelModel;
|
import ru.volgorobot.vrcatalog.model.FirstLevelModel;
|
||||||
|
import ru.volgorobot.vrcatalog.model.ImageItemModel;
|
||||||
import ru.volgorobot.vrcatalog.model.SecondLevelModel;
|
import ru.volgorobot.vrcatalog.model.SecondLevelModel;
|
||||||
import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
|
import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
|
||||||
|
|
||||||
@ -42,10 +43,11 @@ public interface MainContract {
|
|||||||
ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
|
ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException;
|
||||||
ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException;
|
ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException;
|
||||||
void reinitializeApi() throws IllegalStateException;
|
void reinitializeApi() throws IllegalStateException;
|
||||||
boolean getApiState();
|
boolean isApiNotNull();
|
||||||
ArrayList<ThirdLevelModel> fetchDetailsByName(String name) throws NetworkErrorException, NullPointerException;
|
ArrayList<ThirdLevelModel> fetchDetailsByName(String name) throws NetworkErrorException, NullPointerException;
|
||||||
ArrayList<FirstLevelModel> fetchCategoryByID(int id) throws NetworkErrorException, NullPointerException;
|
ArrayList<FirstLevelModel> fetchCategoryByID(int id) throws NetworkErrorException, NullPointerException;
|
||||||
ArrayList<SecondLevelModel> fetchSubCategoryByID(int id) throws NetworkErrorException, NullPointerException;
|
ArrayList<SecondLevelModel> fetchSubCategoryByID(int id) throws NetworkErrorException, NullPointerException;
|
||||||
|
ArrayList<ImageItemModel> fetchImagesByItemID(int id) throws NetworkErrorException, NullPointerException;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SearchablePresenter {
|
interface SearchablePresenter {
|
||||||
@ -57,4 +59,13 @@ public interface MainContract {
|
|||||||
void onFailureAnswer(int errorCode);
|
void onFailureAnswer(int errorCode);
|
||||||
void swipeLayoutSetRefreshing(boolean state);
|
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()) {
|
switch (result.getErrorCode()) {
|
||||||
case 0: {
|
case 0: {
|
||||||
Intent intent = new Intent(context, DetailActivity.class);
|
Intent intent = new Intent(context, DetailActivity.class);
|
||||||
|
intent.putExtra("itemID", result.getData().getID().toString());
|
||||||
intent.putExtra("detailName", result.getData().getName());
|
intent.putExtra("detailName", result.getData().getName());
|
||||||
intent.putExtra("detailQuantity", result.getData().getNumber().toString());
|
intent.putExtra("detailQuantity", result.getData().getNumber().toString());
|
||||||
intent.putExtra("detailPrice", result.getData().getPrice());
|
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 me.texy.treeview.base.BaseNodeViewFactory;
|
||||||
import ru.volgorobot.vrcatalog.MainContract;
|
import ru.volgorobot.vrcatalog.MainContract;
|
||||||
import ru.volgorobot.vrcatalog.nodeViewBinders.ThirdLevelNodeViewBinder;
|
import ru.volgorobot.vrcatalog.nodeViewBinders.ThirdLevelNodeViewBinder;
|
||||||
import ru.volgorobot.vrcatalog.searchNodeViewBinders.SecondLevelNodeViewBinder;
|
|
||||||
import ru.volgorobot.vrcatalog.searchNodeViewBinders.FirstLevelNodeViewBinder;
|
import ru.volgorobot.vrcatalog.searchNodeViewBinders.FirstLevelNodeViewBinder;
|
||||||
|
import ru.volgorobot.vrcatalog.searchNodeViewBinders.SecondLevelNodeViewBinder;
|
||||||
|
|
||||||
public class SearchableNodeViewFactory extends BaseNodeViewFactory {
|
public class SearchableNodeViewFactory extends BaseNodeViewFactory {
|
||||||
private Context context;
|
private Context context;
|
||||||
|
@ -4,32 +4,37 @@ import java.util.List;
|
|||||||
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Path;
|
||||||
import retrofit2.http.Query;
|
import retrofit2.http.Query;
|
||||||
import ru.volgorobot.vrcatalog.model.DetailModel;
|
import ru.volgorobot.vrcatalog.model.DetailModel;
|
||||||
import ru.volgorobot.vrcatalog.model.FirstLevelModel;
|
import ru.volgorobot.vrcatalog.model.FirstLevelModel;
|
||||||
|
import ru.volgorobot.vrcatalog.model.ImageItemModel;
|
||||||
import ru.volgorobot.vrcatalog.model.SecondLevelModel;
|
import ru.volgorobot.vrcatalog.model.SecondLevelModel;
|
||||||
import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
|
import ru.volgorobot.vrcatalog.model.ThirdLevelModel;
|
||||||
|
|
||||||
public interface VRApi {
|
public interface VRApi {
|
||||||
|
|
||||||
@GET("/API/Api.php?action=getFirstLevel")
|
@GET("/api/level/1")
|
||||||
Call<List<FirstLevelModel>> getFirstLevel();
|
Call<List<FirstLevelModel>> getFirstLevel();
|
||||||
|
|
||||||
@GET("/API/Api.php?action=getSecondLevel")
|
@GET("/api/level/2")
|
||||||
Call<List<SecondLevelModel>> getSecondLevel(@Query("parentTypeID") int parentTypeID);
|
Call<List<SecondLevelModel>> getSecondLevel(@Query("categoryID") int categoryID);
|
||||||
|
|
||||||
@GET("/API/Api.php?action=getDetailsByParentID")
|
@GET("/api/level/3")
|
||||||
Call<List<ThirdLevelModel>> getDetails(@Query("parentID") int parentID);
|
Call<List<ThirdLevelModel>> getDetails(@Query("subcategoryID") int subcategoryID);
|
||||||
|
|
||||||
@GET("/API/Api.php?action=getDetailByID")
|
@GET("/api/item/{id}")
|
||||||
Call<List<DetailModel>> getDetailByID(@Query("detailID") int detailID);
|
Call<List<DetailModel>> getDetailByID(@Path("id") int itemID);
|
||||||
|
|
||||||
@GET("/API/Api.php?action=getCategoryByID")
|
@GET("/api/level/1/{id}")
|
||||||
Call<List<FirstLevelModel>> getCategoryByID(@Query("id") int id);
|
Call<List<FirstLevelModel>> getCategoryByID(@Path("id") int categoryID);
|
||||||
|
|
||||||
@GET("/API/Api.php?action=getSubCategoryByID")
|
@GET("/api/level/2/{id}")
|
||||||
Call<List<SecondLevelModel>> getSubCategoryByID(@Query("id") int 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);
|
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
|
@Override
|
||||||
public ArrayList<FirstLevelModel> fetchFirstLevel() throws NetworkErrorException, NullPointerException {
|
public ArrayList<FirstLevelModel> fetchFirstLevel() throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
|
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
|
||||||
@ -51,7 +51,7 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<SecondLevelModel> fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
|
public ArrayList<SecondLevelModel> fetchSecondLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
|
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
|
||||||
@ -70,7 +70,7 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
|
public ArrayList<ThirdLevelModel> fetchThirdLevelByParentID(int parentID) throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
|
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
|
||||||
@ -89,7 +89,7 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException {
|
public ArrayList<DetailModel> fetchDetailByID(int detailID) throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
ArrayList<DetailModel> detail = new ArrayList<>();
|
ArrayList<DetailModel> detail = new ArrayList<>();
|
||||||
@ -118,17 +118,13 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getApiState() {
|
public boolean isApiNotNull() {
|
||||||
if(vrApi != null) {
|
return vrApi != null;
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<ThirdLevelModel> fetchDetailsByName(String name) throws NetworkErrorException, NullPointerException {
|
public ArrayList<ThirdLevelModel> fetchDetailsByName(String name) throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
|
final ArrayList<ThirdLevelModel> thirdLevelModels = new ArrayList<>();
|
||||||
@ -147,7 +143,7 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<FirstLevelModel> fetchCategoryByID(int id) throws NetworkErrorException, NullPointerException {
|
public ArrayList<FirstLevelModel> fetchCategoryByID(int id) throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
|
final ArrayList<FirstLevelModel> firstLevelModels = new ArrayList<>();
|
||||||
@ -166,7 +162,7 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<SecondLevelModel> fetchSubCategoryByID(int id) throws NetworkErrorException, NullPointerException {
|
public ArrayList<SecondLevelModel> fetchSubCategoryByID(int id) throws NetworkErrorException, NullPointerException {
|
||||||
if(vrApi == null) {
|
if(!isApiNotNull()) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
|
final ArrayList<SecondLevelModel> secondLevelModels = new ArrayList<>();
|
||||||
@ -182,4 +178,23 @@ public class CoreModel implements MainContract.MainModel {
|
|||||||
}
|
}
|
||||||
return secondLevelModels;
|
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.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import ru.volgorobot.vrcatalog.R;
|
import ru.volgorobot.vrcatalog.R;
|
||||||
|
@ -1,94 +1,100 @@
|
|||||||
package ru.volgorobot.vrcatalog.view;
|
package ru.volgorobot.vrcatalog.view;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.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.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.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.R;
|
||||||
|
import ru.volgorobot.vrcatalog.additional.ImagePagerAdapter;
|
||||||
|
import ru.volgorobot.vrcatalog.additional.PropertiesListAdapter;
|
||||||
|
|
||||||
public class DetailActivity extends AppCompatActivity {
|
public class DetailActivity extends AppCompatActivity implements MainContract.ItemView {
|
||||||
TextView nameView;
|
private MainContract.ItemPresenter mPresenter;
|
||||||
TextView quantityView;
|
private ViewPager viewPager;
|
||||||
TextView priceView;
|
private ListView propertiesList;
|
||||||
TextView countryView;
|
private ImagePagerAdapter imagePagerAdapter;
|
||||||
TextView analogueView;
|
|
||||||
TextView datasheetView;
|
|
||||||
EditText notesView;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_detail);
|
setContentView(R.layout.activity_detail);
|
||||||
|
Toolbar toolbar = findViewById(R.id.itemactivity_toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
|
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||||
initializeViews();
|
initializeViews();
|
||||||
|
mPresenter = new ItemPresenter(DetailActivity.this, this);
|
||||||
Intent intent = getIntent();
|
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"));
|
LinkedHashMap<String, String> extrasMap = getIntentExtras(intent);
|
||||||
quantityView.setText(extrasMap.get("detailQuantity"));
|
|
||||||
priceView.setText(extrasMap.get("detailPrice"));
|
propertiesList = findViewById(R.id.propertiesList);
|
||||||
countryView.setText(extrasMap.get("detailCountry"));
|
PropertiesListAdapter propertiesListAdapter = new PropertiesListAdapter(extrasMap);
|
||||||
analogueView.setText(extrasMap.get("detailAnalogue"));
|
propertiesList.setAdapter(propertiesListAdapter);
|
||||||
datasheetView.setText(extrasMap.get("detailDatasheet"));
|
|
||||||
notesView.setText(extrasMap.get("detailNotes"));
|
mPresenter.getImagesByItemID(Integer.parseInt(intent.getStringExtra("itemID")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeViews() {
|
void initializeViews() {
|
||||||
nameView = findViewById(R.id.name);
|
viewPager = findViewById(R.id.viewPager);
|
||||||
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) {
|
LinkedHashMap<String, String> getIntentExtras(Intent intent) {
|
||||||
HashMap<String, String> hashMap = new HashMap<>();
|
LinkedHashMap<String, String> hashMap = new LinkedHashMap<>();
|
||||||
String tmp;
|
String tmp;
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailName");
|
|
||||||
hashMap.put("detailName", tmp);
|
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailQuantity");
|
tmp = intent.getStringExtra("detailQuantity");
|
||||||
if(tmp.equals("0")) {
|
if(tmp.equals("0")) {
|
||||||
tmp = "Под заказ";
|
tmp = "Под заказ";
|
||||||
}
|
}
|
||||||
hashMap.put("detailQuantity", tmp);
|
hashMap.put("Количество", tmp);
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailPrice");
|
|
||||||
if(tmp.equals("0")) {
|
|
||||||
tmp = "Уточните у продавца";
|
|
||||||
}
|
|
||||||
hashMap.put("detailPrice", tmp);
|
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailCountry");
|
tmp = intent.getStringExtra("detailCountry");
|
||||||
if(tmp.equals("")) {
|
if(tmp.equals("")) {
|
||||||
tmp = "Не указано";
|
tmp = "Не указано";
|
||||||
}
|
}
|
||||||
hashMap.put("detailCountry", tmp);
|
hashMap.put("Страна изготовления", tmp);
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailAnalogue");
|
tmp = intent.getStringExtra("detailAnalogue");
|
||||||
if(tmp.equals("")) {
|
if(tmp.equals("")) {
|
||||||
tmp = "Нет аналогов";
|
tmp = "Нет аналогов";
|
||||||
}
|
}
|
||||||
hashMap.put("detailAnalogue", tmp);
|
hashMap.put("Аналоги", tmp);
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailDatasheet");
|
tmp = intent.getStringExtra("detailDatasheet");
|
||||||
if(!tmp.matches("\\S")) {
|
if(!(tmp.trim().length() > 0)) {
|
||||||
tmp = "Не указано";
|
tmp = "Не указано";
|
||||||
}
|
}
|
||||||
hashMap.put("detailDatasheet", tmp);
|
hashMap.put("Техническая спецификация", tmp);
|
||||||
|
|
||||||
tmp = intent.getStringExtra("detailNotes");
|
tmp = intent.getStringExtra("detailNotes");
|
||||||
if(tmp != null && tmp.equals("")) {
|
if(tmp != null && tmp.equals("")) {
|
||||||
@ -96,7 +102,7 @@ public class DetailActivity extends AppCompatActivity {
|
|||||||
} else if (tmp == null){
|
} else if (tmp == null){
|
||||||
tmp = "Нет описания";
|
tmp = "Нет описания";
|
||||||
}
|
}
|
||||||
hashMap.put("detailNotes", tmp);
|
hashMap.put("Описание", tmp);
|
||||||
|
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
@ -110,4 +116,126 @@ public class DetailActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
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.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -39,6 +42,9 @@ public class MainActivity extends AppCompatActivity
|
|||||||
private TreeView treeView;
|
private TreeView treeView;
|
||||||
private TreeNode rootNode = TreeNode.root();
|
private TreeNode rootNode = TreeNode.root();
|
||||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||||
|
private ImageView mConnectionErrorImageView;
|
||||||
|
private ViewGroup mTreeViewContainer;
|
||||||
|
private TextView mErrorTextView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -56,19 +62,25 @@ public class MainActivity extends AppCompatActivity
|
|||||||
NavigationView navigationView = findViewById(R.id.nav_view);
|
NavigationView navigationView = findViewById(R.id.nav_view);
|
||||||
navigationView.setNavigationItemSelectedListener(this);
|
navigationView.setNavigationItemSelectedListener(this);
|
||||||
|
|
||||||
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
|
mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||||
mSwipeRefreshLayout.setOnRefreshListener(MainActivity.this);
|
mSwipeRefreshLayout.setOnRefreshListener(MainActivity.this);
|
||||||
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
|
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
|
||||||
|
|
||||||
|
mErrorTextView = findViewById(R.id.errorTextView);
|
||||||
|
mConnectionErrorImageView = findViewById(R.id.connectionErrorImageView);
|
||||||
|
|
||||||
mPresenter = new MainPresenter(this, MainActivity.this);
|
mPresenter = new MainPresenter(this, MainActivity.this);
|
||||||
|
|
||||||
treeView = new TreeView(rootNode, MainActivity.this, new NodeViewFactory(MainActivity.this, this, this.mPresenter.getCoreModel()));
|
treeView = new TreeView(rootNode, MainActivity.this, new NodeViewFactory(MainActivity.this, this, this.mPresenter.getCoreModel()));
|
||||||
treeView.setItemAnimator(new DefaultItemAnimator());
|
treeView.setItemAnimator(new DefaultItemAnimator());
|
||||||
((ViewGroup) findViewById(R.id.treeViewContainer)).addView(treeView.getView());
|
mTreeViewContainer = findViewById(R.id.treeViewContainer);
|
||||||
|
mTreeViewContainer.addView(treeView.getView());
|
||||||
mSwipeRefreshLayout.setRefreshing(true);
|
mSwipeRefreshLayout.setRefreshing(true);
|
||||||
mPresenter.getFirstLevel();
|
mPresenter.getFirstLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||||
@ -111,26 +123,44 @@ public class MainActivity extends AppCompatActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRefresh() {
|
public void onRefresh() {
|
||||||
|
mConnectionErrorImageView.setVisibility(View.INVISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.INVISIBLE);
|
||||||
|
mTreeViewContainer.setVisibility(View.VISIBLE);
|
||||||
|
rootNode.setChildren(new ArrayList<TreeNode>());
|
||||||
|
treeView.refreshTreeView();
|
||||||
mPresenter.getFirstLevel();
|
mPresenter.getFirstLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFailureAnswer(int errorCode) {
|
public void onFailureAnswer(int errorCode) {
|
||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
case 1: {
|
case 1: {
|
||||||
|
mErrorTextView.setText("Ошибка сети. Проверьте подключение к сети или данные подключения к API!");
|
||||||
Toast.makeText(MainActivity.this, "Ошибка сети. Проверьте подключение к сети или данные подключения к API!", Toast.LENGTH_LONG).show();
|
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);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
mTreeViewContainer.setVisibility(View.GONE);
|
||||||
|
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
|
mErrorTextView.setText("Ответ от сервера неверен! Перепроверьте данные подключения!");
|
||||||
Toast.makeText(MainActivity.this, "Ответ от сервера неверен! Перепроверьте данные подключения!", Toast.LENGTH_LONG).show();
|
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);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
mTreeViewContainer.setVisibility(View.GONE);
|
||||||
|
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
|
mErrorTextView.setText("Вы ввели неверный URL. Пример: http://example.ru");
|
||||||
Toast.makeText(this, "Вы ввели неверный URL. Пример: http://example.ru", Toast.LENGTH_LONG).show();
|
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);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
mTreeViewContainer.setVisibility(View.GONE);
|
||||||
|
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,17 @@ package ru.volgorobot.vrcatalog.view;
|
|||||||
|
|
||||||
import android.app.SearchManager;
|
import android.app.SearchManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.widget.NestedScrollView;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.widget.DefaultItemAnimator;
|
import android.support.v7.widget.DefaultItemAnimator;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -27,6 +30,9 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
|||||||
private String detailName;
|
private String detailName;
|
||||||
private TreeView treeView;
|
private TreeView treeView;
|
||||||
private TreeNode rootNode = TreeNode.root();
|
private TreeNode rootNode = TreeNode.root();
|
||||||
|
private ImageView mConnectionErrorImageView;
|
||||||
|
private NestedScrollView mTreeViewContainer;
|
||||||
|
private TextView mErrorTextView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -41,6 +47,10 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
|||||||
mSwipeRefreshLayout.setOnRefreshListener(SearchableActivity.this);
|
mSwipeRefreshLayout.setOnRefreshListener(SearchableActivity.this);
|
||||||
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
|
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 = new TreeView(rootNode, SearchableActivity.this, new SearchableNodeViewFactory(SearchableActivity.this, this));
|
||||||
treeView.setItemAnimator(new DefaultItemAnimator());
|
treeView.setItemAnimator(new DefaultItemAnimator());
|
||||||
((ViewGroup) findViewById(R.id.searchableTreeViewContainer)).addView(treeView.getView());
|
((ViewGroup) findViewById(R.id.searchableTreeViewContainer)).addView(treeView.getView());
|
||||||
@ -62,20 +72,32 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
|||||||
public void onFailureAnswer(int errorCode) {
|
public void onFailureAnswer(int errorCode) {
|
||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
case 1: {
|
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");
|
Log.e("VRCatalog", "Network Error! Re-check your connection credentials or network settings! Technical info: null");
|
||||||
mSwipeRefreshLayout.setRefreshing(false);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
mTreeViewContainer.setVisibility(View.GONE);
|
||||||
|
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
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");
|
Log.e("VRCatalog", "Answer of server is wrong! Re-check your connection credentials! Technical info: null");
|
||||||
mSwipeRefreshLayout.setRefreshing(false);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
mTreeViewContainer.setVisibility(View.GONE);
|
||||||
|
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
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);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
mTreeViewContainer.setVisibility(View.GONE);
|
||||||
|
mConnectionErrorImageView.setVisibility(View.VISIBLE);
|
||||||
|
mErrorTextView.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,6 +105,11 @@ public class SearchableActivity extends AppCompatActivity implements MainContrac
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRefresh() {
|
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);
|
searchablePresenter.fetchDetailsTreeByName(detailName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ru.volgorobot.vrcatalog.view;
|
package ru.volgorobot.vrcatalog.view;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import ru.volgorobot.vrcatalog.R;
|
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"?>
|
<?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: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="wrap_content">
|
||||||
tools:layout_editor_absoluteY="81dp">
|
|
||||||
|
|
||||||
<TextView
|
<android.support.design.widget.AppBarLayout
|
||||||
android:id="@+id/name_text"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:fitsSystemWindows="true">
|
||||||
android:layout_marginStart="16dp"
|
<android.support.design.widget.CollapsingToolbarLayout
|
||||||
android:text="Название: "
|
android:layout_width="match_parent"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:layout_height="match_parent"
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/name"
|
app:layout_scrollFlags="scroll|enterAlways">
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
<android.support.v4.view.ViewPager
|
||||||
android:id="@+id/name"
|
android:id="@+id/viewPager"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="311dp"
|
||||||
android:layout_marginTop="16dp"
|
app:layout_collapseMode="parallax" />
|
||||||
android:text="TextView"
|
<android.support.design.widget.TabLayout
|
||||||
app:layout_constraintStart_toEndOf="@+id/name_text"
|
android:id="@+id/tabDots"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
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.support.design.widget.CollapsingToolbarLayout>
|
||||||
android:id="@+id/notes_text"
|
</android.support.design.widget.AppBarLayout>
|
||||||
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.support.v4.widget.NestedScrollView
|
||||||
android:id="@+id/quantity_text"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="619dp"
|
||||||
android:layout_height="19dp"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:text="Количество на складе: "
|
android:fillViewport="true">
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/quantity"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/name_text" />
|
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/quantity"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="19dp"
|
android:orientation="vertical">
|
||||||
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
|
<TextView
|
||||||
android:id="@+id/notes"
|
android:id="@+id/itemName"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="99dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginLeft="9dp"
|
||||||
android:layout_marginTop="18dp"
|
android:text="Item Name"
|
||||||
android:layout_marginEnd="16dp"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
android:ems="10"
|
android:textSize="30sp" />
|
||||||
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 />
|
<TextView
|
||||||
</EditText>
|
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
|
<ListView
|
||||||
android:id="@+id/price_text"
|
android:id="@+id/propertiesList"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Цена: "
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:nestedScrollingEnabled="false"/>
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/price"
|
</LinearLayout>
|
||||||
app:layout_constraintStart_toStartOf="@+id/quantity_text" />
|
</android.support.v4.widget.NestedScrollView>
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
<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>
|
|
@ -10,12 +10,45 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:id="@+id/searchableSwipeRefreshLayout">
|
android:id="@+id/searchableSwipeRefreshLayout">
|
||||||
|
|
||||||
<android.support.v4.widget.NestedScrollView
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/searchableTreeViewContainer"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:scrollbarAlwaysDrawVerticalTrack="true">
|
|
||||||
</android.support.v4.widget.NestedScrollView>
|
|
||||||
|
|
||||||
|
<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>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
@ -10,12 +10,53 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:id="@+id/swipeRefreshLayout">
|
android:id="@+id/swipeRefreshLayout">
|
||||||
|
|
||||||
<android.support.v4.widget.NestedScrollView
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/treeViewContainer"
|
android:id="@+id/mainActivityConstraint"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:scrollbarAlwaysDrawVerticalTrack="true">
|
|
||||||
</android.support.v4.widget.NestedScrollView>
|
|
||||||
|
|
||||||
|
<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>
|
</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="windowNoTitle">true</item>
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
</style>
|
</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>
|
</resources>
|
||||||
|
@ -17,4 +17,8 @@
|
|||||||
|
|
||||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||||
|
|
||||||
|
<style name="ItemActivityTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<item name="android:windowTranslucentStatus">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -8,7 +8,7 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
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
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
Loading…
Reference in New Issue
Block a user