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 6a46573a7..ee977b6ff 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 @@ -7,12 +7,15 @@ import io.legado.app.data.entities.BookSource @Dao interface BookSourceDao { - @Query("select * from book_sources") + @Query("select * from book_sources order by customOrder asc") fun observeAll(): DataSource.Factory @Query("select * from book_sources where origin = :key") fun findByKey(key:String): BookSource? + @Query("select count(*) from book_sources") + fun allCount(): Int + @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(bookSource: BookSource): Long diff --git a/app/src/main/java/io/legado/app/help/ItemTouchCallback.kt b/app/src/main/java/io/legado/app/help/ItemTouchCallback.kt new file mode 100644 index 000000000..9cf1fccf5 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/ItemTouchCallback.kt @@ -0,0 +1,127 @@ +package io.legado.app.help + + +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.viewpager.widget.ViewPager + +/** + * Created by GKF on 2018/3/16. + */ + +class ItemTouchCallback : ItemTouchHelper.Callback() { + + private var swipeRefreshLayout: SwipeRefreshLayout? = null + private var viewPager: ViewPager? = null + + /** + * Item操作的回调 + */ + var onItemTouchCallbackListener: OnItemTouchCallbackListener? = null + + /** + * 是否可以拖拽 + */ + var isCanDrag = false + /** + * 是否可以被滑动 + */ + var isCanSwipe = false + + /** + * 当Item被长按的时候是否可以被拖拽 + */ + override fun isLongPressDragEnabled(): Boolean { + return isCanDrag + } + + /** + * Item是否可以被滑动(H:左右滑动,V:上下滑动) + */ + override fun isItemViewSwipeEnabled(): Boolean { + return isCanSwipe + } + + /** + * 当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向 + */ + override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { + val layoutManager = recyclerView.layoutManager + if (layoutManager is GridLayoutManager) {// GridLayoutManager + // flag如果值是0,相当于这个功能被关闭 + val dragFlag = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN + val swipeFlag = 0 + // create make + return makeMovementFlags(dragFlag, swipeFlag) + } else if (layoutManager is LinearLayoutManager) {// linearLayoutManager + val linearLayoutManager = layoutManager as LinearLayoutManager? + val orientation = linearLayoutManager!!.orientation + + var dragFlag = 0 + var swipeFlag = 0 + + // 为了方便理解,相当于分为横着的ListView和竖着的ListView + if (orientation == LinearLayoutManager.HORIZONTAL) {// 如果是横向的布局 + swipeFlag = ItemTouchHelper.UP or ItemTouchHelper.DOWN + dragFlag = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT + } else if (orientation == LinearLayoutManager.VERTICAL) {// 如果是竖向的布局,相当于ListView + dragFlag = ItemTouchHelper.UP or ItemTouchHelper.DOWN + swipeFlag = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT + } + return makeMovementFlags(dragFlag, swipeFlag) + } + return 0 + } + + /** + * 当Item被拖拽的时候被回调 + * + * @param recyclerView recyclerView + * @param srcViewHolder 拖拽的ViewHolder + * @param targetViewHolder 目的地的viewHolder + */ + override fun onMove( + recyclerView: RecyclerView, + srcViewHolder: RecyclerView.ViewHolder, + targetViewHolder: RecyclerView.ViewHolder + ): Boolean { + onItemTouchCallbackListener?.let { + return it.onMove(srcViewHolder.adapterPosition, targetViewHolder.adapterPosition) + } + return false + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + onItemTouchCallbackListener?.let { + return it.onSwiped(viewHolder.adapterPosition) + } + } + + override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { + super.onSelectedChanged(viewHolder, actionState) + val swiping = actionState == ItemTouchHelper.ACTION_STATE_DRAG + swipeRefreshLayout?.isEnabled = !swiping + viewPager?.requestDisallowInterceptTouchEvent(swiping) + } + + interface OnItemTouchCallbackListener { + /** + * 当某个Item被滑动删除的时候 + * + * @param adapterPosition item的position + */ + fun onSwiped(adapterPosition: Int) + + /** + * 当两个Item位置互换的时候被回调 + * + * @param srcPosition 拖拽的item的position + * @param targetPosition 目的地的Item的position + * @return 开发者处理了操作应该返回true,开发者没有处理就返回false + */ + fun onMove(srcPosition: Int, targetPosition: Int): Boolean + } +} diff --git a/app/src/main/java/io/legado/app/ui/main/booksource/BookSourceAdapter.kt b/app/src/main/java/io/legado/app/ui/main/booksource/BookSourceAdapter.kt index 01d64fcca..6f468b563 100644 --- a/app/src/main/java/io/legado/app/ui/main/booksource/BookSourceAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/main/booksource/BookSourceAdapter.kt @@ -11,8 +11,12 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.data.entities.BookSource +import io.legado.app.help.ItemTouchCallback +import io.legado.app.help.ItemTouchCallback.OnItemTouchCallbackListener import kotlinx.android.synthetic.main.item_book_source.view.* import org.jetbrains.anko.sdk27.listeners.onClick +import java.util.* +import kotlin.collections.HashSet class BookSourceAdapter : PagedListAdapter(DIFF_CALLBACK) { @@ -34,6 +38,27 @@ class BookSourceAdapter : PagedListAdapter() + val itemTouchCallbackListener = object : OnItemTouchCallbackListener { + 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) + } + } + } + return true + } + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_book_source, parent, false)) } @@ -86,5 +111,6 @@ class BookSourceAdapter : PagedListAdapter(Pair("data", bookSource.origin)) } } diff --git a/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditActivity.kt index ef6f4e14b..178f0fc68 100644 --- a/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditActivity.kt @@ -54,7 +54,7 @@ class SourceEditActivity : BaseActivity() { toast("书源名称和URL不能为空") } else { GlobalScope.launch { - App.db.bookSourceDao().insert(bookSource) + viewModel.save(bookSource) GlobalScope.launch(Dispatchers.Main) { finish() } } } diff --git a/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditViewModel.kt index 1ec3a5258..ed90408f9 100644 --- a/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/sourceedit/SourceEditViewModel.kt @@ -20,6 +20,13 @@ class SourceEditViewModel(application: Application) : AndroidViewModel(applicati } } + fun save(bookSource: BookSource) { + val source = App.db.bookSourceDao().findByKey(bookSource.origin) + if (source == null) { + bookSource.customOrder = App.db.bookSourceDao().allCount() + } + App.db.bookSourceDao().insert(bookSource) + } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_book_source.xml b/app/src/main/res/layout/item_book_source.xml index b6a58c7ef..1958e1759 100644 --- a/app/src/main/res/layout/item_book_source.xml +++ b/app/src/main/res/layout/item_book_source.xml @@ -2,6 +2,7 @@