diff --git a/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt new file mode 100644 index 000000000..c9b9f0cf2 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt @@ -0,0 +1,398 @@ +package io.legado.app.base.adapter + +import android.content.Context +import android.util.SparseArray +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import java.util.* + + +/** + * Created by Invincible on 2017/11/24. + * + * 通用的adapter 可添加header,footer,以及不同类型item + */ +abstract class CommonRecyclerAdapter(protected val context: Context) : RecyclerView.Adapter() { + + constructor(context: Context, vararg delegates: Pair>) : this(context) { + addItemViewDelegates(*delegates) + } + + constructor(context: Context, vararg delegates: ItemViewDelegate) : this(context) { + addItemViewDelegates(*delegates) + } + + private val inflater: LayoutInflater = LayoutInflater.from(context) + + private var headerItems: SparseArray? = null + private var footerItems: SparseArray? = null + + private val itemDelegates: HashMap> = hashMapOf() + private val items: MutableList = mutableListOf() + + private val lock = Object() + + private var itemClickListener: ((holder: ItemViewHolder, item: ITEM) -> Unit)? = null + private var itemLongClickListener: ((holder: ItemViewHolder, item: ITEM) -> Boolean)? = null + + private var itemAnimation: ItemAnimation? = null + + fun setOnItemClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Unit) { + itemClickListener = listener + } + + fun setOnItemLongClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Boolean) { + itemLongClickListener = listener + } + + fun bindToRecyclerView(recyclerView: RecyclerView) { + recyclerView.adapter = this + } + + fun > addItemViewDelegate(viewType: Int, delegate: DELEGATE) { + itemDelegates.put(viewType, delegate) + } + + fun > addItemViewDelegate(delegate: DELEGATE) { + itemDelegates.put(itemDelegates.size, delegate) + } + + fun > addItemViewDelegates(vararg delegates: DELEGATE) { + delegates.forEach { + addItemViewDelegate(it) + } + } + + fun addItemViewDelegates(vararg delegates: Pair>) { + delegates.forEach { + addItemViewDelegate(it.first, it.second) + } + } + + fun addHeaderView(header: View) { + synchronized(lock) { + if (headerItems == null) { + headerItems = SparseArray() + } + headerItems?.let { + val index = it.size() + it.put(TYPE_HEADER_VIEW + it.size(), header) + notifyItemInserted(index) + } + } + } + + fun addFooterView(footer: View) { + synchronized(lock) { + if (footerItems == null) { + footerItems = SparseArray() + } + footerItems?.let { + val index = getActualItemCount() + it.size() + it.put(TYPE_FOOTER_VIEW + it.size(), footer) + notifyItemInserted(index) + } + } + } + + fun removeHeaderView(header: View) { + synchronized(lock) { + headerItems?.let { + val index = it.indexOfValue(header) + if (index >= 0) { + it.remove(index) + notifyItemRemoved(index) + } + } + } + } + + fun removeFooterView(footer: View) { + synchronized(lock) { + footerItems?.let { + val index = it.indexOfValue(footer) + if (index >= 0) { + it.remove(index) + notifyItemRemoved(getActualItemCount() + index - 2) + } + } + } + } + + fun setItems(items: List?) { + synchronized(lock) { + if (this.items.isNotEmpty()) { + this.items.clear() + } + if (items != null) { + this.items.addAll(items) + } + notifyDataSetChanged() + } + } + + fun setItem(position: Int, item: ITEM) { + synchronized(lock) { + val oldSize = getActualItemCount() + if (position in 0 until oldSize) { + this.items[position] = item + notifyItemChanged(position + getHeaderCount()) + } + } + } + + fun addItem(item: ITEM) { + synchronized(lock) { + val oldSize = getActualItemCount() + if (this.items.add(item)) { + if (oldSize == 0) { + notifyDataSetChanged() + } else { + notifyItemInserted(oldSize + getHeaderCount()) + } + } + } + } + + fun addItems(position: Int, newItems: List) { + synchronized(lock) { + val oldSize = getActualItemCount() + if (position in 0 until oldSize) { + if (if (oldSize == 0) this.items.addAll(newItems) else this.items.addAll(position, newItems)) { + if (oldSize == 0) { + notifyDataSetChanged() + } else { + notifyItemRangeChanged(position + getHeaderCount(), newItems.size) + } + } + } + } + } + + fun addItems(newItems: List) { + synchronized(lock) { + val oldSize = getActualItemCount() + if (this.items.addAll(newItems)) { + if (oldSize == 0) { + notifyDataSetChanged() + } else { + notifyItemRangeChanged(oldSize + getHeaderCount(), newItems.size) + } + } + } + } + + fun removeItem(position: Int) { + synchronized(lock) { + if (this.items.removeAt(position) != null) + notifyItemRemoved(position + getHeaderCount()) + } + } + + fun removeItem(item: ITEM) { + synchronized(lock) { + if (this.items.remove(item)) + notifyItemRemoved(this.items.indexOf(item) + getHeaderCount()) + } + } + + fun removeItems(items: List) { + synchronized(lock) { + if (this.items.removeAll(items)) + notifyDataSetChanged() + } + } + + fun swapItem(oldPosition: Int, newPosition: Int) { + synchronized(lock) { + val size = getActualItemCount() + if (oldPosition in 0 until size && newPosition in 0 until size) { + Collections.swap(this.items, oldPosition + getHeaderCount(), newPosition + getHeaderCount()) + notifyDataSetChanged() + } + } + } + + fun updateItem(position: Int, payload: Any) { + synchronized(lock) { + val size = getActualItemCount() + if (position in 0 until size) { + notifyItemChanged(position + getHeaderCount(), payload) + } + } + } + + fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) { + synchronized(lock) { + val size = getActualItemCount() + if (fromPosition in 0 until size && toPosition in 0 until size) { + notifyItemRangeChanged(fromPosition + getHeaderCount(), toPosition - fromPosition + 1, payloads) + } + } + } + + fun isEmpty(): Boolean { + return items.isEmpty() + } + + fun isNotEmpty(): Boolean { + return items.isNotEmpty() + } + + /** + * 除去header和footer + */ + fun getActualItemCount(): Int { + return items.size + } + + fun getHeaderCount(): Int { + return headerItems?.size() ?: 0 + } + + fun getFooterCount(): Int { + return footerItems?.size() ?: 0 + } + + fun getItem(position: Int): ITEM = items[position % items.size] + + fun getItems(): List = items + + protected open fun getItemViewType(item: ITEM, position: Int): Int { + return 0 + } + + /** + * grid 模式下使用 + */ + protected open fun getSpanSize(item: ITEM, viewType: Int, position: Int): Int { + return 1 + } + + final override fun getItemCount(): Int { + return getActualItemCount() + getHeaderCount() + getFooterCount() + } + + final override fun getItemViewType(position: Int): Int { + return when { + isHeader(position) -> TYPE_HEADER_VIEW + position + isFooter(position) -> TYPE_FOOTER_VIEW + position - getActualItemCount() - getHeaderCount() + else -> getItemViewType(getItem(getRealPosition(position)), getRealPosition(position)) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + return when { + viewType < TYPE_HEADER_VIEW + getHeaderCount() -> { + ItemViewHolder(headerItems!!.get(viewType)) + } + + viewType >= TYPE_FOOTER_VIEW -> { + ItemViewHolder(footerItems!!.get(viewType)) + } + + else -> { + val holder = ItemViewHolder(inflater.inflate(itemDelegates.getValue(viewType).layoutID, parent, false)) + + if (itemClickListener != null) { + holder.itemView.setOnClickListener { + itemClickListener!!.invoke(holder, getItem(holder.layoutPosition)) + } + } + + if (itemLongClickListener != null) { + holder.itemView.setOnLongClickListener { + itemLongClickListener!!.invoke(holder, getItem(holder.layoutPosition)) + } + } + + holder + } + } + } + + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + onBindViewHolder(holder, position, mutableListOf()) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int, payloads: MutableList) { + if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) { + itemDelegates.getValue(getItemViewType(holder.layoutPosition)) + .convert(holder, getItem(holder.layoutPosition), payloads) + } + } + + override fun onViewAttachedToWindow(holder: ItemViewHolder) { + super.onViewAttachedToWindow(holder) + if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) { + addAnimation(holder) + } + } + + override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { + super.onAttachedToRecyclerView(recyclerView) + val manager = recyclerView.layoutManager + if (manager is GridLayoutManager) { + manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + return if (isHeader(position) || isFooter(position)) manager.spanCount else getSpanSize( + getItem(position), getItemViewType(position), position + ) + } + } + } + } + + fun setAnimationConfig(item: ItemAnimation) { + itemAnimation = item + } + + private fun isHeader(position: Int): Boolean { + return position < getHeaderCount() + } + + private fun isFooter(position: Int): Boolean { + return position >= getActualItemCount() + getHeaderCount() + } + + private fun getRealPosition(position: Int): Int { + return position - getHeaderCount() + } + + private fun addAnimation(holder: ItemViewHolder) { + if (itemAnimation == null) { + itemAnimation = ItemAnimation.create().enabled(true) + } + + itemAnimation?.let { + if (it.itemAnimEnabled) { + if (!it.itemAnimFirstOnly || holder.layoutPosition > it.itemAnimStartPosition) { + startAnimation(holder, it) + it.itemAnimStartPosition = holder.layoutPosition + } + } + } + } + + + protected open fun startAnimation(holder: ItemViewHolder, item: ItemAnimation) { + for (anim in item.itemAnimation.getAnimators(holder.itemView)) { + anim.setDuration(item.itemAnimDuration).start() + anim.interpolator = item.itemAnimInterpolator + } + } + + companion object { + private const val TYPE_HEADER_VIEW = Int.MIN_VALUE + private const val TYPE_FOOTER_VIEW = Int.MAX_VALUE - 999 + } + +} + + + + diff --git a/app/src/main/java/io/legado/app/base/adapter/ItemAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/ItemAnimation.kt new file mode 100644 index 000000000..9e6f20c61 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/ItemAnimation.kt @@ -0,0 +1,91 @@ +package io.legado.app.base.adapter + +import android.view.animation.Interpolator +import android.view.animation.LinearInterpolator +import io.legado.app.base.adapter.animations.AlphaInAnimation +import io.legado.app.base.adapter.animations.BaseAnimation +import io.legado.app.base.animations.ScaleInAnimation +import io.legado.app.base.adapter.animations.SlideInBottomAnimation +import io.legado.app.base.adapter.animations.SlideInLeftAnimation +import io.legado.app.base.adapter.animations.SlideInRightAnimation + +/** + * Created by Invincible on 2017/12/15. + */ +class ItemAnimation private constructor() { + + var itemAnimEnabled = false + var itemAnimFirstOnly = true + var itemAnimation: BaseAnimation = SlideInBottomAnimation() + var itemAnimInterpolator: Interpolator = LinearInterpolator() + var itemAnimDuration: Long = 300L + var itemAnimStartPosition: Int = -1 + + fun interpolator(interpolator: Interpolator): ItemAnimation { + itemAnimInterpolator = interpolator + return this + } + + fun duration(duration: Long): ItemAnimation { + itemAnimDuration = duration + return this + } + + fun startPostion(startPos: Int): ItemAnimation { + itemAnimStartPosition = startPos + return this + } + + fun animation(animationType: Int = FADE_IN, animation: BaseAnimation? = null): ItemAnimation { + if (animation != null) { + itemAnimation = animation + } else { + when (animationType) { + FADE_IN -> itemAnimation = AlphaInAnimation() + SCALE_IN -> itemAnimation = ScaleInAnimation() + BOTTOM_SLIDE_IN -> itemAnimation = SlideInBottomAnimation() + LEFT_SLIDE_IN -> itemAnimation = SlideInLeftAnimation() + RIGHT_SLIDE_IN -> itemAnimation = SlideInRightAnimation() + } + } + return this + } + + fun enabled(enabled: Boolean): ItemAnimation { + itemAnimEnabled = enabled + return this + } + + fun firstOnly(firstOnly: Boolean): ItemAnimation { + itemAnimFirstOnly = firstOnly + return this + } + + companion object { + + /** + * Use with [.openLoadAnimation] + */ + const val FADE_IN: Int = 0x00000001 + /** + * Use with [.openLoadAnimation] + */ + const val SCALE_IN: Int = 0x00000002 + /** + * Use with [.openLoadAnimation] + */ + const val BOTTOM_SLIDE_IN: Int = 0x00000003 + /** + * Use with [.openLoadAnimation] + */ + const val LEFT_SLIDE_IN: Int = 0x00000004 + /** + * Use with [.openLoadAnimation] + */ + const val RIGHT_SLIDE_IN: Int = 0x00000005 + + fun create(): ItemAnimation { + return ItemAnimation() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/base/adapter/ItemViewDelegate.kt b/app/src/main/java/io/legado/app/base/adapter/ItemViewDelegate.kt new file mode 100644 index 000000000..789ca250e --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/ItemViewDelegate.kt @@ -0,0 +1,16 @@ +package io.legado.app.base.adapter + +import android.content.Context + +/** + * Created by Invincible on 2017/11/24. + * + * item代理, + */ +abstract class ItemViewDelegate(protected val context: Context) { + + abstract val layoutID: Int + + abstract fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList) + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/base/adapter/ItemViewHolder.kt b/app/src/main/java/io/legado/app/base/adapter/ItemViewHolder.kt new file mode 100644 index 000000000..c415fa4b6 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/ItemViewHolder.kt @@ -0,0 +1,9 @@ +package io.legado.app.base.adapter + +import android.view.View +import androidx.recyclerview.widget.RecyclerView + +/** + * Created by Invincible on 2017/11/28. + */ +class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/base/adapter/SimpleRecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/SimpleRecyclerAdapter.kt new file mode 100644 index 000000000..176098f50 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/SimpleRecyclerAdapter.kt @@ -0,0 +1,26 @@ +package io.legado.app.base.adapter + +import android.content.Context + +/** + * Created by Invincible on 2017/12/15. + */ +abstract class SimpleRecyclerAdapter(context: Context) : CommonRecyclerAdapter(context) { + + init { + addItemViewDelegate(object : ItemViewDelegate(context) { + override val layoutID: Int + get() = this@SimpleRecyclerAdapter.layoutID + + override fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList) { + this@SimpleRecyclerAdapter.convert(holder, item, payloads) + } + + }) + + } + + abstract val layoutID: Int + + abstract fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList) +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/base/adapter/animations/AlphaInAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/animations/AlphaInAnimation.kt new file mode 100644 index 000000000..b307300a3 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/animations/AlphaInAnimation.kt @@ -0,0 +1,17 @@ +package io.legado.app.base.adapter.animations + +import android.animation.Animator +import android.animation.ObjectAnimator +import android.view.View + + +class AlphaInAnimation @JvmOverloads constructor(private val mFrom: Float = DEFAULT_ALPHA_FROM) : BaseAnimation { + + override fun getAnimators(view: View): Array = + arrayOf(ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f)) + + companion object { + + private const val DEFAULT_ALPHA_FROM = 0f + } +} diff --git a/app/src/main/java/io/legado/app/base/adapter/animations/BaseAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/animations/BaseAnimation.kt new file mode 100644 index 000000000..735ceca57 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/animations/BaseAnimation.kt @@ -0,0 +1,13 @@ +package io.legado.app.base.adapter.animations + +import android.animation.Animator +import android.view.View + +/** + * adapter item 动画 + */ +interface BaseAnimation { + + fun getAnimators(view: View): Array + +} diff --git a/app/src/main/java/io/legado/app/base/adapter/animations/ScaleInAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/animations/ScaleInAnimation.kt new file mode 100644 index 000000000..3f73e7a3c --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/animations/ScaleInAnimation.kt @@ -0,0 +1,21 @@ +package io.legado.app.base.animations + +import android.animation.Animator +import android.animation.ObjectAnimator +import android.view.View +import io.legado.app.base.adapter.animations.BaseAnimation + + +class ScaleInAnimation @JvmOverloads constructor(private val mFrom: Float = DEFAULT_SCALE_FROM) : BaseAnimation { + + override fun getAnimators(view: View): Array { + val scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f) + val scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f) + return arrayOf(scaleX, scaleY) + } + + companion object { + + private const val DEFAULT_SCALE_FROM = .5f + } +} diff --git a/app/src/main/java/io/legado/app/base/adapter/animations/SlideInBottomAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/animations/SlideInBottomAnimation.kt new file mode 100644 index 000000000..0fd2bfde6 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/animations/SlideInBottomAnimation.kt @@ -0,0 +1,13 @@ +package io.legado.app.base.adapter.animations + +import android.animation.Animator +import android.animation.ObjectAnimator +import android.view.View +import io.legado.app.base.adapter.animations.BaseAnimation + +class SlideInBottomAnimation : BaseAnimation { + + + override fun getAnimators(view: View): Array = + arrayOf(ObjectAnimator.ofFloat(view, "translationY", view.measuredHeight.toFloat(), 0f)) +} diff --git a/app/src/main/java/io/legado/app/base/adapter/animations/SlideInLeftAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/animations/SlideInLeftAnimation.kt new file mode 100644 index 000000000..daa6f17a1 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/animations/SlideInLeftAnimation.kt @@ -0,0 +1,14 @@ +package io.legado.app.base.adapter.animations + +import android.animation.Animator +import android.animation.ObjectAnimator +import android.view.View +import io.legado.app.base.adapter.animations.BaseAnimation + + +class SlideInLeftAnimation : BaseAnimation { + + + override fun getAnimators(view: View): Array = + arrayOf(ObjectAnimator.ofFloat(view, "translationX", -view.rootView.width.toFloat(), 0f)) +} diff --git a/app/src/main/java/io/legado/app/base/adapter/animations/SlideInRightAnimation.kt b/app/src/main/java/io/legado/app/base/adapter/animations/SlideInRightAnimation.kt new file mode 100644 index 000000000..71c8feac7 --- /dev/null +++ b/app/src/main/java/io/legado/app/base/adapter/animations/SlideInRightAnimation.kt @@ -0,0 +1,14 @@ +package io.legado.app.base.adapter.animations + +import android.animation.Animator +import android.animation.ObjectAnimator +import android.view.View +import io.legado.app.base.adapter.animations.BaseAnimation + + +class SlideInRightAnimation : BaseAnimation { + + + override fun getAnimators(view: View): Array = + arrayOf(ObjectAnimator.ofFloat(view, "translationX", view.rootView.width.toFloat(), 0f)) +} diff --git a/app/src/main/java/io/legado/app/help/LayoutManager.kt b/app/src/main/java/io/legado/app/help/LayoutManager.kt index 9fc551222..e633993c7 100644 --- a/app/src/main/java/io/legado/app/help/LayoutManager.kt +++ b/app/src/main/java/io/legado/app/help/LayoutManager.kt @@ -6,7 +6,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.StaggeredGridLayoutManager -class LayoutManager private constructor() { +object LayoutManager { interface LayoutManagerFactory { fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager @@ -16,50 +16,46 @@ class LayoutManager private constructor() { @Retention(AnnotationRetention.SOURCE) annotation class Orientation - companion object { - - - fun linear(): LayoutManagerFactory { - return object : LayoutManagerFactory { - override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { - return LinearLayoutManager(recyclerView.context) - } + fun linear(): LayoutManagerFactory { + return object : LayoutManagerFactory { + override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { + return LinearLayoutManager(recyclerView.context) } } + } - fun linear(@Orientation orientation: Int, reverseLayout: Boolean): LayoutManagerFactory { - return object : LayoutManagerFactory { - override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { - return LinearLayoutManager(recyclerView.context, orientation, reverseLayout) - } + fun linear(@Orientation orientation: Int, reverseLayout: Boolean): LayoutManagerFactory { + return object : LayoutManagerFactory { + override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { + return LinearLayoutManager(recyclerView.context, orientation, reverseLayout) } } + } - fun grid(spanCount: Int): LayoutManagerFactory { - return object : LayoutManagerFactory { - override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { - return GridLayoutManager(recyclerView.context, spanCount) - } + fun grid(spanCount: Int): LayoutManagerFactory { + return object : LayoutManagerFactory { + override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { + return GridLayoutManager(recyclerView.context, spanCount) } } + } - fun grid(spanCount: Int, @Orientation orientation: Int, reverseLayout: Boolean): LayoutManagerFactory { - return object : LayoutManagerFactory { - override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { - return GridLayoutManager(recyclerView.context, spanCount, orientation, reverseLayout) - } + fun grid(spanCount: Int, @Orientation orientation: Int, reverseLayout: Boolean): LayoutManagerFactory { + return object : LayoutManagerFactory { + override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { + return GridLayoutManager(recyclerView.context, spanCount, orientation, reverseLayout) } } + } - fun staggeredGrid(spanCount: Int, @Orientation orientation: Int): LayoutManagerFactory { - return object : LayoutManagerFactory { - override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { - return StaggeredGridLayoutManager(spanCount, orientation) - } + fun staggeredGrid(spanCount: Int, @Orientation orientation: Int): LayoutManagerFactory { + return object : LayoutManagerFactory { + override fun create(recyclerView: RecyclerView): RecyclerView.LayoutManager { + return StaggeredGridLayoutManager(spanCount, orientation) } } } diff --git a/app/src/main/java/io/legado/app/ui/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/search/SearchActivity.kt index 2d4f64ba2..33be6236f 100644 --- a/app/src/main/java/io/legado/app/ui/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/search/SearchActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import androidx.lifecycle.ViewModelProvider import io.legado.app.R import io.legado.app.base.BaseActivity +import io.legado.app.help.LayoutManager class SearchActivity : BaseActivity() { @@ -15,7 +16,6 @@ class SearchActivity : BaseActivity() { override fun onViewModelCreated(viewModel: SearchViewModel, savedInstanceState: Bundle?) { - } }