From 430d172f810d52d08268776e2712076efece63e0 Mon Sep 17 00:00:00 2001 From: Sergey Atroshchenko Date: Thu, 4 Aug 2016 15:46:33 +0300 Subject: [PATCH 1/3] Task 1 complete, maybe ... --- app/build.gradle | 16 ++ app/src/main/java/ru/yandex/yamblz/App.java | 3 +- .../ru/yandex/yamblz/api/YandexArtistApi.java | 18 ++ .../yamblz/api/YandexArtistResponse.java | 165 ++++++++++++++++++ .../yandex/yamblz/loader/CollageLoader.java | 4 +- .../yamblz/loader/MyCollageStrategy.java | 82 +++++++++ .../yamblz/loader/MyImageViewTarget.java | 26 +++ .../yamblz/loader/StubCollageLoader.java | 50 +++++- .../java/ru/yandex/yamblz/models/Genre.java | 106 +++++++++++ .../ui/adapters/GenreRecyclerViewAdapter.java | 97 ++++++++++ .../yamblz/ui/fragments/ContentFragment.java | 133 ++++++++++++++ app/src/main/res/drawable/placeholder.png | Bin 0 -> 6909 bytes app/src/main/res/layout/fragment_content.xml | 17 +- .../main/res/layout/item_recycler_view.xml | 42 +++++ dependencies.gradle | 2 +- 15 files changed, 739 insertions(+), 22 deletions(-) create mode 100644 app/src/main/java/ru/yandex/yamblz/api/YandexArtistApi.java create mode 100644 app/src/main/java/ru/yandex/yamblz/api/YandexArtistResponse.java create mode 100644 app/src/main/java/ru/yandex/yamblz/loader/MyCollageStrategy.java create mode 100644 app/src/main/java/ru/yandex/yamblz/loader/MyImageViewTarget.java create mode 100644 app/src/main/java/ru/yandex/yamblz/models/Genre.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java create mode 100644 app/src/main/res/drawable/placeholder.png create mode 100644 app/src/main/res/layout/item_recycler_view.xml diff --git a/app/build.gradle b/app/build.gradle index 445372a..0d6d111 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,6 +105,21 @@ dependencies { compile libraries.lynx compile libraries.processPhoenix + // okhttp + compile 'com.squareup.okhttp3:okhttp:3.4.1' + compile 'com.squareup.okhttp3:logging-interceptor:3.4.1' + + // RxJava + compile 'io.reactivex:rxjava:1.1.8' + + // RxAndroid + compile 'io.reactivex:rxandroid:1.2.1' + + // retrofit + stuff + compile 'com.squareup.retrofit2:retrofit:2.1.0' + compile 'com.squareup.retrofit2:converter-gson:2.1.0' + compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' + testCompile libraries.junit testCompile libraries.robolectric testCompile libraries.assertJ @@ -121,6 +136,7 @@ dependencies { exclude module: 'recyclerview-v7' exclude module: 'support-v4' } + compile 'javax.annotation:javax.annotation-api:1.2' } configurations.all { diff --git a/app/src/main/java/ru/yandex/yamblz/App.java b/app/src/main/java/ru/yandex/yamblz/App.java index e5f9972..4efcce1 100644 --- a/app/src/main/java/ru/yandex/yamblz/App.java +++ b/app/src/main/java/ru/yandex/yamblz/App.java @@ -8,6 +8,7 @@ import ru.yandex.yamblz.developer_settings.DeveloperSettingsModel; import ru.yandex.yamblz.handler.CriticalSectionsManager; import ru.yandex.yamblz.loader.CollageLoaderManager; +import ru.yandex.yamblz.loader.StubCollageLoader; import timber.log.Timber; public class App extends Application { @@ -34,7 +35,7 @@ public void onCreate() { devMetricsProxy.apply(); } - CollageLoaderManager.init(null); // add implementation + CollageLoaderManager.init(new StubCollageLoader()); // add implementation CriticalSectionsManager.init(null); // add implementation } diff --git a/app/src/main/java/ru/yandex/yamblz/api/YandexArtistApi.java b/app/src/main/java/ru/yandex/yamblz/api/YandexArtistApi.java new file mode 100644 index 0000000..573bc1b --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/api/YandexArtistApi.java @@ -0,0 +1,18 @@ +package ru.yandex.yamblz.api; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.http.GET; + +/** + * Created by user on 01.08.16. + */ + +public interface YandexArtistApi { + + String URL = "http://download.cdn.yandex.net/"; + + @GET("mobilization-2016/artists.json") + Call> getListArtist(); +} diff --git a/app/src/main/java/ru/yandex/yamblz/api/YandexArtistResponse.java b/app/src/main/java/ru/yandex/yamblz/api/YandexArtistResponse.java new file mode 100644 index 0000000..22ac385 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/api/YandexArtistResponse.java @@ -0,0 +1,165 @@ +package ru.yandex.yamblz.api; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Generated; + +/** + * Created by user on 01.08.16. + */ +@Generated("org.jsonschema2pojo") +public class YandexArtistResponse { + @SerializedName("id") + @Expose + private int id; + @SerializedName("name") + @Expose + private String name; + @SerializedName("genres") + @Expose + private List genres = new ArrayList(); + @SerializedName("tracks") + @Expose + private int tracks; + @SerializedName("albums") + @Expose + private int albums; + @SerializedName("link") + @Expose + private String link; + @SerializedName("description") + @Expose + private String description; + @SerializedName("cover") + @Expose + private Cover cover; + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public List getGenres() { + return genres; + } + + public int getTracks() { + return tracks; + } + + public int getAlbums() { + return albums; + } + + public String getLink() { + return link; + } + + public String getDescription() { + return description; + } + + public Cover getCover() { + return cover; + } + + @Override + public String toString() { + return "YandexArtistResponse{" + + "id=" + id + + ", name='" + name + '\'' + + ", genres=" + genres + + ", tracks=" + tracks + + ", albums=" + albums + + ", link='" + link + '\'' + + ", description='" + description + '\'' + + ", cover=" + cover + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + YandexArtistResponse that = (YandexArtistResponse) o; + + if (id != that.id) return false; + if (tracks != that.tracks) return false; + if (albums != that.albums) return false; + if (!name.equals(that.name)) return false; + if (!genres.equals(that.genres)) return false; + if (!link.equals(that.link)) return false; + if (!description.equals(that.description)) return false; + if (!cover.equals(that.cover)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + name.hashCode(); + result = 31 * result + genres.hashCode(); + result = 31 * result + tracks; + result = 31 * result + albums; + result = 31 * result + link.hashCode(); + result = 31 * result + description.hashCode(); + result = 31 * result + cover.hashCode(); + return result; + } + + @Generated("org.jsonschema2pojo") + public class Cover { + + @SerializedName("small") + @Expose + private String small; + @SerializedName("big") + @Expose + private String big; + + public String getSmall() { + return small; + } + + public String getBig() { + return big; + } + + @Override + public String toString() { + return "Cover{" + + "small='" + small + '\'' + + ", big='" + big + '\'' + + '}'; + } + + @Override + public int hashCode() { + int result = small.hashCode(); + result = 31 * result + big.hashCode(); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Cover cover = (Cover) o; + + if (!small.equals(cover.small)) return false; + if (!big.equals(cover.big)) return false; + + return true; + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java index dad5b76..d597aaa 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java @@ -4,6 +4,8 @@ import java.util.List; +import rx.Subscription; + public interface CollageLoader { void loadCollage(List urls, ImageView imageView); @@ -12,6 +14,6 @@ public interface CollageLoader { void loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy); - void loadCollage(List urls, ImageTarget imageTarget, CollageStrategy collageStrategy); + Subscription loadCollage(List urls, ImageTarget imageTarget, CollageStrategy collageStrategy); } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/MyCollageStrategy.java b/app/src/main/java/ru/yandex/yamblz/loader/MyCollageStrategy.java new file mode 100644 index 0000000..8c04429 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/loader/MyCollageStrategy.java @@ -0,0 +1,82 @@ +package ru.yandex.yamblz.loader; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; + +import java.util.List; + +/** + * Created by SerG3z on 02.08.16. + */ + +public class MyCollageStrategy implements CollageStrategy { + + @Override + public Bitmap create(List bitmaps) { + int size = bitmaps.size(); + int sqr = (int) Math.sqrt(size); + + Bitmap bitmap = Bitmap.createBitmap(600, 600, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + if (size >= 4) { + if (sqr > 10) { + sqr = 10; + } + int width = bitmap.getWidth() / sqr; + int index = 0; + Rect rect; + for (int i = 0; i < sqr; i++) { + for (int j = 0; j < sqr; j++) { +// first version +// canvas.drawBitmap(getResizedBitmap(bitmaps.get(index++), width, width), j * width, i * width, null); + rect = new Rect(j * width, i * width, j * width + width, i * width + width); + canvas.drawBitmap(bitmaps.get(index++), null, rect, null); + } + } + canvas.save(); + return bitmap; + } else if (size == 3) { + canvas.drawBitmap(bitmaps.get(0), null, new Rect(0, 0, 298, 298), null); + canvas.drawBitmap(bitmaps.get(1), null, new Rect(302, 0, 600, 298), null); + canvas.drawBitmap(bitmaps.get(2), null, new Rect(150, 302, 450, 600), null); + canvas.save(); + return bitmap; + } else if (size == 2) { + Paint paint = new Paint(); + paint.setColor(Color.WHITE); + canvas.drawBitmap(bitmaps.get(0), null, new Rect(0, 0, 600, 600), null); + canvas.drawRect(new Rect(300, 300, 600, 600), paint); //for beauty + canvas.drawBitmap(bitmaps.get(1), null, new Rect(305, 305, 595, 595), null); + canvas.save(); + return bitmap; + } else { + canvas.drawBitmap(bitmaps.get(0), 0, 0, null); + canvas.save(); + return bitmaps.get(0); + } + } +// +// first version +// private Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) { +// int width = bm.getWidth(); +// int height = bm.getHeight(); +// float scaleWidth = ((float) newWidth) / width; +// float scaleHeight = ((float) newHeight) / height; +// Timber.d("scaleW = " + scaleWidth); +// Timber.d("scaleH = " + scaleHeight); +// if (scaleHeight >= 1.0 && scaleWidth >= 1.0) { +// return bm; +// } +// Matrix matrix = new Matrix(); +// matrix.postScale(scaleWidth, scaleHeight); +// Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); +// if (bm != null && !bm.isRecycled()) { +// bm.recycle(); +// bm = null; +// } +// return resizedBitmap; +// } +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/MyImageViewTarget.java b/app/src/main/java/ru/yandex/yamblz/loader/MyImageViewTarget.java new file mode 100644 index 0000000..ee5f79f --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/loader/MyImageViewTarget.java @@ -0,0 +1,26 @@ +package ru.yandex.yamblz.loader; + +import android.graphics.Bitmap; +import android.widget.ImageView; + +import java.lang.ref.WeakReference; + +/** + * Created by SerG3z on 02.08.16. + */ + +public class MyImageViewTarget implements ImageTarget { + private final WeakReference imageViewWeakReference; + + public MyImageViewTarget(ImageView imageView) { + imageViewWeakReference = new WeakReference<>(imageView); + } + + @Override + public void onLoadBitmap(Bitmap bitmap) { + ImageView imageView = imageViewWeakReference.get(); + if (imageView != null) { + imageView.setImageBitmap(bitmap); + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java index 1dc051b..c5b451a 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java @@ -1,31 +1,69 @@ package ru.yandex.yamblz.loader; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.LruCache; import android.widget.ImageView; +import java.net.URL; import java.util.List; +import rx.Observable; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + public class StubCollageLoader implements CollageLoader { + private LruCache, Bitmap> cache; + + public StubCollageLoader() { + final int maxMemory = (int) (Runtime.getRuntime().maxMemory()); + final int cacheSize = maxMemory / 8; + cache = new LruCache<>(cacheSize); + } @Override public void loadCollage(List urls, ImageView imageView) { - + loadCollage(urls, new MyImageViewTarget(imageView), new MyCollageStrategy()); } @Override public void loadCollage(List urls, ImageTarget imageTarget) { - + loadCollage(urls, imageTarget, new MyCollageStrategy()); } @Override public void loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy) { + loadCollage(urls, new MyImageViewTarget(imageView), collageStrategy); } - @Override - public void loadCollage(List urls, ImageTarget imageTarget, - CollageStrategy collageStrategy) { + @Override + public Subscription loadCollage(List urls, ImageTarget imageTarget, + CollageStrategy collageStrategy) { + return Observable + .from(urls) + .take(100) + .flatMap(s -> { + if (cache.get(urls) == null) { + return Observable.fromCallable(() -> BitmapFactory.decodeStream(new URL(s).openStream())); + } else + return Observable.empty(); + }) + .toList() + .map(bitmaps -> { + if (cache.get(urls) == null) { + Bitmap bitmap = collageStrategy.create(bitmaps); + cache.put(urls, bitmap); + return bitmap; + } else { + return cache.get(urls); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe((imageTarget::onLoadBitmap)); } - } diff --git a/app/src/main/java/ru/yandex/yamblz/models/Genre.java b/app/src/main/java/ru/yandex/yamblz/models/Genre.java new file mode 100644 index 0000000..c2ed623 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/models/Genre.java @@ -0,0 +1,106 @@ +package ru.yandex.yamblz.models; + +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.NonNull; + +import java.util.ArrayList; +import java.util.List; + +import ru.yandex.yamblz.api.YandexArtistResponse; + +/** + * Created by SerG3z on 02.08.16. + */ + +public class Genre implements Comparable, Parcelable { + private String genre; + private List listArtist; + private List imageUrls; + + public Genre(String genreStr) { + genre = genreStr; + listArtist = new ArrayList<>(); + imageUrls = new ArrayList<>(); + } + + protected Genre(Parcel in) { + genre = in.readString(); + listArtist = in.createStringArrayList(); + imageUrls = in.createStringArrayList(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Genre createFromParcel(Parcel in) { + return new Genre(in); + } + + @Override + public Genre[] newArray(int size) { + return new Genre[size]; + } + }; + + public String getGenre() { + return genre; + } + + public List getListArtist() { + return listArtist; + } + + public List getImageUrls() { + return imageUrls; + } + + @Override + public String toString() { + return "Genre{" + + "genre='" + genre + '\'' + + ", listArtist=" + listArtist + + ", imageUrls=" + imageUrls + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Genre genre1 = (Genre) o; + + return genre.equals(genre1.genre) && listArtist.equals(genre1.listArtist) && imageUrls.equals(genre1.imageUrls); + + } + + @Override + public int hashCode() { + int result = genre.hashCode(); + result = 31 * result + listArtist.hashCode(); + result = 31 * result + imageUrls.hashCode(); + return result; + } + + @Override + public int compareTo(@NonNull Genre another) { + return genre.compareToIgnoreCase(another.genre); + } + + public void appendArtist(YandexArtistResponse yandexArtistResponse) { + imageUrls.add(yandexArtistResponse.getCover().getSmall()); + listArtist.add(yandexArtistResponse.getName()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(genre); + dest.writeStringList(listArtist); + dest.writeStringList(imageUrls); + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java new file mode 100644 index 0000000..7a851c1 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java @@ -0,0 +1,97 @@ +package ru.yandex.yamblz.ui.adapters; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ru.yandex.yamblz.R; +import ru.yandex.yamblz.loader.CollageLoaderManager; +import ru.yandex.yamblz.loader.MyCollageStrategy; +import ru.yandex.yamblz.loader.MyImageViewTarget; +import ru.yandex.yamblz.models.Genre; +import rx.Subscription; + +/** + * Created by user on 02.08.16. + */ + +public class GenreRecyclerViewAdapter extends RecyclerView.Adapter { + + private List genreList; + + public GenreRecyclerViewAdapter() { + genreList = new ArrayList<>(); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_view, parent, false)); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + holder.bind(position); + } + + @Override + public int getItemCount() { + return genreList.size(); + } + + public void addAllData(List tmpListGenre) { + genreList.addAll(tmpListGenre); + notifyDataSetChanged(); + } + + public List getAllData() { + return genreList; + } + + public Genre getItem(int position) { + return genreList.get(position); + } + + @Override + public void onViewRecycled(ViewHolder holder) { + super.onViewRecycled(holder); + holder.getSubscription().unsubscribe(); + } + + class ViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.genres_image_view) + ImageView genreImageView; + @BindView(R.id.artists_text_view) + TextView artistList; + @BindView(R.id.genres_text_view) + TextView genreTextView; + + public Subscription getSubscription() { + return subscription; + } + + private Subscription subscription; + + ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + + void bind(int position) { + Genre genre = getItem(position); + genreImageView.setImageBitmap(null); + genreTextView.setText(genre.getGenre()); + artistList.setText(genre.getListArtist().toString()); + + subscription = CollageLoaderManager.getLoader().loadCollage(genre.getImageUrls(), new MyImageViewTarget(genreImageView), new MyCollageStrategy()); + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java index d46490f..a735aad 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java @@ -1,18 +1,151 @@ package ru.yandex.yamblz.ui.fragments; import android.os.Bundle; +import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import butterknife.BindView; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import ru.yandex.yamblz.BuildConfig; import ru.yandex.yamblz.R; +import ru.yandex.yamblz.api.YandexArtistApi; +import ru.yandex.yamblz.api.YandexArtistResponse; +import ru.yandex.yamblz.models.Genre; +import ru.yandex.yamblz.ui.adapters.GenreRecyclerViewAdapter; +import rx.Observable; +import rx.Single; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; public class ContentFragment extends BaseFragment { + + @BindView(R.id.recyclerView) + RecyclerView recyclerView; + private YandexArtistApi artistApi; + private List genreList; + private GenreRecyclerViewAdapter adapter; + private static final String TAG_SAVE_ARRAY = "save array"; + @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_content, container, false); } + + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + adapter = new GenreRecyclerViewAdapter(); + recyclerView.setAdapter(adapter); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + genreList = new ArrayList<>(); + + if (savedInstanceState == null) { + final OkHttpClient client = new OkHttpClient(); + final OkHttpClient.Builder retrofitClientBuilder = client.newBuilder(); + + if (BuildConfig.DEBUG) { + final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + retrofitClientBuilder.addInterceptor(interceptor); + retrofitClientBuilder.addNetworkInterceptor(interceptor); + } + + Retrofit retrofit = new Retrofit.Builder() + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .baseUrl(YandexArtistApi.URL) + .client(retrofitClientBuilder.build()) + .build(); + + artistApi = retrofit.create(YandexArtistApi.class); + startDownload(); + } else { + genreList = savedInstanceState.getParcelableArrayList(TAG_SAVE_ARRAY); + if (genreList != null) adapter.addAllData(genreList); + } + + + } + + + private void startDownload() { +// first variants + /*Single.fromCallable(this::getResult) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(responseList -> { + Map genreMap = new HashMap<>(); + for (YandexArtistResponse yandexArtistResponse : responseList) { + for (String keyGenre : yandexArtistResponse.getGenres()) { + if (genreMap.get(keyGenre) == null) { + Genre genre = new Genre(); + genre.add(keyGenre, yandexArtistResponse.getName(), yandexArtistResponse.getCover().getSmall()); + genreMap.put(keyGenre, genre); + } else { + genreMap.get(keyGenre).add(keyGenre, yandexArtistResponse.getName(), yandexArtistResponse.getCover().getSmall()); + } + } + } + + for (String key : genreMap.keySet()) { + genreList.add(genreMap.get(key)); + } + Collections.sort(genreList); + adapter.addAllData(genreList); + }); +*/ + Single.fromCallable(this::getResult) + .subscribeOn(Schedulers.io()) + .flatMapObservable(Observable::from) + .reduce(new HashMap(), (genres, yandexArtistResponse) -> { + for (String genreStr : yandexArtistResponse.getGenres()) { + Genre genre = genres.get(genreStr); + if (genre == null) { + genres.put(genreStr, genre = new Genre(genreStr)); + } + genre.appendArtist(yandexArtistResponse); + } + return genres; + }) + .flatMap(genresMap -> Observable.from(genresMap.values())) + .toSortedList() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(genres -> { + adapter.addAllData(genres); + genreList.addAll(genres); + }); + } + + private List getResult() throws IOException { + Response> response; + response = artistApi.getListArtist() + .execute(); + return response.body(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(TAG_SAVE_ARRAY, (ArrayList) genreList); + } } diff --git a/app/src/main/res/drawable/placeholder.png b/app/src/main/res/drawable/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..541d531c5d0a44d47534d30dd7ef161b6824af69 GIT binary patch literal 6909 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 QhW0oCFf+rV^UmS_1?=|+xBvhE literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/fragment_content.xml b/app/src/main/res/layout/fragment_content.xml index 81016ea..60735b3 100644 --- a/app/src/main/res/layout/fragment_content.xml +++ b/app/src/main/res/layout/fragment_content.xml @@ -1,14 +1,5 @@ - - - - - \ No newline at end of file + diff --git a/app/src/main/res/layout/item_recycler_view.xml b/app/src/main/res/layout/item_recycler_view.xml new file mode 100644 index 0000000..79918a5 --- /dev/null +++ b/app/src/main/res/layout/item_recycler_view.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle index d9cb375..d340e7b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,7 +7,7 @@ ext.versions = [ compileSdk : 23, buildTools : '23.0.3', - androidGradlePlugin : '2.2.0-alpha4', + androidGradlePlugin : '2.2.0-alpha6', aptGradlePlugin : '1.8', retrolambdaGradlePlugin : '3.2.5', lombokGradlePlugin : '0.2.3.a2', From 1133a2abe54bf4e6a2ba527c6a9ab46c6ecc0e7f Mon Sep 17 00:00:00 2001 From: Sergey Atroshchenko Date: Sat, 6 Aug 2016 04:52:49 +0300 Subject: [PATCH 2/3] Task 2 complete --- .../handler/CriticalSectionsHandler.java | 4 +- .../handler/StubCriticalSectionsHandler.java | 52 +++++++-- .../yandex/yamblz/loader/CollageLoader.java | 6 +- .../yamblz/loader/StubCollageLoader.java | 14 +-- .../ui/adapters/GenreRecyclerViewAdapter.java | 40 ++++--- .../yamblz/ui/fragments/ContentFragment.java | 27 ++++- app/src/main/res/drawable/red.png | Bin 0 -> 3115 bytes app/src/main/res/drawable/red_progress.xml | 5 + .../main/res/layout/item_recycler_view.xml | 99 +++++++++++------- app/src/main/res/values/dimens.xml | 5 + 10 files changed, 177 insertions(+), 75 deletions(-) create mode 100644 app/src/main/res/drawable/red.png create mode 100644 app/src/main/res/drawable/red_progress.xml diff --git a/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsHandler.java index 8b8cc56..81209c4 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsHandler.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsHandler.java @@ -8,9 +8,9 @@ public interface CriticalSectionsHandler { void stopSections(); - void postLowPriorityTask(Task task); + Task postLowPriorityTask(Task task); - void postLowPriorityTaskDelayed(Task task, int delay); + Task postLowPriorityTaskDelayed(Task task, int delay); void removeLowPriorityTask(Task task); diff --git a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java index 0af9646..35132d7 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java @@ -1,39 +1,75 @@ package ru.yandex.yamblz.handler; +import android.os.Handler; +import android.os.Looper; + +import java.util.HashSet; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; + +import timber.log.Timber; + public class StubCriticalSectionsHandler implements CriticalSectionsHandler { + private Handler mainHandler; + private Queue taskQueue; + private Set criticalSections; + + StubCriticalSectionsHandler() { + mainHandler = new Handler(Looper.getMainLooper()); + taskQueue = new ConcurrentLinkedQueue<>(); + criticalSections = new HashSet<>(); + } + @Override public void startSection(int id) { - + criticalSections.add(id); } @Override public void stopSection(int id) { - + criticalSections.remove(id); + if (criticalSections.isEmpty()) { + startLowPriorityTask(); + } } @Override public void stopSections() { - + criticalSections.clear(); + startLowPriorityTask(); } @Override - public void postLowPriorityTask(Task task) { - + public Task postLowPriorityTask(Task task) { + taskQueue.add(task); + startLowPriorityTask(); + return task; } @Override - public void postLowPriorityTaskDelayed(Task task, int delay) { - + public Task postLowPriorityTaskDelayed(Task task, int delay) { + mainHandler.postDelayed(() -> postLowPriorityTask(task), delay); + return task; } @Override public void removeLowPriorityTask(Task task) { - + taskQueue.remove(task); } @Override public void removeLowPriorityTasks() { + taskQueue.clear(); + } + private void startLowPriorityTask() { + Timber.d("low priority size = " + taskQueue.size()); + while (!taskQueue.isEmpty() && criticalSections.isEmpty()) { + Task task = taskQueue.poll(); + Timber.d("start task"); + mainHandler.post(() -> task.run()); + } } } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java index d597aaa..152d256 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java @@ -8,11 +8,11 @@ public interface CollageLoader { - void loadCollage(List urls, ImageView imageView); + Subscription loadCollage(List urls, ImageView imageView); - void loadCollage(List urls, ImageTarget imageTarget); + Subscription loadCollage(List urls, ImageTarget imageTarget); - void loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy); + Subscription loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy); Subscription loadCollage(List urls, ImageTarget imageTarget, CollageStrategy collageStrategy); diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java index c5b451a..9619e7f 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java @@ -23,19 +23,19 @@ public StubCollageLoader() { } @Override - public void loadCollage(List urls, ImageView imageView) { - loadCollage(urls, new MyImageViewTarget(imageView), new MyCollageStrategy()); + public Subscription loadCollage(List urls, ImageView imageView) { + return loadCollage(urls, new MyImageViewTarget(imageView), new MyCollageStrategy()); } @Override - public void loadCollage(List urls, ImageTarget imageTarget) { - loadCollage(urls, imageTarget, new MyCollageStrategy()); + public Subscription loadCollage(List urls, ImageTarget imageTarget) { + return loadCollage(urls, imageTarget, new MyCollageStrategy()); } @Override - public void loadCollage(List urls, ImageView imageView, - CollageStrategy collageStrategy) { - loadCollage(urls, new MyImageViewTarget(imageView), collageStrategy); + public Subscription loadCollage(List urls, ImageView imageView, + CollageStrategy collageStrategy) { + return loadCollage(urls, new MyImageViewTarget(imageView), collageStrategy); } diff --git a/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java index 7a851c1..a528694 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenreRecyclerViewAdapter.java @@ -5,6 +5,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.ProgressBar; import android.widget.TextView; import java.util.ArrayList; @@ -13,6 +14,8 @@ import butterknife.BindView; import butterknife.ButterKnife; import ru.yandex.yamblz.R; +import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.handler.Task; import ru.yandex.yamblz.loader.CollageLoaderManager; import ru.yandex.yamblz.loader.MyCollageStrategy; import ru.yandex.yamblz.loader.MyImageViewTarget; @@ -20,7 +23,7 @@ import rx.Subscription; /** - * Created by user on 02.08.16. + * Created by SerG3z on 02.08.16. */ public class GenreRecyclerViewAdapter extends RecyclerView.Adapter { @@ -51,10 +54,6 @@ public void addAllData(List tmpListGenre) { notifyDataSetChanged(); } - public List getAllData() { - return genreList; - } - public Genre getItem(int position) { return genreList.get(position); } @@ -62,7 +61,14 @@ public Genre getItem(int position) { @Override public void onViewRecycled(ViewHolder holder) { super.onViewRecycled(holder); - holder.getSubscription().unsubscribe(); + Subscription subscription = holder.getSubscription(); + if (subscription != null) { + subscription.unsubscribe(); + } + Task task = holder.getTask(); + if (task != null) { + CriticalSectionsManager.getHandler().removeLowPriorityTask(task); + } } class ViewHolder extends RecyclerView.ViewHolder { @@ -73,12 +79,10 @@ class ViewHolder extends RecyclerView.ViewHolder { TextView artistList; @BindView(R.id.genres_text_view) TextView genreTextView; - - public Subscription getSubscription() { - return subscription; - } - + @BindView(R.id.progress_bar) + ProgressBar progressBar; private Subscription subscription; + private Task task; ViewHolder(View itemView) { super(itemView); @@ -91,7 +95,19 @@ void bind(int position) { genreTextView.setText(genre.getGenre()); artistList.setText(genre.getListArtist().toString()); - subscription = CollageLoaderManager.getLoader().loadCollage(genre.getImageUrls(), new MyImageViewTarget(genreImageView), new MyCollageStrategy()); + task = CriticalSectionsManager.getHandler().postLowPriorityTask(() -> + subscription = CollageLoaderManager + .getLoader() + .loadCollage(genre.getImageUrls(), + new MyImageViewTarget(genreImageView), new MyCollageStrategy())); + } + + Subscription getSubscription() { + return subscription; + } + + Task getTask() { + return task; } } } diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java index a735aad..9446c55 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java @@ -4,8 +4,9 @@ import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.OrientationHelper; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -26,6 +27,8 @@ import ru.yandex.yamblz.R; import ru.yandex.yamblz.api.YandexArtistApi; import ru.yandex.yamblz.api.YandexArtistResponse; +import ru.yandex.yamblz.handler.CriticalSectionsHandler; +import ru.yandex.yamblz.handler.CriticalSectionsManager; import ru.yandex.yamblz.models.Genre; import ru.yandex.yamblz.ui.adapters.GenreRecyclerViewAdapter; import rx.Observable; @@ -35,12 +38,12 @@ public class ContentFragment extends BaseFragment { + private static final String TAG_SAVE_ARRAY = "save array"; @BindView(R.id.recyclerView) RecyclerView recyclerView; private YandexArtistApi artistApi; private List genreList; private GenreRecyclerViewAdapter adapter; - private static final String TAG_SAVE_ARRAY = "save array"; @NonNull @Override @@ -55,8 +58,11 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { adapter = new GenreRecyclerViewAdapter(); recyclerView.setAdapter(adapter); - recyclerView.setHasFixedSize(true); - recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); +// GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2); +// recyclerView.setLayoutManager(gridLayoutManager); + + StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL); + recyclerView.setLayoutManager(staggeredGridLayoutManager); genreList = new ArrayList<>(); if (savedInstanceState == null) { @@ -84,6 +90,19 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { if (genreList != null) adapter.addAllData(genreList); } + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + CriticalSectionsHandler criticalSectionsHandler = CriticalSectionsManager.getHandler(); + super.onScrollStateChanged(recyclerView, newState); + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + criticalSectionsHandler.stopSections(); + } else { + criticalSectionsHandler.startSection(1); + } + } + }); + } diff --git a/app/src/main/res/drawable/red.png b/app/src/main/res/drawable/red.png new file mode 100644 index 0000000000000000000000000000000000000000..5a3d15f6705c62fd02313de45f705fe8845b9213 GIT binary patch literal 3115 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 FV1mNhuiF3s literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/red_progress.xml b/app/src/main/res/drawable/red_progress.xml new file mode 100644 index 0000000..118e261 --- /dev/null +++ b/app/src/main/res/drawable/red_progress.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_recycler_view.xml b/app/src/main/res/layout/item_recycler_view.xml index 79918a5..2adec82 100644 --- a/app/src/main/res/layout/item_recycler_view.xml +++ b/app/src/main/res/layout/item_recycler_view.xml @@ -1,42 +1,63 @@ - - - - - - - - - + + + + + android:orientation="vertical"> + + + + + + + + + + + + - - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 02d4637..391094a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,5 +2,10 @@ 16dp 16dp + 6dp + 50dp + 6dp + 10dp + 14dp From 13b67b5113bef5af390dfa96176183c6a184015b Mon Sep 17 00:00:00 2001 From: Sergey Atroshchenko Date: Sat, 6 Aug 2016 04:58:24 +0300 Subject: [PATCH 3/3] add implementation in App --- app/src/main/java/ru/yandex/yamblz/App.java | 3 ++- .../ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/ru/yandex/yamblz/App.java b/app/src/main/java/ru/yandex/yamblz/App.java index 4efcce1..fcefd03 100644 --- a/app/src/main/java/ru/yandex/yamblz/App.java +++ b/app/src/main/java/ru/yandex/yamblz/App.java @@ -7,6 +7,7 @@ import ru.yandex.yamblz.developer_settings.DevMetricsProxy; import ru.yandex.yamblz.developer_settings.DeveloperSettingsModel; import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.handler.StubCriticalSectionsHandler; import ru.yandex.yamblz.loader.CollageLoaderManager; import ru.yandex.yamblz.loader.StubCollageLoader; import timber.log.Timber; @@ -36,7 +37,7 @@ public void onCreate() { } CollageLoaderManager.init(new StubCollageLoader()); // add implementation - CriticalSectionsManager.init(null); // add implementation + CriticalSectionsManager.init(new StubCriticalSectionsHandler()); // add implementation } @NonNull diff --git a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java index 35132d7..a75772c 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java @@ -16,7 +16,7 @@ public class StubCriticalSectionsHandler implements CriticalSectionsHandler { private Queue taskQueue; private Set criticalSections; - StubCriticalSectionsHandler() { + public StubCriticalSectionsHandler() { mainHandler = new Handler(Looper.getMainLooper()); taskQueue = new ConcurrentLinkedQueue<>(); criticalSections = new HashSet<>();