From ed76520ebc401ee33f9b72b2d66d229b9c71fb12 Mon Sep 17 00:00:00 2001 From: inorichi Date: Tue, 13 Oct 2015 20:16:15 +0200 Subject: [PATCH] Load catalogue with thumbnails --- .../presenter/CatalogueListPresenter.java | 65 ++++++++++++------ .../ui/activity/CatalogueListActivity.java | 37 +++++++++-- .../ui/adapter/CatalogueListHolder.java | 19 ++++++ .../mangafeed/view/CatalogueListView.java | 2 + .../widget/EndlessScrollListener.java | 6 ++ .../res/layout/activity_catalogue_list.xml | 15 +++-- app/src/main/res/layout/item_catalogue.xml | 66 ++++++++++++++++--- 7 files changed, 173 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/CatalogueListPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/CatalogueListPresenter.java index 496466445..0ee743e56 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/CatalogueListPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/CatalogueListPresenter.java @@ -3,6 +3,7 @@ package eu.kanade.mangafeed.presenter; import android.content.Intent; import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; import javax.inject.Inject; @@ -38,6 +39,7 @@ public class CatalogueListPresenter extends BasePresenter { private Subscription mMangaFetchSubscription; private Subscription mMangaSearchSubscription; private Subscription mSearchViewSubscription; + private Subscription mMangaDetailFetchSubscription; private PublishSubject> mSearchViewPublishSubject; @@ -69,7 +71,10 @@ public class CatalogueListPresenter extends BasePresenter { .flatMap(Observable::from) .map(this::networkToLocalManga) .toList() - .subscribe(adapter::addItems); + .subscribe(newMangas -> { + adapter.addItems(newMangas); + getMangaDetails(newMangas); + }); subscriptions.add(mMangaFetchSubscription); } @@ -83,7 +88,10 @@ public class CatalogueListPresenter extends BasePresenter { .flatMap(Observable::from) .map(this::networkToLocalManga) .toList() - .subscribe(adapter::addItems); + .subscribe(newMangas -> { + adapter.addItems(newMangas); + getMangaDetails(newMangas); + }); subscriptions.add(mMangaSearchSubscription); } @@ -97,23 +105,40 @@ public class CatalogueListPresenter extends BasePresenter { return localManga; } - private Observable getMangaDetails(Manga manga) { - Observable mangaObs = Observable.just(manga); - if (!manga.initialized) { - return mangaObs - .subscribeOn(Schedulers.io()) - .flatMap(localManga -> { - Timber.e("Request " + localManga.url); - return selectedSource.pullMangaFromNetwork(localManga.url); - }) - .flatMap(networkManga -> { - Manga.copyFromNetwork(manga, networkManga); - Timber.w("Net manga " + manga.thumbnail_url); - db.insertMangaBlock(manga); - return Observable.just(manga); - }); - } - return mangaObs; + private void getMangaDetails(List mangas) { + subscriptions.remove(mMangaDetailFetchSubscription); + + mMangaDetailFetchSubscription = Observable.from(mangas) + .subscribeOn(Schedulers.io()) + .filter(manga -> !manga.initialized) + .buffer(3) + .concatMap(localMangas -> { + List> mangaObservables = new ArrayList<>(); + for (Manga manga : localMangas) { + Observable tempObs = selectedSource.pullMangaFromNetwork(manga.url) + .flatMap(networkManga -> { + Manga.copyFromNetwork(manga, networkManga); + db.insertMangaBlock(manga); + return Observable.just(manga); + }) + .subscribeOn(Schedulers.io()); + mangaObservables.add(tempObs); + } + return Observable.merge(mangaObservables); + }) + .filter(manga -> manga.initialized) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(manga -> { + int i; + for (i = 0; i < adapter.getCount(); i++) { + if (manga.id == adapter.getItem(i).id) { + break; + } + } + view.updateImage(i, manga.thumbnail_url); + }); + + subscriptions.add(mMangaDetailFetchSubscription); } public void onQueryTextChange(String query) { @@ -152,8 +177,8 @@ public class CatalogueListPresenter extends BasePresenter { mSearchName = query; adapter.getItems().clear(); + view.resetScrollListener(); loadMoreMangas(1); - view.setScrollListener(); } public void loadMoreMangas(int page) { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/activity/CatalogueListActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/activity/CatalogueListActivity.java index 81ea71914..8420f7b04 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/activity/CatalogueListActivity.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/activity/CatalogueListActivity.java @@ -4,7 +4,11 @@ import android.os.Bundle; import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.view.Menu; -import android.widget.ListView; +import android.view.View; +import android.widget.GridView; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; import butterknife.Bind; import butterknife.ButterKnife; @@ -19,11 +23,13 @@ public class CatalogueListActivity extends BaseActivity implements CatalogueList @Bind(R.id.toolbar) Toolbar toolbar; - @Bind(R.id.catalogue_manga_list) - ListView manga_list; + @Bind(R.id.gridView) + GridView manga_list; private CatalogueListPresenter presenter; + private EndlessScrollListener scrollListener; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -75,13 +81,34 @@ public class CatalogueListActivity extends BaseActivity implements CatalogueList } public void setScrollListener() { - manga_list.setOnScrollListener(new EndlessScrollListener() { + scrollListener = new EndlessScrollListener() { @Override public boolean onLoadMore(int page, int totalItemsCount) { presenter.loadMoreMangas(page); return true; } - }); + }; + + manga_list.setOnScrollListener(scrollListener); } + public void resetScrollListener() { + scrollListener.resetScroll(); + } + + @Override + public void updateImage(int position, String thumbnail) { + View v = manga_list.getChildAt(position - + manga_list.getFirstVisiblePosition()); + + if(v == null) + return; + + ImageView imageView = (ImageView) v.findViewById(R.id.catalogue_thumbnail); + + Glide.with(getActivity()) + .load(thumbnail) + .centerCrop() + .into(imageView); + } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/adapter/CatalogueListHolder.java b/app/src/main/java/eu/kanade/mangafeed/ui/adapter/CatalogueListHolder.java index f5432a69d..435d5c062 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/adapter/CatalogueListHolder.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/adapter/CatalogueListHolder.java @@ -1,8 +1,12 @@ package eu.kanade.mangafeed.ui.adapter; import android.view.View; +import android.widget.ImageView; import android.widget.TextView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; + import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.models.Manga; import uk.co.ribot.easyadapter.ItemViewHolder; @@ -16,6 +20,9 @@ public class CatalogueListHolder extends ItemViewHolder { @ViewId(R.id.catalogue_title) TextView title; + @ViewId(R.id.catalogue_thumbnail) + ImageView image; + public CatalogueListHolder(View view) { super(view); } @@ -23,5 +30,17 @@ public class CatalogueListHolder extends ItemViewHolder { @Override public void onSetValues(Manga manga, PositionInfo positionInfo) { title.setText(manga.title); + + String thumbnail; + if (manga.thumbnail_url != null) + thumbnail = manga.thumbnail_url; + else + thumbnail = "http://img1.wikia.nocookie.net/__cb20090524204255/starwars/images/thumb/1/1a/R2d2.jpg/400px-R2d2.jpg"; + + Glide.with(getContext()) + .load(thumbnail) + .diskCacheStrategy(DiskCacheStrategy.RESULT) + .centerCrop() + .into(image); } } diff --git a/app/src/main/java/eu/kanade/mangafeed/view/CatalogueListView.java b/app/src/main/java/eu/kanade/mangafeed/view/CatalogueListView.java index c304d904f..cd485330d 100644 --- a/app/src/main/java/eu/kanade/mangafeed/view/CatalogueListView.java +++ b/app/src/main/java/eu/kanade/mangafeed/view/CatalogueListView.java @@ -10,4 +10,6 @@ public interface CatalogueListView extends BaseView { void setSourceTitle(String title); void setAdapter(EasyAdapter adapter); void setScrollListener(); + void resetScrollListener(); + void updateImage(int position, String thumbnail); } diff --git a/app/src/main/java/eu/kanade/mangafeed/widget/EndlessScrollListener.java b/app/src/main/java/eu/kanade/mangafeed/widget/EndlessScrollListener.java index 95c2d3b4f..f10ae1088 100644 --- a/app/src/main/java/eu/kanade/mangafeed/widget/EndlessScrollListener.java +++ b/app/src/main/java/eu/kanade/mangafeed/widget/EndlessScrollListener.java @@ -28,6 +28,12 @@ public abstract class EndlessScrollListener implements AbsListView.OnScrollListe this.currentPage = startPage; } + public void resetScroll() { + this.currentPage = 0; + this.startingPageIndex = 0; + this.loading = true; + } + // This happens many times a second during a scroll, so be wary of the code you place here. // We are given a few useful parameters to help us work out if we need to load some more data, // but first we check if we are waiting for the previous load to finish. diff --git a/app/src/main/res/layout/activity_catalogue_list.xml b/app/src/main/res/layout/activity_catalogue_list.xml index 238cefee6..94691010d 100644 --- a/app/src/main/res/layout/activity_catalogue_list.xml +++ b/app/src/main/res/layout/activity_catalogue_list.xml @@ -11,11 +11,18 @@ android:id="@+id/toolbar" layout="@layout/toolbar"/> - + android:id="@+id/gridView" + android:padding="10dp" + android:clipToPadding="false" + android:verticalSpacing="8dp" + android:horizontalSpacing="8dp" + android:columnWidth="96dp" + android:numColumns="auto_fit" + android:stretchMode="columnWidth" + android:fastScrollEnabled="true" + tools:listitem="@layout/item_catalogue" /> diff --git a/app/src/main/res/layout/item_catalogue.xml b/app/src/main/res/layout/item_catalogue.xml index 125ecebff..71a1019d6 100644 --- a/app/src/main/res/layout/item_catalogue.xml +++ b/app/src/main/res/layout/item_catalogue.xml @@ -1,14 +1,64 @@ - + android:layout_height="match_parent" + android:background="@drawable/library_item_background" + > - - \ No newline at end of file + android:layout_height="wrap_content"> + + + + + + + + + + + + + +