diff --git a/app/build.gradle b/app/build.gradle index 445372a..02f6476 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,6 +98,19 @@ dependencies { compile libraries.timber + compile (libraries.retrofit) { + exclude module: 'okhttp' + } + compile libraries.converterGson + compile libraries.adapterRxJava + compile libraries.gson + compile libraries.okhttp + compile libraries.glide + compile libraries.okhttpLogging + + compile libraries.rxJava + compile libraries.rxAndroid + // Developer tools (Developer Settings) compile libraries.stetho compile libraries.leakCanary diff --git a/app/src/main/java/ru/yandex/yamblz/App.java b/app/src/main/java/ru/yandex/yamblz/App.java index e5f9972..26933cb 100644 --- a/app/src/main/java/ru/yandex/yamblz/App.java +++ b/app/src/main/java/ru/yandex/yamblz/App.java @@ -7,7 +7,9 @@ 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.DefaultCriticalSectionsHandler; import ru.yandex.yamblz.loader.CollageLoaderManager; +import ru.yandex.yamblz.loader.DefaultCollageLoader; import timber.log.Timber; public class App extends Application { @@ -34,8 +36,8 @@ public void onCreate() { devMetricsProxy.apply(); } - CollageLoaderManager.init(null); // add implementation - CriticalSectionsManager.init(null); // add implementation + CollageLoaderManager.init(new DefaultCollageLoader()); + CriticalSectionsManager.init(new DefaultCriticalSectionsHandler()); } @NonNull diff --git a/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsManager.java b/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsManager.java index 8a3d496..5053cc7 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsManager.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/CriticalSectionsManager.java @@ -10,7 +10,7 @@ public static void init(CriticalSectionsHandler criticalSectionsHandler) { public static CriticalSectionsHandler getHandler() { if (sCriticalSectionsHandler == null) { - sCriticalSectionsHandler = new StubCriticalSectionsHandler(); + sCriticalSectionsHandler = new DefaultCriticalSectionsHandler(); } return sCriticalSectionsHandler; } diff --git a/app/src/main/java/ru/yandex/yamblz/handler/DefaultCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/DefaultCriticalSectionsHandler.java new file mode 100644 index 0000000..c0c04de --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/handler/DefaultCriticalSectionsHandler.java @@ -0,0 +1,89 @@ +package ru.yandex.yamblz.handler; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CopyOnWriteArrayList; + +import timber.log.Timber; + +public class DefaultCriticalSectionsHandler implements CriticalSectionsHandler { + private static int MAX_QUEUE_SIZE = 6; // столько влазит на экран ._. + private ConcurrentLinkedQueue lowPriorityTasksQueue; + private CopyOnWriteArrayList sections; + private Handler mainHandler; + + public DefaultCriticalSectionsHandler() { + lowPriorityTasksQueue = new ConcurrentLinkedQueue<>(); + sections = new CopyOnWriteArrayList<>(); + mainHandler = new Handler(Looper.getMainLooper()); + } + + @Override + public void startSection(int id) { + Timber.d("Start section with id=" + String.valueOf(id)); + sections.add(id); + } + + @Override + public void stopSection(int id) { + Timber.d("Stop section with id=" + String.valueOf(id)); + sections.remove(sections.indexOf(id)); + + if (sections.isEmpty()) { + runLowPriorityTasksQueue(); + } + } + + @Override + public void stopSections() { + Timber.d("Stop all sections"); + sections.clear(); + runLowPriorityTasksQueue(); + } + + @Override + public void postLowPriorityTask(Task task) { + if (sections.isEmpty()) { + Timber.d("Low priority task running"); + mainHandler.post(task::run); + } else { + Timber.d("Add to queue"); + lowPriorityTasksQueue.add(task); + + if (lowPriorityTasksQueue.size() > MAX_QUEUE_SIZE) { + lowPriorityTasksQueue.poll(); + } + } + } + + @Override + public void postLowPriorityTaskDelayed(Task task, int delay) { + Timber.d("Post low priority task with delay"); + mainHandler.postDelayed(() -> postLowPriorityTask(task), delay); + } + + @Override + public void removeLowPriorityTask(Task task) { + lowPriorityTasksQueue.remove(); + } + + @Override + public void removeLowPriorityTasks() { + lowPriorityTasksQueue.clear(); + } + + private void runLowPriorityTasksQueue() { + while (!lowPriorityTasksQueue.isEmpty()) { + Timber.d("Get task from queue"); + Task task = lowPriorityTasksQueue.peek(); + postLowPriorityTask(task); + removeLowPriorityTask(task); + + if (!sections.isEmpty()) { + break; + } + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java deleted file mode 100644 index 0af9646..0000000 --- a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.yandex.yamblz.handler; - -public class StubCriticalSectionsHandler implements CriticalSectionsHandler { - - @Override - public void startSection(int id) { - - } - - @Override - public void stopSection(int id) { - - } - - @Override - public void stopSections() { - - } - - @Override - public void postLowPriorityTask(Task task) { - - } - - @Override - public void postLowPriorityTaskDelayed(Task task, int delay) { - - } - - @Override - public void removeLowPriorityTask(Task task) { - - } - - @Override - public void removeLowPriorityTasks() { - - } -} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoaderManager.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoaderManager.java index ef00d00..53bdd57 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoaderManager.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoaderManager.java @@ -10,7 +10,7 @@ public static void init(CollageLoader collageLoader) { public static CollageLoader getLoader() { if (sCollageLoader == null) { - sCollageLoader = new StubCollageLoader(); + sCollageLoader = new DefaultCollageLoader(); } return sCollageLoader; } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/DefaultCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/DefaultCollageLoader.java new file mode 100644 index 0000000..f6e6be6 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/loader/DefaultCollageLoader.java @@ -0,0 +1,79 @@ +package ru.yandex.yamblz.loader; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.widget.ImageView; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; + +import rx.Observable; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; +import timber.log.Timber; + +public class DefaultCollageLoader implements CollageLoader { + private static final int MAX_COLLAGE_SIZE = 4; + + + @Override + public void loadCollage(List urls, ImageView imageView) { + loadCollage(urls, new DefaultImageTarget(imageView)); + } + + @Override + public void loadCollage(List urls, ImageTarget imageTarget) { + StripCollageStrategy stripCollageStrategy = new StripCollageStrategy(MAX_COLLAGE_SIZE, + StripCollageStrategy.HORIZONTAL_STRIPES); + loadCollage(urls, imageTarget, stripCollageStrategy); + } + + @Override + public void loadCollage(List urls, ImageView imageView, + CollageStrategy collageStrategy) { + loadCollage(urls, new DefaultImageTarget(imageView), collageStrategy); + } + + @Override + public void loadCollage(List urls, ImageTarget imageTarget, + CollageStrategy collageStrategy) { + + Subscription subscription = Observable.from(urls) + .take(MAX_COLLAGE_SIZE) + .flatMap(this::loadBitmap) + .toList() + .map(collageStrategy::create) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(imageTarget::onLoadBitmap, + throwable -> Timber.d(throwable.getMessage()), + () -> Timber.d("Completed")); + + imageTarget.setTag(subscription); + } + + private Observable loadBitmap(String urlString) { + return Observable.create(subscriber -> { + HttpURLConnection httpURLConnection = null; + + try { + httpURLConnection = (HttpURLConnection) new URL(urlString).openConnection(); + subscriber.onNext(BitmapFactory.decodeStream( + httpURLConnection.getInputStream())); + subscriber.onCompleted(); + } catch (IOException e) { + subscriber.onError(e); + } finally { + if (httpURLConnection != null) { + httpURLConnection.disconnect(); + } + } + } + ); + } + + +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/DefaultImageTarget.java b/app/src/main/java/ru/yandex/yamblz/loader/DefaultImageTarget.java new file mode 100644 index 0000000..aef2b3e --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/loader/DefaultImageTarget.java @@ -0,0 +1,39 @@ +package ru.yandex.yamblz.loader; + +import android.graphics.Bitmap; +import android.widget.ImageView; + +import java.lang.ref.WeakReference; + +import rx.Subscription; + +/** + * Created by shmakova on 30.07.16. + */ + +public class DefaultImageTarget implements ImageTarget { + private WeakReference weakReferenceImageView; + + public DefaultImageTarget(ImageView imageView) { + this.weakReferenceImageView = new WeakReference<>(imageView); + } + + + @Override + public void onLoadBitmap(Bitmap bitmap) { + ImageView imageView = weakReferenceImageView.get(); + + if (imageView != null) { + imageView.setImageBitmap(bitmap); + } + } + + @Override + public void setTag(Subscription subscription) { + ImageView imageView = weakReferenceImageView.get(); + + if (imageView != null) { + imageView.setTag(subscription); + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/ImageTarget.java b/app/src/main/java/ru/yandex/yamblz/loader/ImageTarget.java index 9a8be2b..ac5677d 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/ImageTarget.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/ImageTarget.java @@ -2,7 +2,11 @@ import android.graphics.Bitmap; +import rx.Subscription; + public interface ImageTarget { void onLoadBitmap(Bitmap bitmap); + + void setTag(Subscription subscription); } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StripCollageStrategy.java b/app/src/main/java/ru/yandex/yamblz/loader/StripCollageStrategy.java new file mode 100644 index 0000000..c98b3e9 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/loader/StripCollageStrategy.java @@ -0,0 +1,85 @@ +package ru.yandex.yamblz.loader; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Rect; + +import java.util.List; + +/** + * Created by shmakova on 30.07.16. + */ + +public class StripCollageStrategy implements CollageStrategy { + public static final int VERTICAL_STRIPES = 0; + public static final int HORIZONTAL_STRIPES = 1; + private int size; + private int orientation; + + + public StripCollageStrategy(int size, int orientation) { + this.size = size; + this.orientation = orientation; + } + + public StripCollageStrategy(int size) { + this.size = size; + this.orientation = HORIZONTAL_STRIPES; + } + + @Override + public Bitmap create(List bitmaps) { + if (bitmaps.size() < size) { + size = bitmaps.size(); + } + + Bitmap bitmap = bitmaps.get(0); + Bitmap.Config config = bitmap.getConfig(); + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + Bitmap collage = Bitmap.createBitmap(width, height, config); + Canvas canvas = new Canvas(collage); + + int canvasWidth = canvas.getWidth(); + int canvasHeight = canvas.getHeight(); + + int squareWidth = 0; + int squareHeight = 0; + + if (orientation == VERTICAL_STRIPES) { + squareWidth = canvasWidth / size; + squareHeight = canvasHeight; + } else { + squareWidth = canvasWidth; + squareHeight = canvasHeight / size; + } + + Rect destinationRect = new Rect(); + + int xOffset = 0; + int yOffset = 0; + + destinationRect.set(0, 0, squareWidth, squareHeight); + + for (int i = 0; i < size; i++) { + if (orientation == VERTICAL_STRIPES) { + xOffset = i * squareWidth; + yOffset = 0; + } else { + xOffset = 0; + yOffset = i * squareHeight; + } + + Rect srcRect = new Rect(); + srcRect.set(0, 0, squareWidth, squareHeight); + srcRect.offsetTo(xOffset, yOffset); + + destinationRect.offsetTo(xOffset, yOffset); + + canvas.drawBitmap(bitmaps.get(i), srcRect, destinationRect, null); + } + + return collage; + + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java deleted file mode 100644 index 1dc051b..0000000 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.yandex.yamblz.loader; - -import android.widget.ImageView; - -import java.util.List; - -public class StubCollageLoader implements CollageLoader { - - @Override - public void loadCollage(List urls, ImageView imageView) { - - } - - @Override - public void loadCollage(List urls, ImageTarget imageTarget) { - - } - - @Override - public void loadCollage(List urls, ImageView imageView, - CollageStrategy collageStrategy) { - - } - - @Override - public void loadCollage(List urls, ImageTarget imageTarget, - CollageStrategy collageStrategy) { - - } - -} diff --git a/app/src/main/java/ru/yandex/yamblz/managers/DataManager.java b/app/src/main/java/ru/yandex/yamblz/managers/DataManager.java new file mode 100644 index 0000000..aead877 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/managers/DataManager.java @@ -0,0 +1,35 @@ +package ru.yandex.yamblz.managers; + +import java.util.List; + +import retrofit2.Call; +import ru.yandex.yamblz.network.ArtistResponse; +import ru.yandex.yamblz.network.ServiceGenerator; +import ru.yandex.yamblz.network.YandexService; + +/** + * Created by shmakova on 29.07.16. + */ + +public class DataManager { + private static DataManager INSTANCE = null; + private YandexService yandexService; + + public DataManager() { + this.yandexService = ServiceGenerator.createService(YandexService.class); + } + + public static DataManager getInstance() { + if (INSTANCE == null) { + INSTANCE = new DataManager(); + } + + return INSTANCE; + } + + + public Call> getArtistsList() { + return yandexService.getArtistsList(); + } + +} \ No newline at end of file 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..0bd5dc0 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/models/Genre.java @@ -0,0 +1,61 @@ +package ru.yandex.yamblz.models; + +import java.util.List; + +/** + * Created by shmakova on 29.07.16. + */ + +public class Genre { + private String name; + private List urls; + + public Genre(String name, List urls) { + this.name = name; + this.urls = urls; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getUrls() { + return urls; + } + + public void setUrls(List urls) { + this.urls = urls; + } + + @Override + public String toString() { + return "Genre{" + + "name='" + name + '\'' + + ", urls=" + urls.toString() + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Genre)) return false; + + Genre genre = (Genre) o; + + if (getName() != null ? !getName().equals(genre.getName()) : genre.getName() != null) + return false; + return getUrls() != null ? getUrls().equals(genre.getUrls()) : genre.getUrls() == null; + + } + + @Override + public int hashCode() { + int result = getName() != null ? getName().hashCode() : 0; + result = 31 * result + (getUrls() != null ? getUrls().hashCode() : 0); + return result; + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/network/ArtistResponse.java b/app/src/main/java/ru/yandex/yamblz/network/ArtistResponse.java new file mode 100644 index 0000000..7810106 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/network/ArtistResponse.java @@ -0,0 +1,63 @@ +package ru.yandex.yamblz.network; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Created by shmakova on 29.07.16. + */ +public class ArtistResponse { + @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 List getGenres() { + return genres; + } + + public Cover getCover() { + return cover; + } + + 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; + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/network/ServiceGenerator.java b/app/src/main/java/ru/yandex/yamblz/network/ServiceGenerator.java new file mode 100644 index 0000000..5e03c67 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/network/ServiceGenerator.java @@ -0,0 +1,31 @@ +package ru.yandex.yamblz.network; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; +import ru.yandex.yamblz.utils.AppConfig; + +/** + * Created by shmakova on 16.07.16. + */ + +public class ServiceGenerator { + private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); + + private static Retrofit.Builder builder = new Retrofit.Builder() + .baseUrl(AppConfig.BASE_URL) + .addConverterFactory(GsonConverterFactory.create()); + + public static S createService(Class serviceClass) { + HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); + logging.setLevel(HttpLoggingInterceptor.Level.BODY); + httpClient.addInterceptor(logging); + + Retrofit retrofit = builder + .client(httpClient.build()) + .build(); + + return retrofit.create(serviceClass); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/yandex/yamblz/network/YandexService.java b/app/src/main/java/ru/yandex/yamblz/network/YandexService.java new file mode 100644 index 0000000..6cdb9c8 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/network/YandexService.java @@ -0,0 +1,14 @@ +package ru.yandex.yamblz.network; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.http.GET; + +/** + * Created by shmakova on 13.04.16. + */ +public interface YandexService { + @GET("mobilization-2016/artists.json") + Call> getArtistsList(); +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenresAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenresAdapter.java new file mode 100644 index 0000000..1137df9 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/adapters/GenresAdapter.java @@ -0,0 +1,78 @@ +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.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ru.yandex.yamblz.R; +import ru.yandex.yamblz.handler.CriticalSectionsHandler; +import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.loader.CollageLoaderManager; +import ru.yandex.yamblz.models.Genre; +import rx.Subscription; + +/** + * Created by shmakova on 29.07.16. + */ + +public class GenresAdapter extends RecyclerView.Adapter { + private List genres; + + public GenresAdapter(List genres) { + this.genres = genres; + } + + @Override + public GenreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_genres, parent, false); + return new GenreViewHolder(convertView); + } + + @Override + public void onBindViewHolder(GenreViewHolder holder, int position) { + Genre genre = genres.get(position); + holder.name.setText(genre.getName()); + holder.collage.setImageDrawable(null); + + CriticalSectionsHandler criticalSectionsHandler = CriticalSectionsManager.getHandler(); + + criticalSectionsHandler.postLowPriorityTask(() -> + CollageLoaderManager.getLoader().loadCollage(genre.getUrls(), holder.collage) + ); + } + + @Override + public void onViewRecycled(GenreViewHolder holder) { + super.onViewRecycled(holder); + Subscription subscription = (Subscription) holder.collage.getTag(); + + if (subscription != null && !subscription.isUnsubscribed()) { + subscription.unsubscribe(); + } + + } + + @Override + public int getItemCount() { + return genres.size(); + } + + public static class GenreViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.collage) + ImageView collage; + @BindView(R.id.name) + TextView name; + + public GenreViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } +} \ No newline at end of file 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..5ebc987 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 @@ -3,16 +3,98 @@ import android.os.Bundle; 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 java.util.Map; +import java.util.Random; + +import butterknife.BindView; +import retrofit2.Response; import ru.yandex.yamblz.R; +import ru.yandex.yamblz.handler.CriticalSectionsHandler; +import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.managers.DataManager; +import ru.yandex.yamblz.models.Genre; +import ru.yandex.yamblz.network.ArtistResponse; +import ru.yandex.yamblz.ui.adapters.GenresAdapter; +import rx.Single; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; public class ContentFragment extends BaseFragment { + @BindView(R.id.genres_list) + RecyclerView recyclerView; + + private List genres; + private DataManager dataManager; + @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(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); + recyclerView.setLayoutManager(linearLayoutManager); + + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + CriticalSectionsHandler criticalSectionsHandler = CriticalSectionsManager.getHandler(); + + if (newState != RecyclerView.SCROLL_STATE_IDLE) { + criticalSectionsHandler.startSection(new Random().nextInt()); + } else { + criticalSectionsHandler.stopSections(); + } + } + }); + + dataManager = DataManager.getInstance(); + genres = new ArrayList<>(); + + Single.fromCallable(() -> getResult()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(artistsList -> { + Map> map = new HashMap<>(); + + for (ArtistResponse artistResponse : artistsList) { + for (String genre : artistResponse.getGenres()) { + if (map.get(genre) == null) { + List covers = new ArrayList<>(); + covers.add(artistResponse.getCover().getSmall()); + map.put(genre, covers); + } else { + map.get(genre).add(artistResponse.getCover().getSmall()); + } + } + } + + for (String genre : map.keySet()) { + Genre genreObject = new Genre(genre, map.get(genre)); + genres.add(genreObject); + } + + recyclerView.setAdapter(new GenresAdapter(genres)); + }); + } + + private List getResult() throws IOException { + Response> response; + response = dataManager.getArtistsList().execute(); + return response.body(); + } } diff --git a/app/src/main/java/ru/yandex/yamblz/utils/AppConfig.java b/app/src/main/java/ru/yandex/yamblz/utils/AppConfig.java new file mode 100644 index 0000000..23e75be --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/utils/AppConfig.java @@ -0,0 +1,9 @@ +package ru.yandex.yamblz.utils; + +/** + * Created by shmakova on 29.07.16. + */ + +public interface AppConfig { + String BASE_URL = "http://download.cdn.yandex.net/"; +} diff --git a/app/src/main/res/layout/fragment_content.xml b/app/src/main/res/layout/fragment_content.xml index 81016ea..e74be9f 100644 --- a/app/src/main/res/layout/fragment_content.xml +++ b/app/src/main/res/layout/fragment_content.xml @@ -3,12 +3,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="wrap_content" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_genres.xml b/app/src/main/res/layout/item_genres.xml new file mode 100644 index 0000000..99ff761 --- /dev/null +++ b/app/src/main/res/layout/item_genres.xml @@ -0,0 +1,30 @@ + + + + + + + + + + \ 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..1e05604 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -3,4 +3,24 @@ 16dp 16dp + + 24dp + 56dp + 72dp + + + 8dp + 16dp + 24dp + 32dp + 56dp + 72dp + + + 24sp + 20sp + 14sp + + 100dp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7474f04..9393cda 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,5 @@ Yamblz Hello + Коллаж diff --git a/dependencies.gradle b/dependencies.gradle index d9cb375..0361f2d 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-alpha7', aptGradlePlugin : '1.8', retrolambdaGradlePlugin : '3.2.5', lombokGradlePlugin : '0.2.3.a2', @@ -20,6 +20,14 @@ ext.versions = [ dagger : '2.4', + retrofit : '2.1.0', + gson : '2.6.2', + okhttp : '3.4.1', + glide : '3.7.0', + + rxJava : '1.1.8', + rxAndroid : '1.2.1', + supportLibs : '23.1.1', butterKnife : '8.0.1', timber : '4.1.2', @@ -67,6 +75,17 @@ ext.libraries = [ butterKnifeCompiler : "com.jakewharton:butterknife-compiler:$versions.butterKnife", timber : "com.jakewharton.timber:timber:$versions.timber", + retrofit : "com.squareup.retrofit2:retrofit:$versions.retrofit", + adapterRxJava : "com.squareup.retrofit2:adapter-rxjava:$versions.retrofit", + converterGson : "com.squareup.retrofit2:converter-gson:$versions.retrofit", + gson : "com.google.code.gson:gson:$versions.gson", + okhttp : "com.squareup.okhttp3:okhttp:$versions.okhttp", + okhttpLogging : "com.squareup.okhttp3:logging-interceptor:$versions.okhttp", + glide : "com.github.bumptech.glide:glide:$versions.glide", + + rxJava : "io.reactivex:rxjava:$versions.rxJava", + rxAndroid : "io.reactivex:rxandroid:$versions.rxAndroid", + // Developer Tools stetho : "com.facebook.stetho:stetho:$versions.stetho", leakCanary : "com.squareup.leakcanary:leakcanary-android:$versions.leakCanary", diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 86a3e94..92a54d3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon May 30 20:17:48 ICT 2016 +#Wed Aug 03 17:10:19 MSK 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip