From 0e52c81970d46ef0d04b377274c2e85856826488 Mon Sep 17 00:00:00 2001 From: inorichi Date: Sat, 17 Oct 2015 13:51:54 +0200 Subject: [PATCH] Add MangaDetailActivity with two fragments, info and chapters --- .../eu/kanade/mangafeed/AppComponent.java | 4 + .../data/helpers/DatabaseHelper.java | 2 +- .../mangafeed/data/managers/MangaManager.java | 2 +- .../data/managers/MangaManagerImpl.java | 12 +- .../mangafeed/presenter/LibraryPresenter.java | 10 - .../presenter/MangaChaptersPresenter.java | 6 + .../presenter/MangaDetailPresenter.java | 14 +- .../presenter/MangaInfoPresenter.java | 36 ++++ .../ui/activity/MangaDetailActivity.java | 125 +++++++---- .../ui/fragment/LibraryFragment.java | 12 +- .../ui/fragment/MangaChaptersFragment.java | 43 ++++ .../ui/fragment/MangaInfoFragment.java | 76 +++++++ .../main/res/layout/activity_manga_detail.xml | 42 ++-- .../res/layout/fragment_manga_chapters.xml | 6 + .../main/res/layout/fragment_manga_info.xml | 197 ++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 16 files changed, 508 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/presenter/MangaInfoPresenter.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaInfoFragment.java create mode 100644 app/src/main/res/layout/fragment_manga_chapters.xml create mode 100644 app/src/main/res/layout/fragment_manga_info.xml diff --git a/app/src/main/java/eu/kanade/mangafeed/AppComponent.java b/app/src/main/java/eu/kanade/mangafeed/AppComponent.java index ad081c7ce6..825ac29ef7 100644 --- a/app/src/main/java/eu/kanade/mangafeed/AppComponent.java +++ b/app/src/main/java/eu/kanade/mangafeed/AppComponent.java @@ -9,7 +9,9 @@ import eu.kanade.mangafeed.data.DataModule; import eu.kanade.mangafeed.presenter.CataloguePresenter; import eu.kanade.mangafeed.presenter.LibraryPresenter; import eu.kanade.mangafeed.presenter.MangaCataloguePresenter; +import eu.kanade.mangafeed.presenter.MangaChaptersPresenter; import eu.kanade.mangafeed.presenter.MangaDetailPresenter; +import eu.kanade.mangafeed.presenter.MangaInfoPresenter; import eu.kanade.mangafeed.presenter.SourcePresenter; @Singleton @@ -26,6 +28,8 @@ public interface AppComponent { void inject(SourcePresenter sourcePresenter); void inject(CataloguePresenter cataloguePresenter); void inject(MangaCataloguePresenter mangaCataloguePresenter); + void inject(MangaInfoPresenter mangaInfoPresenter); + void inject(MangaChaptersPresenter mangaChaptersPresenter); Application application(); diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java index 7ffddb21f8..2cdff7a0b3 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java @@ -98,7 +98,7 @@ public class DatabaseHelper implements MangaManager, ChapterManager { } @Override - public Observable> getManga(int id) { + public Observable> getManga(long id) { return mMangaManager.getManga(id); } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManager.java b/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManager.java index f1c5d48719..1ff99c2317 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManager.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManager.java @@ -18,7 +18,7 @@ public interface MangaManager { Observable> getManga(String url); - Observable> getManga(int id); + Observable> getManga(long id); Manga getMangaBlock(String url); diff --git a/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManagerImpl.java b/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManagerImpl.java index 4d6d1a0a23..5ced02879a 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManagerImpl.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManagerImpl.java @@ -66,8 +66,16 @@ public class MangaManagerImpl extends BaseManager implements MangaManager { .createObservable(); } - public Observable> getManga(int id) { - return null; + public Observable> getManga(long id) { + return db.get() + .listOfObjects(Manga.class) + .withQuery(Query.builder() + .table(MangasTable.TABLE) + .where(MangasTable.COLUMN_ID + "=?") + .whereArgs(id) + .build()) + .prepare() + .createObservable(); } @Override diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java index 7f567b968a..2b1dd9df6e 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java @@ -1,6 +1,5 @@ package eu.kanade.mangafeed.presenter; -import android.content.Intent; import android.os.Bundle; import android.util.SparseBooleanArray; @@ -9,7 +8,6 @@ import javax.inject.Inject; import eu.kanade.mangafeed.data.helpers.DatabaseHelper; import eu.kanade.mangafeed.data.helpers.PreferencesHelper; import eu.kanade.mangafeed.data.models.Manga; -import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.fragment.LibraryFragment; import rx.Observable; import rx.Subscription; @@ -36,14 +34,6 @@ public class LibraryPresenter extends BasePresenter2 { getFavoriteMangas(); } - public void onMangaClick(LibraryFragment view, int position) { - Intent intent = MangaDetailActivity.newIntent( - view.getActivity(), - view.getAdapter().getItem(position) - ); - view.getActivity().startActivity(intent); - } - public void getFavoriteMangas() { if (mFavoriteMangasSubscription != null) remove(mFavoriteMangasSubscription); diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java new file mode 100644 index 0000000000..2545a1b409 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java @@ -0,0 +1,6 @@ +package eu.kanade.mangafeed.presenter; + +import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; + +public class MangaChaptersPresenter extends BasePresenter2 { +} diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaDetailPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaDetailPresenter.java index 8f08945897..95c406df0a 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaDetailPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaDetailPresenter.java @@ -2,33 +2,23 @@ package eu.kanade.mangafeed.presenter; import javax.inject.Inject; -import de.greenrobot.event.EventBus; -import eu.kanade.mangafeed.App; import eu.kanade.mangafeed.data.helpers.DatabaseHelper; import eu.kanade.mangafeed.data.models.Manga; +import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.view.MangaDetailView; -public class MangaDetailPresenter extends BasePresenter { +public class MangaDetailPresenter extends BasePresenter2 { private MangaDetailView view; @Inject DatabaseHelper db; - public MangaDetailPresenter(MangaDetailView view) { - this.view = view; - App.getComponent(view.getActivity()).inject(this); - } - public void onEventMainThread(Manga manga) { view.loadManga(manga); initializeChapters(manga); } - public static void newIntent(Manga manga) { - EventBus.getDefault().postSticky(manga); - } - public void initializeChapters(Manga manga) { db.getChapters(manga) .subscribe(view::setChapters); diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaInfoPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaInfoPresenter.java new file mode 100644 index 0000000000..5c2588a8d7 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaInfoPresenter.java @@ -0,0 +1,36 @@ +package eu.kanade.mangafeed.presenter; + +import javax.inject.Inject; + +import eu.kanade.mangafeed.data.helpers.DatabaseHelper; +import eu.kanade.mangafeed.ui.fragment.MangaInfoFragment; +import rx.Observable; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; + +public class MangaInfoPresenter extends BasePresenter2 { + + @Inject DatabaseHelper db; + + private Subscription mangaInfoSubscription; + + @Override + protected void onTakeView(MangaInfoFragment view) { + super.onTakeView(view); + + getMangaInfo(view); + } + + private void getMangaInfo(MangaInfoFragment view) { + if (mangaInfoSubscription != null) + remove(mangaInfoSubscription); + + mangaInfoSubscription = db.getManga(view.getMangaId()) + .observeOn(AndroidSchedulers.mainThread()) + .take(1) + .flatMap(Observable::from) + .subscribe(view::setMangaInfo); + + add(mangaInfoSubscription); + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaDetailActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaDetailActivity.java index 8372984a92..a1ee6ad96b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaDetailActivity.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaDetailActivity.java @@ -2,37 +2,45 @@ package eu.kanade.mangafeed.ui.activity; import android.content.Context; import android.content.Intent; +import android.os.Build; import android.os.Bundle; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; import android.support.v7.widget.Toolbar; -import android.widget.ListView; - -import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; import eu.kanade.mangafeed.R; -import eu.kanade.mangafeed.data.models.Chapter; import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.presenter.MangaDetailPresenter; -import eu.kanade.mangafeed.ui.adapter.ChapterListHolder; -import eu.kanade.mangafeed.view.MangaDetailView; -import uk.co.ribot.easyadapter.EasyAdapter; +import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; +import eu.kanade.mangafeed.ui.fragment.MangaInfoFragment; +import nucleus.factory.RequiresPresenter; -public class MangaDetailActivity extends BaseActivity implements MangaDetailView { - - Manga manga; - MangaDetailPresenter presenter; - EasyAdapter adapter; +@RequiresPresenter(MangaDetailPresenter.class) +public class MangaDetailActivity extends BaseActivity2 { @Bind(R.id.toolbar) Toolbar toolbar; - @Bind(R.id.manga_chapters_list) - ListView list_chapters; + @Bind(R.id.tabs) + TabLayout tabs; + + @Bind(R.id.viewpager) + ViewPager view_pager; + + long manga_id; + + public final static String MANGA_ID = "manga_id"; + public final static String MANGA_TITLE = "manga_title"; public static Intent newIntent(Context context, Manga manga) { Intent intent = new Intent(context, MangaDetailActivity.class); - MangaDetailPresenter.newIntent(manga); + intent.putExtra(MANGA_ID, manga.id); + intent.putExtra(MANGA_TITLE, manga.title); return intent; } @@ -41,38 +49,71 @@ public class MangaDetailActivity extends BaseActivity implements MangaDetailView super.onCreate(savedInstanceState); setContentView(R.layout.activity_manga_detail); ButterKnife.bind(this); - presenter = new MangaDetailPresenter(this); setupToolbar(toolbar); + disableToolbarElevation(); + + String manga_title = getIntent().getStringExtra(MANGA_TITLE); + setToolbarTitle(manga_title); + + manga_id = getIntent().getLongExtra(MANGA_ID, -1); + setupViewPager(); } - @Override - public void onStart() { - super.onStart(); - presenter.registerForStickyEvents(); - } - - @Override - public void onStop() { - presenter.unregisterForEvents(); - super.onStop(); - } - - public void loadManga(Manga manga) { - setToolbarTitle(manga.title); - } - - public void setChapters(List chapters) { - if (adapter == null) { - adapter = new EasyAdapter( - getActivity(), - ChapterListHolder.class, - chapters - ); - list_chapters.setAdapter(adapter); - } else { - adapter.setItems(chapters); + private void disableToolbarElevation() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setElevation(0); } } + private void setupViewPager() { + view_pager.setAdapter(new MangaDetailAdapter( + getSupportFragmentManager(), + getActivity(), + manga_id)); + + tabs.setupWithViewPager(view_pager); + } + +} + +class MangaDetailAdapter extends FragmentPagerAdapter { + + final int PAGE_COUNT = 2; + private String tab_titles[]; + private Context context; + private long manga_id; + + 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 0: + return MangaInfoFragment.newInstance(manga_id); + case 1: + return MangaChaptersFragment.newInstance(manga_id); + + default: return null; + } + } + + @Override + public CharSequence getPageTitle(int position) { + // Generate title based on item position + return tab_titles[position]; + } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/LibraryFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/LibraryFragment.java index a63ed0905b..b6895a6198 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/LibraryFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/LibraryFragment.java @@ -1,5 +1,6 @@ package eu.kanade.mangafeed.ui.fragment; +import android.content.Intent; import android.os.Bundle; import android.support.v7.widget.SearchView; import android.view.ActionMode; @@ -17,6 +18,7 @@ import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.presenter.LibraryPresenter; import eu.kanade.mangafeed.ui.activity.MainActivity; +import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.adapter.LibraryAdapter; import nucleus.factory.RequiresPresenter; @@ -90,7 +92,7 @@ public class LibraryFragment extends BaseFragment2 { public void setMangaClickListener() { grid.setOnItemClickListener( (parent, view, position, id) -> - getPresenter().onMangaClick(this, position) + onMangaClick(position) ); grid.setMultiChoiceModeListener(new GridView.MultiChoiceModeListener() { @Override @@ -129,4 +131,12 @@ public class LibraryFragment extends BaseFragment2 { }); } + private void onMangaClick(int position) { + Intent intent = MangaDetailActivity.newIntent( + getActivity(), + adapter.getItem(position) + ); + getActivity().startActivity(intent); + } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java new file mode 100644 index 0000000000..3aa330b070 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java @@ -0,0 +1,43 @@ +package eu.kanade.mangafeed.ui.fragment; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import butterknife.ButterKnife; +import eu.kanade.mangafeed.R; +import eu.kanade.mangafeed.presenter.MangaChaptersPresenter; +import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; +import nucleus.factory.RequiresPresenter; + +@RequiresPresenter(MangaChaptersPresenter.class) +public class MangaChaptersFragment extends BaseFragment2 { + + private long manga_id; + + public static Fragment newInstance(long manga_id) { + MangaChaptersFragment fragment = new MangaChaptersFragment(); + Bundle args = new Bundle(); + args.putLong(MangaDetailActivity.MANGA_ID, manga_id); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedState) { + super.onCreate(savedState); + manga_id = getArguments().getLong(MangaDetailActivity.MANGA_ID); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_manga_chapters, container, false); + ButterKnife.bind(this, view); + + return view; + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaInfoFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaInfoFragment.java new file mode 100644 index 0000000000..d0fbf2e4a1 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaInfoFragment.java @@ -0,0 +1,76 @@ +package eu.kanade.mangafeed.ui.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; + +import butterknife.Bind; +import butterknife.ButterKnife; +import eu.kanade.mangafeed.R; +import eu.kanade.mangafeed.data.models.Manga; +import eu.kanade.mangafeed.presenter.MangaInfoPresenter; +import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; +import nucleus.factory.RequiresPresenter; + +@RequiresPresenter(MangaInfoPresenter.class) +public class MangaInfoFragment extends BaseFragment2 { + + @Bind(R.id.manga_artist) TextView mArtist; + @Bind(R.id.manga_author) TextView mAuthor; + @Bind(R.id.manga_chapters) TextView mChapters; + @Bind(R.id.manga_genres) TextView mGenres; + @Bind(R.id.manga_status) TextView mStatus; + @Bind(R.id.manga_summary) TextView mDescription; + @Bind(R.id.manga_cover) ImageView mCover; + + private long manga_id; + + public static MangaInfoFragment newInstance(long manga_id) { + MangaInfoFragment fragment = new MangaInfoFragment(); + Bundle args = new Bundle(); + args.putLong(MangaDetailActivity.MANGA_ID, manga_id); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedState) { + super.onCreate(savedState); + manga_id = getArguments().getLong(MangaDetailActivity.MANGA_ID); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_manga_info, container, false); + ButterKnife.bind(this, view); + + return view; + } + + public long getMangaId() { + return manga_id; + } + + public void setMangaInfo(Manga manga) { + mArtist.setText(manga.artist); + mAuthor.setText(manga.author); + mChapters.setText("0"); // TODO + mGenres.setText(manga.genre); + mStatus.setText("Ongoing"); //TODO + mDescription.setText(manga.description); + + Glide.with(getActivity()) + .load(manga.thumbnail_url) + .diskCacheStrategy(DiskCacheStrategy.RESULT) + .centerCrop() + .into(mCover); + } +} diff --git a/app/src/main/res/layout/activity_manga_detail.xml b/app/src/main/res/layout/activity_manga_detail.xml index 5de20a8c4b..3faf4ca94a 100644 --- a/app/src/main/res/layout/activity_manga_detail.xml +++ b/app/src/main/res/layout/activity_manga_detail.xml @@ -1,19 +1,37 @@ - - - - + android:layout_height="wrap_content" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_manga_chapters.xml b/app/src/main/res/layout/fragment_manga_chapters.xml new file mode 100644 index 0000000000..3509b84116 --- /dev/null +++ b/app/src/main/res/layout/fragment_manga_chapters.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_manga_info.xml b/app/src/main/res/layout/fragment_manga_info.xml new file mode 100644 index 0000000000..e637dbbca6 --- /dev/null +++ b/app/src/main/res/layout/fragment_manga_info.xml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9c8f62119..b3d4aa065e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,5 +43,7 @@ Artist Status Description + Info + Chapters