Add minor improvements and retry button to webtoon reader.

This commit is contained in:
inorichi 2016-01-07 21:21:42 +01:00
parent 39c9fd5945
commit b735a1f581
7 changed files with 175 additions and 84 deletions

View File

@ -51,7 +51,7 @@ public class PagerReaderFragment extends BaseFragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_page, container, false); View view = inflater.inflate(R.layout.item_pager_reader, container, false);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
ReaderActivity activity = (ReaderActivity) getActivity(); ReaderActivity activity = (ReaderActivity) getActivity();

View File

@ -4,31 +4,23 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ProgressBar;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.data.source.model.Page;
public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonAdapter.ImageHolder> { public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonHolder> {
private List<Page> pages;
private WebtoonReader fragment; private WebtoonReader fragment;
private View.OnTouchListener listener; private List<Page> pages;
private View.OnTouchListener touchListener;
public WebtoonAdapter(WebtoonReader fragment) { public WebtoonAdapter(WebtoonReader fragment) {
this.fragment = fragment; this.fragment = fragment;
pages = new ArrayList<>(); pages = new ArrayList<>();
listener = (v, event) -> fragment.onImageTouch(event); touchListener = (v, event) -> fragment.onImageTouch(event);
} }
public Page getItem(int position) { public Page getItem(int position) {
@ -36,14 +28,14 @@ public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonAdapter.ImageHol
} }
@Override @Override
public ImageHolder onCreateViewHolder(ViewGroup parent, int viewType) { public WebtoonHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = fragment.getActivity().getLayoutInflater(); LayoutInflater inflater = fragment.getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.item_webtoon_reader, parent, false); View v = inflater.inflate(R.layout.item_webtoon_reader, parent, false);
return new ImageHolder(v, listener); return new WebtoonHolder(v, this, touchListener);
} }
@Override @Override
public void onBindViewHolder(ImageHolder holder, int position) { public void onBindViewHolder(WebtoonHolder holder, int position) {
final Page page = getItem(position); final Page page = getItem(position);
holder.onSetValues(page); holder.onSetValues(page);
} }
@ -53,9 +45,9 @@ public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonAdapter.ImageHol
return pages.size(); return pages.size();
} }
public void addPage(Page page) { public void setPages(List<Page> pages) {
pages.add(page); this.pages = pages;
notifyItemInserted(page.getPageNumber()); notifyDataSetChanged();
} }
public void clear() { public void clear() {
@ -65,41 +57,8 @@ public class WebtoonAdapter extends RecyclerView.Adapter<WebtoonAdapter.ImageHol
} }
} }
public static class ImageHolder extends RecyclerView.ViewHolder { public void retryPage(Page page) {
fragment.getReaderActivity().getPresenter().retryPage(page);
@Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;
@Bind(R.id.progress) ProgressBar progressBar;
private Animation fadeInAnimation;
public ImageHolder(View view, View.OnTouchListener listener) {
super(view);
ButterKnife.bind(this, view);
fadeInAnimation = AnimationUtils.loadAnimation(view.getContext(), R.anim.fade_in);
imageView.setParallelLoadingEnabled(true);
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
imageView.setOnTouchListener(listener);
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
@Override
public void onImageLoaded() {
imageView.startAnimation(fadeInAnimation);
}
});
}
public void onSetValues(Page page) {
if (page.getImagePath() != null) {
imageView.setVisibility(View.VISIBLE);
imageView.setImage(ImageSource.uri(page.getImagePath()));
progressBar.setVisibility(View.GONE);
} else {
imageView.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
}
} }
} }

View File

@ -0,0 +1,117 @@
package eu.kanade.mangafeed.ui.reader.viewer.webtoon;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ProgressBar;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.source.model.Page;
public class WebtoonHolder extends RecyclerView.ViewHolder {
@Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;
@Bind(R.id.frame_container) ViewGroup container;
@Bind(R.id.progress) ProgressBar progressBar;
@Bind(R.id.retry_button) Button retryButton;
private Animation fadeInAnimation;
private Page page;
public WebtoonHolder(View view, WebtoonAdapter adapter, View.OnTouchListener touchListener) {
super(view);
ButterKnife.bind(this, view);
fadeInAnimation = AnimationUtils.loadAnimation(view.getContext(), R.anim.fade_in);
imageView.setParallelLoadingEnabled(true);
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
imageView.setOnTouchListener(touchListener);
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
@Override
public void onImageLoaded() {
imageView.startAnimation(fadeInAnimation);
}
});
progressBar.setMinimumHeight(view.getResources().getDisplayMetrics().heightPixels);
container.setOnTouchListener(touchListener);
retryButton.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (page != null)
adapter.retryPage(page);
return true;
}
return true;
});
}
public void onSetValues(Page page) {
this.page = page;
switch (page.getStatus()) {
case Page.QUEUE:
onQueue();
break;
case Page.LOAD_PAGE:
onLoading();
break;
case Page.DOWNLOAD_IMAGE:
onLoading();
break;
case Page.READY:
onReady();
break;
case Page.ERROR:
onError();
break;
}
}
private void onLoading() {
setErrorButtonVisible(false);
setImageVisible(false);
setProgressVisible(true);
}
private void onReady() {
setErrorButtonVisible(false);
setProgressVisible(false);
setImageVisible(true);
imageView.setImage(ImageSource.uri(page.getImagePath()));
}
private void onError() {
setImageVisible(false);
setProgressVisible(false);
setErrorButtonVisible(true);
}
private void onQueue() {
setImageVisible(false);
setErrorButtonVisible(false);
setProgressVisible(false);
}
private void setProgressVisible(boolean visible) {
progressBar.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private void setImageVisible(boolean visible) {
imageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private void setErrorButtonVisible(boolean visible) {
retryButton.setVisibility(visible ? View.VISIBLE : View.GONE);
}
}

View File

@ -25,6 +25,7 @@ public class WebtoonReader extends BaseReader {
private WebtoonAdapter adapter; private WebtoonAdapter adapter;
private RecyclerView recycler; private RecyclerView recycler;
private PreCachingLayoutManager layoutManager;
private Subscription subscription; private Subscription subscription;
private GestureDetector gestureDetector; private GestureDetector gestureDetector;
@ -32,7 +33,7 @@ public class WebtoonReader extends BaseReader {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
adapter = new WebtoonAdapter(this); adapter = new WebtoonAdapter(this);
PreCachingLayoutManager layoutManager = new PreCachingLayoutManager(getActivity()); layoutManager = new PreCachingLayoutManager(getActivity());
layoutManager.setExtraLayoutSpace(getResources().getDisplayMetrics().heightPixels); layoutManager.setExtraLayoutSpace(getResources().getDisplayMetrics().heightPixels);
recycler = new RecyclerView(getActivity()); recycler = new RecyclerView(getActivity());
@ -40,15 +41,6 @@ public class WebtoonReader extends BaseReader {
recycler.setLayoutManager(layoutManager); recycler.setLayoutManager(layoutManager);
recycler.setItemAnimator(null); recycler.setItemAnimator(null);
recycler.setAdapter(adapter); recycler.setAdapter(adapter);
recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
currentPage = layoutManager.findLastVisibleItemPosition();
updatePageNumber();
}
});
gestureDetector = new GestureDetector(getActivity(), new SimpleOnGestureListener() { gestureDetector = new GestureDetector(getActivity(), new SimpleOnGestureListener() {
@Override @Override
@ -100,11 +92,27 @@ public class WebtoonReader extends BaseReader {
private void setPages() { private void setPages() {
if (pages != null) { if (pages != null) {
unsubscribeStatus(); unsubscribeStatus();
recycler.clearOnScrollListeners();
adapter.clear(); adapter.clear();
recycler.scrollTo(0, 0);
adapter.setPages(pages);
setScrollListener();
observeStatus(0); observeStatus(0);
} }
} }
private void setScrollListener() {
recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
currentPage = layoutManager.findLastVisibleItemPosition();
updatePageNumber();
}
});
}
@Override @Override
public boolean onImageTouch(MotionEvent motionEvent) { public boolean onImageTouch(MotionEvent motionEvent) {
return gestureDetector.onTouchEvent(motionEvent); return gestureDetector.onTouchEvent(motionEvent);
@ -115,7 +123,6 @@ public class WebtoonReader extends BaseReader {
return; return;
final Page page = pages.get(position); final Page page = pages.get(position);
adapter.addPage(page);
PublishSubject<Integer> statusSubject = PublishSubject.create(); PublishSubject<Integer> statusSubject = PublishSubject.create();
page.setStatusSubject(statusSubject); page.setStatusSubject(statusSubject);
@ -130,17 +137,9 @@ public class WebtoonReader extends BaseReader {
} }
private void processStatus(int position, int status) { private void processStatus(int position, int status) {
switch (status) { adapter.notifyItemChanged(position);
case Page.LOAD_PAGE: if (status == Page.READY) {
break; observeStatus(position + 1);
case Page.DOWNLOAD_IMAGE:
break;
case Page.READY:
adapter.notifyItemChanged(position);
observeStatus(position + 1);
break;
case Page.ERROR:
break;
} }
} }

View File

@ -34,7 +34,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/retry_button" android:id="@+id/retry_button"
android:text="Retry" android:text="@string/action_retry"
android:layout_gravity="center" android:layout_gravity="center"
android:visibility="gone"/> android:visibility="gone"/>

View File

@ -4,12 +4,27 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ProgressBar <FrameLayout
android:id="@+id/progress" android:layout_width="match_parent"
style="?android:attr/progressBarStyleLarge" android:layout_height="300dp"
android:layout_width="wrap_content" android:id="@+id/frame_container">
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"/> <ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/retry_button"
android:text="@string/action_retry"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone" />
</FrameLayout>
<include layout="@layout/chapter_image"/> <include layout="@layout/chapter_image"/>

View File

@ -36,6 +36,7 @@
<string name="action_stop">Stop</string> <string name="action_stop">Stop</string>
<string name="action_previous_chapter">Previous chapter</string> <string name="action_previous_chapter">Previous chapter</string>
<string name="action_next_chapter">Next chapter</string> <string name="action_next_chapter">Next chapter</string>
<string name="action_retry">Retry</string>
<!-- Buttons --> <!-- Buttons -->