pull/32/head
gedoor 6 years ago
parent 67aeb9404d
commit 6a07b6544e
  1. 5
      app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt
  2. 127
      app/src/main/java/io/legado/app/help/ItemTouchCallback.kt
  3. 26
      app/src/main/java/io/legado/app/ui/main/booksource/BookSourceAdapter.kt
  4. 10
      app/src/main/java/io/legado/app/ui/main/booksource/BookSourceFragment.kt
  5. 2
      app/src/main/java/io/legado/app/ui/sourceedit/SourceEditActivity.kt
  6. 7
      app/src/main/java/io/legado/app/ui/sourceedit/SourceEditViewModel.kt
  7. 1
      app/src/main/res/layout/item_book_source.xml

@ -7,12 +7,15 @@ import io.legado.app.data.entities.BookSource
@Dao @Dao
interface BookSourceDao { interface BookSourceDao {
@Query("select * from book_sources") @Query("select * from book_sources order by customOrder asc")
fun observeAll(): DataSource.Factory<Int, BookSource> fun observeAll(): DataSource.Factory<Int, BookSource>
@Query("select * from book_sources where origin = :key") @Query("select * from book_sources where origin = :key")
fun findByKey(key:String): BookSource? fun findByKey(key:String): BookSource?
@Query("select count(*) from book_sources")
fun allCount(): Int
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(bookSource: BookSource): Long fun insert(bookSource: BookSource): Long

@ -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
}
}

@ -11,8 +11,12 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.data.entities.BookSource 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 kotlinx.android.synthetic.main.item_book_source.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.*
import kotlin.collections.HashSet
class BookSourceAdapter : PagedListAdapter<BookSource, BookSourceAdapter.MyViewHolder>(DIFF_CALLBACK) { class BookSourceAdapter : PagedListAdapter<BookSource, BookSourceAdapter.MyViewHolder>(DIFF_CALLBACK) {
@ -34,6 +38,27 @@ class BookSourceAdapter : PagedListAdapter<BookSource, BookSourceAdapter.MyViewH
var callBack: CallBack? = null var callBack: CallBack? = null
val checkedList = HashSet<String>() val checkedList = HashSet<String>()
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 { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_book_source, parent, false)) return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_book_source, parent, false))
} }
@ -86,5 +111,6 @@ class BookSourceAdapter : PagedListAdapter<BookSource, BookSourceAdapter.MyViewH
fun del(bookSource: BookSource) fun del(bookSource: BookSource)
fun edit(bookSource: BookSource) fun edit(bookSource: BookSource)
fun update(bookSource: BookSource) fun update(bookSource: BookSource)
fun update(vararg bookSource: BookSource)
} }
} }

@ -9,12 +9,14 @@ import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList import androidx.paging.PagedList
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.App import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseFragment import io.legado.app.base.BaseFragment
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.ItemTouchCallback
import io.legado.app.ui.sourceedit.SourceEditActivity import io.legado.app.ui.sourceedit.SourceEditActivity
import kotlinx.android.synthetic.main.fragment_book_source.* import kotlinx.android.synthetic.main.fragment_book_source.*
import kotlinx.android.synthetic.main.view_titlebar.* import kotlinx.android.synthetic.main.view_titlebar.*
@ -51,6 +53,10 @@ class BookSourceFragment : BaseFragment(R.layout.fragment_book_source), BookSour
adapter = BookSourceAdapter() adapter = BookSourceAdapter()
adapter.callBack = this adapter.callBack = this
recycler_view.adapter = adapter recycler_view.adapter = adapter
val itemTouchCallback = ItemTouchCallback()
itemTouchCallback.onItemTouchCallbackListener = adapter.itemTouchCallbackListener
itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view)
} }
private fun initDataObservers() { private fun initDataObservers() {
@ -67,6 +73,10 @@ class BookSourceFragment : BaseFragment(R.layout.fragment_book_source), BookSour
GlobalScope.launch { App.db.bookSourceDao().update(bookSource) } GlobalScope.launch { App.db.bookSourceDao().update(bookSource) }
} }
override fun update(vararg bookSource: BookSource) {
GlobalScope.launch { App.db.bookSourceDao().update(*bookSource) }
}
override fun edit(bookSource: BookSource) { override fun edit(bookSource: BookSource) {
context?.let { it.startActivity<SourceEditActivity>(Pair("data", bookSource.origin)) } context?.let { it.startActivity<SourceEditActivity>(Pair("data", bookSource.origin)) }
} }

@ -54,7 +54,7 @@ class SourceEditActivity : BaseActivity<SourceEditViewModel>() {
toast("书源名称和URL不能为空") toast("书源名称和URL不能为空")
} else { } else {
GlobalScope.launch { GlobalScope.launch {
App.db.bookSourceDao().insert(bookSource) viewModel.save(bookSource)
GlobalScope.launch(Dispatchers.Main) { finish() } GlobalScope.launch(Dispatchers.Main) { finish() }
} }
} }

@ -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)
}
} }

@ -2,6 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/background"
android:padding="16dp" android:padding="16dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical"> android:gravity="center_vertical">

Loading…
Cancel
Save