diff --git a/app/build.gradle b/app/build.gradle index 49e5e39..e030691 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId 'top.fumiama.copymanga' minSdkVersion 23 targetSdkVersion 34 - versionCode 63 - versionName '2.3.5' + versionCode 64 + versionName '2.3.6' resourceConfigurations += ['zh', 'zh-rCN'] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -95,5 +95,5 @@ dependencies { //noinspection GradleDependency implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0' implementation 'com.airbnb.android:lottie:6.5.2' - implementation 'net.java.dev.jna:jna:5.14.0@aar' + implementation 'net.java.dev.jna:jna:5.15.0@aar' } diff --git a/app/src/main/java/top/fumiama/copymanga/MainActivity.kt b/app/src/main/java/top/fumiama/copymanga/MainActivity.kt index 65c662c..080d63a 100644 --- a/app/src/main/java/top/fumiama/copymanga/MainActivity.kt +++ b/app/src/main/java/top/fumiama/copymanga/MainActivity.kt @@ -53,6 +53,7 @@ import kotlinx.coroutines.withContext import top.fumiama.copymanga.manga.Shelf import top.fumiama.copymanga.tools.ui.UITools import top.fumiama.copymanga.ui.book.BookFragment.Companion.bookHandler +import top.fumiama.copymanga.ui.book.BookHandler import top.fumiama.copymanga.ui.cardflow.rank.RankFragment import top.fumiama.copymanga.ui.comicdl.ComicDlFragment import top.fumiama.copymanga.ui.download.DownloadFragment @@ -189,7 +190,7 @@ class MainActivity : AppCompatActivity() { true } R.id.action_download -> { - bookHandler.get()?.sendEmptyMessage(6) + bookHandler.get()?.sendEmptyMessage(BookHandler.NAVIGATE_TO_DOWNLOAD) true } R.id.action_sort -> { diff --git a/app/src/main/java/top/fumiama/copymanga/manga/Book.kt b/app/src/main/java/top/fumiama/copymanga/manga/Book.kt index 0cb3924..f7c2ff7 100644 --- a/app/src/main/java/top/fumiama/copymanga/manga/Book.kt +++ b/app/src/main/java/top/fumiama/copymanga/manga/Book.kt @@ -97,14 +97,16 @@ class Book(val path: String, private val getString: (Int) -> String, private val /** * 更新云端最新章节信息并缓存到本地 */ - suspend fun updateVolumes(whenFinish: suspend () -> Unit) = withContext(Dispatchers.IO) withIO@ { + suspend fun updateVolumes(setProgress: (Int) -> Unit, whenFinish: suspend () -> Unit) = withContext(Dispatchers.IO) withIO@ { var isDownload = false var volumes = if(loadCache && loadVolumes()) mVolumes else emptyArray() + if(mGroupPathWords.isEmpty()) return@withIO if(volumes.isEmpty()) { isDownload = true + val delta = 100/mGroupPathWords.size mGroupPathWords.forEachIndexed { i, g -> - Volume(path, g, getString) { - return@Volume exit + Volume(path, g, getString, { return@Volume exit }) { p -> + setProgress(i*delta+100*p/delta) }.updateChapters(mCounts[i])?.let { volumes += it } @@ -116,6 +118,7 @@ class Book(val path: String, private val getString: (Int) -> String, private val mVolumes = volumes } goSaveHead(isDownload) + setProgress(100) whenFinish() } } diff --git a/app/src/main/java/top/fumiama/copymanga/manga/Volume.kt b/app/src/main/java/top/fumiama/copymanga/manga/Volume.kt index c703d2c..65595c9 100644 --- a/app/src/main/java/top/fumiama/copymanga/manga/Volume.kt +++ b/app/src/main/java/top/fumiama/copymanga/manga/Volume.kt @@ -10,7 +10,7 @@ import top.fumiama.copymanga.template.http.PausableDownloader import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.dmzj.copymanga.R -class Volume(private val path: String, private val groupPathWord: String, getString: (Int) -> String, private val isExit: ()->Boolean) { +class Volume(private val path: String, private val groupPathWord: String, getString: (Int) -> String, private val isExit: ()->Boolean, private val setProgress: ((Int) -> Unit)? = null) { private val mGroupInfoApiUrlTemplate = getString(R.string.groupInfoApiUrl) private val exit: Boolean get() { @@ -21,12 +21,20 @@ class Volume(private val path: String, private val groupPathWord: String, getStr } private var mDownloaders = arrayOf() private var mVolume: VolumeStructure? = null + private var mProgress = 0 + set(value) { + setProgress?.let { it(field) } + field = value + } + private var mDelta = 0 suspend fun updateChapters(count: Int): VolumeStructure? = withContext(Dispatchers.IO) { val times = count / 100 val remain = count % 100 val re = arrayOfNulls(if(remain != 0) (times+1) else (times)) if (re.isEmpty()) return@withContext null Log.d("MyV", "${groupPathWord}卷共需加载${if(times == 0) 1 else times}次") + mProgress = 0 + mDelta = 100/re.size download(re, 0, count) return@withContext mVolume } @@ -40,6 +48,7 @@ class Volume(private val path: String, private val groupPathWord: String, getStr mDownloaders += ad ad.run() } + mProgress += mDelta } private fun whenFinish(re: Array, c: Int, offset: Int): suspend (ByteArray) -> Unit = lambda@ { result: ByteArray -> try { diff --git a/app/src/main/java/top/fumiama/copymanga/template/general/MangaPagesFragmentTemplate.kt b/app/src/main/java/top/fumiama/copymanga/template/general/MangaPagesFragmentTemplate.kt index fc29a61..7db41b0 100644 --- a/app/src/main/java/top/fumiama/copymanga/template/general/MangaPagesFragmentTemplate.kt +++ b/app/src/main/java/top/fumiama/copymanga/template/general/MangaPagesFragmentTemplate.kt @@ -1,5 +1,6 @@ package top.fumiama.copymanga.template.general +import android.animation.ObjectAnimator import android.annotation.SuppressLint import android.content.Context import android.net.ConnectivityManager @@ -8,6 +9,7 @@ import android.os.Build import android.os.Bundle import android.util.Log import android.view.View +import androidx.core.animation.doOnEnd import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController @@ -157,18 +159,31 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, private val isLazy: Boolea var newP = p mypl?.post { if (p == mypl?.progress) return@post - if (newP >= 100) { - Log.d("MyMPFT", "set 100, hide") - mypc?.visibility = View.GONE - return@post - } + if (newP >= 100) newP = 100 else if (newP < 0) newP = 0 + if (mypl?.progress == 0) { + Log.d("MyMPFT", "set from 0, show") + mypc?.apply { + visibility = View.VISIBLE + invalidate() + ObjectAnimator.ofFloat(this, "alpha", 0f, 1f) + .setDuration(300) + .start() + } + } + if(newP == 100) { + Log.d("MyMPFT", "set to 100, hide") + mypc?.apply { + val oa = ObjectAnimator.ofFloat(this, "alpha", 1f, 0f).setDuration(300) + oa.doOnEnd { visibility = View.GONE } + oa.start() + } + } mypl?.apply { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - setProgress(newP, true) - } else progress = newP - invalidate() - Log.d("MyMPFT", "set ${mypl?.progress}") + val oa = ObjectAnimator.ofInt(this, "progress", newP).setDuration(100) + oa.addUpdateListener { invalidate() } + oa.start() + Log.d("MyMPFT", "set $progress") } } } diff --git a/app/src/main/java/top/fumiama/copymanga/template/ui/InfoCardLoader.kt b/app/src/main/java/top/fumiama/copymanga/template/ui/InfoCardLoader.kt index fe24712..783f826 100644 --- a/app/src/main/java/top/fumiama/copymanga/template/ui/InfoCardLoader.kt +++ b/app/src/main/java/top/fumiama/copymanga/template/ui/InfoCardLoader.kt @@ -49,7 +49,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT book?.comic?.path_word, null, null, isFinish = false, isNew = false ) - setProgress(20+80*i/size) + setProgress(20+80*(i+1)/size) } offset += size } @@ -71,7 +71,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT book?.comic?.path_word, null, null, book?.comic?.status==1 ) - setProgress(20+80*i/size) + setProgress(20+80*(i+1)/size) } offset += size } @@ -94,7 +94,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT book?.comic?.status==1, book.comic?.browse?.chapter_uuid != book.comic?.last_chapter_id ) - setProgress(20+80*i/size) + setProgress(20+80*(i+1)/size) } offset += size } @@ -112,7 +112,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT Log.d("MyICL", "load @ $i") if(ad?.exit == true) return@PausableDownloader cardList?.addCard(book?.name?:"null", null, book?.cover, book?.path_word, null, null, false) - setProgress(20+80*i/size) + setProgress(20+80*(i+1)/size) } offset += size } diff --git a/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt b/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt index 018e0fa..6f5efb1 100644 --- a/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt +++ b/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt @@ -1,11 +1,14 @@ package top.fumiama.copymanga.ui.book +import android.animation.ObjectAnimator import android.annotation.SuppressLint import android.content.Context.MODE_PRIVATE import android.os.Bundle import android.util.Log import android.view.View import android.widget.Toast +import androidx.core.animation.addListener +import androidx.core.animation.doOnEnd import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import kotlinx.android.synthetic.main.app_bar_main.* @@ -42,6 +45,12 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) { lifecycleScope.launch { prepareHandler() try { + fbloading?.apply { + post { + progress = 0 + invalidate() + } + } book?.updateInfo() } catch (e: Exception) { e.printStackTrace() @@ -52,12 +61,25 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) { } Log.d("MyBF", "read path: ${book?.path}") for (i in 1..3) { - mBookHandler?.sendEmptyMessageDelayed(i, (i*100).toLong()) + mBookHandler?.sendEmptyMessage(i) } try { - book?.updateVolumes { - delay(300) - mBookHandler?.sendEmptyMessage(10) + fbc?.apply { + alpha = 0f + visibility = View.VISIBLE + invalidate() + ObjectAnimator.ofFloat(this, "alpha", 0f, 1f) + .setDuration(300) + .start() + } + book?.updateVolumes({ fbloading?.apply { post { + val oa = ObjectAnimator.ofInt(this, "progress", 20 + it*8/10) + .setDuration(128) + oa.addUpdateListener { invalidate() } + oa.start() + Log.d("MyBF", "set progress $it") + } } }) { + mBookHandler?.sendEmptyMessage(BookHandler.SET_VOLUMES) } } catch (e: Exception) { e.printStackTrace() @@ -95,14 +117,15 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) { } fun setStartRead() { - if(mBookHandler?.chapterNames?.isNotEmpty() == true) activity?.apply { + if(mBookHandler?.chapterNames?.isNotEmpty() != true) return + activity?.apply { book?.name?.let { name -> getPreferences(MODE_PRIVATE).getInt(name, -1).let { p -> this@BookFragment.lbbstart.apply { var i = 0 - if(p >= 0) { - text = mBookHandler!!.chapterNames[p] - i = p + if(p >= 0) mBookHandler!!.chapterNames.let { + i = if (p >= it.size) it.size-1 else p + text = it[i] } setOnClickListener { mBookHandler?.apply { diff --git a/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt b/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt index 10d55a7..b9c1c86 100644 --- a/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt +++ b/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt @@ -1,5 +1,6 @@ package top.fumiama.copymanga.ui.book +import android.animation.ObjectAnimator import android.graphics.drawable.Drawable import android.os.Bundle import android.os.Handler @@ -10,6 +11,7 @@ import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView +import androidx.core.animation.doOnEnd import androidx.core.widget.NestedScrollView import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController @@ -70,9 +72,10 @@ class BookHandler(private val th: WeakReference): Handler(Looper.m private fun endSetLayouts() { if (exit) return - that?.fbloading?.apply { - pauseAnimation() - visibility = View.GONE + that?.fbc?.apply { + val oa = ObjectAnimator.ofFloat(this, "alpha", 1f, 0f).setDuration(300) + oa.doOnEnd { visibility = View.GONE } + oa.start() } complete = true that?.setStartRead() @@ -291,7 +294,7 @@ class BookHandler(private val th: WeakReference): Handler(Looper.m } } } - sendEmptyMessage(9) // end set layout + sendEmptyMessage(END_SET_LAYOUTS) } private fun loadVolume(name: String, path: String, nav: Int){ @@ -331,4 +334,10 @@ class BookHandler(private val th: WeakReference): Handler(Looper.m override fun getItemCount(): Int = that?.book?.keys?.size?:0 } } + + companion object { + const val NAVIGATE_TO_DOWNLOAD = 6 + const val END_SET_LAYOUTS = 9 + const val SET_VOLUMES = 10 + } } diff --git a/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlFragment.kt b/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlFragment.kt index 3f5789b..61f8f24 100644 --- a/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlFragment.kt +++ b/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlFragment.kt @@ -8,6 +8,7 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import com.google.gson.Gson import kotlinx.android.synthetic.main.fragment_dlcomic.* +import kotlinx.android.synthetic.main.widget_downloadbar.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -24,6 +25,7 @@ class ComicDlFragment: NoBackRefreshFragment(R.layout.fragment_dlcomic) { super.onViewCreated(view, savedInstanceState) exit = false ldwn?.setPadding(0, 0, 0, navBarHeight) + dlsdwn?.translationY = -navBarHeight.toFloat() if(isFirstInflate) lifecycleScope.launch { withContext(Dispatchers.IO) { when { diff --git a/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt b/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt index 03db6b4..d5acdc3 100644 --- a/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt +++ b/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt @@ -199,8 +199,11 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference - + android:alpha="0"> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line_lazybooklines.xml b/app/src/main/res/layout/line_lazybooklines.xml index 9b7e2b6..3971029 100644 --- a/app/src/main/res/layout/line_lazybooklines.xml +++ b/app/src/main/res/layout/line_lazybooklines.xml @@ -1,6 +1,7 @@ @@ -34,17 +35,20 @@ android:id="@+id/mypc" android:layout_width="@dimen/book_card_width" android:layout_height="@dimen/icon_size_middle" + android:alpha="0" + android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible"> + android:padding="16dp" /> \ No newline at end of file