1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-05 07:20:23 +08:00
新增
1. 搜索可以加载更多
修复
1. 服务器错误数据导致的闪退(#34)
2. 保存封面超时导致的闪退(870551a6)
优化
1. 更新 targetSdkVersion 到 34(870551a6)
2. 搜索支持嵌套滚动
3. 底部按导航栏高度垫高
4. 升级 Gson 库
This commit is contained in:
源文雨
2023-10-31 00:03:10 +09:00
parent 870551a67c
commit 9972530851
20 changed files with 153 additions and 40 deletions

View File

@@ -8,8 +8,8 @@ android {
applicationId 'top.fumiama.copymanga'
minSdkVersion 23
targetSdkVersion 34
versionCode 37
versionName '2.0.1'
versionCode 38
versionName '2.0.2'
resConfigs 'zh', 'zh-rCN'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -69,7 +69,7 @@ dependencies {
implementation 'com.to.aboomy:pager2banner:1.0.1'
implementation 'com.github.bumptech.glide:glide:4.14.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2'
implementation 'com.google.code.gson:gson:2.9.1'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.github.vovaksenov99:OverscrollableScrollView:1.0'
implementation 'com.liaoinstan.springview:library:1.7.0'
implementation 'com.github.zawadz88.materialpopupmenu:material-popup-menu:4.0.1'

View File

@@ -91,6 +91,8 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, val isLazy: Boolean = true
Log.d("MyMPAT", "Card per row: $cardPerRow")
Log.d("MyMPAT", "Card width: $cardWidth")
mydll?.setPadding(0, 0, 0, navBarHeight)
initCardList(WeakReference(this))
managePage()
setListeners()

View File

@@ -6,11 +6,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import top.fumiama.copymanga.tools.ui.UITools
open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
private var _rootView: View? = null
val rootView: View get() = _rootView!!
var isFirstInflate = true
var navBarHeight = 0
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -24,6 +26,7 @@ open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
isFirstInflate = false
Log.d("MyNBRF", "not first inflate")
}
navBarHeight = context?.let { UITools.getNavigationBarHeight(it) } ?: 0
return rootView
}
override fun onDestroy() {

View File

@@ -113,14 +113,25 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
val totalWidth = ((zis?.resources?.displayMetrics?.widthPixels?:1080)-marginPx)/numPerRow
return listOf(numPerRow, w, totalWidth)
}
fun toHexStr(byteArray: ByteArray) =
with(StringBuilder()) {
byteArray.forEach {
val hex = it.toInt() and (0xFF)
val hexStr = Integer.toHexString(hex)
if (hexStr.length == 1) append("0").append(hexStr)
else append(hexStr)
companion object {
fun toHexStr(byteArray: ByteArray) =
with(StringBuilder()) {
byteArray.forEach {
val hex = it.toInt() and (0xFF)
val hexStr = Integer.toHexString(hex)
if (hexStr.length == 1) append("0").append(hexStr)
else append(hexStr)
}
toString()
}
fun getNavigationBarHeight(context: Context): Int {
val resources = context.resources
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
return if (resourceId > 0) {
resources.getDimensionPixelSize(resourceId)
} else {
0
}
toString()
}
}
}

View File

@@ -8,6 +8,7 @@ import android.view.View
import android.widget.Toast
import androidx.navigation.fragment.findNavController
import com.google.gson.Gson
import kotlinx.android.synthetic.main.fragment_book.*
import kotlinx.android.synthetic.main.line_bookinfo_text.*
import kotlinx.android.synthetic.main.line_booktandb.*
import top.fumiama.copymanga.MainActivity
@@ -30,6 +31,7 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
super.onViewCreated(view, savedInstanceState)
ComicDlFragment.exit = false
fbl?.setPadding(0, 0, 0, navBarHeight)
if(isFirstInflate) {
var path = ""

View File

@@ -385,19 +385,24 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
File(mangaFolder, "grps.json").writeText(Gson().toJson(keys))
that?.apply {
Thread {
sleep(1000)
if (exit) return@Thread
File(mangaFolder, "head.jpg").let { head ->
val fo = head.outputStream()
try {
imic.drawable.toBitmap().compress(Bitmap.CompressFormat.JPEG, 90, fo)
} catch (e: Exception) {
e.printStackTrace()
that?.activity?.runOnUiThread {
Toast.makeText(that?.context, R.string.download_cover_timeout, Toast.LENGTH_SHORT).show()
var cnt = 0
var success = false
while (cnt++ < 10 && !success) {
sleep(1000)
if (exit) return@Thread
File(mangaFolder, "head.jpg").let { head ->
val fo = head.outputStream()
try {
imic.drawable.toBitmap().compress(Bitmap.CompressFormat.JPEG, 90, fo)
success = true
} catch (e: Exception) {
e.printStackTrace()
}
fo.close()
}
fo.close()
}
if (!success) that?.activity?.runOnUiThread {
Toast.makeText(that?.context, R.string.download_cover_timeout, Toast.LENGTH_SHORT).show()
}
}.start()
}

View File

@@ -0,0 +1,24 @@
package top.fumiama.copymanga.ui.cardflow.search
import android.os.Bundle
import android.util.Log
import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi
class SearchFragment : InfoCardLoader(R.layout.fragment_search, R.id.action_nav_search_to_nav_book) {
private var query: String? = null
private var type: String? = null
override fun getApiUrl() =
getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, page * 21, query, type)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isFirstInflate) {
query = arguments?.getCharSequence("query")?.toString()
type = arguments?.getString("type")
Log.d("MySF", "get query=$query, type=$type")
}
}
}

View File

@@ -5,6 +5,7 @@ import android.os.Looper
import android.util.Log
import android.view.View
import com.google.gson.Gson
import kotlinx.android.synthetic.main.fragment_dlcomic.*
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.json.ChapterStructure
import top.fumiama.copymanga.json.VolumeStructure
@@ -22,6 +23,7 @@ class ComicDlFragment: NoBackRefreshFragment(R.layout.fragment_dlcomic) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
exit = false
ldwn?.setPadding(0, 0, 0, navBarHeight)
if(isFirstInflate){
when {
arguments?.getBoolean("callFromOldDL", false) == true -> initOldComicData()

View File

@@ -38,7 +38,8 @@ class DownloadFragment: NoBackRefreshFragment(R.layout.fragment_download) {
if(o1.endsWith(".zip") && o2.endsWith(".zip")) (10000*getFloat(o1) - 10000*getFloat(o2) + 0.5).toInt()
else o1[0] - o2[0]
}?.let {
mylv.apply {
mylv?.apply {
setPadding(0, 0, 0, navBarHeight)
context.let { c ->
adapter = ArrayAdapter(c, android.R.layout.simple_list_item_1, it)
setOnItemClickListener { _, _, position, _ ->

View File

@@ -30,6 +30,7 @@ import top.fumiama.copymanga.template.general.NoBackRefreshFragment
import top.fumiama.copymanga.template.http.AutoDownloadThread
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.ui.Navigate
import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep
import java.lang.ref.WeakReference
@@ -37,6 +38,7 @@ import java.lang.ref.WeakReference
class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
lateinit var homeHandler: HomeHandler
@SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if(isFirstInflate) {
@@ -47,8 +49,13 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
resources.getColor(R.color.colorGreen, theme))
swiperefresh?.isEnabled = true
fhs.apply {
fhl?.setPadding(0, 0, 0, navBarHeight)
fhs?.apply {
isNestedScrollingEnabled = true
val recyclerView = findViewById<RecyclerView>(R.id.search_recycler_view)
recyclerView.isNestedScrollingEnabled = true
recyclerView.setPadding(0, 0, 0, navBarHeight)
setAdapterLayoutManager(LinearLayoutManager(context))
val adapter = ListViewHolder(recyclerView).RecyclerViewAdapter()
setAdapter(adapter)
@@ -182,7 +189,9 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
inner class RecyclerViewAdapter :
RecyclerView.Adapter<ListViewHolder>() {
private var results: BookListStructure? = null
var type = ""
var type = ""
private var query: CharSequence? = null
private var count = 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
return ListViewHolder(
LayoutInflater.from(parent.context)
@@ -193,7 +202,21 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
Log.d("MyMain", "Bind open at $position")
if (position == itemCount-1) {
holder.itemView.tn.setText(R.string.button_more)
holder.itemView.ta.text = "搜索 \"$query\""
holder.itemView.tb.text = "$count 条结果"
holder.itemView.lwi.visibility = View.INVISIBLE
if (query?.isNotEmpty() == true) holder.itemView.lwc.setOnClickListener {
val bundle = Bundle()
bundle.putCharSequence("query", query)
bundle.putString("type", type)
Navigate.safeNavigateTo(findNavController(), R.id.action_nav_home_to_nav_search, bundle)
}
return
}
results?.results?.list?.get(position)?.apply {
holder.itemView.lwi.visibility = View.VISIBLE
holder.itemView.tn.text = name
holder.itemView.ta.text = author.let {
var t = ""
@@ -215,12 +238,14 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
}
}
override fun getItemCount() = results?.results?.list?.size?:0
override fun getItemCount() = (results?.results?.list?.size?:0)+1
fun refresh(query: CharSequence) {
fun refresh(q: CharSequence) {
query = q
mainWeakReference?.get()?.apply {
AutoDownloadThread(getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, 0, query, type)) {
results = Gson().fromJson(it?.decodeToString(), BookListStructure::class.java)
count = results?.results?.total?:0
runOnUiThread { notifyDataSetChanged() }
}.start()
}

View File

@@ -4,12 +4,14 @@ import android.animation.ObjectAnimator
import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import androidx.annotation.Keep
import androidx.preference.EditTextPreference
import androidx.preference.EditTextPreferenceDialogFragmentCompat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep
@@ -18,6 +20,13 @@ class SettingsFragment: PreferenceFragmentCompat() {
setPreferencesFromResource(R.xml.pref_setting, rootKey)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
context?.let { c ->
view.setPadding(0, 0, 0, UITools.getNavigationBarHeight(c))
}
}
override fun onDisplayPreferenceDialog(preference: Preference) {
if (preference is EditTextPreference) {
Log.d("MySF", "preference is EditTextPreference")
@@ -41,7 +50,7 @@ class SettingsFragment: PreferenceFragmentCompat() {
Log.d("MySF", "diff: $diff")
}
Log.d("MySF", "diff out while: $diff")
if (diff == 0) return@Thread
if (diff <= 0) return@Thread
Log.d("MySF", "f.dialog is ${f.dialog}")
f.activity?.runOnUiThread {
f.dialog?.window?.apply {

View File

@@ -47,7 +47,7 @@ object Update {
}
}) {
val md5 = msg.substringAfterLast("md5:")
if (md5 == toolsBox.toHexStr(
if (md5 == UITools.toHexStr(
MessageDigest.getInstance("MD5").digest(it)
)
) {

View File

@@ -13,8 +13,7 @@
android:id="@+id/fbl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/global_content_padding_bottom"/>
android:orientation="vertical"/>
</top.fumiama.copymanga.views.OverScrollView>
<ProgressBar

View File

@@ -14,8 +14,7 @@
android:id="@+id/ldwn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/global_content_padding_bottom"/>
android:orientation="vertical"/>
</top.fumiama.copymanga.views.LazyScrollView>
<include

View File

@@ -3,5 +3,4 @@
android:id="@+id/mylv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="true"
android:paddingBottom="@dimen/global_content_padding_bottom"/>
android:nestedScrollingEnabled="true"/>

View File

@@ -28,8 +28,7 @@
android:id="@+id/fhl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/global_content_padding_bottom">
android:orientation="vertical">
</LinearLayout>
</top.fumiama.copymanga.views.ScrollRefreshView>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/line_lazybooklines"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -25,8 +25,7 @@
android:id="@+id/mydll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/global_content_padding_bottom"/>
android:orientation="vertical"/>
</androidx.core.widget.NestedScrollView>
</com.liaoinstan.springview.widget.SpringView>

View File

@@ -45,6 +45,13 @@
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
<action
android:id="@+id/action_nav_home_to_nav_search"
app:destination="@id/nav_search"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment>
<fragment
@@ -217,7 +224,7 @@
<fragment
android:id="@+id/nav_newest"
android:name="top.fumiama.copymanga.ui.cardflow.newest.NewestFragment"
android:name="top.fumiama.copymanga.ui.cardflow.search.SearchFragment"
android:label="@string/new_list"
tools:layout="@layout/fragment_newest" >
<action
@@ -284,4 +291,18 @@
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment>
<fragment
android:id="@+id/nav_search"
android:name="top.fumiama.copymanga.ui.cardflow.search.SearchFragment"
android:label="@string/page_search"
tools:layout="@layout/fragment_search" >
<action
android:id="@+id/action_nav_search_to_nav_book"
app:destination="@id/nav_book"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment>
</navigation>

View File

@@ -21,6 +21,7 @@
<string name="page_chapter">章节内容</string>
<string name="page_group">漫画下载</string>
<string name="page_topic">专题系列</string>
<string name="page_search">漫画搜索</string>
<string name="check_update">检查更新</string>
<string name="set_search_types">设置搜索类别</string>
@@ -37,6 +38,7 @@
<string name="text_null">N/A</string>
<string name="null_book">获取图书信息失败</string>
<string name="web_error">网络错误</string>
<string name="download_cover_failed">保存封面失败</string>
<string name="download_cover_timeout">保存封面超时</string>
<string name="mainPageApiUrl">https://%1$s/api/v3/h5/homeIndex?platform=3</string>
@@ -93,6 +95,7 @@
<string name="button_sub">加入书架</string>
<string name="button_sub_subscribed">已加书架</string>
<string name="button_start">开始阅读</string>
<string name="button_more">更多</string>
<string name="text_format_hit">热度 %1$d</string>
<string name="text_format_stat">状态 %1$s</string>