先看效果圖
- IMG_2494.PNG
- IMG_2495.PNG
需求
- 類似微博九宮圖一樣违帆,單張圖片顯示比例(此處具體先省略)
- 2張圖和4張圖片顯示 格子列數(shù)為4宮格
需要的庫
com.github.bumptech.glide:glide:4.9.0
com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.44
大概思路
- 數(shù)據(jù)請求 省略(我用的酷安的數(shù)據(jù)熱門評論接口)
- 根據(jù)評論中圖片數(shù)據(jù)設(shè)置圖片
RecyclerView
等SpanCount
描扯,每一條評論都含有一個展示圖片的RecycleView
,再設(shè)置ItemDecoration
- 對不同的圖片個數(shù)的
ViewHolder
設(shè)置不同的type
上代碼
CmsStyleCommentNormalViewHolder
:類中
if (!TextUtils.isEmpty(dateItem.pic) && dateItem.picArr != null) {
val nineImageList = arrayListOf<NineImageBean>()
var spanCount = 0
dateItem.picArr?.let { it1 ->
spanCount = if (it1.size == 1) {
1
} else if (it1.size == 2 || it1.size == 4) {
2
} else {
3
}
it1.forEachIndexed { index, s ->
nineImageList.add(NineImageBean().apply {
this.isGif = StringUtils.isGifUrl(s)
this.url = s
this.positionAdapter = index
if (spanCount == 1) {
this.type = NineImageBean.LargeImageType
} else {
this.type = NineImageBean.SmallImageType
}
})
}
}
val cmsChildImageNineAdapter: CmsChildImageNineAdapter
val adapterTag = nineImageRv.tag
if (adapterTag is CmsChildImageNineAdapter) {
cmsChildImageNineAdapter = adapterTag
} else {
cmsChildImageNineAdapter = CmsChildImageNineAdapter(ArrayList())
nineImageRv.apply {
cmsChildImageNineAdapter.bindToRecyclerView(this)
this.isNestedScrollingEnabled = false
this.setHasFixedSize(true)
this.tag = cmsChildImageNineAdapter
}
cmsChildImageNineAdapter.setOnItemClickListener { adapter, _, position ->
val pictureBeanList = ArrayList<PictureBean>()
for (item in adapter.data) {
if (item is NineImageBean) {
pictureBeanList.add(PictureBean().apply {
this.originalUrl = item.url
})
}
}
if (pictureBeanList.isNotEmpty()) {
LaunchNormalUtils.startPictureActivity(mContext, pictureBeanList, position)
}
}
}
nineImageRv.apply {
this.layoutParams.width = if (spanCount == 4 || spanCount == 2) {
singleImageWidth.toInt() * 2
} else if (spanCount == 1) {
ViewGroup.LayoutParams.WRAP_CONTENT
} else {
ViewGroup.LayoutParams.MATCH_PARENT
}
for (i in 0 until this.itemDecorationCount) {
this.removeItemDecorationAt(i)
}
this.layoutManager = GridLayoutManager(mContext, spanCount)
this.addItemDecoration(RecyclerViewItemDividerHelper.getNineImageAdapterDividerItem(mContext, spanCount, this, 16f))
}
cmsChildImageNineAdapter.setNewData(nineImageList)
nineImageRv.visibility = View.VISIBLE
} else {
nineImageRv.visibility = View.GONE
}
}
- 上面代碼位于一個評論ViewHolder類
- CmsChildImageNineAdapter:
class CmsChildImageNineAdapter(data: MutableList<NineImageBean>?): BaseMultiItemQuickAdapter<NineImageBean, BaseViewHolder>(data) {
init {
addItemType(NineImageBean.emptyType, R.layout.item_multi_not_found)
addItemType(NineImageBean.SmallImageType, R.layout.item_multi_nine_image_small)
addItemType(NineImageBean.LargeImageType, R.layout.item_multi_nine_image_large)
}
override fun convert(helper: BaseViewHolder, item: NineImageBean) {
var associatedObject = helper.associatedObject
when (item.itemType) {
NineImageBean.SmallImageType -> {
if (associatedObject == null) {
associatedObject = NineSmallViewHolder(mContext, helper)
helper.associatedObject = associatedObject
}
if (associatedObject is NineSmallViewHolder) {
associatedObject.updateView(item)
}
}
NineImageBean.LargeImageType -> {
if (associatedObject == null) {
associatedObject = NineLargeViewHolder(mContext, helper)
helper.associatedObject = associatedObject
}
if (associatedObject is NineLargeViewHolder) {
associatedObject.updateView(item)
}
}
}
}
-
NineSmallViewHolder
:
class NineSmallViewHolder(val mContext: Context, val baseViewHolder: BaseViewHolder) : IBaseViewMultiHolder<NineImageBean>(baseViewHolder.itemView) {
private val smallImageIv: CustomGifImageView = itemView.findViewById(R.id.small_image_iv)
private val smallGifFlagRtv: RoundTextView = itemView.findViewById(R.id.small_gif_flag_rtv)
private var gifHandler: GifHandler? = null
private inner class ParamTag {
var isFirstFrame = true
var isAlwaysPlayerGif = true
}
override fun updateView(dateItem: NineImageBean) {
super.updateView(dateItem)
smallImageIv.apply {
if (dateItem.isGif && !this.isGifRunning()) {
smallGifFlagRtv.visibility = View.VISIBLE
} else {
smallGifFlagRtv.visibility = View.GONE
}
if (!dateItem.isGif) {
loadNormalImage(dateItem)
} else {
if (!this.isGifRunning()) {
loadGifImage(ParamTag().apply {
this.isFirstFrame = true
})
}
}
}
}
private fun loadNormalImage(dateItem: NineImageBean) {
ImageLoader.Builder(mContext)
.getRequestManager()
.asBitmap()
.load(dateItem.url)
.apply(ImageLoader.defaultRequestOptions(R.color.placeholder_color))
.into(smallImageIv)
}
- 我粘貼的事項目中代碼涯贞,我也懶得刪除了,所以
CustomGifImageView
就用imageview
就行,也不用判斷GIF加載什么的贷洲,就gilde直接加載就OK -
NineLargeViewHolder
:
class NineLargeViewHolder(val mContext: Context, val baseViewHolder: BaseViewHolder) : IBaseViewMultiHolder<NineImageBean>(baseViewHolder.itemView) {
private val largeIv: MatrixScaleImageView = itemView.findViewById(R.id.large_iv)
private val largeFlagRtv: RoundTextView = itemView.findViewById(R.id.large_flag_rtv)
private val gifFlagRtv: RoundTextView = itemView.findViewById(R.id.gif_flag_rtv)
override fun updateView(dateItem: NineImageBean) {
super.updateView(dateItem)
largeFlagRtv.visibility = View.GONE
gifFlagRtv.visibility = View.GONE
dateItem.picImageSize?.apply {
val matrixScaleHelper = MatrixScaleHelper(this[0].toFloat(), this[1].toFloat())
largeIv.apply {
gifFlagRtv.visibility = if (dateItem.isGif && !this.isGifRunning()) {
View.VISIBLE
} else {
View.GONE
}
largeFlagRtv.visibility = if (matrixScaleHelper.isLongBitmap && !dateItem.isGif) {
View.VISIBLE
} else {
View.GONE
}
if (!dateItem.isGif) {
loadNormalImage()
} else {
if (!this.isGifRunning()) {
loadGifImage(true)
}
}
}
}
}
override fun changeTheme(theme: Theme) {
super.changeTheme(theme)
largeFlagRtv.setBackgroundColor(ColorUtils.getThemeColor(mContext, R.attr.colorAccent))
gifFlagRtv.setBackgroundColor(ColorUtils.getThemeColor(mContext, R.attr.colorAccent))
}
fun startPlayerGif() {
val nineImageBean = getItemTagDate() as? NineImageBean ?: return
if (nineImageBean.isGif) {
loadGifImage(false)
}
}
fun stopPlayerGif() {
val nineImageBean = getItemTagDate() as? NineImageBean ?: return
if (nineImageBean.isGif) {
loadGifImage(true)
}
}
private fun loadNormalImage() {
val nineImageBean = getItemTagDate()
if (nineImageBean is NineImageBean) {
val picImageSize = nineImageBean.picImageSize ?: return
val matrixScaleHelper = MatrixScaleHelper(picImageSize[0].toFloat(), picImageSize[1].toFloat())
ImageLoader.Builder(mContext, nineImageBean.url)
.setTransition(ImageLoader.defaultTransitionOptions())
.setRequestOptions(ImageLoader.defaultRequestOptions(R.color.placeholder_color)
.transform(matrixScaleHelper.getCropTransformation(largeIv)))
.build(largeIv)
}
}
- GIF 代碼我就不粘貼了盏筐,其中一部分围俘,這個viewHolder比較特殊,一問微博中單個圖片比較特殊琢融,是有比例顯示的界牡,大長圖顯示上半部分,普通圖片等比例縮放,
MatrixScaleHelper
類就是一個等比縮放類 - 粘貼的是部分代碼和思路漾抬,全部代碼整理起來比較麻煩宿亡,實現(xiàn)效果比較多
- 后面會陸續(xù)貼出來實現(xiàn)微博九宮圖 GIF圖片依次播放,還有單張圖片等比縮放纳令,以及換膚(不重啟應(yīng)用)過程中RecycleView的處理
最后看一樣我實現(xiàn)的效果圖吧
Screenshot_20190225-163519.png
Screenshot_20190225-163534.png
Screenshot_20190225-163557.png
Screenshot_20190225-163649.png