前言
需求做一个Android 本地海报分享图 ,使用viewPager+RecyclerView 联动 选择
一:需求
利用网络图片生成带个人信息的二维码海报分享图片
二:技术
使用横向RecyclerView+RecyclerView 联动
三: 难点
初看 项目需求,容易使用ViewPager+RecyclerView 去实现,
但是在使用过程中 这种方案容易出现 图片保存重复。
四:具体代码如下
1.布局如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/blur_bg"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/black_2626"
android:scaleType="matrix"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="0dp"
android:layout_height="@dimen/tab_bar_height"
android:background="@color/transparent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="6dp"
android:padding="9dp"
android:src="@drawable/icon_white_back" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="推荐有礼"
android:textColor="@color/white"
android:textSize="19sp" />
</RelativeLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rl_title">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.yarolegovich.discretescrollview.DiscreteScrollView
android:id="@+id/view_pager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="320:457"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.85"
android:orientation="horizontal"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/choice_poster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15sp"
android:layout_marginTop="8dp"
android:text="@string/choice_poster"
android:textColor="@color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view_pager" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_poster"
android:layout_width="0dp"
android:layout_height="90dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/choice_poster" />
<com.ysj.live.kotlinmvvm.weight.DrawableCenterTextView
android:id="@+id/share_link"
android:layout_width="165dp"
android:layout_height="52dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="15dp"
android:background="@drawable/shape_white_radius26_t50_bg"
android:drawableStart="@drawable/icon_post_fenxiang"
android:drawablePadding="12dp"
android:gravity="center"
android:text="@string/share_link"
android:textColor="#A75804"
app:layout_constraintEnd_toStartOf="@+id/share_post"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rv_poster" />
<com.ysj.live.kotlinmvvm.weight.DrawableCenterTextView
android:id="@+id/share_post"
android:layout_width="165dp"
android:layout_height="52dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="15dp"
android:background="@drawable/shape_yellow_radius26_t50_bg"
android:drawableStart="@drawable/icon_post_lianjie"
android:drawablePadding="12dp"
android:gravity="center"
android:text="@string/save_post_to_share"
android:textColor="#AC6009"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/share_link"
app:layout_constraintTop_toBottomOf="@+id/rv_poster" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
2.kotlin 代码如下
package com.ysj.live.kotlinmvvm.ui.member.activity
import android.graphics.Bitmap
import android.os.AsyncTask
import android.os.Bundle
import android.view.View
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseViewHolder
import com.lc.library.tool.util.ToastUtils
import com.yarolegovich.discretescrollview.DiscreteScrollView
import com.yarolegovich.discretescrollview.InfiniteScrollAdapter
import com.yarolegovich.discretescrollview.transform.ScaleTransformer
import com.ysj.live.R
import com.ysj.live.app.base.YSJApplication
import com.ysj.live.app.utils.StatusBarUtil
import com.ysj.live.databinding.ActivityRecommendPosterBinding
import com.ysj.live.kotlinmvvm.base.activity.BaseVmDbActivity
import com.ysj.live.kotlinmvvm.ui.member.adapter.PostViewpagerAdapter
import com.ysj.live.kotlinmvvm.ui.member.adapter.PosterThumbAdapter
import com.ysj.live.kotlinmvvm.util.BitmapUtils
import com.ysj.live.kotlinmvvm.viewModel.request.RequestPosterListModelView
import com.ysj.live.mvp.live.entity.ShareEntity
import com.ysj.live.mvp.live.view.FileUtils
import com.ysj.live.mvp.live.view.PushShareDialog
import com.ysj.live.mvp.version.util.ImageParseUtil
import kotlinx.android.synthetic.main.activity_recommend_poster.*
import me.hgj.jetpackmvvm.ext.getViewModel
import me.jessyan.art.utils.LogUtils
/**
* @Description: java类作用描述
* @Author: newway
* @CreateDate: 2020/11/12 9:24
* @UpdateUser:
* @UpdateDate: 2020/11/12 9:24
* @UpdateRemark: 更新说明
*/
class RecommendPosterActivity : BaseVmDbActivity<RequestPosterListModelView, ActivityRecommendPosterBinding>(), DiscreteScrollView.OnItemChangedListener<BaseViewHolder> {
private lateinit var pastPagerAdapter2: PostViewpagerAdapter
private var thumbPosterAdapter: PosterThumbAdapter? = null
override fun layoutId() = R.layout.activity_recommend_poster
private val requestPosterListModelView: RequestPosterListModelView by lazy { getViewModel<RequestPosterListModelView>() }
var dataList = arrayListOf<String>()
var publishShareDialog: PushShareDialog? = null
lateinit var shareEntity: ShareEntity
lateinit var shareView: View
var mainBitmap: Bitmap? = null
var currentPosition: Int = 0
private var infiniteAdapter: InfiniteScrollAdapter<*>? = null
override fun initView(savedInstanceState: Bundle?) {
StatusBarUtil.immersive(this)
StatusBarUtil.setMargin(this, rl_title)
requestPosterListModelView.getPosterList()
back.setOnClickListener {
onBackPressed()
}
share_link.setOnClickListener {
publishShareDialog = PushShareDialog().setShareBean(shareEntity).setListener {
PushShareDialog.PushShareListener { ToastUtils.showShort("分享成功") }
}
publishShareDialog?.show(supportFragmentManager, "share")
}
share_post.setOnClickListener {
var baseViewHolder: RecyclerView.ViewHolder? = view_pager.findViewHolderForAdapterPosition(infiniteAdapter!!.getClosestPosition(currentPosition))
if (baseViewHolder != null) {
ToastUtils.showShort("保存图片中...")
shareView = baseViewHolder.itemView
savePhoto(shareView)
}
}
}
override fun showLoading(message: String) {
}
override fun dismissLoading() {
}
override fun createObserver() {
requestPosterListModelView.posterListLiveData.observe(this, Observer {
if (it.isSuccess) {
shareEntity = ShareEntity()
shareEntity.desc = it.data.share_user?.desc
shareEntity.shareUrl = it.data.share_user?.http_url
shareEntity.picUrl = it.data.share_user?.pic_url
shareEntity.title = it.data.share_user?.title
it.data.share_list?.let { it1 -> dataList.addAll(it1) }
pastPagerAdapter2 = it.data.share_list?.let { it1 -> PostViewpagerAdapter(it1, it.data, context = this) }!!
infiniteAdapter = pastPagerAdapter2.let { it1 -> InfiniteScrollAdapter.wrap(it1) }
view_pager.adapter = infiniteAdapter
view_pager.setItemTransformer(ScaleTransformer.Builder()
.setMinScale(0.8f)
.build())
view_pager.setSlideOnFling(true)
thumbPosterAdapter = it.data.share_list?.let { it1 -> PosterThumbAdapter(it1, 0) }
rv_poster.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
rv_poster.adapter = thumbPosterAdapter
view_pager.addOnItemChangedListener(this);
onItemChanged(currentPosition)
thumbPosterAdapter!!.setOnItemClickListener { adapter, view, position ->
onItemChanged(position)
}
} else {
//网络错误!
LogUtils.debugInfo("vivo", it.errorMsg)
}
})
}
//协程处理保存图片
private fun savePhoto(v: View) { //关键字suspend:在另外的线程允许挂起
showDialog()
val task = LoadImageTask()
task.execute(v)
}
override fun onDestroy() {
super.onDestroy()
}
private inner class LoadImageTask : AsyncTask<View, Void?, Bitmap>() {
override fun doInBackground(vararg params: View): Bitmap? {
return BitmapUtils.getBitmapFromView(params[0])
}
override fun onPostExecute(result: Bitmap) {
super.onPostExecute(result)
if (mainBitmap != null) {
mainBitmap!!.recycle()
mainBitmap = null
System.gc()
}
mainBitmap = result
FileUtils.saveImageToGallery(YSJApplication.getContext(), mainBitmap, "${System.currentTimeMillis()}.jpg")
dismissDialog()
}
override fun onPreExecute() {
super.onPreExecute()
}
override fun onCancelled() {
super.onCancelled()
}
}
override fun onCurrentItemChanged(viewHolder: BaseViewHolder?, adapterPosition: Int) {
val positionInDataSet = infiniteAdapter!!.getRealPosition(adapterPosition)
onItemChanged(positionInDataSet)
}
private fun onItemChanged(position: Int) {
var destination = infiniteAdapter!!.getClosestPosition(position)
view_pager.smoothScrollToPosition(destination)
rv_poster.smoothScrollToPosition(position)
thumbPosterAdapter!!.setPosition(position)
ImageParseUtil.showBlurImage(this@RecommendPosterActivity, blur_bg, dataList[position])
currentPosition = position
}
}