diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index ef66a2372..a68e7e9e3 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -9,10 +9,10 @@ import io.legado.app.data.entities.BookSource interface BookSourceDao { @Query("select * from book_sources order by customOrder asc") - fun observeAll(): DataSource.Factory + fun liveDataAll(): LiveData> @Query("select * from book_sources where bookSourceName like :searchKey or `bookSourceGroup` like :searchKey or bookSourceUrl like :searchKey order by customOrder asc") - fun observeSearch(searchKey: String = ""): DataSource.Factory + fun liveDataSearch(searchKey: String = ""): LiveData> @Query("select * from book_sources where enabledExplore = 1 and exploreUrl is not null and exploreUrl <> '' order by customOrder asc") fun liveExplore(): LiveData> diff --git a/app/src/main/java/io/legado/app/ui/booksource/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/booksource/BookSourceActivity.kt index b98a8bf2f..6de1926ef 100644 --- a/app/src/main/java/io/legado/app/ui/booksource/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/booksource/BookSourceActivity.kt @@ -9,8 +9,7 @@ import androidx.appcompat.widget.SearchView import androidx.core.content.ContextCompat import androidx.lifecycle.LiveData import androidx.lifecycle.Observer -import androidx.paging.LivePagedListBuilder -import androidx.paging.PagedList +import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -42,15 +41,16 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity private val qrRequestCode = 101 private lateinit var adapter: BookSourceAdapter - private var bookSourceLiveDate: LiveData>? = null + private var bookSourceLiveDate: LiveData>? = null private var groups = hashSetOf() private var groupMenu: SubMenu? = null override fun onActivityCreated(savedInstanceState: Bundle?) { setSupportActionBar(toolbar) initRecyclerView() - initDataObserve() initSearchView() + initLiveDataBookSource() + initLiveDataGroup() } override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { @@ -104,7 +104,7 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity this.setDrawable(it) } }) - adapter = BookSourceAdapter(this) + adapter = BookSourceAdapter(this, this) recycler_view.adapter = adapter val itemTouchCallback = ItemTouchCallback() itemTouchCallback.onItemTouchCallbackListener = adapter @@ -120,12 +120,22 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity search_view.setOnQueryTextListener(this) } - private fun initDataObserve(searchKey: String = "") { + private fun initLiveDataBookSource(searchKey: String? = null) { bookSourceLiveDate?.removeObservers(this) - val dataFactory = App.db.bookSourceDao().observeSearch("%$searchKey%") - bookSourceLiveDate = LivePagedListBuilder(dataFactory, 10000).build() - bookSourceLiveDate?.observe(this, Observer { adapter.submitList(it) }) + bookSourceLiveDate = if (searchKey.isNullOrEmpty()) { + App.db.bookSourceDao().liveDataAll() + } else { + App.db.bookSourceDao().liveDataSearch("%$searchKey%") + } + bookSourceLiveDate?.observe(this, Observer { + search_view.queryHint = getString(R.string.search_book_source_num, it.size) + val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it)) + adapter.setItemsNoNotify(it) + diffResult.dispatchUpdatesTo(adapter) + }) + } + private fun initLiveDataGroup() { App.db.bookSourceDao().liveGroup().observe(this, Observer { groups.clear() it.map { group -> @@ -144,7 +154,7 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity override fun onQueryTextChange(newText: String?): Boolean { newText?.let { - initDataObserve(it) + initLiveDataBookSource(it) } return false } @@ -153,10 +163,6 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity return false } - override fun upCount(count: Int) { - search_view.queryHint = getString(R.string.search_book_source_num, count) - } - override fun del(bookSource: BookSource) { viewModel.del(bookSource) } @@ -169,6 +175,10 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity startActivity(Pair("data", bookSource.bookSourceUrl)) } + override fun upOrder() { + viewModel.upOrder() + } + override fun topSource(bookSource: BookSource) { viewModel.topSource(bookSource) } diff --git a/app/src/main/java/io/legado/app/ui/booksource/BookSourceAdapter.kt b/app/src/main/java/io/legado/app/ui/booksource/BookSourceAdapter.kt index 4faf0de8e..4e5100e25 100644 --- a/app/src/main/java/io/legado/app/ui/booksource/BookSourceAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/booksource/BookSourceAdapter.kt @@ -1,107 +1,64 @@ package io.legado.app.ui.booksource -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.paging.PagedList -import androidx.paging.PagedListAdapter -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.RecyclerView +import android.content.Context import io.legado.app.R +import io.legado.app.base.adapter.ItemViewHolder +import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.data.entities.BookSource import io.legado.app.help.ItemTouchCallback.OnItemTouchCallbackListener import io.legado.app.lib.theme.backgroundColor import kotlinx.android.synthetic.main.item_book_source.view.* import org.jetbrains.anko.sdk27.listeners.onClick -class BookSourceAdapter(val callBack: CallBack) : - PagedListAdapter(DIFF_CALLBACK), +class BookSourceAdapter(context: Context, val callBack: CallBack) : + SimpleRecyclerAdapter(context, R.layout.item_book_source), OnItemTouchCallbackListener { - companion object { - - @JvmField - val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: BookSource, newItem: BookSource): Boolean = - oldItem.bookSourceUrl == newItem.bookSourceUrl - - override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean = - oldItem.bookSourceUrl == newItem.bookSourceUrl - && oldItem.bookSourceName == newItem.bookSourceName - && oldItem.bookSourceGroup == newItem.bookSourceGroup - && oldItem.enabled == newItem.enabled - } - } - override fun onSwiped(adapterPosition: Int) { } override fun onMove(srcPosition: Int, targetPosition: Int): Boolean { - currentList?.let { - val srcSource = it[srcPosition] - val targetSource = it[targetPosition] - srcSource?.let { a -> - targetSource?.let { b -> - a.customOrder = targetPosition - b.customOrder = srcPosition - callBack.update(a, b) - } + val srcItem = getItem(srcPosition) + val targetItem = getItem(targetPosition) + if (srcItem != null && targetItem != null) { + if (srcItem.customOrder == targetItem.customOrder) { + callBack.upOrder() + } else { + val srcOrder = srcItem.customOrder + srcItem.customOrder = targetItem.customOrder + targetItem.customOrder = srcOrder + callBack.update(srcItem, targetItem) } } return true } - override fun onCurrentListChanged( - previousList: PagedList?, - currentList: PagedList? - ) { - super.onCurrentListChanged(previousList, currentList) - callBack.upCount(itemCount) - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { - return MyViewHolder( - LayoutInflater.from(parent.context).inflate( - R.layout.item_book_source, - parent, - false - ) - ) - } - - - override fun onBindViewHolder(holder: MyViewHolder, position: Int) { - getItem(position)?.let { holder.bind(it, callBack) } - } - - - class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { - - fun bind(bookSource: BookSource, callBack: CallBack) = with(itemView) { + override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList) { + with(holder.itemView) { this.setBackgroundColor(context.backgroundColor) - if (bookSource.bookSourceGroup.isNullOrEmpty()) { - cb_book_source.text = bookSource.bookSourceName + if (item.bookSourceGroup.isNullOrEmpty()) { + cb_book_source.text = item.bookSourceName } else { cb_book_source.text = - String.format("%s (%s)", bookSource.bookSourceName, bookSource.bookSourceGroup) + String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup) } - cb_book_source.isChecked = bookSource.enabled + cb_book_source.isChecked = item.enabled cb_book_source.setOnClickListener { - bookSource.enabled = cb_book_source.isChecked - callBack.update(bookSource) + item.enabled = cb_book_source.isChecked + callBack.update(item) } - iv_edit_source.onClick { callBack.edit(bookSource) } - iv_top_source.onClick { callBack.topSource(bookSource) } - iv_del_source.onClick { callBack.del(bookSource) } + iv_edit_source.onClick { callBack.edit(item) } + iv_top_source.onClick { callBack.topSource(item) } + iv_del_source.onClick { callBack.del(item) } } } interface CallBack { - fun upCount(count: Int) fun del(bookSource: BookSource) fun edit(bookSource: BookSource) fun update(vararg bookSource: BookSource) fun topSource(bookSource: BookSource) + fun upOrder() } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/booksource/BookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/booksource/BookSourceViewModel.kt index ab58abc35..605fefce1 100644 --- a/app/src/main/java/io/legado/app/ui/booksource/BookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/booksource/BookSourceViewModel.kt @@ -26,6 +26,16 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) execute { App.db.bookSourceDao().update(*bookSource) } } + fun upOrder() { + execute { + val sources = App.db.bookSourceDao().all + for ((index: Int, source: BookSource) in sources.withIndex()) { + source.customOrder = index + 1 + } + App.db.bookSourceDao().update(*sources.toTypedArray()) + } + } + fun addGroup(group: String) { execute { val sources = App.db.bookSourceDao().noGroup diff --git a/app/src/main/java/io/legado/app/ui/booksource/DiffCallBack.kt b/app/src/main/java/io/legado/app/ui/booksource/DiffCallBack.kt new file mode 100644 index 000000000..90036ba58 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/booksource/DiffCallBack.kt @@ -0,0 +1,43 @@ +package io.legado.app.ui.booksource + +import androidx.recyclerview.widget.DiffUtil +import io.legado.app.data.entities.BookSource + +class DiffCallBack( + private val oldItems: List, + private val newItems: List +) : DiffUtil.Callback() { + + override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + val oldItem = oldItems[oldItemPosition] + val newItem = newItems[newItemPosition] + return oldItem.bookSourceUrl == newItem.bookSourceUrl + } + + override fun getOldListSize(): Int { + return oldItems.size + } + + override fun getNewListSize(): Int { + return newItems.size + } + + override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + val oldItem = oldItems[oldItemPosition] + val newItem = newItems[newItemPosition] + return oldItem.bookSourceName == newItem.bookSourceName + && oldItem.bookSourceGroup == newItem.bookSourceGroup + && oldItem.enabled == newItem.enabled + } + + override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { + val oldItem = oldItems[oldItemPosition] + val newItem = newItems[newItemPosition] + return when { + oldItem.bookSourceName == newItem.bookSourceName + && oldItem.bookSourceGroup == newItem.bookSourceGroup + && oldItem.enabled != newItem.enabled -> 2 + else -> null + } + } +} \ No newline at end of file