More changes to MangaDetailActivity and its fragments

This commit is contained in:
inorichi 2015-10-17 21:31:10 +02:00
parent c13d747665
commit 1802dd04e4
11 changed files with 249 additions and 253 deletions

View file

@ -57,6 +57,11 @@ public class DatabaseHelper implements MangaManager, ChapterManager {
return mChapterManager.getChapters(manga); return mChapterManager.getChapters(manga);
} }
@Override
public Observable<List<Chapter>> getChapters(long manga_id) {
return mChapterManager.getChapters(manga_id);
}
@Override @Override
public Observable<PutResult> insertChapter(Chapter chapter) { public Observable<PutResult> insertChapter(Chapter chapter) {
return mChapterManager.insertChapter(chapter); return mChapterManager.insertChapter(chapter);

View file

@ -15,6 +15,8 @@ public interface ChapterManager {
Observable<List<Chapter>> getChapters(Manga manga); Observable<List<Chapter>> getChapters(Manga manga);
Observable<List<Chapter>> getChapters(long manga_id);
Observable<PutResult> insertChapter(Chapter chapter); Observable<PutResult> insertChapter(Chapter chapter);
Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters); Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters);

View file

@ -38,6 +38,19 @@ public class ChapterManagerImpl extends BaseManager implements ChapterManager {
return prepareGetChapters(manga).createObservable(); return prepareGetChapters(manga).createObservable();
} }
@Override
public Observable<List<Chapter>> getChapters(long manga_id) {
return db.get()
.listOfObjects(Chapter.class)
.withQuery(Query.builder()
.table(ChaptersTable.TABLE)
.where(ChaptersTable.COLUMN_MANGA_ID + "=?")
.whereArgs(manga_id)
.build())
.prepare()
.createObservable();
}
@Override @Override
public Observable<PutResult> insertChapter(Chapter chapter) { public Observable<PutResult> insertChapter(Chapter chapter) {
return db.put() return db.put()

View file

@ -1,6 +1,67 @@
package eu.kanade.mangafeed.presenter; package eu.kanade.mangafeed.presenter;
import javax.inject.Inject;
import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
import eu.kanade.mangafeed.data.helpers.SourceManager;
import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.sources.Source;
import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> { public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> {
@Inject DatabaseHelper db;
@Inject SourceManager sourceManager;
private Subscription chaptersSubscription;
private Subscription onlineChaptersSubscription;
private boolean doingRequest = false;
@Override
protected void onTakeView(MangaChaptersFragment view) {
super.onTakeView(view);
getChapters(view.getMangaId());
}
public void refreshChapters(Manga manga) {
if (manga != null && !doingRequest)
getChaptersFromSource(manga);
}
private void getChapters(long manga_id) {
if (chaptersSubscription != null)
remove(chaptersSubscription);
chaptersSubscription = db.getChapters(manga_id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(deliverLatestCache())
.subscribe(this.split(MangaChaptersFragment::onNextChapters));
add(chaptersSubscription);
}
public void getChaptersFromSource(Manga manga) {
if (onlineChaptersSubscription != null)
remove(onlineChaptersSubscription);
Source source = sourceManager.get(manga.source);
doingRequest = true;
onlineChaptersSubscription = source.pullChaptersFromNetwork(manga.url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(deliverLatestCache())
.subscribe(this.split((view, chapters) -> {
doingRequest = false;
}), throwable -> {
doingRequest = false;
});
add(onlineChaptersSubscription);
}
} }

View file

@ -1,7 +1,37 @@
package eu.kanade.mangafeed.presenter; package eu.kanade.mangafeed.presenter;
import javax.inject.Inject;
import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.activity.MangaDetailActivity;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MangaDetailPresenter extends BasePresenter<MangaDetailActivity> { public class MangaDetailPresenter extends BasePresenter<MangaDetailActivity> {
@Inject DatabaseHelper db;
private Subscription mangaSubscription;
@Override
protected void onTakeView(MangaDetailActivity view) {
super.onTakeView(view);
if (mangaSubscription == null)
initializeManga(view);
}
private void initializeManga(MangaDetailActivity view) {
mangaSubscription = db.getManga(view.getMangaId())
.subscribeOn(Schedulers.io())
.take(1)
.flatMap(Observable::from)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(view::onMangaNext);
add(mangaSubscription);
}
} }

View file

@ -32,6 +32,7 @@ public class MangaDetailActivity extends BaseActivity<MangaDetailPresenter> {
@Bind(R.id.viewpager) @Bind(R.id.viewpager)
ViewPager view_pager; ViewPager view_pager;
private MangaDetailAdapter adapter;
private long manga_id; private long manga_id;
private boolean is_online = false; private boolean is_online = false;
@ -73,59 +74,70 @@ public class MangaDetailActivity extends BaseActivity<MangaDetailPresenter> {
} }
private void setupViewPager() { private void setupViewPager() {
view_pager.setAdapter(new MangaDetailAdapter( adapter = new MangaDetailAdapter(
getSupportFragmentManager(), getSupportFragmentManager(),
getActivity(), getActivity(),
manga_id)); manga_id);
view_pager.setAdapter(adapter);
tabs.setupWithViewPager(view_pager); tabs.setupWithViewPager(view_pager);
if (!is_online) if (!is_online)
view_pager.setCurrentItem(MangaDetailAdapter.CHAPTERS_FRAGMENT); view_pager.setCurrentItem(MangaDetailAdapter.CHAPTERS_FRAGMENT);
} }
} public long getMangaId() {
return manga_id;
class MangaDetailAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private String tab_titles[];
private Context context;
private long manga_id;
final static int INFO_FRAGMENT = 0;
final static int CHAPTERS_FRAGMENT = 1;
public MangaDetailAdapter(FragmentManager fm, Context context, long manga_id) {
super(fm);
this.context = context;
tab_titles = new String[]{
context.getString(R.string.manga_detail_tab),
context.getString(R.string.manga_chapters_tab)
};
this.manga_id = manga_id;
} }
@Override public void onMangaNext(Manga manga) {
public int getCount() { ((MangaChaptersFragment) adapter.getItem(MangaDetailAdapter.CHAPTERS_FRAGMENT))
return PAGE_COUNT; .onMangaNext(manga);
} }
@Override class MangaDetailAdapter extends FragmentPagerAdapter {
public Fragment getItem(int position) {
switch (position) {
case INFO_FRAGMENT:
return MangaInfoFragment.newInstance(manga_id);
case CHAPTERS_FRAGMENT:
return MangaChaptersFragment.newInstance(manga_id);
default: return null; final int PAGE_COUNT = 2;
private String tab_titles[];
private Context context;
private long manga_id;
final static int INFO_FRAGMENT = 0;
final static int CHAPTERS_FRAGMENT = 1;
public MangaDetailAdapter(FragmentManager fm, Context context, long manga_id) {
super(fm);
this.context = context;
tab_titles = new String[]{
context.getString(R.string.manga_detail_tab),
context.getString(R.string.manga_chapters_tab)
};
this.manga_id = manga_id;
}
@Override
public int getCount() {
return PAGE_COUNT;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case INFO_FRAGMENT:
return MangaInfoFragment.newInstance(manga_id);
case CHAPTERS_FRAGMENT:
return MangaChaptersFragment.newInstance(manga_id);
default:
return null;
}
}
@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tab_titles[position];
} }
} }
@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tab_titles[position];
}
} }

View file

@ -14,6 +14,7 @@ import android.widget.GridView;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnItemClick;
import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.presenter.LibraryPresenter; import eu.kanade.mangafeed.presenter.LibraryPresenter;
@ -53,7 +54,7 @@ public class LibraryFragment extends BaseFragment<LibraryPresenter> {
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
createAdapter(); createAdapter();
setMangaClickListener(); setMangaLongClickListener();
return view; return view;
} }
@ -80,7 +81,7 @@ public class LibraryFragment extends BaseFragment<LibraryPresenter> {
}); });
} }
public void createAdapter() { private void createAdapter() {
adapter = new LibraryAdapter<>(getActivity()); adapter = new LibraryAdapter<>(getActivity());
grid.setAdapter(adapter); grid.setAdapter(adapter);
} }
@ -89,11 +90,16 @@ public class LibraryFragment extends BaseFragment<LibraryPresenter> {
return adapter; return adapter;
} }
public void setMangaClickListener() { @OnItemClick(R.id.gridView)
grid.setOnItemClickListener( protected void onMangaClick(int position) {
(parent, view, position, id) -> Intent intent = MangaDetailActivity.newIntent(
onMangaClick(position) getActivity(),
adapter.getItem(position)
); );
getActivity().startActivity(intent);
}
private void setMangaLongClickListener() {
grid.setMultiChoiceModeListener(new GridView.MultiChoiceModeListener() { grid.setMultiChoiceModeListener(new GridView.MultiChoiceModeListener() {
@Override @Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
@ -131,12 +137,4 @@ public class LibraryFragment extends BaseFragment<LibraryPresenter> {
}); });
} }
private void onMangaClick(int position) {
Intent intent = MangaDetailActivity.newIntent(
getActivity(),
adapter.getItem(position)
);
getActivity().startActivity(intent);
}
} }

View file

@ -2,20 +2,37 @@ package eu.kanade.mangafeed.ui.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.models.Chapter;
import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.presenter.MangaChaptersPresenter; import eu.kanade.mangafeed.presenter.MangaChaptersPresenter;
import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.activity.MangaDetailActivity;
import eu.kanade.mangafeed.ui.adapter.ChapterListHolder;
import nucleus.factory.RequiresPresenter; import nucleus.factory.RequiresPresenter;
import timber.log.Timber;
import uk.co.ribot.easyadapter.EasyRecyclerAdapter;
@RequiresPresenter(MangaChaptersPresenter.class) @RequiresPresenter(MangaChaptersPresenter.class)
public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> { public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> {
@Bind(R.id.chapter_list) RecyclerView chapters;
private long manga_id; private long manga_id;
private Manga manga;
private EasyRecyclerAdapter<Chapter> adapter;
public static Fragment newInstance(long manga_id) { public static Fragment newInstance(long manga_id) {
MangaChaptersFragment fragment = new MangaChaptersFragment(); MangaChaptersFragment fragment = new MangaChaptersFragment();
@ -28,6 +45,8 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter>
@Override @Override
public void onCreate(Bundle savedState) { public void onCreate(Bundle savedState) {
super.onCreate(savedState); super.onCreate(savedState);
setHasOptionsMenu(true);
manga_id = getArguments().getLong(MangaDetailActivity.MANGA_ID); manga_id = getArguments().getLong(MangaDetailActivity.MANGA_ID);
} }
@ -38,6 +57,46 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter>
View view = inflater.inflate(R.layout.fragment_manga_chapters, container, false); View view = inflater.inflate(R.layout.fragment_manga_chapters, container, false);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
chapters.setLayoutManager(new LinearLayoutManager(getActivity()));
createAdapter();
return view; return view;
} }
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.chapters, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
getPresenter().refreshChapters(manga);
break;
}
return super.onOptionsItemSelected(item);
}
private void createAdapter() {
adapter = new EasyRecyclerAdapter<>(getActivity(), ChapterListHolder.class);
chapters.setAdapter(adapter);
}
public long getMangaId() {
return manga_id;
}
public Manga getManga() {
return manga;
}
public void onNextChapters(List<Chapter> chapters) {
adapter.setItems(chapters);
}
public void onMangaNext(Manga manga) {
this.manga = manga;
}
} }

View file

@ -1,201 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context="eu.kanade.mangafeed.ui.activity.CatalogueActivity">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bkg_shadow_img"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center"
android:padding="4dp">
<ImageView
android:id="@+id/manga_cover"
android:layout_width="138dp"
android:layout_height="190dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:scaleType="fitXY"
android:visibility="visible" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/grid_item_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:paddingLeft="15.0dip">
<TextView
android:id="@+id/manga_author_label"
style="@style/manga_detail_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="@+id/manga_genres_label"
android:layout_marginTop="5dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="@string/author" />
<TextView
android:id="@+id/manga_author"
style="@style/manga_detail_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/manga_author_label"
android:layout_toRightOf="@id/manga_author_label"
android:ellipsize="end"
android:focusable="false"
android:focusableInTouchMode="false"
android:maxLines="1"
android:singleLine="true" />
<TextView
android:id="@+id/manga_artist_label"
style="@style/manga_detail_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="@id/manga_genres_label"
android:layout_below="@id/manga_author_label"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="@string/artist" />
<TextView
android:id="@+id/manga_artist"
style="@style/manga_detail_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/manga_artist_label"
android:layout_toRightOf="@id/manga_artist_label"
android:ellipsize="end"
android:focusable="false"
android:focusableInTouchMode="false"
android:maxLines="1"
android:singleLine="true" />
<TextView
android:id="@+id/manga_chapters_label"
style="@style/manga_detail_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="@id/manga_genres_label"
android:layout_below="@id/manga_artist_label"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="@string/chapters" />
<TextView
android:id="@+id/manga_chapters"
style="@style/manga_detail_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/manga_chapters_label"
android:layout_toRightOf="@id/manga_chapters_label"
android:ellipsize="end"
android:focusable="false"
android:focusableInTouchMode="false"
android:maxLines="1"
android:singleLine="true" />
<TextView
android:id="@+id/manga_status_label"
style="@style/manga_detail_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="@id/manga_genres_label"
android:layout_below="@id/manga_chapters_label"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="@string/status" />
<TextView
android:id="@+id/manga_status"
style="@style/manga_detail_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/manga_status_label"
android:layout_toRightOf="@id/manga_chapters_label"
android:ellipsize="end"
android:focusable="false"
android:focusableInTouchMode="false"
android:maxLines="1"
android:singleLine="true" />
<TextView
android:id="@+id/manga_genres_label"
style="@style/manga_detail_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/manga_status_label"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="@string/genres" />
<TextView
android:id="@+id/manga_genres"
style="@style/manga_detail_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/manga_genres_label"
android:singleLine="false"
android:focusable="false"
android:focusableInTouchMode="false"
/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/manga_summary_label"
style="@style/manga_detail_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:singleLine="false"
android:text="@string/description" />
<TextView
android:id="@+id/manga_summary"
style="@style/manga_detail_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"
android:singleLine="false" />
</LinearLayout>
</LinearLayout>

View file

@ -3,4 +3,11 @@
android:orientation="vertical" android:layout_width="match_parent" android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/chapter_list">
</android.support.v7.widget.RecyclerView>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MangaDetailActivity">
<item
android:id="@+id/action_refresh"
android:title="@string/action_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="1"
app:showAsAction="ifRoom" />
</menu>