Merge remote-tracking branch 'origin/master'

pull/61/head
Administrator 5 years ago
commit e9f3779ed0
  1. 4
      app/src/main/assets/updateLog.md
  2. 2
      app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt
  3. 20
      app/src/main/java/io/legado/app/service/AudioPlayService.kt
  4. 12
      app/src/main/java/io/legado/app/service/help/AudioPlay.kt
  5. 14
      app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt
  6. 5
      app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt
  7. 3
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  8. 29
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  9. 3
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt
  10. 6
      app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt
  11. 1
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt
  12. 17
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  13. 13
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt
  14. 16
      app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt
  15. 4
      app/src/main/java/io/legado/app/web/controller/SourceController.kt
  16. 1
      app/src/main/res/layout/activity_rss_read.xml
  17. 78
      app/src/main/res/layout/dialog_download_choice.xml

@ -4,6 +4,10 @@
* 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。 * 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。
* 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。 * 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。
**2019/12/16**
* 添加几个主题选择
* 音频播放添加header支持
**2019/12/15** **2019/12/15**
* 修复清理缓存会把其他文件删除的问题 * 修复清理缓存会把其他文件删除的问题
* 详情页模糊背景 * 详情页模糊背景

@ -75,7 +75,7 @@ interface BookSourceDao {
fun update(vararg bookSource: BookSource) fun update(vararg bookSource: BookSource)
@Delete @Delete
fun delete(vararg bookSource: BookSource) fun delete(bookSource: BookSource)
@Query("delete from book_sources where bookSourceUrl = :key") @Query("delete from book_sources where bookSourceUrl = :key")
fun delete(key: String) fun delete(key: String)

@ -9,6 +9,7 @@ import android.graphics.BitmapFactory
import android.media.AudioFocusRequest import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
import android.media.MediaPlayer import android.media.MediaPlayer
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
@ -44,10 +45,10 @@ class AudioPlayService : BaseService(),
companion object { companion object {
var isRun = false var isRun = false
var pause = false
var timeMinute: Int = 0 var timeMinute: Int = 0
} }
var pause = false
private val handler = Handler() private val handler = Handler()
private lateinit var audioManager: AudioManager private lateinit var audioManager: AudioManager
private var mFocusRequest: AudioFocusRequest? = null private var mFocusRequest: AudioFocusRequest? = null
@ -91,7 +92,6 @@ class AudioPlayService : BaseService(),
Action.prev -> moveToPrev() Action.prev -> moveToPrev()
Action.next -> moveToNext() Action.next -> moveToNext()
Action.adjustSpeed -> upSpeed(intent.getFloatExtra("adjust", 1f)) Action.adjustSpeed -> upSpeed(intent.getFloatExtra("adjust", 1f))
Action.moveTo -> moveTo(intent.getIntExtra("index", AudioPlay.durChapterIndex))
Action.addTimer -> addTimer() Action.addTimer -> addTimer()
Action.setTimer -> setTimer(intent.getIntExtra("minute", 0)) Action.setTimer -> setTimer(intent.getIntExtra("minute", 0))
Action.adjustProgress -> adjustProgress(intent.getIntExtra("position", position)) Action.adjustProgress -> adjustProgress(intent.getIntExtra("position", position))
@ -121,7 +121,8 @@ class AudioPlayService : BaseService(),
AudioPlay.status = Status.PLAY AudioPlay.status = Status.PLAY
postEvent(Bus.AUDIO_STATE, Status.PLAY) postEvent(Bus.AUDIO_STATE, Status.PLAY)
mediaPlayer.reset() mediaPlayer.reset()
mediaPlayer.setDataSource(url) val uri = Uri.parse(url)
mediaPlayer.setDataSource(this, uri, AudioPlay.headers())
mediaPlayer.prepareAsync() mediaPlayer.prepareAsync()
} catch (e: Exception) { } catch (e: Exception) {
launch { launch {
@ -133,7 +134,7 @@ class AudioPlayService : BaseService(),
} }
private fun pause(pause: Boolean) { private fun pause(pause: Boolean) {
this.pause = pause AudioPlayService.pause = pause
handler.removeCallbacks(mpRunnable) handler.removeCallbacks(mpRunnable)
position = mediaPlayer.currentPosition position = mediaPlayer.currentPosition
mediaPlayer.pause() mediaPlayer.pause()
@ -311,16 +312,6 @@ class AudioPlayService : BaseService(),
} }
} }
private fun moveTo(index: Int) {
mediaPlayer.pause()
AudioPlay.durChapterIndex = index
AudioPlay.durPageIndex = 0
AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex
saveRead()
position = 0
loadContent(AudioPlay.durChapterIndex)
}
private fun moveToPrev() { private fun moveToPrev() {
if (AudioPlay.durChapterIndex > 0) { if (AudioPlay.durChapterIndex > 0) {
mediaPlayer.pause() mediaPlayer.pause()
@ -354,6 +345,7 @@ class AudioPlayService : BaseService(),
book.durChapterTime = System.currentTimeMillis() book.durChapterTime = System.currentTimeMillis()
book.durChapterIndex = AudioPlay.durChapterIndex book.durChapterIndex = AudioPlay.durChapterIndex
book.durChapterPos = AudioPlay.durPageIndex book.durChapterPos = AudioPlay.durPageIndex
book.durChapterTitle = subtitle
App.db.bookDao().update(book) App.db.bookDao().update(book)
} }
} }

@ -21,6 +21,10 @@ object AudioPlay {
var webBook: WebBook? = null var webBook: WebBook? = null
val loadingChapters = arrayListOf<Int>() val loadingChapters = arrayListOf<Int>()
fun headers(): Map<String, String>? {
return webBook?.bookSource?.getHeaderMap()
}
fun play(context: Context) { fun play(context: Context) {
val intent = Intent(context, AudioPlayService::class.java) val intent = Intent(context, AudioPlayService::class.java)
intent.action = Action.play intent.action = Action.play
@ -85,12 +89,4 @@ object AudioPlay {
} }
} }
fun moveTo(context: Context, index: Int) {
if (AudioPlayService.isRun) {
val intent = Intent(context, AudioPlayService::class.java)
intent.action = Action.moveTo
intent.putExtra("index", index)
context.startService(intent)
}
}
} }

@ -10,6 +10,7 @@ import android.view.MenuItem
import android.widget.SeekBar import android.widget.SeekBar
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@ -21,6 +22,7 @@ import io.legado.app.help.ImageLoader
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.okButton import io.legado.app.lib.dialogs.okButton
import io.legado.app.service.AudioPlayService
import io.legado.app.service.help.AudioPlay import io.legado.app.service.help.AudioPlay
import io.legado.app.ui.changesource.ChangeSourceDialog import io.legado.app.ui.changesource.ChangeSourceDialog
import io.legado.app.ui.chapterlist.ChapterListActivity import io.legado.app.ui.chapterlist.ChapterListActivity
@ -117,6 +119,7 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
.centerCrop() .centerCrop()
.into(iv_cover) .into(iv_cover)
ImageLoader.load(this, path) ImageLoader.load(this, path)
.transition(DrawableTransitionOptions.withCrossFade(1500))
.thumbnail(defaultCover()) .thumbnail(defaultCover())
.centerCrop() .centerCrop()
.apply(RequestOptions.bitmapTransform(BlurTransformation(this, 25))) .apply(RequestOptions.bitmapTransform(BlurTransformation(this, 25)))
@ -170,7 +173,16 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
when (requestCode) { when (requestCode) {
requestCodeChapter -> data?.getIntExtra("index", AudioPlay.durChapterIndex)?.let { requestCodeChapter -> data?.getIntExtra("index", AudioPlay.durChapterIndex)?.let {
if (it != AudioPlay.durChapterIndex) { if (it != AudioPlay.durChapterIndex) {
AudioPlay.moveTo(this, it) val isPlay = !AudioPlayService.pause
AudioPlay.pause(this)
AudioPlay.status = Status.STOP
AudioPlay.durChapterIndex = it
AudioPlay.durPageIndex = 0
AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex
viewModel.saveRead()
if (isPlay) {
AudioPlay.play(this)
}
} }
} }
} }

@ -124,13 +124,16 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
} }
} }
private fun saveRead() { fun saveRead() {
execute { execute {
AudioPlay.book?.let { book -> AudioPlay.book?.let { book ->
book.lastCheckCount = 0 book.lastCheckCount = 0
book.durChapterTime = System.currentTimeMillis() book.durChapterTime = System.currentTimeMillis()
book.durChapterIndex = AudioPlay.durChapterIndex book.durChapterIndex = AudioPlay.durChapterIndex
book.durChapterPos = AudioPlay.durPageIndex book.durChapterPos = AudioPlay.durPageIndex
App.db.bookChapterDao().getChapter(book.bookUrl, book.durChapterIndex)?.let {
book.durChapterTitle = it.title
}
App.db.bookDao().update(book) App.db.bookDao().update(book)
} }
} }

@ -7,7 +7,6 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions.bitmapTransform import com.bumptech.glide.request.RequestOptions.bitmapTransform
@ -115,7 +114,7 @@ class BookInfoActivity :
.error(R.drawable.image_cover_default) .error(R.drawable.image_cover_default)
.centerCrop() .centerCrop()
.into(iv_cover) .into(iv_cover)
Glide.with(this).load(it) ImageLoader.load(this, it)
.transition(DrawableTransitionOptions.withCrossFade(1500)) .transition(DrawableTransitionOptions.withCrossFade(1500))
.thumbnail(defaultCover()) .thumbnail(defaultCover())
.centerCrop() .centerCrop()

@ -1,5 +1,6 @@
package io.legado.app.ui.book.read package io.legado.app.ui.book.read
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
@ -8,6 +9,7 @@ import android.text.SpannableStringBuilder
import android.view.KeyEvent import android.view.KeyEvent
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
@ -18,11 +20,10 @@ import io.legado.app.constant.Status
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.*
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.okButton
import io.legado.app.receiver.TimeElectricityReceiver import io.legado.app.receiver.TimeElectricityReceiver
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.Download
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.service.help.ReadBook import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.config.* import io.legado.app.ui.book.read.config.*
@ -38,6 +39,7 @@ import io.legado.app.ui.widget.page.PageView
import io.legado.app.ui.widget.page.delegate.PageDelegate import io.legado.app.ui.widget.page.delegate.PageDelegate
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.activity_book_read.* import kotlinx.android.synthetic.main.activity_book_read.*
import kotlinx.android.synthetic.main.dialog_download_choice.view.*
import kotlinx.android.synthetic.main.view_book_page.* import kotlinx.android.synthetic.main.view_book_page.*
import kotlinx.android.synthetic.main.view_read_menu.* import kotlinx.android.synthetic.main.view_read_menu.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
@ -131,6 +133,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
/** /**
* 菜单 * 菜单
*/ */
@SuppressLint("InflateParams")
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.menu_change_source -> { R.id.menu_change_source -> {
@ -146,6 +149,26 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
viewModel.refreshContent(it) viewModel.refreshContent(it)
} }
} }
R.id.menu_download -> ReadBook.book?.let { book ->
alert(titleResource = R.string.download_offline) {
var view: View? = null
customView {
layoutInflater.inflate(R.layout.dialog_download_choice, null).apply {
view = this
edit_start.setText(book.durChapterIndex.toString())
edit_end.setText(book.totalChapterNum.toString())
}
}
yesButton {
view?.apply {
val start = edit_start?.text?.toString()?.toInt() ?: 0
val end = edit_end?.text?.toString()?.toInt() ?: book.totalChapterNum
Download.start(this@ReadBookActivity, book.bookUrl, start, end)
}
}
noButton()
}.show().applyTint()
}
} }
return super.onCompatOptionsItemSelected(item) return super.onCompatOptionsItemSelected(item)
} }

@ -91,7 +91,8 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application)
App.db.bookSourceDao().getBookSource(it) App.db.bookSourceDao().getBookSource(it)
}.let { }.let {
val json = GSON.toJson(it) val json = GSON.toJson(it)
val file = FileHelp.getFile(Backup.exportPath + File.separator + "exportBookSource.json") val file =
FileHelp.getFile(Backup.exportPath + File.separator + "exportBookSource.json")
file.writeText(json) file.writeText(json)
} }
}.onSuccess { }.onSuccess {

@ -48,9 +48,9 @@ class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragme
viewModel.bookUrl?.let { bookUrl -> viewModel.bookUrl?.let { bookUrl ->
App.db.bookChapterDao().observeByBook(bookUrl).observe(viewLifecycleOwner, Observer { App.db.bookChapterDao().observeByBook(bookUrl).observe(viewLifecycleOwner, Observer {
adapter.setItems(it) adapter.setItems(it)
viewModel.book?.let { viewModel.book?.let { book ->
durChapterIndex = it.durChapterIndex durChapterIndex = book.durChapterIndex
tv_current_chapter_info.text = it.durChapterTitle tv_current_chapter_info.text = book.durChapterTitle
recycler_view.scrollToPosition(durChapterIndex) recycler_view.scrollToPosition(durChapterIndex)
} }
}) })

@ -126,6 +126,7 @@ class RssArticlesActivity : VMBaseActivity<RssArticlesViewModel>(R.layout.activi
override fun readRss(rssArticle: RssArticle) { override fun readRss(rssArticle: RssArticle) {
viewModel.read(rssArticle) viewModel.read(rssArticle)
startActivity<ReadRssActivity>( startActivity<ReadRssActivity>(
Pair("title", rssArticle.title),
Pair("origin", rssArticle.origin), Pair("origin", rssArticle.origin),
Pair("link", rssArticle.link) Pair("link", rssArticle.link)
) )

@ -25,7 +25,7 @@ class ReadRssActivity : VMBaseActivity<ReadRssViewModel>(R.layout.activity_rss_r
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.callBack = this viewModel.callBack = this
title = intent.getStringExtra("title") title_bar.title = intent.getStringExtra("title")
initWebView() initWebView()
initLiveData() initLiveData()
viewModel.initData(intent) viewModel.initData(intent)
@ -59,20 +59,11 @@ class ReadRssActivity : VMBaseActivity<ReadRssViewModel>(R.layout.activity_rss_r
viewModel.rssArticle?.let { viewModel.rssArticle?.let {
upJavaScriptEnable() upJavaScriptEnable()
val url = NetworkUtils.getAbsoluteURL(it.origin, it.link) val url = NetworkUtils.getAbsoluteURL(it.origin, it.link)
val html = viewModel.clHtml(content)
if (viewModel.rssSource?.loadWithBaseUrl == true) { if (viewModel.rssSource?.loadWithBaseUrl == true) {
webView.loadDataWithBaseURL( webView.loadDataWithBaseURL(url, html, "text/html", "utf-8", url)
url,
"<style>img{max-width:100%}</style>$content",
"text/html",
"utf-8",
url
)
} else { } else {
webView.loadData( webView.loadData(html, "text/html", "utf-8")
"<style>img{max-width:100%}</style>$content",
"text/html",
"utf-8"
)
} }
} }
}) })

@ -77,6 +77,19 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) {
} }
} }
fun clHtml(content: String): String {
return """
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<style>img{max-width:100% !important; width:auto; height:auto;}</style>
</head>
<body style:"height:auto;max-width: 100%; width:auto;">
$content
</body></html>
"""
}
interface CallBack { interface CallBack {
fun upStarMenu() fun upStarMenu()
} }

@ -4,6 +4,8 @@ import android.text.Spannable
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan import android.text.style.RelativeSizeSpan
import androidx.core.text.HtmlCompat
import androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
import io.legado.app.App import io.legado.app.App
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
@ -17,7 +19,9 @@ object ChapterProvider {
fun getTextChapter( fun getTextChapter(
bookChapter: BookChapter, bookChapter: BookChapter,
content: String, chapterSize: Int content: String,
chapterSize: Int,
isHtml: Boolean = false
): TextChapter { ): TextChapter {
textView?.let { textView?.let {
val textPages = arrayListOf<TextPage>() val textPages = arrayListOf<TextPage>()
@ -26,7 +30,15 @@ object ChapterProvider {
var surplusText = content var surplusText = content
var pageIndex = 0 var pageIndex = 0
while (surplusText.isNotEmpty()) { while (surplusText.isNotEmpty()) {
val spannableStringBuilder = SpannableStringBuilder(surplusText) val spannableStringBuilder =
if (isHtml) {
HtmlCompat.fromHtml(
surplusText,
FROM_HTML_MODE_COMPACT
) as SpannableStringBuilder
} else {
SpannableStringBuilder(surplusText)
}
if (pageIndex == 0) { if (pageIndex == 0) {
val end = surplusText.indexOf("\n") val end = surplusText.indexOf("\n")
if (end > 0) { if (end > 0) {

@ -71,7 +71,9 @@ class SourceController {
fun deleteSources(postData: String?): ReturnData { fun deleteSources(postData: String?): ReturnData {
kotlin.runCatching { kotlin.runCatching {
GSON.fromJsonArray<BookSource>(postData)?.let { GSON.fromJsonArray<BookSource>(postData)?.let {
App.db.bookSourceDao().delete(*it.toTypedArray()) it.forEach { source ->
App.db.bookSourceDao().delete(source)
}
} }
} }
return ReturnData().setData("已执行"/*okSources*/) return ReturnData().setData("已执行"/*okSources*/)

@ -5,6 +5,7 @@
android:orientation="vertical"> android:orientation="vertical">
<io.legado.app.ui.widget.TitleBar <io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:background="@color/background"
android:gravity="center"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:text="@string/chapter"
android:textColor="@color/tv_text_default"
android:textSize="16sp"
tools:ignore="RtlHardcoded" />
<EditText
android:id="@+id/edit_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/bg_edit"
android:inputType="number"
android:lines="1"
android:maxLength="5"
android:minWidth="60dp"
android:paddingLeft="5dp"
android:paddingTop="4dp"
android:paddingRight="5dp"
android:paddingBottom="4dp"
android:textColor="@color/tv_text_default"
android:textCursorDrawable="@drawable/shape_text_cursor"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:text="@string/to"
android:textColor="@color/tv_text_default"
android:textSize="16sp" />
<EditText
android:id="@+id/edit_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/bg_edit"
android:inputType="number"
android:lines="1"
android:maxLength="5"
android:minWidth="60dp"
android:paddingLeft="5dp"
android:paddingTop="4dp"
android:paddingRight="5dp"
android:paddingBottom="4dp"
android:textColor="@color/tv_text_default"
android:textCursorDrawable="@drawable/shape_text_cursor"
android:textSize="14sp" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Loading…
Cancel
Save