mirror of
https://git.mihon.tech/mihonapp/mihon
synced 2024-11-27 09:44:55 +03:00
Webtoon reader now shows download progress. Keep the progress bar until the image is decoded
This commit is contained in:
parent
22bbcaeed0
commit
90e0e0b72a
7 changed files with 209 additions and 162 deletions
|
@ -29,7 +29,7 @@ class PageDecodeErrorLayout(context: Context) : LinearLayout(context) {
|
|||
|
||||
init {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
setGravity(Gravity.CENTER)
|
||||
gravity = Gravity.CENTER
|
||||
}
|
||||
|
||||
constructor(context: Context, page: Page, theme: Int, retryListener: () -> Unit) : this(context) {
|
||||
|
@ -47,7 +47,6 @@ class PageDecodeErrorLayout(context: Context) : LinearLayout(context) {
|
|||
layoutParams = ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
|
||||
setText(R.string.action_retry)
|
||||
setOnClickListener {
|
||||
removeAllViews()
|
||||
retryListener()
|
||||
}
|
||||
addView(this)
|
||||
|
|
|
@ -12,9 +12,6 @@ import eu.kanade.tachiyomi.R
|
|||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.PageDecodeErrorLayout
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerReader.Companion.ALIGN_CENTER
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerReader.Companion.ALIGN_LEFT
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerReader.Companion.ALIGN_RIGHT
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.RightToLeftReader
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.vertical.VerticalReader
|
||||
import kotlinx.android.synthetic.main.chapter_image.view.*
|
||||
|
@ -33,8 +30,12 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
/**
|
||||
* Page of a chapter.
|
||||
*/
|
||||
var page: Page? = null
|
||||
private set
|
||||
lateinit var page: Page
|
||||
|
||||
/**
|
||||
* Subscription for status changes of the page.
|
||||
*/
|
||||
private var statusSubscription: Subscription? = null
|
||||
|
||||
/**
|
||||
* Subscription for progress changes of the page.
|
||||
|
@ -42,11 +43,11 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
private var progressSubscription: Subscription? = null
|
||||
|
||||
/**
|
||||
* Subscription for status changes of the page.
|
||||
* Layout of decode error.
|
||||
*/
|
||||
private var statusSubscription: Subscription? = null
|
||||
private var decodeErrorLayout: PageDecodeErrorLayout? = null
|
||||
|
||||
fun initialize(reader: PagerReader, page: Page?) {
|
||||
fun initialize(reader: PagerReader, page: Page) {
|
||||
val activity = reader.activity as ReaderActivity
|
||||
|
||||
when (activity.readerTheme) {
|
||||
|
@ -71,19 +72,11 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
setOnTouchListener { v, motionEvent -> reader.gestureDetector.onTouchEvent(motionEvent) }
|
||||
setOnImageEventListener(object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onReady() {
|
||||
when (reader.zoomType) {
|
||||
ALIGN_LEFT -> setScaleAndCenter(scale, PointF(0f, 0f))
|
||||
ALIGN_RIGHT -> setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0f))
|
||||
ALIGN_CENTER -> {
|
||||
val newCenter = center
|
||||
newCenter.y = 0f
|
||||
setScaleAndCenter(scale, newCenter)
|
||||
}
|
||||
}
|
||||
onImageDecoded(reader)
|
||||
}
|
||||
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
onImageDecodeError(activity)
|
||||
onImageDecodeError(reader)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -95,21 +88,15 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
true
|
||||
}
|
||||
|
||||
if (page != null) {
|
||||
this.page = page
|
||||
observeStatus()
|
||||
}
|
||||
}
|
||||
|
||||
fun cleanup() {
|
||||
override fun onDetachedFromWindow() {
|
||||
unsubscribeProgress()
|
||||
unsubscribeStatus()
|
||||
image_view.setOnTouchListener(null)
|
||||
image_view.setOnImageEventListener(null)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
cleanup()
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
|
@ -120,7 +107,6 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
*/
|
||||
private fun observeStatus() {
|
||||
statusSubscription?.unsubscribe()
|
||||
val page = page ?: return
|
||||
|
||||
val statusSubject = SerializedSubject(PublishSubject.create<Int>())
|
||||
page.setStatusSubject(statusSubject)
|
||||
|
@ -135,7 +121,6 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
*/
|
||||
private fun observeProgress() {
|
||||
progressSubscription?.unsubscribe()
|
||||
val page = page ?: return
|
||||
|
||||
progressSubscription = Observable.interval(100, TimeUnit.MILLISECONDS)
|
||||
.map { page.progress }
|
||||
|
@ -154,18 +139,18 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
*/
|
||||
private fun processStatus(status: Int) {
|
||||
when (status) {
|
||||
Page.QUEUE -> hideError()
|
||||
Page.LOAD_PAGE -> onLoading()
|
||||
Page.QUEUE -> setQueued()
|
||||
Page.LOAD_PAGE -> setLoading()
|
||||
Page.DOWNLOAD_IMAGE -> {
|
||||
observeProgress()
|
||||
onDownloading()
|
||||
setDownloading()
|
||||
}
|
||||
Page.READY -> {
|
||||
onReady()
|
||||
setImage()
|
||||
unsubscribeProgress()
|
||||
}
|
||||
Page.ERROR -> {
|
||||
onError()
|
||||
setError()
|
||||
unsubscribeProgress()
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +160,7 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
* Unsubscribes from the status subscription.
|
||||
*/
|
||||
private fun unsubscribeStatus() {
|
||||
page?.setStatusSubject(null)
|
||||
page.setStatusSubject(null)
|
||||
statusSubscription?.unsubscribe()
|
||||
statusSubscription = null
|
||||
}
|
||||
|
@ -188,10 +173,23 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
progressSubscription = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is queued.
|
||||
*/
|
||||
private fun setQueued() {
|
||||
progress_container.visibility = View.VISIBLE
|
||||
progress_text.visibility = View.INVISIBLE
|
||||
retry_button.visibility = View.GONE
|
||||
decodeErrorLayout?.let {
|
||||
removeView(it)
|
||||
decodeErrorLayout = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is loading.
|
||||
*/
|
||||
private fun onLoading() {
|
||||
private fun setLoading() {
|
||||
progress_container.visibility = View.VISIBLE
|
||||
progress_text.visibility = View.VISIBLE
|
||||
progress_text.setText(R.string.downloading)
|
||||
|
@ -200,7 +198,7 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
/**
|
||||
* Called when the page is downloading.
|
||||
*/
|
||||
private fun onDownloading() {
|
||||
private fun setDownloading() {
|
||||
progress_container.visibility = View.VISIBLE
|
||||
progress_text.visibility = View.VISIBLE
|
||||
}
|
||||
|
@ -208,42 +206,51 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
|
|||
/**
|
||||
* Called when the page is ready.
|
||||
*/
|
||||
private fun onReady() {
|
||||
page?.imagePath?.let { path ->
|
||||
if (File(path).exists()) {
|
||||
private fun setImage() {
|
||||
val path = page.imagePath
|
||||
if (path != null && File(path).exists()) {
|
||||
progress_text.visibility = View.INVISIBLE
|
||||
image_view.setImage(ImageSource.uri(path))
|
||||
progress_container.visibility = View.GONE
|
||||
} else {
|
||||
page?.status = Page.ERROR
|
||||
}
|
||||
page.status = Page.ERROR
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page has an error.
|
||||
*/
|
||||
private fun onError() {
|
||||
private fun setError() {
|
||||
progress_container.visibility = View.GONE
|
||||
retry_button.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the error layout.
|
||||
* Called when the image is decoded and going to be displayed.
|
||||
*/
|
||||
private fun hideError() {
|
||||
retry_button.visibility = View.GONE
|
||||
private fun onImageDecoded(reader: PagerReader) {
|
||||
progress_container.visibility = View.GONE
|
||||
|
||||
with(image_view) {
|
||||
when (reader.zoomType) {
|
||||
PagerReader.ALIGN_LEFT -> setScaleAndCenter(scale, PointF(0f, 0f))
|
||||
PagerReader.ALIGN_RIGHT -> setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0f))
|
||||
PagerReader.ALIGN_CENTER -> setScaleAndCenter(scale, center.apply { y = 0f })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an image fails to decode.
|
||||
*/
|
||||
private fun onImageDecodeError(activity: ReaderActivity) {
|
||||
page?.let { page ->
|
||||
val errorLayout = PageDecodeErrorLayout(context, page, activity.readerTheme,
|
||||
private fun onImageDecodeError(reader: PagerReader) {
|
||||
if (decodeErrorLayout != null || !reader.isAdded) return
|
||||
|
||||
val activity = reader.activity as ReaderActivity
|
||||
|
||||
decodeErrorLayout = PageDecodeErrorLayout(context, page, activity.readerTheme,
|
||||
{ activity.presenter.retryPage(page) })
|
||||
|
||||
addView(errorLayout)
|
||||
}
|
||||
addView(decodeErrorLayout)
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ class PagerReaderAdapter(private val reader: PagerReader) : ViewPagerAdapter() {
|
|||
/**
|
||||
* Pages stored in the adapter.
|
||||
*/
|
||||
var pages: List<Page>? = null
|
||||
var pages: List<Page> = emptyList()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
|
@ -23,17 +23,15 @@ class PagerReaderAdapter(private val reader: PagerReader) : ViewPagerAdapter() {
|
|||
|
||||
override fun createView(container: ViewGroup, position: Int): View {
|
||||
val view = container.inflate(R.layout.item_pager_reader) as PageView
|
||||
view.initialize(reader, pages?.getOrNull(position))
|
||||
view.initialize(reader, pages[position])
|
||||
return view
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of pages.
|
||||
*
|
||||
* @return the number of pages or 0 if the list is null.
|
||||
*/
|
||||
override fun getCount(): Int {
|
||||
return pages?.size ?: 0
|
||||
return pages.size
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ class WebtoonAdapter(val fragment: WebtoonReader) : RecyclerView.Adapter<Webtoon
|
|||
* @param holder the holder to recycle.
|
||||
*/
|
||||
override fun onViewRecycled(holder: WebtoonHolder) {
|
||||
holder.unsubscribeStatus()
|
||||
holder.onRecycle()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,16 +6,19 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.PageDecodeErrorLayout
|
||||
import kotlinx.android.synthetic.main.chapter_image.view.*
|
||||
import kotlinx.android.synthetic.main.item_webtoon_reader.view.*
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.subjects.PublishSubject
|
||||
import rx.subjects.SerializedSubject
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Holder for webtoon reader for a single page of a chapter.
|
||||
|
@ -38,6 +41,11 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
*/
|
||||
private var statusSubscription: Subscription? = null
|
||||
|
||||
/**
|
||||
* Subscription for progress changes of the page.
|
||||
*/
|
||||
private var progressSubscription: Subscription? = null
|
||||
|
||||
/**
|
||||
* Layout of decode error.
|
||||
*/
|
||||
|
@ -57,8 +65,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
setOnTouchListener(adapter.touchListener)
|
||||
setOnImageEventListener(object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
override fun onImageLoaded() {
|
||||
// When the image is loaded, reset the minimum height to avoid gaps
|
||||
view.frame_container.minimumHeight = 30
|
||||
onImageDecoded()
|
||||
}
|
||||
|
||||
override fun onImageLoadError(e: Exception) {
|
||||
|
@ -67,16 +74,9 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
})
|
||||
}
|
||||
|
||||
// Avoid to create a lot of view holders taking twice the screen height,
|
||||
// saving memory and a possible OOM. When the first image is loaded in this holder,
|
||||
// the minimum size will be removed.
|
||||
// Doing this we get sequential holder instantiation.
|
||||
view.frame_container.minimumHeight = view.resources.displayMetrics.heightPixels * 2
|
||||
view.progress_container.minimumHeight = view.resources.displayMetrics.heightPixels
|
||||
|
||||
// Leave some space between progress bars
|
||||
view.progress.minimumHeight = 300
|
||||
|
||||
view.frame_container.setOnTouchListener(adapter.touchListener)
|
||||
view.setOnTouchListener(adapter.touchListener)
|
||||
view.retry_button.setOnTouchListener { v, event ->
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
readerActivity.presenter.retryPage(page)
|
||||
|
@ -92,13 +92,22 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
* @param page the page to bind.
|
||||
*/
|
||||
fun onSetValues(page: Page) {
|
||||
this.page = page
|
||||
observeStatus()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the view is recycled and added to the view pool.
|
||||
*/
|
||||
fun onRecycle() {
|
||||
unsubscribeStatus()
|
||||
unsubscribeProgress()
|
||||
decodeErrorLayout?.let {
|
||||
(view as ViewGroup).removeView(it)
|
||||
decodeErrorLayout = null
|
||||
}
|
||||
|
||||
this.page = page
|
||||
observeStatus()
|
||||
view.image_view.recycle()
|
||||
view.progress_container.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +116,8 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
* @see processStatus
|
||||
*/
|
||||
private fun observeStatus() {
|
||||
page?.let { page ->
|
||||
val page = page ?: return
|
||||
|
||||
val statusSubject = SerializedSubject(PublishSubject.create<Int>())
|
||||
page.setStatusSubject(statusSubject)
|
||||
|
||||
|
@ -118,6 +128,23 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
|
||||
webtoonReader.subscriptions.add(statusSubscription)
|
||||
}
|
||||
|
||||
/**
|
||||
* Observes the progress of the page and updates view.
|
||||
*/
|
||||
private fun observeProgress() {
|
||||
progressSubscription?.unsubscribe()
|
||||
|
||||
val page = page ?: return
|
||||
|
||||
progressSubscription = Observable.interval(100, TimeUnit.MILLISECONDS)
|
||||
.map { page.progress }
|
||||
.distinctUntilChanged()
|
||||
.onBackpressureLatest()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { progress ->
|
||||
view.progress_text.text = view.context.getString(R.string.download_progress, progress)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,105 +154,110 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter)
|
|||
*/
|
||||
private fun processStatus(status: Int) {
|
||||
when (status) {
|
||||
Page.QUEUE -> onQueue()
|
||||
Page.LOAD_PAGE -> onLoading()
|
||||
Page.DOWNLOAD_IMAGE -> onLoading()
|
||||
Page.READY -> onReady()
|
||||
Page.ERROR -> onError()
|
||||
Page.QUEUE -> setQueued()
|
||||
Page.LOAD_PAGE -> setLoading()
|
||||
Page.DOWNLOAD_IMAGE -> {
|
||||
observeProgress()
|
||||
setDownloading()
|
||||
}
|
||||
Page.READY -> {
|
||||
setImage()
|
||||
unsubscribeProgress()
|
||||
}
|
||||
Page.ERROR -> {
|
||||
setError()
|
||||
unsubscribeProgress()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes from the status subscription.
|
||||
*/
|
||||
fun unsubscribeStatus() {
|
||||
private fun unsubscribeStatus() {
|
||||
page?.setStatusSubject(null)
|
||||
statusSubscription?.unsubscribe()
|
||||
statusSubscription = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes from the progress subscription.
|
||||
*/
|
||||
private fun unsubscribeProgress() {
|
||||
progressSubscription?.unsubscribe()
|
||||
progressSubscription = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is queued.
|
||||
*/
|
||||
private fun setQueued() = with(view) {
|
||||
progress_container.visibility = View.VISIBLE
|
||||
progress_text.visibility = View.INVISIBLE
|
||||
retry_button.visibility = View.GONE
|
||||
decodeErrorLayout?.let {
|
||||
(view as ViewGroup).removeView(it)
|
||||
decodeErrorLayout = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is loading.
|
||||
*/
|
||||
private fun onLoading() {
|
||||
setRetryButtonVisible(false)
|
||||
setImageVisible(false)
|
||||
setProgressVisible(true)
|
||||
private fun setLoading() = with(view) {
|
||||
progress_container.visibility = View.VISIBLE
|
||||
progress_text.visibility = View.VISIBLE
|
||||
progress_text.setText(R.string.downloading)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is downloading
|
||||
*/
|
||||
private fun setDownloading() = with(view) {
|
||||
progress_container.visibility = View.VISIBLE
|
||||
progress_text.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is ready.
|
||||
*/
|
||||
private fun onReady() {
|
||||
setRetryButtonVisible(false)
|
||||
setProgressVisible(false)
|
||||
setImageVisible(true)
|
||||
|
||||
page?.imagePath?.let { path ->
|
||||
if (File(path).exists()) {
|
||||
view.image_view.setImage(ImageSource.uri(path))
|
||||
view.progress.visibility = View.GONE
|
||||
private fun setImage() = with(view) {
|
||||
val path = page?.imagePath
|
||||
if (path != null && File(path).exists()) {
|
||||
progress_text.visibility = View.INVISIBLE
|
||||
image_view.setImage(ImageSource.uri(path))
|
||||
} else {
|
||||
page?.status = Page.ERROR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page has an error.
|
||||
*/
|
||||
private fun onError() {
|
||||
setImageVisible(false)
|
||||
setProgressVisible(false)
|
||||
setRetryButtonVisible(true)
|
||||
private fun setError() = with(view) {
|
||||
progress_container.visibility = View.GONE
|
||||
retry_button.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is queued.
|
||||
* Called when the image is decoded and going to be displayed.
|
||||
*/
|
||||
private fun onQueue() {
|
||||
setImageVisible(false)
|
||||
setRetryButtonVisible(false)
|
||||
setProgressVisible(false)
|
||||
private fun onImageDecoded() {
|
||||
view.progress_container.visibility = View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the image fails to decode.
|
||||
*/
|
||||
private fun onImageDecodeError() {
|
||||
page?.let { page ->
|
||||
val page = page ?: return
|
||||
if (decodeErrorLayout != null || !webtoonReader.isAdded) return
|
||||
|
||||
decodeErrorLayout = PageDecodeErrorLayout(view.context, page, readerActivity.readerTheme,
|
||||
{ readerActivity.presenter.retryPage(page) })
|
||||
|
||||
(view as ViewGroup).addView(decodeErrorLayout)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the progress bar.
|
||||
*
|
||||
* @param visible whether to show it or not.
|
||||
*/
|
||||
private fun setProgressVisible(visible: Boolean) {
|
||||
view.progress.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the image view.
|
||||
*
|
||||
* @param visible whether to show it or not.
|
||||
*/
|
||||
private fun setImageVisible(visible: Boolean) {
|
||||
view.image_view.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the retry button.
|
||||
*
|
||||
* @param visible whether to show it or not.
|
||||
*/
|
||||
private fun setRetryButtonVisible(visible: Boolean) {
|
||||
view.retry_button.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Property to get the reader activity.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<eu.kanade.tachiyomi.ui.reader.viewer.pager.PageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -1,31 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="32dp"
|
||||
android:id="@+id/progress_container"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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"/>
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/retry_button"
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:text="@string/action_retry"
|
||||
android:visibility="gone"/>
|
||||
android:layout_marginTop="16dp"
|
||||
android:id="@+id/progress_text"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/chapter_image"/>
|
||||
|
||||
<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"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</FrameLayout>
|
Loading…
Reference in a new issue