Android viewPager+RecyclerView 联动 合成图片保存到本地

前言

需求做一个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
    }
}


个人二维码,有问题可以问

效果如图
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值