mirror of
https://github.com/gedoor/legado.git
synced 2024-09-03 09:55:00 +08:00
优化
This commit is contained in:
parent
e5d8441c54
commit
1c0e9731b8
@ -31,21 +31,12 @@ interface RssSourceDao {
|
||||
@Query("select sourceGroup from rssSources where sourceGroup is not null and sourceGroup <> ''")
|
||||
fun liveGroup(): LiveData<List<String>>
|
||||
|
||||
@Query("update rssSources set enabled = 1 where sourceUrl in (:sourceUrls)")
|
||||
fun enableSection(vararg sourceUrls: String)
|
||||
|
||||
@Query("update rssSources set enabled = 0 where sourceUrl in (:sourceUrls)")
|
||||
fun disableSection(vararg sourceUrls: String)
|
||||
|
||||
@get:Query("select min(customOrder) from rssSources")
|
||||
val minOrder: Int
|
||||
|
||||
@get:Query("select max(customOrder) from rssSources")
|
||||
val maxOrder: Int
|
||||
|
||||
@Query("delete from rssSources where sourceUrl in (:sourceUrls)")
|
||||
fun delSection(vararg sourceUrls: String)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg rssSource: RssSource)
|
||||
|
||||
@ -55,9 +46,6 @@ interface RssSourceDao {
|
||||
@Delete
|
||||
fun delete(vararg rssSource: RssSource)
|
||||
|
||||
@Query("delete from rssSources where sourceUrl = :sourceUrl")
|
||||
fun delete(sourceUrl: String)
|
||||
|
||||
@get:Query("select * from rssSources where sourceGroup is null or sourceGroup = ''")
|
||||
val noGroup: List<RssSource>
|
||||
|
||||
|
@ -39,6 +39,17 @@ data class RssSource(
|
||||
var customOrder: Int = 0
|
||||
) : Parcelable, JsExtensions {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is RssSource) {
|
||||
return other.sourceUrl == sourceUrl
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return sourceUrl.hashCode()
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun getHeaderMap(): Map<String, String> {
|
||||
val headerMap = HashMap<String, String>()
|
||||
|
@ -128,9 +128,6 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
|
||||
search_view.queryHint = getString(R.string.search_book_source)
|
||||
search_view.clearFocus()
|
||||
search_view.setOnQueryTextListener(this)
|
||||
selMenu = PopupMenu(this, iv_menu_more)
|
||||
selMenu.inflate(R.menu.book_source_sel)
|
||||
selMenu.setOnMenuItemClickListener(this)
|
||||
}
|
||||
|
||||
private fun initLiveDataBookSource(searchKey: String? = null) {
|
||||
@ -160,6 +157,9 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
|
||||
}
|
||||
|
||||
private fun initViewEvent() {
|
||||
selMenu = PopupMenu(this, iv_menu_more)
|
||||
selMenu.inflate(R.menu.book_source_sel)
|
||||
selMenu.setOnMenuItemClickListener(this)
|
||||
cb_selected_all.onClick {
|
||||
if (adapter.getSelection().size == adapter.getActualItemCount()) {
|
||||
adapter.revertSelection()
|
||||
|
@ -7,6 +7,7 @@ import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.SubMenu
|
||||
import android.widget.PopupMenu
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
@ -35,6 +36,7 @@ import io.legado.app.utils.*
|
||||
import kotlinx.android.synthetic.main.activity_rss_source.*
|
||||
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
|
||||
import kotlinx.android.synthetic.main.view_search.*
|
||||
import org.jetbrains.anko.sdk27.listeners.onClick
|
||||
import org.jetbrains.anko.startActivity
|
||||
import org.jetbrains.anko.startActivityForResult
|
||||
import org.jetbrains.anko.toast
|
||||
@ -42,6 +44,7 @@ import java.io.FileNotFoundException
|
||||
|
||||
|
||||
class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_rss_source),
|
||||
PopupMenu.OnMenuItemClickListener,
|
||||
FileChooserDialog.CallBack,
|
||||
RssSourceAdapter.CallBack {
|
||||
|
||||
@ -54,12 +57,14 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
|
||||
private var sourceLiveData: LiveData<List<RssSource>>? = null
|
||||
private var groups = hashSetOf<String>()
|
||||
private var groupMenu: SubMenu? = null
|
||||
private lateinit var selMenu: PopupMenu
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
initRecyclerView()
|
||||
initSearchView()
|
||||
initLiveDataGroup()
|
||||
initLiveDataSource()
|
||||
initViewEvent()
|
||||
}
|
||||
|
||||
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
|
||||
@ -76,12 +81,6 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.menu_add -> startActivity<RssSourceEditActivity>()
|
||||
R.id.menu_select_all -> adapter.selectAll()
|
||||
R.id.menu_revert_selection -> adapter.revertSelection()
|
||||
R.id.menu_enable_selection -> viewModel.enableSelection(adapter.getSelectionIds())
|
||||
R.id.menu_disable_selection -> viewModel.disableSelection(adapter.getSelectionIds())
|
||||
R.id.menu_del_selection -> viewModel.delSelection(adapter.getSelectionIds())
|
||||
R.id.menu_export_selection -> viewModel.exportSelection(adapter.getSelectionIds())
|
||||
R.id.menu_import_source_local -> selectFileSys()
|
||||
R.id.menu_import_source_onLine -> showImportDialog()
|
||||
R.id.menu_import_source_qr -> startActivityForResult<QrCodeActivity>(qrRequestCode)
|
||||
@ -94,6 +93,18 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
when (item?.itemId) {
|
||||
R.id.menu_select_all -> adapter.selectAll()
|
||||
R.id.menu_revert_selection -> adapter.revertSelection()
|
||||
R.id.menu_enable_selection -> viewModel.enableSelection(adapter.getSelection())
|
||||
R.id.menu_disable_selection -> viewModel.disableSelection(adapter.getSelection())
|
||||
R.id.menu_del_selection -> viewModel.delSelection(adapter.getSelection())
|
||||
R.id.menu_export_selection -> viewModel.exportSelection(adapter.getSelection())
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun initRecyclerView() {
|
||||
ATH.applyEdgeEffectColor(recycler_view)
|
||||
recycler_view.layoutManager = LinearLayoutManager(this)
|
||||
@ -133,6 +144,25 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
|
||||
})
|
||||
}
|
||||
|
||||
private fun initViewEvent() {
|
||||
selMenu = PopupMenu(this, iv_menu_more)
|
||||
selMenu.inflate(R.menu.rss_source_sel)
|
||||
selMenu.setOnMenuItemClickListener(this)
|
||||
cb_selected_all.onClick {
|
||||
if (adapter.getSelection().size == adapter.getActualItemCount()) {
|
||||
adapter.revertSelection()
|
||||
} else {
|
||||
adapter.selectAll()
|
||||
}
|
||||
}
|
||||
btn_revert_selection.onClick {
|
||||
adapter.revertSelection()
|
||||
}
|
||||
iv_menu_more.onClick {
|
||||
selMenu.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun upGroupMenu() {
|
||||
groupMenu?.removeGroup(R.id.source_group)
|
||||
groups.map {
|
||||
@ -153,9 +183,44 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
|
||||
.calculateDiff(DiffCallBack(adapter.getItems(), it))
|
||||
adapter.setItems(it, false)
|
||||
diffResult.dispatchUpdatesTo(adapter)
|
||||
upCountView()
|
||||
})
|
||||
}
|
||||
|
||||
override fun upCountView() {
|
||||
val selectCount = adapter.getSelection().size
|
||||
if (selectCount == 0) {
|
||||
cb_selected_all.isChecked = false
|
||||
} else {
|
||||
cb_selected_all.isChecked = selectCount >= adapter.getActualItemCount()
|
||||
}
|
||||
|
||||
//重置全选的文字
|
||||
if (cb_selected_all.isChecked) {
|
||||
cb_selected_all.text = getString(
|
||||
R.string.select_cancel_count,
|
||||
selectCount,
|
||||
adapter.getActualItemCount()
|
||||
)
|
||||
} else {
|
||||
cb_selected_all.text = getString(
|
||||
R.string.select_all_count,
|
||||
selectCount,
|
||||
adapter.getActualItemCount()
|
||||
)
|
||||
}
|
||||
setMenuClickable(selectCount > 0)
|
||||
}
|
||||
|
||||
private fun setMenuClickable(isClickable: Boolean) {
|
||||
//设置是否可删除
|
||||
btn_delete.isEnabled = isClickable
|
||||
btn_delete.isClickable = isClickable
|
||||
//设置是否可添加书籍
|
||||
btn_revert_selection.isEnabled = isClickable
|
||||
btn_revert_selection.isClickable = isClickable
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
private fun showImportDialog() {
|
||||
val aCache = ACache.get(this, cacheDir = false)
|
||||
|
@ -18,31 +18,33 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
|
||||
SimpleRecyclerAdapter<RssSource>(context, R.layout.item_rss_source),
|
||||
ItemTouchCallback.OnItemTouchCallbackListener {
|
||||
|
||||
private val selectedIds = linkedSetOf<String>()
|
||||
private val selected = linkedSetOf<RssSource>()
|
||||
|
||||
fun selectAll() {
|
||||
getItems().forEach {
|
||||
selectedIds.add(it.sourceUrl)
|
||||
selected.add(it)
|
||||
}
|
||||
notifyItemRangeChanged(0, itemCount, 1)
|
||||
callBack.upCountView()
|
||||
}
|
||||
|
||||
fun revertSelection() {
|
||||
getItems().forEach {
|
||||
if (selectedIds.contains(it.sourceUrl)) {
|
||||
selectedIds.remove(it.sourceUrl)
|
||||
if (selected.contains(it)) {
|
||||
selected.remove(it)
|
||||
} else {
|
||||
selectedIds.add(it.sourceUrl)
|
||||
selected.add(it)
|
||||
}
|
||||
}
|
||||
notifyItemRangeChanged(0, itemCount, 1)
|
||||
callBack.upCountView()
|
||||
}
|
||||
|
||||
fun getSelectionIds(): LinkedHashSet<String> {
|
||||
val selection = linkedSetOf<String>()
|
||||
fun getSelection(): LinkedHashSet<RssSource> {
|
||||
val selection = linkedSetOf<RssSource>()
|
||||
getItems().forEach {
|
||||
if (selectedIds.contains(it.sourceUrl)) {
|
||||
selection.add(it.sourceUrl)
|
||||
if (selected.contains(it)) {
|
||||
selection.add(it)
|
||||
}
|
||||
}
|
||||
return selection
|
||||
@ -63,13 +65,14 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
|
||||
item.enabled = swt_enabled.isChecked
|
||||
callBack.update(item)
|
||||
}
|
||||
cb_source.isChecked = selectedIds.contains(item.sourceUrl)
|
||||
cb_source.isChecked = selected.contains(item)
|
||||
cb_source.setOnClickListener {
|
||||
if (cb_source.isChecked) {
|
||||
selectedIds.add(item.sourceUrl)
|
||||
selected.add(item)
|
||||
} else {
|
||||
selectedIds.remove(item.sourceUrl)
|
||||
selected.remove(item)
|
||||
}
|
||||
callBack.upCountView()
|
||||
}
|
||||
iv_edit.onClick { callBack.edit(item) }
|
||||
iv_menu_more.onClick {
|
||||
@ -87,7 +90,7 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
|
||||
}
|
||||
} else {
|
||||
when (payloads[0]) {
|
||||
1 -> cb_source.isChecked = selectedIds.contains(item.sourceUrl)
|
||||
1 -> cb_source.isChecked = selected.contains(item)
|
||||
2 -> swt_enabled.isChecked = item.enabled
|
||||
}
|
||||
}
|
||||
@ -128,5 +131,6 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
|
||||
fun update(vararg source: RssSource)
|
||||
fun toTop(source: RssSource)
|
||||
fun upOrder()
|
||||
fun upCountView()
|
||||
}
|
||||
}
|
||||
|
@ -41,32 +41,38 @@ class RssSourceViewModel(application: Application) : BaseViewModel(application)
|
||||
}
|
||||
}
|
||||
|
||||
fun enableSelection(ids: LinkedHashSet<String>) {
|
||||
fun enableSelection(sources: LinkedHashSet<RssSource>) {
|
||||
execute {
|
||||
App.db.rssSourceDao().enableSection(*ids.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun disableSelection(ids: LinkedHashSet<String>) {
|
||||
execute {
|
||||
App.db.rssSourceDao().disableSection(*ids.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun delSelection(ids: LinkedHashSet<String>) {
|
||||
execute {
|
||||
App.db.rssSourceDao().delSection(*ids.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun exportSelection(ids: LinkedHashSet<String>) {
|
||||
execute {
|
||||
App.db.rssSourceDao().getRssSources(*ids.toTypedArray()).let {
|
||||
val json = GSON.toJson(it)
|
||||
val file =
|
||||
FileUtils.createFileIfNotExist(Backup.exportPath + File.separator + "exportRssSource.json")
|
||||
file.writeText(json)
|
||||
val list = arrayListOf<RssSource>()
|
||||
sources.forEach {
|
||||
list.add(it.copy(enabled = true))
|
||||
}
|
||||
App.db.rssSourceDao().update(*list.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun disableSelection(sources: LinkedHashSet<RssSource>) {
|
||||
execute {
|
||||
val list = arrayListOf<RssSource>()
|
||||
sources.forEach {
|
||||
list.add(it.copy(enabled = false))
|
||||
}
|
||||
App.db.rssSourceDao().update(*list.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun delSelection(sources: LinkedHashSet<RssSource>) {
|
||||
execute {
|
||||
App.db.rssSourceDao().delete(*sources.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
fun exportSelection(sources: LinkedHashSet<RssSource>) {
|
||||
execute {
|
||||
val json = GSON.toJson(sources)
|
||||
val file =
|
||||
FileUtils.createFileIfNotExist(Backup.exportPath + File.separator + "exportRssSource.json")
|
||||
file.writeText(json)
|
||||
}.onSuccess {
|
||||
context.toast("成功导出至\n${Backup.exportPath}")
|
||||
}.onError {
|
||||
|
@ -3,6 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical">
|
||||
|
||||
<io.legado.app.ui.widget.TitleBar
|
||||
@ -16,7 +17,8 @@
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
@ -25,4 +27,57 @@
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!--文件点击按钮-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:elevation="2dp">
|
||||
|
||||
<io.legado.app.lib.theme.view.ATECheckBox
|
||||
android:id="@+id/cb_selected_all"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:padding="5dp"
|
||||
android:text="@string/select_all_count"
|
||||
android:textColor="@color/tv_text_default" />
|
||||
|
||||
<io.legado.app.lib.theme.view.ATEAccentStrokeTextView
|
||||
android:id="@+id/btn_revert_selection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:padding="5dp"
|
||||
android:gravity="center"
|
||||
android:minWidth="80dp"
|
||||
android:text="@string/revert_selection" />
|
||||
|
||||
<io.legado.app.lib.theme.view.ATEAccentStrokeTextView
|
||||
android:id="@+id/btn_delete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:padding="5dp"
|
||||
android:minWidth="80dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/delete" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_menu_more"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/ic_more_vert"
|
||||
android:tint="@color/tv_text_default"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
25
app/src/main/res/menu/rss_source_sel.xml
Normal file
25
app/src/main/res/menu/rss_source_sel.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_enable_selection"
|
||||
android:title="@string/enable_selection"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_disable_selection"
|
||||
android:title="@string/disable_selection"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_del_selection"
|
||||
android:title="@string/del_select"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_export_selection"
|
||||
android:title="@string/export_selection"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
Loading…
Reference in New Issue
Block a user