diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 67af4688e..543c13f6c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -185,6 +185,7 @@
             android:launchMode="singleTop" />
         
         
         【备份与恢复】,选择【导入旧版本数据】。
 * 请关注[开源阅读软件]()支持我,同时关注合作公众号[小说拾遗](),阅读公众号小编。
 
+**2020/03/10**
+* 优化文字选择菜单弹出位置
+* 添加屏幕方向控制
+
+**2020/03/09**
+* 底部文字对齐
+* 主题添加阴影调节 by yangyxd
+
 **2020/03/08**
 * 订阅长按保存图片
 * 订阅全屏播放
diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt
index 1ba9ba6cf..e14ec42f6 100644
--- a/app/src/main/java/io/legado/app/constant/PreferKey.kt
+++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt
@@ -3,7 +3,6 @@ package io.legado.app.constant
 object PreferKey {
     const val versionCode = "versionCode"
     const val themeMode = "themeMode"
-    const val downloadPath = "downloadPath"
     const val hideStatusBar = "hideStatusBar"
     const val clickTurnPage = "clickTurnPage"
     const val clickAllNext = "clickAllNext"
diff --git a/app/src/main/java/io/legado/app/help/AppConfig.kt b/app/src/main/java/io/legado/app/help/AppConfig.kt
index 6eef2bfa0..4b768b9e7 100644
--- a/app/src/main/java/io/legado/app/help/AppConfig.kt
+++ b/app/src/main/java/io/legado/app/help/AppConfig.kt
@@ -32,6 +32,9 @@ object AppConfig {
             App.INSTANCE.putPrefBoolean("transparentStatusBar", value)
         }
 
+    val requestedDirection: String?
+        get() = App.INSTANCE.getPrefString(R.string.pk_requested_direction)
+
     var backupPath: String?
         get() = App.INSTANCE.getPrefString(PreferKey.backupPath)
         set(value) {
@@ -49,7 +52,7 @@ object AppConfig {
         }
 
     val autoRefreshBook: Boolean
-        get() = App.INSTANCE.getPrefBoolean(App.INSTANCE.getString(R.string.pk_auto_refresh))
+        get() = App.INSTANCE.getPrefBoolean(R.string.pk_auto_refresh)
 
     var threadCount: Int
         get() = App.INSTANCE.getPrefInt(PreferKey.threadCount, 16)
@@ -111,4 +114,9 @@ object AppConfig {
             App.INSTANCE.putPrefBoolean("bookGroupAudio", value)
         }
 
+    var elevation: Int
+        get() = App.INSTANCE.getPrefInt("elevation", -1)
+        set(value) {
+            App.INSTANCE.putPrefInt("elevation", value)
+        }
 }
diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt
index 304df9997..b6e3ec000 100644
--- a/app/src/main/java/io/legado/app/help/BookHelp.kt
+++ b/app/src/main/java/io/legado/app/help/BookHelp.kt
@@ -4,8 +4,8 @@ import android.net.Uri
 import androidx.documentfile.provider.DocumentFile
 import com.github.houbb.opencc4j.core.impl.ZhConvertBootstrap
 import io.legado.app.App
+import io.legado.app.R
 import io.legado.app.constant.EventBus
-import io.legado.app.constant.PreferKey
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookChapter
 import io.legado.app.data.entities.ReplaceRule
@@ -21,7 +21,7 @@ import kotlin.math.min
 object BookHelp {
     private const val cacheFolderName = "book_cache"
     val downloadPath: String
-        get() = App.INSTANCE.getPrefString(PreferKey.downloadPath)
+        get() = App.INSTANCE.getPrefString(R.string.pk_download_path)
             ?: App.INSTANCE.getExternalFilesDir(null)?.absolutePath
             ?: App.INSTANCE.cacheDir.absolutePath
 
@@ -300,6 +300,8 @@ object BookHelp {
             1 -> c = ZhConvertBootstrap.newInstance().toSimple(c)
             2 -> c = ZhConvertBootstrap.newInstance().toTraditional(c)
         }
-        return c.replace("\\s*\\n+\\s*".toRegex(), "\n${ReadBookConfig.bodyIndent}")
+        return c
+            .replace("\\s*\\n+\\s*".toRegex(), "\n${ReadBookConfig.bodyIndent}")
+            .replace("[\\n\\s]+$".toRegex(), "") //移除尾部空行
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/lib/theme/ATHUtils.kt b/app/src/main/java/io/legado/app/lib/theme/ATHUtils.kt
index 73e342713..ddd6fc816 100644
--- a/app/src/main/java/io/legado/app/lib/theme/ATHUtils.kt
+++ b/app/src/main/java/io/legado/app/lib/theme/ATHUtils.kt
@@ -19,4 +19,16 @@ object ATHUtils {
             a.recycle()
         }
     }
+
+    @JvmOverloads
+    fun resolveFloat(context: Context, @AttrRes attr: Int, fallback: Float = 0.0f): Float {
+        val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
+        return try {
+            a.getFloat(0, fallback)
+        } catch (e: Exception) {
+            fallback
+        } finally {
+            a.recycle()
+        }
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt b/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt
index fab853c6b..bc898d065 100644
--- a/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt
+++ b/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt
@@ -107,4 +107,7 @@ val Context.isDarkTheme: Boolean
     get() = ColorUtils.isColorLight(ThemeStore.primaryColor(this))
 
 val Fragment.isDarkTheme: Boolean
-    get() = requireContext().isDarkTheme
\ No newline at end of file
+    get() = requireContext().isDarkTheme
+
+val Context.elevation: Float
+    get() = ThemeStore.elevation(this)
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/lib/theme/ThemeStore.kt b/app/src/main/java/io/legado/app/lib/theme/ThemeStore.kt
index 927fc2fb0..5b3997081 100644
--- a/app/src/main/java/io/legado/app/lib/theme/ThemeStore.kt
+++ b/app/src/main/java/io/legado/app/lib/theme/ThemeStore.kt
@@ -284,6 +284,14 @@ private constructor(private val mContext: Context) : ThemeStoreInterface {
             )
         }
 
+        @CheckResult
+        fun elevation(context: Context): Float {
+            return prefs(context).getFloat(
+                ThemeStorePrefKeys.KEY_ELEVATION,
+                ATHUtils.resolveFloat(context, android.R.attr.elevation, context.resources.getDimension(R.dimen.design_appbar_elevation))
+            )
+        }
+
         @CheckResult
         @ColorInt
         fun bottomBackground(context: Context): Int {
diff --git a/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.kt b/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.kt
index a2ab19d60..ca8e85fc1 100644
--- a/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.kt
+++ b/app/src/main/java/io/legado/app/lib/theme/ThemeStorePrefKeys.kt
@@ -27,4 +27,6 @@ object ThemeStorePrefKeys {
         const val KEY_APPLY_PRIMARYDARK_STATUSBAR = "apply_primarydark_statusbar"
         const val KEY_APPLY_PRIMARY_NAVBAR = "apply_primary_navbar"
         const val KEY_AUTO_GENERATE_PRIMARYDARK = "auto_generate_primarydark"
+
+        const val KEY_ELEVATION = "elevation"
 }
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
index 9a893b8a3..fc94613d8 100644
--- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
+++ b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
@@ -4,6 +4,7 @@ import android.net.Uri
 import androidx.documentfile.provider.DocumentFile
 import io.legado.app.App
 import io.legado.app.data.entities.Book
+import io.legado.app.help.BookHelp
 import io.legado.app.utils.FileUtils
 
 
@@ -12,8 +13,17 @@ object LocalBook {
     fun importFile(doc: DocumentFile) {
         doc.name?.let { fileName ->
             val str = fileName.substringBeforeLast(".")
-            var name = str.substringBefore("作者")
-            val author = str.substringAfter("作者", "")
+            val authorIndex = str.indexOf("作者")
+            var name: String
+            var author: String
+            if (authorIndex == -1) {
+                name = str
+                author = ""
+            } else {
+                name = str.substring(0, authorIndex)
+                author = str.substring(authorIndex)
+                author = BookHelp.formatAuthor(author)
+            }
             val smhStart = name.indexOf("《")
             val smhEnd = name.indexOf("》")
             if (smhStart != -1 && smhEnd != -1) {
diff --git a/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt b/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt
index 6fd32219d..e54900db7 100644
--- a/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt
+++ b/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt
@@ -175,9 +175,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
         }
 
         override fun onError(s: String) {
-            launch {
-                toast(s)
-            }
+            pauseReadAloud(true)
         }
 
     }
diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
index 769b47b21..42e56f206 100644
--- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
@@ -207,7 +207,7 @@ class BookInfoActivity :
                 ChangeSourceDialog.show(supportFragmentManager, it.name, it.author)
             }
         }
-        tv_toc.onClick {
+        tv_toc_view.onClick {
             if (!viewModel.inBookshelf) {
                 viewModel.saveBook {
                     viewModel.saveChapterList {
@@ -218,7 +218,7 @@ class BookInfoActivity :
                 openChapterList()
             }
         }
-        tv_group.onClick {
+        tv_change_group.onClick {
             viewModel.bookData.value?.let {
                 GroupSelectDialog.show(supportFragmentManager, it.group)
             }
diff --git a/app/src/main/java/io/legado/app/ui/book/read/Help.kt b/app/src/main/java/io/legado/app/ui/book/read/Help.kt
index 549b7b987..f5144977e 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/Help.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/Help.kt
@@ -3,6 +3,7 @@ package io.legado.app.ui.book.read
 import android.annotation.SuppressLint
 import android.app.Activity
 import android.content.Context
+import android.content.pm.ActivityInfo
 import android.os.AsyncTask
 import android.os.Build
 import android.view.*
@@ -62,6 +63,18 @@ object Help {
         }
     }
 
+
+    @SuppressLint("SourceLockedOrientationActivity")
+    fun setOrientation(activity: Activity) = activity.apply {
+        when (AppConfig.requestedDirection) {
+            "0" -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
+            "1" -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+            "2" -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+            "3" -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
+        }
+    }
+
+
     /**
      * 返回NavigationBar是否存在
      * 该方法需要在View完全被绘制出来之后调用,否则判断不了
diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
index 2ca4555a3..3de366ec3 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
@@ -3,6 +3,7 @@ package io.legado.app.ui.book.read
 import android.annotation.SuppressLint
 import android.app.Activity
 import android.content.Intent
+import android.content.res.Configuration
 import android.net.Uri
 import android.os.Bundle
 import android.os.Handler
@@ -13,6 +14,7 @@ import androidx.core.view.isVisible
 import androidx.core.view.size
 import androidx.lifecycle.Observer
 import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
+import io.legado.app.BuildConfig
 import io.legado.app.R
 import io.legado.app.base.VMBaseActivity
 import io.legado.app.constant.EventBus
@@ -88,6 +90,11 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
     override val pageFactory: TextPageFactory get() = page_view.pageFactory
     override val headerHeight: Int get() = page_view.curPage.headerHeight
 
+    override fun onCreate(savedInstanceState: Bundle?) {
+        Help.setOrientation(this)
+        super.onCreate(savedInstanceState)
+    }
+
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         Help.upLayoutInDisplayCutoutMode(window)
         initView()
@@ -106,6 +113,11 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
         upSystemUiVisibility()
     }
 
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        super.onConfigurationChanged(newConfig)
+        ReadBook.loadContent()
+    }
+
     override fun onResume() {
         super.onResume()
         upSystemUiVisibility()
@@ -338,7 +350,8 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
     @SuppressLint("ClickableViewAccessibility")
     override fun onTouch(v: View, event: MotionEvent): Boolean {
         when (event.action) {
-            MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP -> {
+            MotionEvent.ACTION_DOWN -> textActionMenu?.dismiss()
+            MotionEvent.ACTION_MOVE -> {
                 when (v.id) {
                     R.id.cursor_left -> page_view.curPage.selectStartMove(
                         event.rawX + cursor_left.width,
@@ -350,6 +363,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
                     )
                 }
             }
+            MotionEvent.ACTION_UP -> showTextActionMenu()
         }
         return true
     }
@@ -357,11 +371,12 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
     /**
      * 更新文字选择开始位置
      */
-    override fun upSelectedStart(x: Float, y: Float) {
+    override fun upSelectedStart(x: Float, y: Float, top: Float) {
         cursor_left.x = x - cursor_left.width
         cursor_left.y = y
         cursor_left.visible(true)
-        showTextActionMenu()
+        text_menu_position.x = x
+        text_menu_position.y = top
     }
 
     /**
@@ -371,7 +386,6 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
         cursor_right.x = x
         cursor_right.y = y
         cursor_right.visible(true)
-        showTextActionMenu()
     }
 
     /**
@@ -386,19 +400,24 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
     /**
      * 显示文本操作菜单
      */
-    private fun showTextActionMenu() {
+    override fun showTextActionMenu() {
         textActionMenu ?: let {
-            textActionMenu = TextActionMenu(this, this)
-        }
-        val x = cursor_left.x.toInt() + cursor_left.width
-        val y = if (cursor_left.y - statusBarHeight > ReadBookConfig.textSize.dp * 1.5 + 20.dp) {
-            (page_view.height - cursor_left.y + ReadBookConfig.textSize.dp * 1.5).toInt()
-        } else {
-            (page_view.height - cursor_left.y - cursor_left.height - 40.dp).toInt()
+            textActionMenu = TextActionMenu(this, this).apply {
+                contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
+            }
         }
         textActionMenu?.let { popup ->
+            val popupHeight = popup.contentView.measuredHeight
+            val x = text_menu_position.x.toInt()
+            var y = text_menu_position.y.toInt() - popupHeight
+            if (y < statusBarHeight) {
+                y = (cursor_left.y + cursor_left.height).toInt()
+            }
+            if (cursor_right.y > y && cursor_right.y < y + popupHeight) {
+                y = (cursor_right.y + cursor_right.height).toInt()
+            }
             if (!popup.isShowing) {
-                popup.showAtLocation(cursor_left, Gravity.BOTTOM or Gravity.START, x, y)
+                popup.showAtLocation(text_menu_position, Gravity.TOP or Gravity.START, x, y)
             } else {
                 popup.update(x, y, WRAP_CONTENT, WRAP_CONTENT)
             }
@@ -663,7 +682,9 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo
         mHandler.removeCallbacks(keepScreenRunnable)
         textActionMenu?.dismiss()
         page_view.onDestroy()
-        SyncBookProgress.uploadBookProgress()
+        if (!BuildConfig.DEBUG) {
+            SyncBookProgress.uploadBookProgress()
+        }
     }
 
     override fun observeLiveBus() {
diff --git a/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
index 7e90c7ad1..9d7046f6e 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
@@ -151,15 +151,16 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
      */
     @RequiresApi(Build.VERSION_CODES.M)
     private fun onInitializeMenu(menu: Menu) {
-        // Start with a menu Item order value that is high enough
-        // so that your "PROCESS_TEXT" menu items appear after the
-        // standard selection menu items like Cut, Copy, Paste.
-        var menuItemOrder = 100
-        for (resolveInfo in getSupportedActivities()) {
-            menu.add(
-                Menu.NONE, Menu.NONE,
-                menuItemOrder++, resolveInfo.loadLabel(context.packageManager)
-            ).intent = createProcessTextIntentForResolveInfo(resolveInfo)
+        try {
+            var menuItemOrder = 100
+            for (resolveInfo in getSupportedActivities()) {
+                menu.add(
+                    Menu.NONE, Menu.NONE,
+                    menuItemOrder++, resolveInfo.loadLabel(context.packageManager)
+                ).intent = createProcessTextIntentForResolveInfo(resolveInfo)
+            }
+        } catch (e: Exception) {
+            context.toast("获取文字操作菜单出错:${e.localizedMessage}")
         }
     }
 
diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt
index 6f472f270..a23725143 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt
@@ -104,6 +104,11 @@ class MoreConfigDialog : DialogFragment() {
                 }
                 PreferKey.keepLight -> postEvent(key, true)
                 PreferKey.textSelectAble -> postEvent(key, getPrefBoolean(key))
+                getString(R.string.pk_requested_direction) -> {
+                    activity?.let {
+                        Help.setOrientation(it)
+                    }
+                }
             }
         }
 
diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt
index 65121906c..b7cf7182e 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt
@@ -75,6 +75,7 @@ object ChapterProvider {
             item.chapterIndex = bookChapter.index
             item.chapterSize = chapterSize
             item.title = bookChapter.title
+            item.upLinesPosition(visibleHeight)
         }
         return TextChapter(
             bookChapter.index,
diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
index 44baa68f6..53f03462f 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
@@ -31,6 +31,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
     private val selectStart = arrayOf(0, 0, 0)
     private val selectEnd = arrayOf(0, 0, 0)
     private var textPage: TextPage = TextPage()
+
     //滚动参数
     private val pageFactory: TextPageFactory get() = callBack.pageFactory
     private val maxScrollOffset = 100f
@@ -210,7 +211,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
                         selectEnd[0] = 0
                         selectEnd[1] = lineIndex
                         selectEnd[2] = charIndex
-                        upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
+                        upSelectedStart(
+                            textChar.start,
+                            textLine.lineBottom + relativeOffset,
+                            textLine.lineTop + relativeOffset
+                        )
                         upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
                         select(0, lineIndex, charIndex)
                         return
@@ -236,7 +241,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
                         selectEnd[0] = 1
                         selectEnd[1] = lineIndex
                         selectEnd[2] = charIndex
-                        upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
+                        upSelectedStart(
+                            textChar.start,
+                            textLine.lineBottom + relativeOffset,
+                            textLine.lineTop + relativeOffset
+                        )
                         upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
                         select(1, lineIndex, charIndex)
                         return
@@ -259,7 +268,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
                         selectEnd[0] = 2
                         selectEnd[1] = lineIndex
                         selectEnd[2] = charIndex
-                        upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
+                        upSelectedStart(
+                            textChar.start,
+                            textLine.lineBottom + relativeOffset,
+                            textLine.lineTop + relativeOffset
+                        )
                         upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
                         select(2, lineIndex, charIndex)
                         return
@@ -287,7 +300,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
                             selectStart[0] = 0
                             selectStart[1] = lineIndex
                             selectStart[2] = charIndex
-                            upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
+                            upSelectedStart(
+                                textChar.start,
+                                textLine.lineBottom + relativeOffset,
+                                textLine.lineTop + relativeOffset
+                            )
                             upSelectChars()
                         }
                         return
@@ -311,7 +328,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
                             selectStart[0] = 1
                             selectStart[1] = lineIndex
                             selectStart[2] = charIndex
-                            upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
+                            upSelectedStart(
+                                textChar.start,
+                                textLine.lineBottom + relativeOffset,
+                                textLine.lineTop + relativeOffset
+                            )
                             upSelectChars()
                         }
                         return
@@ -333,7 +354,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
                             selectStart[0] = 2
                             selectStart[1] = lineIndex
                             selectStart[2] = charIndex
-                            upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
+                            upSelectedStart(
+                                textChar.start,
+                                textLine.lineBottom + relativeOffset,
+                                textLine.lineTop + relativeOffset
+                            )
                             upSelectChars()
                         }
                         return
@@ -427,7 +452,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         selectStart[2] = charIndex
         val textLine = relativePage(relativePage).textLines[lineIndex]
         val textChar = textLine.textChars[charIndex]
-        upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset(relativePage))
+        upSelectedStart(
+            textChar.start,
+            textLine.lineBottom + relativeOffset(relativePage),
+            textLine.lineTop
+        )
         upSelectChars()
     }
 
@@ -475,12 +504,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         invalidate()
     }
 
-    private fun upSelectedStart(x: Float, y: Float) {
-        callBack.upSelectedStart(x, y + callBack.headerHeight)
+    private fun upSelectedStart(x: Float, y: Float, top: Float) = callBack.apply {
+        upSelectedStart(x, y + headerHeight, top + headerHeight)
     }
 
-    private fun upSelectedEnd(x: Float, y: Float) {
-        callBack.upSelectedEnd(x, y + callBack.headerHeight)
+    private fun upSelectedEnd(x: Float, y: Float) = callBack.apply {
+        upSelectedEnd(x, y + headerHeight)
     }
 
     fun cancelSelect() {
@@ -580,7 +609,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
     }
 
     interface CallBack {
-        fun upSelectedStart(x: Float, y: Float)
+        fun upSelectedStart(x: Float, y: Float, top: Float)
         fun upSelectedEnd(x: Float, y: Float)
         fun onCancelSelect()
         val headerHeight: Int
diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt
index a9a752303..4e820008e 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt
@@ -109,7 +109,6 @@ class ContentView(context: Context) : FrameLayout(context) {
 
     fun setContent(textPage: TextPage) {
         setProgress(textPage)
-        content_text_view.resetPageOffset()
         content_text_view.setContent(textPage)
     }
 
diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
index dbde99c7e..1b7b71b07 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
@@ -16,25 +16,20 @@ class PageView(context: Context, attrs: AttributeSet) :
     FrameLayout(context, attrs),
     DataSource {
 
-    var callBack: CallBack
-    var pageFactory: TextPageFactory
+    val callBack: CallBack get() = activity as CallBack
+    var pageFactory: TextPageFactory = TextPageFactory(this)
     var pageDelegate: PageDelegate? = null
 
-    var prevPage: ContentView
-    var curPage: ContentView
-    var nextPage: ContentView
+    var prevPage: ContentView = ContentView(context)
+    var curPage: ContentView = ContentView(context)
+    var nextPage: ContentView = ContentView(context)
 
     init {
-        callBack = activity as CallBack
-        nextPage = ContentView(context)
         addView(nextPage)
-        curPage = ContentView(context)
         addView(curPage)
-        prevPage = ContentView(context)
         addView(prevPage)
         upBg()
         setWillNotDraw(false)
-        pageFactory = TextPageFactory(this)
         upPageAnim()
     }
 
@@ -170,5 +165,6 @@ class PageView(context: Context, attrs: AttributeSet) :
         val isInitFinish: Boolean
         fun clickCenter()
         fun screenOffTimerStart()
+        fun showTextActionMenu()
     }
 }
diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt
index 4173ffb09..d83f60edb 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt
@@ -200,11 +200,16 @@ abstract class PageDelegate(protected val pageView: PageView) :
             //GestureDetector.onFling小幅移动不会触发,所以要自己判断
             when (event.action) {
                 MotionEvent.ACTION_UP,
-                MotionEvent.ACTION_CANCEL -> if (isMoved) {
-                    if (selectedOnDown) {
-                        selectedOnDown = false
+                MotionEvent.ACTION_CANCEL -> {
+                    if (isTextSelected) {
+                        pageView.callBack.showTextActionMenu()
+                    }
+                    if (isMoved) {
+                        if (selectedOnDown) {
+                            selectedOnDown = false
+                        }
+                        if (!noNext) onAnimStart()
                     }
-                    if (!noNext) onAnimStart()
                 }
             }
         }
diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt
index bfb8e822c..6c4e27073 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt
@@ -18,6 +18,21 @@ data class TextPage(
     var height: Float = 0f
 ) {
 
+    fun upLinesPosition(visibleHeight: Int) {
+        if (textLines.size <= 1) return
+        if (visibleHeight - height > with(textLines.last()) { lineBottom - lineTop }) return
+        val surplus = (visibleHeight - textLines.last().lineBottom)
+        if (surplus == 0f) return
+        height += surplus
+        val tj = surplus / (textLines.size - 1)
+        for (i in 1 until textLines.size) {
+            val line = textLines[i]
+            line.lineTop = line.lineTop + tj * i
+            line.lineBase = line.lineBase + tj * i
+            line.lineBottom = line.lineBottom + tj * i
+        }
+    }
+
     @Suppress("DEPRECATION")
     fun format(): TextPage {
         if (textLines.isEmpty() && ChapterProvider.visibleWidth > 0) {
@@ -101,4 +116,5 @@ data class TextPage(
             }
             return percent
         }
+
 }
diff --git a/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
index 58caa351d..a010428fd 100644
--- a/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
+++ b/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
@@ -40,7 +40,7 @@ class OtherConfigFragment : PreferenceFragmentCompat(),
     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
         putPrefBoolean(PreferKey.processText, isProcessTextEnabled())
         addPreferencesFromResource(R.xml.pref_config_other)
-        upPreferenceSummary(PreferKey.downloadPath, BookHelp.downloadPath)
+        upPreferenceSummary(getString(R.string.pk_download_path), BookHelp.downloadPath)
         upPreferenceSummary(PreferKey.threadCount, AppConfig.threadCount.toString())
         upPreferenceSummary(PreferKey.webPort, webPort.toString())
     }
@@ -74,7 +74,7 @@ class OtherConfigFragment : PreferenceFragmentCompat(),
                 .show {
                     putPrefInt(PreferKey.webPort, it)
                 }
-            PreferKey.downloadPath -> selectDownloadPath()
+            getString(R.string.pk_download_path) -> selectDownloadPath()
             PreferKey.cleanCache -> {
                 BookHelp.clearCache()
                 toast(R.string.clear_cache_success)
@@ -85,7 +85,7 @@ class OtherConfigFragment : PreferenceFragmentCompat(),
 
     override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
         when (key) {
-            PreferKey.downloadPath -> {
+            getString(R.string.pk_download_path) -> {
                 upPreferenceSummary(key, BookHelp.downloadPath)
             }
             PreferKey.threadCount -> upPreferenceSummary(
@@ -141,13 +141,17 @@ class OtherConfigFragment : PreferenceFragmentCompat(),
 
     private fun selectDownloadPath() {
         FilePicker.selectFolder(this, requestCodeDownloadPath) {
-            removePref(PreferKey.downloadPath)
+            removePref(getString(R.string.pk_download_path))
         }
     }
 
+    private fun putDownloadPath(path: String) {
+        putPrefString(getString(R.string.pk_download_path), path)
+    }
+
     override fun onFilePicked(requestCode: Int, currentPath: String) {
         if (requestCode == requestCodeDownloadPath) {
-            putPrefString(PreferKey.downloadPath, currentPath)
+            putDownloadPath(currentPath)
         }
     }
 
@@ -160,7 +164,7 @@ class OtherConfigFragment : PreferenceFragmentCompat(),
                         uri,
                         Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                     )
-                    putPrefString(PreferKey.downloadPath, uri.toString())
+                    putDownloadPath(uri.toString())
                 }
             }
         }
diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
index 99d7d1e54..da2672841 100644
--- a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
+++ b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
@@ -1,6 +1,7 @@
 package io.legado.app.ui.config
 
 import android.content.SharedPreferences
+import android.os.Build
 import android.os.Bundle
 import android.view.View
 import androidx.preference.Preference
@@ -16,6 +17,8 @@ import io.legado.app.lib.dialogs.noButton
 import io.legado.app.lib.dialogs.yesButton
 import io.legado.app.lib.theme.ATH
 import io.legado.app.lib.theme.ColorUtils
+import io.legado.app.ui.widget.number.NumberPickerDialog
+import io.legado.app.ui.widget.prefs.IconListPreference
 import io.legado.app.utils.*
 
 
@@ -25,6 +28,12 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
 
     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
         addPreferencesFromResource(R.xml.pref_config_theme)
+        if (Build.VERSION.SDK_INT < 26) {
+            findPreference(PreferKey.launcherIcon)?.let {
+                preferenceScreen.removePreference(it)
+            }
+        }
+        upPreferenceSummary("barElevation", AppConfig.elevation.toString())
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -145,6 +154,19 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
                     recreateActivities()
                 }
             }.show().applyTint()
+            "barElevation" -> NumberPickerDialog(requireContext())
+                .setTitle(getString(R.string.bar_elevation))
+                .setMaxValue(32)
+                .setMinValue(0)
+                .setValue(AppConfig.elevation)
+                .setCustomButton((R.string.btn_default_s)) {
+                    AppConfig.elevation = App.INSTANCE.resources.getDimension(R.dimen.design_appbar_elevation).toInt()
+                    recreateActivities()
+                }
+                .show {
+                    AppConfig.elevation = it
+                    recreateActivities()
+                }
         }
         return super.onPreferenceTreeClick(preference)
     }
@@ -180,4 +202,10 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
         postEvent(EventBus.RECREATE, "")
     }
 
+    private fun upPreferenceSummary(preferenceKey: String, value: String?) {
+        val preference = findPreference(preferenceKey) ?: return
+        when (preferenceKey) {
+            "barElevation" -> preference.summary = getString(R.string.bar_elevation_s, value)
+        }
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt
index 5c84aa679..46e1e446e 100644
--- a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt
@@ -48,7 +48,7 @@ open class WelcomeActivity : BaseActivity(R.layout.activity_welcome) {
 
     private fun startMainActivity() {
         startActivity()
-        if (getPrefBoolean(getString(R.string.pk_default_read))) {
+        if (getPrefBoolean(R.string.pk_default_read)) {
             startActivity()
         }
         finish()
diff --git a/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt b/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt
index 60e781c93..f11db64e8 100644
--- a/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt
+++ b/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt
@@ -1,67 +1,57 @@
 package io.legado.app.ui.widget
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.graphics.Canvas
 import android.graphics.Paint
 import android.graphics.Rect
-import android.graphics.Typeface
-import android.text.StaticLayout
-import android.text.TextPaint
 import android.util.AttributeSet
-import android.view.View
 import androidx.annotation.ColorInt
-import io.legado.app.R
+import androidx.appcompat.widget.AppCompatTextView
 import io.legado.app.utils.dp
-import io.legado.app.utils.getCompatColor
-import io.legado.app.utils.sp
 
-class BatteryView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
-    private var battery = 100
-    private val textPaint = TextPaint()
-    private var batteryHeight: Int = 0
-    private var batteryWidth: Int = 0
+class BatteryView(context: Context, attrs: AttributeSet?) : AppCompatTextView(context, attrs) {
+    private val batteryPaint = Paint()
     private val outFrame = Rect()
     private val polar = Rect()
 
     init {
-        textPaint.textSize = 10.sp.toFloat()
-        textPaint.strokeWidth = 1.dp.toFloat()
-        textPaint.isAntiAlias = true
-        textPaint.textAlign = Paint.Align.CENTER
-        textPaint.color = context.getCompatColor(R.color.tv_text_default)
-        textPaint.typeface = Typeface.createFromAsset(context.assets, "number.ttf")
-        batteryHeight = with(textPaint.fontMetrics) { descent - ascent + leading }.toInt()
-        batteryWidth = StaticLayout.getDesiredWidth("100", textPaint).toInt() + 10.dp
-        outFrame.set(1.dp, 1.dp, batteryWidth - 3.dp, batteryHeight - 1.dp)
-        polar.set(outFrame.right, batteryHeight / 3, batteryWidth, batteryHeight * 2 / 3)
-    }
-
-    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
-        super.onMeasure(
-            MeasureSpec.makeMeasureSpec(batteryWidth, MeasureSpec.EXACTLY),
-            MeasureSpec.makeMeasureSpec(batteryHeight, MeasureSpec.EXACTLY)
-        )
+        setPadding(4.dp, 0, 6.dp, 0)
+        batteryPaint.strokeWidth = 1.dp.toFloat()
+        batteryPaint.isAntiAlias = true
+        batteryPaint.color = paint.color
     }
 
     fun setColor(@ColorInt color: Int) {
-        textPaint.color = color
+        setTextColor(color)
+        batteryPaint.color = color
         invalidate()
     }
 
+    @SuppressLint("SetTextI18n")
     fun setBattery(battery: Int) {
-        this.battery = battery
-        invalidate()
+        text = "$battery"
     }
 
     override fun onDraw(canvas: Canvas) {
         super.onDraw(canvas)
-        textPaint.style = Paint.Style.STROKE
-        canvas.drawRect(outFrame, textPaint)
-        textPaint.style = Paint.Style.FILL
-        canvas.drawRect(polar, textPaint)
-        val text = battery.toString()
-        val baseHeight = batteryHeight - textPaint.fontMetrics.descent
-        canvas.drawText(text, outFrame.right / 2.toFloat(), baseHeight, textPaint)
+        outFrame.set(
+            1.dp,
+            layout.getLineTop(0) + 2.dp,
+            width - 3.dp,
+            layout.getLineBottom(0) - 2.dp
+        )
+        val dj = (outFrame.bottom - outFrame.top) / 3
+        polar.set(
+            outFrame.right,
+            outFrame.top + dj,
+            width - 1.dp,
+            outFrame.bottom - dj
+        )
+        batteryPaint.style = Paint.Style.STROKE
+        canvas.drawRect(outFrame, batteryPaint)
+        batteryPaint.style = Paint.Style.FILL
+        canvas.drawRect(polar, batteryPaint)
     }
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt
index d19c8929f..663bb55a8 100644
--- a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt
+++ b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt
@@ -10,6 +10,8 @@ import androidx.annotation.StyleRes
 import androidx.appcompat.widget.Toolbar
 import com.google.android.material.appbar.AppBarLayout
 import io.legado.app.R
+import io.legado.app.help.AppConfig
+import io.legado.app.lib.theme.elevation
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.utils.activity
 import io.legado.app.utils.navigationBarHeight
@@ -141,6 +143,13 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
 
         backgroundColor = context.primaryColor
 
+        stateListAnimator = null
+        elevation = if (AppConfig.elevation < 0) {
+            context.elevation
+        } else {
+            AppConfig.elevation.toFloat()
+        }
+
         a.recycle()
     }
 
diff --git a/app/src/main/java/io/legado/app/ui/widget/number/NumberPickerDialog.kt b/app/src/main/java/io/legado/app/ui/widget/number/NumberPickerDialog.kt
index 17fe9ab53..3b4c8f5db 100644
--- a/app/src/main/java/io/legado/app/ui/widget/number/NumberPickerDialog.kt
+++ b/app/src/main/java/io/legado/app/ui/widget/number/NumberPickerDialog.kt
@@ -40,6 +40,17 @@ class NumberPickerDialog(context: Context) {
         return this
     }
 
+    fun setCustomButton(textId: Int, listener: (() -> Unit)?): NumberPickerDialog {
+        builder.setNeutralButton(textId) { _, _ ->
+            numberPicker?.let {
+                it.clearFocus()
+                it.hideSoftInput()
+                listener?.invoke()
+            }
+        }
+        return this;
+    }
+
     fun show(callBack: ((value: Int) -> Unit)?) {
         builder.setPositiveButton(R.string.ok) { _, _ ->
             numberPicker?.let {
diff --git a/app/src/main/java/io/legado/app/utils/ContextExtensions.kt b/app/src/main/java/io/legado/app/utils/ContextExtensions.kt
index 3436c9d94..bc3f6f9fa 100644
--- a/app/src/main/java/io/legado/app/utils/ContextExtensions.kt
+++ b/app/src/main/java/io/legado/app/utils/ContextExtensions.kt
@@ -12,6 +12,7 @@ import android.os.BatteryManager
 import android.provider.Settings
 import androidx.annotation.ColorRes
 import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
 import androidx.core.content.ContextCompat
 import androidx.core.content.FileProvider
 import androidx.core.content.edit
@@ -28,6 +29,9 @@ import java.io.FileOutputStream
 fun Context.getPrefBoolean(key: String, defValue: Boolean = false) =
     defaultSharedPreferences.getBoolean(key, defValue)
 
+fun Context.getPrefBoolean(@StringRes keyId: Int, defValue: Boolean = false) =
+    defaultSharedPreferences.getBoolean(getString(keyId), defValue)
+
 fun Context.putPrefBoolean(key: String, value: Boolean = false) =
     defaultSharedPreferences.edit { putBoolean(key, value) }
 
@@ -46,6 +50,9 @@ fun Context.putPrefLong(key: String, value: Long) =
 fun Context.getPrefString(key: String, defValue: String? = null) =
     defaultSharedPreferences.getString(key, defValue)
 
+fun Context.getPrefString(@StringRes keyId: Int, defValue: String? = null) =
+    defaultSharedPreferences.getString(getString(keyId), defValue)
+
 fun Context.putPrefString(key: String, value: String) =
     defaultSharedPreferences.edit { putString(key, value) }
 
diff --git a/app/src/main/res/layout-land/activity_book_info.xml b/app/src/main/res/layout-land/activity_book_info.xml
new file mode 100644
index 000000000..27e0bec0d
--- /dev/null
+++ b/app/src/main/res/layout-land/activity_book_info.xml
@@ -0,0 +1,419 @@
+
+
+
+    
+
+    
+
+    
+
+        
+
+            
+
+                
+
+                
+
+                    
+
+                
+
+            
+
+            
+
+                
+
+                
+
+                
+
+                    
+
+                    
+
+                
+
+            
+
+
+        
+
+
+        
+
+            
+
+                
+
+                    
+
+                        
+
+                            
+
+                            
+
+                            
+
+                        
+
+                        
+
+                            
+
+                            
+
+                        
+
+                        
+
+                            
+
+                            
+
+                            
+
+                        
+
+                        
+
+                            
+
+                            
+
+                            
+
+                        
+
+                    
+
+                    
+
+                
+
+            
+
+            
+
+            
+
+                
+
+                
+
+            
+
+        
+
+    
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_book_info.xml b/app/src/main/res/layout/activity_book_info.xml
index 8e58e34cb..568a4e60a 100644
--- a/app/src/main/res/layout/activity_book_info.xml
+++ b/app/src/main/res/layout/activity_book_info.xml
@@ -64,40 +64,6 @@
 
         
 
-    
-
-        
-
-        
-
-    
-
         
 
+                
+
+                    
+
+                    
+
+                
+
                 
 
                     
@@ -241,6 +241,94 @@
 
                     
 
+                    
+
+                        
+
+                        
+
+                        
+
+                    
+
+                    
+
+                        
+
+                        
+
+                        
+
+                    
+
                 
 
                 
 
             
 
         
 
-        
-
-            
-
-            
-
-        
+            android:layout_height="8dp"
+            android:background="@color/background">
 
         
 
+    
+
     
+            android:textSize="10sp"
+            tools:ignore="RtlHardcoded,RtlSymmetry,SmallSp" />
 
     
 
diff --git a/app/src/main/res/values/array_values.xml b/app/src/main/res/values/array_values.xml
index 2aa918837..c517c46ce 100644
--- a/app/src/main/res/values/array_values.xml
+++ b/app/src/main/res/values/array_values.xml
@@ -38,5 +38,11 @@
         - 9+    
+
- 0+
- 1+
- 2+
- 3+    
 
 
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 104febad6..a53546e7f 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -67,7 +67,7 @@
- @string/app_folder_picker-    
+
- @string/screen_unspecified
- @string/screen_portrait
- @string/screen_landscapediff --git a/app/src/main/res/values/pref_key_value.xml b/app/src/main/res/values/pref_key_value.xml
index 7bcded4da..0c535ad67 100644
--- a/app/src/main/res/values/pref_key_value.xml
+++ b/app/src/main/res/values/pref_key_value.xml
@@ -1,7 +1,7 @@
 
 
     auto_refresh
-    list_screen_direction
+    list_screen_direction
     full_screen
     threads_num
     user_agent
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2af658b79..84e6e6bb2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -160,7 +160,7 @@
     添加书籍网址
     背景
     作者
-    作者:%s
+    作者: %s
     朗读停止
     清除缓存
     成功清理缓存
@@ -641,4 +641,10 @@
     加入分组
     保存图片
     没有默认路径
+    设置分组
+    查看目录
+    导航栏阴影
+    当前阴影大小(elevation): %s
+    默认
+
 
diff --git a/app/src/main/res/xml/pref_config_read.xml b/app/src/main/res/xml/pref_config_read.xml
index a19a8ba4c..ef360b43c 100644
--- a/app/src/main/res/xml/pref_config_read.xml
+++ b/app/src/main/res/xml/pref_config_read.xml
@@ -2,6 +2,14 @@
 
 
+    
+
     
 
+    
+