Load catalogue with thumbnails

This commit is contained in:
inorichi 2015-10-13 20:16:15 +02:00
parent c88d8f0ded
commit ed76520ebc
7 changed files with 173 additions and 37 deletions

View file

@ -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<Observable<String>> 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<Manga> getMangaDetails(Manga manga) {
Observable<Manga> 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<Manga> mangas) {
subscriptions.remove(mMangaDetailFetchSubscription);
mMangaDetailFetchSubscription = Observable.from(mangas)
.subscribeOn(Schedulers.io())
.filter(manga -> !manga.initialized)
.buffer(3)
.concatMap(localMangas -> {
List<Observable<Manga>> mangaObservables = new ArrayList<>();
for (Manga manga : localMangas) {
Observable<Manga> 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) {

View file

@ -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);
}
}

View file

@ -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<Manga> {
@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<Manga> {
@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);
}
}

View file

@ -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);
}

View file

@ -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.

View file

@ -11,11 +11,18 @@
android:id="@+id/toolbar"
layout="@layout/toolbar"/>
<ListView
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/catalogue_manga_list"
tools:listitem="@layout/item_catalogue"
/>
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" />
</LinearLayout>

View file

@ -1,14 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@drawable/library_item_background"
>
<TextView
<FrameLayout
android:layout_width="match_parent"
android:layout_height="40dp"
tools:text="New Text"
android:gravity="center_vertical"
android:id="@+id/catalogue_title" />
</LinearLayout>
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="144dp"
android:id="@+id/catalogue_thumbnail"
tools:src="@mipmap/ic_launcher"
tools:background="@color/md_red_100"/>
<eu.kanade.mangafeed.widget.PTSansTextView
android:id="@+id/unreadText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
app:typeface="ptsansNarrowBold"
android:background="@color/md_red_300"
android:layout_gravity="right"
android:textSize="12sp"
android:visibility="gone"
android:textColor="@color/white"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="1dp"
android:paddingBottom="1dp" />
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="36dp"
android:id="@+id/footerLinearLayout"
>
<eu.kanade.mangafeed.widget.PTSansTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
app:typeface="ptsansNarrowBold"
android:ellipsize="middle"
android:maxLines="2"
android:textColor="@color/black_87pc"
android:textSize="13sp"
android:id="@+id/catalogue_title"
android:paddingRight="8dp"
android:paddingLeft="8dp"
tools:text="Sample name"/>
</LinearLayout>
</LinearLayout>