浏览代码

Load catalogue with thumbnails

inorichi 9 年之前
父节点
当前提交
ed76520ebc

+ 45 - 20
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<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) {

+ 32 - 5
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);
+    }
 }

+ 19 - 0
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<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);
     }
 }

+ 2 - 0
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);
 }

+ 6 - 0
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.

+ 11 - 4
app/src/main/res/layout/activity_catalogue_list.xml

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

+ 58 - 8
app/src/main/res/layout/item_catalogue.xml

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