Merge pull request #33 from gedoor/master

up
pull/379/head
口口吕 5 years ago committed by GitHub
commit 613cb383ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/build.gradle
  2. 8
      app/src/main/assets/updateLog.md
  3. 14
      app/src/main/java/io/legado/app/data/entities/RssStar.kt
  4. 42
      app/src/main/java/io/legado/app/help/storage/Backup.kt
  5. 6
      app/src/main/java/io/legado/app/model/Debug.kt
  6. 12
      app/src/main/java/io/legado/app/model/Rss.kt
  7. 6
      app/src/main/java/io/legado/app/model/webBook/BookContent.kt
  8. 5
      app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt
  9. 6
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  10. 5
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt
  11. 12
      app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt
  12. 5
      app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleViewModel.kt
  13. 2
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  14. 31
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt
  15. 5
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceViewModel.kt
  16. 6
      app/src/main/java/io/legado/app/ui/widget/TitleBar.kt
  17. 4
      app/src/main/res/drawable/ic_help.xml
  18. 26
      app/src/main/res/layout-land/activity_book_info.xml
  19. 11
      app/src/main/res/layout/activity_audio_play.xml
  20. 7
      app/src/main/res/layout/activity_book_info.xml
  21. 11
      app/src/main/res/layout/view_book_page.xml

@ -136,12 +136,12 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
//room
def room_version = '2.2.4'
def room_version = '2.2.5'
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
//paging
implementation 'androidx.paging:paging-runtime:2.1.1'
implementation 'androidx.paging:paging-runtime:2.1.2'
//anko
def anko_version = '0.10.8'

@ -3,6 +3,14 @@
* 请关注[开源阅读]()支持我,同时关注合作公众号[小说拾遗](),阅读公众号小编。
* 弄了个企业公众号[开源阅读](),后面弄好后会把原来的[开源阅读软件]()迁移过来
**2020/03/21**
* 详情页点击书名搜索
**2020/03/20**
* 自动备份文件和手动备份文件分开
* 修复一些rss收藏取消不了的bug
* 修复rss请求头无效bug
**2020/03/19**
* 美化界面我的 by yangyxd
* 优化搜索

@ -16,4 +16,16 @@ data class RssStar(
var description: String? = null,
var content: String? = null,
var image: String? = null
)
) {
fun toRssArticle(): RssArticle {
return RssArticle(
origin = origin,
title = title,
link = link,
pubDate = pubDate,
description = description,
content = content,
image = image
)
}
}

@ -21,14 +21,6 @@ object Backup {
FileUtils.getDirFile(App.INSTANCE.filesDir, "backup").absolutePath
}
val legadoPath by lazy {
FileUtils.getSdCardPath() + File.separator + "YueDu3.0"
}
val exportPath by lazy {
legadoPath + File.separator + "Export"
}
val backupFileNames by lazy {
arrayOf(
"bookshelf.json", "bookGroup.json", "bookSource.json", "rssSource.json",
@ -42,16 +34,13 @@ object Backup {
return
}
Coroutine.async {
val backupPath = context.getPrefString(PreferKey.backupPath)
if (backupPath.isNullOrEmpty()) {
backup(context)
} else {
backup(context, backupPath)
context.getPrefString(PreferKey.backupPath)?.let {
backup(context, it, true)
}
}
}
suspend fun backup(context: Context, path: String = legadoPath) {
suspend fun backup(context: Context, path: String, isAuto: Boolean = false) {
context.putPrefLong(PreferKey.lastBackup, System.currentTimeMillis())
withContext(IO) {
synchronized(this@Backup) {
@ -81,9 +70,9 @@ object Backup {
}
WebDavHelp.backUpWebDav(backupPath)
if (path.isContentPath()) {
copyBackup(context, Uri.parse(path))
copyBackup(context, Uri.parse(path), isAuto)
} else {
copyBackup(File(path))
copyBackup(File(path), isAuto)
}
}
}
@ -97,12 +86,19 @@ object Backup {
}
@Throws(java.lang.Exception::class)
private fun copyBackup(context: Context, uri: Uri) {
private fun copyBackup(context: Context, uri: Uri, isAuto: Boolean) {
DocumentFile.fromTreeUri(context, uri)?.let { treeDoc ->
for (fileName in backupFileNames) {
val file = File(backupPath + File.separator + fileName)
if (file.exists()) {
if (isAuto) {
treeDoc.findFile("auto")?.findFile(fileName)?.delete()
DocumentUtils.createFileIfNotExist(
treeDoc,
fileName,
subDirs = *arrayOf("auto")
)?.writeBytes(context, file.readBytes())
} else {
treeDoc.findFile(fileName)?.delete()
treeDoc.createFile("", fileName)
?.writeBytes(context, file.readBytes())
@ -110,15 +106,19 @@ object Backup {
}
}
}
}
@Throws(java.lang.Exception::class)
private fun copyBackup(rootFile: File) {
private fun copyBackup(rootFile: File, isAuto: Boolean) {
for (fileName in backupFileNames) {
val file = File(backupPath + File.separator + fileName)
if (file.exists()) {
file.copyTo(
FileUtils.createFileIfNotExist(rootFile, fileName),
true
if (isAuto) {
FileUtils.createFileIfNotExist(rootFile, fileName, "auto")
} else {
FileUtils.createFileIfNotExist(rootFile, fileName)
}, true
)
}
}

@ -67,7 +67,7 @@ object Debug {
if (ruleContent.isNullOrEmpty()) {
log(debugSource, "⇒内容规则为空,默认获取整个网页", state = 1000)
} else {
rssContentDebug(it.articles[0], ruleContent)
rssContentDebug(it.articles[0], ruleContent, rssSource)
}
} else {
log(debugSource, "⇒存在描述规则,不解析内容页")
@ -80,9 +80,9 @@ object Debug {
}
}
private fun rssContentDebug(rssArticle: RssArticle, ruleContent: String) {
private fun rssContentDebug(rssArticle: RssArticle, ruleContent: String, rssSource: RssSource) {
log(debugSource, "︾开始解析内容页")
Rss.getContent(rssArticle, ruleContent)
Rss.getContent(rssArticle, ruleContent, rssSource)
.onSuccess {
log(debugSource, it)
log(debugSource, "︽内容页解析完成", state = 1000)

@ -21,7 +21,10 @@ object Rss {
context: CoroutineContext = Dispatchers.IO
): Coroutine<Result> {
return Coroutine.async(scope, context) {
val analyzeUrl = AnalyzeUrl(pageUrl ?: rssSource.sourceUrl)
val analyzeUrl = AnalyzeUrl(
pageUrl ?: rssSource.sourceUrl,
headerMapF = rssSource.getHeaderMap()
)
val body = analyzeUrl.getResponseAwait(rssSource.sourceUrl).body
RssParserByRule.parseXML(body, rssSource)
}
@ -30,12 +33,15 @@ object Rss {
fun getContent(
rssArticle: RssArticle,
ruleContent: String,
rssSource: RssSource?,
scope: CoroutineScope = Coroutine.DEFAULT,
context: CoroutineContext = Dispatchers.IO
): Coroutine<String> {
return Coroutine.async(scope, context) {
val body = AnalyzeUrl(rssArticle.link, baseUrl = rssArticle.origin)
.getResponseAwait(rssArticle.origin)
val body = AnalyzeUrl(
rssArticle.link, baseUrl = rssArticle.origin,
headerMapF = rssSource?.getHeaderMap()
).getResponseAwait(rssArticle.origin)
.body
val analyzeRule = AnalyzeRule()
analyzeRule.setContent(

@ -2,6 +2,7 @@ package io.legado.app.model.webBook
import io.legado.app.App
import io.legado.app.R
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookSource
@ -39,7 +40,12 @@ object BookContent {
var contentData = analyzeContent(
book, baseUrl, body, contentRule, bookChapter, bookSource
)
if (bookSource.bookSourceType == BookType.default) {
content.append(contentData.content.replace(bookChapter.title, "")).append("\n")
} else {
content.append(contentData.content).append("\n")
}
if (contentData.nextUrl.size == 1) {
var nextUrl = contentData.nextUrl[0]
val nextChapterUrl = if (!nextChapterUrlF.isNullOrEmpty())

@ -46,9 +46,8 @@ class AudioPlayActivity :
private var adjustProgress = false
override fun onActivityCreated(savedInstanceState: Bundle?) {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
AudioPlay.titleData.observe(this, Observer { toolbar.title = it })
title_bar.transparent()
AudioPlay.titleData.observe(this, Observer { title_bar.title = it })
AudioPlay.coverData.observe(this, Observer { upCover(it) })
viewModel.initData(intent)
initView()

@ -57,8 +57,7 @@ class BookInfoActivity :
get() = getViewModel(BookInfoViewModel::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
title_bar.transparent()
viewModel.bookData.observe(this, Observer { showBook(it) })
viewModel.chapterListData.observe(this, Observer { upLoading(false, it) })
viewModel.initData(intent)
@ -231,6 +230,9 @@ class BookInfoActivity :
tv_author.onClick {
startActivity<SearchActivity>(Pair("key", viewModel.bookData.value?.author))
}
tv_name.onClick {
startActivity<SearchActivity>(Pair("key", viewModel.bookData.value?.name))
}
}
@SuppressLint("InflateParams")

@ -8,7 +8,6 @@ import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.BookSource
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.OldRule
import io.legado.app.help.storage.Restore.jsonPath
import io.legado.app.utils.*
@ -96,7 +95,7 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application)
FileUtils.createFileIfNotExist(file, "exportBookSource.json")
.writeText(json)
}.onSuccess {
context.toast("成功导出至\n${Backup.exportPath}")
context.toast("成功导出至\n${file.absolutePath}")
}.onError {
context.toast("导出失败\n${it.localizedMessage}")
}
@ -109,7 +108,7 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application)
doc.createFile("", "exportBookSource.json")
?.writeText(context, json)
}.onSuccess {
context.toast("成功导出至\n${Backup.exportPath}")
context.toast("成功导出至\n${doc.uri.path}")
}.onError {
context.toast("导出失败\n${it.localizedMessage}")
}

@ -48,23 +48,19 @@ object BackupRestoreUi {
selectBackupFolder(fragment, backupSelectRequestCode)
}
} else {
backupUsePermission(fragment, requestCode = backupSelectRequestCode)
backupUsePermission(fragment, backupPath)
}
}
}
private fun backupUsePermission(
fragment: Fragment,
path: String = Backup.legadoPath,
requestCode: Int = selectFolderRequestCode
path: String
) {
PermissionsCompat.Builder(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
when (requestCode) {
selectFolderRequestCode -> AppConfig.backupPath = Backup.legadoPath
else -> {
Coroutine.async {
AppConfig.backupPath = path
Backup.backup(fragment.requireContext(), path)
@ -72,8 +68,6 @@ object BackupRestoreUi {
fragment.toast(R.string.backup_success)
}
}
}
}
.request()
}
@ -107,7 +101,7 @@ object BackupRestoreUi {
}
}
private fun restoreUsePermission(fragment: Fragment, path: String = Backup.legadoPath) {
private fun restoreUsePermission(fragment: Fragment, path: String) {
PermissionsCompat.Builder(fragment)
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)

@ -8,7 +8,6 @@ import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.ReplaceRule
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.ImportOldData
import io.legado.app.utils.*
import org.jetbrains.anko.toast
@ -93,7 +92,7 @@ class ReplaceRuleViewModel(application: Application) : BaseViewModel(application
FileUtils.createFileIfNotExist(file, "exportReplaceRule.json")
.writeText(json)
}.onSuccess {
context.toast("成功导出至\n${Backup.exportPath}")
context.toast("成功导出至\n${file.absolutePath}")
}.onError {
context.toast("导出失败\n${it.localizedMessage}")
}
@ -106,7 +105,7 @@ class ReplaceRuleViewModel(application: Application) : BaseViewModel(application
doc.createFile("", "exportReplaceRule.json")
?.writeText(context, json)
}.onSuccess {
context.toast("成功导出至\n${Backup.exportPath}")
context.toast("成功导出至\n${doc.uri.path}")
}.onError {
context.toast("导出失败\n${it.localizedMessage}")
}

@ -193,7 +193,7 @@ class ReadRssActivity : VMBaseActivity<ReadRssViewModel>(R.layout.activity_rss_r
}
override fun upStarMenu() {
if (viewModel.star) {
if (viewModel.rssStar != null) {
starMenuItem?.setIcon(R.drawable.ic_star)
starMenuItem?.setTitle(R.string.in_favorites)
} else {

@ -15,6 +15,7 @@ import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppConst
import io.legado.app.data.entities.RssArticle
import io.legado.app.data.entities.RssSource
import io.legado.app.data.entities.RssStar
import io.legado.app.help.http.HttpHelper
import io.legado.app.model.Rss
import io.legado.app.model.analyzeRule.AnalyzeUrl
@ -22,6 +23,7 @@ import io.legado.app.utils.DocumentUtils
import io.legado.app.utils.FileUtils
import io.legado.app.utils.isContentPath
import io.legado.app.utils.writeBytes
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import java.io.File
import java.util.*
@ -34,7 +36,7 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application),
var rssArticle: RssArticle? = null
val contentLiveData = MutableLiveData<String>()
val urlLiveData = MutableLiveData<AnalyzeUrl>()
var star = false
var rssStar: RssStar? = null
var textToSpeech: TextToSpeech? = null
private var ttsInitFinish = false
private var ttsTextList = arrayListOf<String>()
@ -45,8 +47,8 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application),
val link = intent.getStringExtra("link")
if (origin != null && link != null) {
rssSource = App.db.rssSourceDao().getByKey(origin)
star = App.db.rssStarDao().get(origin, link) != null
rssArticle = App.db.rssArticleDao().get(origin, link)
rssStar = App.db.rssStarDao().get(origin, link)
rssArticle = rssStar?.toRssArticle() ?: App.db.rssArticleDao().get(origin, link)
rssArticle?.let { rssArticle ->
if (!rssArticle.description.isNullOrBlank()) {
contentLiveData.postValue(rssArticle.description)
@ -78,21 +80,26 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application),
}
private fun loadContent(rssArticle: RssArticle, ruleContent: String) {
Rss.getContent(rssArticle, ruleContent, this)
.onSuccess {
contentLiveData.postValue(it)
Rss.getContent(rssArticle, ruleContent, rssSource, this)
.onSuccess(IO) { body ->
rssArticle.description = body
App.db.rssArticleDao().insert(rssArticle)
rssStar?.let {
it.description = body
App.db.rssStarDao().insert(it)
}
contentLiveData.postValue(body)
}
}
fun favorite() {
execute {
rssArticle?.let {
if (star) {
rssStar?.let {
App.db.rssStarDao().delete(it.origin, it.link)
} else {
App.db.rssStarDao().insert(it.toStar())
}
star = !star
rssStar = null
} ?: rssArticle?.toStar()?.let {
App.db.rssStarDao().insert(it)
rssStar = it
}
}.onSuccess {
callBack?.upStarMenu()

@ -9,7 +9,6 @@ import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssSource
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.Restore.jsonPath
import io.legado.app.utils.*
import org.jetbrains.anko.toast
@ -74,7 +73,7 @@ class RssSourceViewModel(application: Application) : BaseViewModel(application)
FileUtils.createFileIfNotExist(file, "exportRssSource.json")
.writeText(json)
}.onSuccess {
context.toast("成功导出至\n${Backup.exportPath}")
context.toast("成功导出至\n${file.absolutePath}")
}.onError {
context.toast("导出失败\n${it.localizedMessage}")
}
@ -87,7 +86,7 @@ class RssSourceViewModel(application: Application) : BaseViewModel(application)
doc.createFile("", "exportRssSource.json")
?.writeText(context, json)
}.onSuccess {
context.toast("成功导出至\n${Backup.exportPath}")
context.toast("成功导出至\n${doc.uri.path}")
}.onError {
context.toast("导出失败\n${it.localizedMessage}")
}

@ -2,6 +2,7 @@ package io.legado.app.ui.widget
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.util.AttributeSet
import android.view.Menu
import android.view.View
@ -186,6 +187,11 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
toolbar.setSubtitleTextAppearance(context, resId)
}
fun transparent() {
elevation = 0f
backgroundColor = Color.TRANSPARENT
}
private fun attachToActivity() {
if (attachToActivity) {
activity?.let {

@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path

@ -14,13 +14,10 @@
android:contentDescription="@string/bg_image"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
<io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarStyle"
android:fitsSystemWindows="true"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/book_info" />
@ -81,7 +78,8 @@
android:paddingLeft="10dp"
android:paddingTop="8dp"
android:paddingRight="16dp"
android:paddingBottom="3dp">
android:paddingBottom="3dp"
tools:ignore="RtlHardcoded">
<TextView
android:id="@+id/tv_name"
@ -147,14 +145,13 @@
android:layout_weight="1.0"
android:orientation="vertical"
android:layout_marginTop="65dp"
android:layout_marginLeft="1px"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/background"
android:fillViewport="true"
@ -162,7 +159,8 @@
android:focusable="true"
android:padding="0dp"
android:scrollbarStyle="outsideInset"
android:scrollbars="vertical">
android:scrollbars="vertical"
tools:ignore="NestedWeights">
<LinearLayout
android:layout_width="match_parent"
@ -212,7 +210,7 @@
android:text="@string/origin_format"
android:textColor="@color/tv_text_summary"
android:textSize="13sp"
tools:ignore="NestedWeights" />
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry" />
<io.legado.app.ui.widget.text.AccentBgTextView
android:id="@+id/tv_change_source"
@ -257,7 +255,7 @@
android:text="@string/read_dur_progress"
android:textColor="@color/tv_text_summary"
android:textSize="13sp"
tools:ignore="NestedWeights" />
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry" />
</LinearLayout>
@ -290,7 +288,7 @@
android:text="@string/group_s"
android:textColor="@color/tv_text_summary"
android:textSize="13sp"
tools:ignore="NestedWeights" />
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry" />
<io.legado.app.ui.widget.text.AccentBgTextView
android:id="@+id/tv_change_group"
@ -334,7 +332,7 @@
android:text="@string/toc_s"
android:textColor="@color/tv_text_summary"
android:textSize="13sp"
tools:ignore="NestedWeights" />
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry" />
<io.legado.app.ui.widget.text.AccentBgTextView
android:id="@+id/tv_toc_view"
@ -373,7 +371,7 @@
android:layout_marginBottom="1px"
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@color/background"></View>
android:background="@color/background" />
<LinearLayout
android:id="@+id/fl_action"

@ -21,13 +21,10 @@
android:layout_height="match_parent"
android:background="#50000000" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
<io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarStyle"
android:fitsSystemWindows="true"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_constraintTop_toTopOf="parent" />
<TextView
@ -40,7 +37,7 @@
android:paddingStart="3dp"
android:paddingEnd="3dp"
android:visibility="invisible"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintTop_toBottomOf="@id/title_bar"
app:layout_constraintRight_toRightOf="parent" />
<io.legado.app.ui.widget.image.CircleImageView
@ -54,7 +51,7 @@
app:layout_constraintBottom_toTopOf="@+id/ll_player_progress"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
app:layout_constraintTop_toBottomOf="@+id/title_bar" />
<TextView
android:id="@+id/tv_sub_title"

@ -21,13 +21,10 @@
android:background="#50000000"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
<io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarStyle"
android:fitsSystemWindows="true"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/book_info" />

@ -18,6 +18,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:ellipsize="end"
android:textSize="12sp" />
<TextView
@ -26,6 +28,8 @@
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textSize="12sp"
android:maxLines="1"
android:ellipsize="end"
tools:ignore="RtlHardcoded,RtlSymmetry" />
</LinearLayout>
@ -62,7 +66,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"
android:textSize="12sp" />
<TextView
@ -71,6 +76,8 @@
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textSize="12sp"
android:maxLines="1"
android:ellipsize="end"
tools:ignore="RtlHardcoded,RtlSymmetry" />
<io.legado.app.ui.widget.BatteryView
@ -79,6 +86,8 @@
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:textSize="10sp"
android:maxLines="1"
android:ellipsize="end"
tools:ignore="RtlHardcoded,RtlSymmetry,SmallSp" />
</LinearLayout>

Loading…
Cancel
Save