parent
1afb68b233
commit
07d4fa66b6
@ -1,34 +0,0 @@ |
|||||||
package io.legado.app.help |
|
||||||
|
|
||||||
import androidx.recyclerview.widget.ListUpdateCallback |
|
||||||
import androidx.recyclerview.widget.RecyclerView |
|
||||||
import io.legado.app.base.adapter.ItemViewHolder |
|
||||||
|
|
||||||
class FirstTopListUpCallback : ListUpdateCallback { |
|
||||||
var firstInsert = -1 |
|
||||||
lateinit var adapter: RecyclerView.Adapter<ItemViewHolder> |
|
||||||
|
|
||||||
override fun onChanged(position: Int, count: Int, payload: Any?) { |
|
||||||
adapter.notifyItemRangeChanged(position, count, payload) |
|
||||||
} |
|
||||||
|
|
||||||
override fun onMoved(fromPosition: Int, toPosition: Int) { |
|
||||||
if (toPosition == 0) { |
|
||||||
firstInsert = 0 |
|
||||||
} |
|
||||||
adapter.notifyItemMoved(fromPosition, toPosition) |
|
||||||
} |
|
||||||
|
|
||||||
override fun onInserted(position: Int, count: Int) { |
|
||||||
if (firstInsert == -1 || firstInsert > position) { |
|
||||||
firstInsert = position |
|
||||||
} |
|
||||||
adapter.notifyItemRangeInserted(position, count) |
|
||||||
} |
|
||||||
|
|
||||||
override fun onRemoved(position: Int, count: Int) { |
|
||||||
adapter.notifyItemRangeRemoved(position, count) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,159 @@ |
|||||||
|
package io.legado.app.ui.widget.recycler |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import android.graphics.Canvas |
||||||
|
import android.graphics.Rect |
||||||
|
import android.graphics.drawable.Drawable |
||||||
|
import android.util.Log |
||||||
|
import android.view.View |
||||||
|
import android.widget.LinearLayout |
||||||
|
import androidx.recyclerview.widget.RecyclerView |
||||||
|
|
||||||
|
/** |
||||||
|
* 不画最后一条分隔线 |
||||||
|
*/ |
||||||
|
class DividerNoLast(context: Context, orientation: Int) : |
||||||
|
RecyclerView.ItemDecoration() { |
||||||
|
|
||||||
|
companion object { |
||||||
|
const val HORIZONTAL = LinearLayout.HORIZONTAL |
||||||
|
const val VERTICAL = LinearLayout.VERTICAL |
||||||
|
} |
||||||
|
|
||||||
|
private val tag = "DividerItem" |
||||||
|
private val attrs = intArrayOf(android.R.attr.listDivider) |
||||||
|
|
||||||
|
private var mDivider: Drawable? = null |
||||||
|
|
||||||
|
/** |
||||||
|
* Current orientation. Either [.HORIZONTAL] or [.VERTICAL]. |
||||||
|
*/ |
||||||
|
private var mOrientation = 0 |
||||||
|
|
||||||
|
private val mBounds = Rect() |
||||||
|
|
||||||
|
init { |
||||||
|
val a = context.obtainStyledAttributes(attrs) |
||||||
|
mDivider = a.getDrawable(0) |
||||||
|
if (mDivider == null) { |
||||||
|
Log.w( |
||||||
|
tag, "@android:attr/listDivider was not set in the theme used for this " |
||||||
|
+ "DividerItemDecoration. Please set that attribute all call setDrawable()" |
||||||
|
) |
||||||
|
} |
||||||
|
a.recycle() |
||||||
|
setOrientation(orientation) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the orientation for this divider. This should be called if |
||||||
|
* [RecyclerView.LayoutManager] changes orientation. |
||||||
|
* |
||||||
|
* @param orientation [.HORIZONTAL] or [.VERTICAL] |
||||||
|
*/ |
||||||
|
fun setOrientation(orientation: Int) { |
||||||
|
require(!(orientation != HORIZONTAL && orientation != VERTICAL)) { "Invalid orientation. It should be either HORIZONTAL or VERTICAL" } |
||||||
|
mOrientation = orientation |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the [Drawable] for this divider. |
||||||
|
* |
||||||
|
* @param drawable Drawable that should be used as a divider. |
||||||
|
*/ |
||||||
|
fun setDrawable(drawable: Drawable) { |
||||||
|
requireNotNull(drawable) { "Drawable cannot be null." } |
||||||
|
mDivider = drawable |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the [Drawable] for this divider. |
||||||
|
*/ |
||||||
|
fun getDrawable(): Drawable? { |
||||||
|
return mDivider |
||||||
|
} |
||||||
|
|
||||||
|
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { |
||||||
|
if (parent.layoutManager == null || mDivider == null) { |
||||||
|
return |
||||||
|
} |
||||||
|
if (mOrientation == VERTICAL) { |
||||||
|
drawVertical(c, parent) |
||||||
|
} else { |
||||||
|
drawHorizontal(c, parent) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private fun drawVertical( |
||||||
|
canvas: Canvas, |
||||||
|
parent: RecyclerView |
||||||
|
) { |
||||||
|
canvas.save() |
||||||
|
val left: Int |
||||||
|
val right: Int |
||||||
|
if (parent.clipToPadding) { |
||||||
|
left = parent.paddingLeft |
||||||
|
right = parent.width - parent.paddingRight |
||||||
|
canvas.clipRect( |
||||||
|
left, parent.paddingTop, right, |
||||||
|
parent.height - parent.paddingBottom |
||||||
|
) |
||||||
|
} else { |
||||||
|
left = 0 |
||||||
|
right = parent.width |
||||||
|
} |
||||||
|
val childCount = parent.childCount |
||||||
|
for (i in 0 until childCount - 1) { |
||||||
|
val child = parent.getChildAt(i) |
||||||
|
parent.getDecoratedBoundsWithMargins(child, mBounds) |
||||||
|
val bottom = mBounds.bottom + Math.round(child.translationY) |
||||||
|
val top = bottom - mDivider!!.intrinsicHeight |
||||||
|
mDivider!!.setBounds(left, top, right, bottom) |
||||||
|
mDivider!!.draw(canvas) |
||||||
|
} |
||||||
|
canvas.restore() |
||||||
|
} |
||||||
|
|
||||||
|
private fun drawHorizontal(canvas: Canvas, parent: RecyclerView) { |
||||||
|
canvas.save() |
||||||
|
val top: Int |
||||||
|
val bottom: Int |
||||||
|
if (parent.clipToPadding) { |
||||||
|
top = parent.paddingTop |
||||||
|
bottom = parent.height - parent.paddingBottom |
||||||
|
canvas.clipRect( |
||||||
|
parent.paddingLeft, top, |
||||||
|
parent.width - parent.paddingRight, bottom |
||||||
|
) |
||||||
|
} else { |
||||||
|
top = 0 |
||||||
|
bottom = parent.height |
||||||
|
} |
||||||
|
val childCount = parent.childCount |
||||||
|
for (i in 0 until childCount - 1) { |
||||||
|
val child = parent.getChildAt(i) |
||||||
|
parent.layoutManager!!.getDecoratedBoundsWithMargins(child, mBounds) |
||||||
|
val right = mBounds.right + Math.round(child.translationX) |
||||||
|
val left = right - mDivider!!.intrinsicWidth |
||||||
|
mDivider!!.setBounds(left, top, right, bottom) |
||||||
|
mDivider!!.draw(canvas) |
||||||
|
} |
||||||
|
canvas.restore() |
||||||
|
} |
||||||
|
|
||||||
|
override fun getItemOffsets( |
||||||
|
outRect: Rect, view: View, parent: RecyclerView, |
||||||
|
state: RecyclerView.State |
||||||
|
) { |
||||||
|
if (mDivider == null) { |
||||||
|
outRect[0, 0, 0] = 0 |
||||||
|
return |
||||||
|
} |
||||||
|
if (mOrientation == VERTICAL) { |
||||||
|
outRect[0, 0, 0] = mDivider!!.intrinsicHeight |
||||||
|
} else { |
||||||
|
outRect[0, 0, mDivider!!.intrinsicWidth] = 0 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,15 +1,16 @@ |
|||||||
package io.legado.app.utils |
package io.legado.app.ui.widget.recycler |
||||||
|
|
||||||
|
import android.content.Context |
||||||
import androidx.core.content.ContextCompat |
import androidx.core.content.ContextCompat |
||||||
import androidx.recyclerview.widget.DividerItemDecoration |
import androidx.recyclerview.widget.DividerItemDecoration |
||||||
import androidx.recyclerview.widget.RecyclerView |
|
||||||
import io.legado.app.R |
import io.legado.app.R |
||||||
|
|
||||||
|
class VerticalDivider(context: Context) : DividerItemDecoration(context, VERTICAL) { |
||||||
|
|
||||||
fun RecyclerView.getVerticalDivider(): DividerItemDecoration { |
init { |
||||||
return DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply { |
|
||||||
ContextCompat.getDrawable(context, R.drawable.ic_divider)?.let { |
ContextCompat.getDrawable(context, R.drawable.ic_divider)?.let { |
||||||
this.setDrawable(it) |
this.setDrawable(it) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
Loading…
Reference in new issue