Android

Android Banner自適應 網路撈取圖片大小

Android Banner自適應 網路撈取圖片大小

  1. 導入Glide
  2. 一頁式的RecyclerView
  3. 取得真實寬高工具類
  4. 創建BannerAdapter
  5. BannerView
  6. 調用Banner
  7. 效果展示

1.導入Glide

build.gradle(Module)
dependencies {
    implementation 'com.github.bumptech.glide:glide:4.11.0'
}

2.一頁式的RecyclerView

import android.content.Context
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SnapHelper

/**
 * Author: FlyWei
 * E-mail: tony91097@gmail.com
 * Date: 2021/4/7
 */
class ViewPagerRecyclerView(context: Context) : RecyclerView(context) {

    //頁面轉換監聽
    interface OnPagerChangeListener {
        fun onPagerChange(position: Int)
    }

    private var onPageChangeListener: OnPagerChangeListener? = null
    var position = 0

    init {
        layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        //改為一頁式設置滑動監聽
        val snapHelper: SnapHelper = PagerSnapHelper()
        snapHelper.attachToRecyclerView(this)
        addOnScrollListener(object : OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                recyclerView.layoutManager.also { layoutManager ->
                    if (layoutManager is LinearLayoutManager) {
                        val first = layoutManager.findFirstVisibleItemPosition()
                        if (position != first) {
                            position = first
                            onPageChangeListener?.onPagerChange(position)
                        }
                    }
                }
            }
        })
    }

    fun setPagePosition(position: Int) {
        smoothScrollToPosition(position)
    }

    fun setOnPagerChangeListener(onPageChangeListener: OnPagerChangeListener) {
        this.onPageChangeListener = onPageChangeListener
    }
}

3.取得真實寬高工具類

import android.app.Activity
import android.content.res.Resources
import android.util.DisplayMetrics
import android.util.TypedValue

/**
 * Author: FlyWei
 * E-mail: tony91097@gmail.com
 * Date: 2021/4/12
 */

class GetDisplayUtil {

    companion object {
        private lateinit var displayMetrics: DisplayMetrics

        @JvmStatic
        fun getInstance(activity: Activity): GetDisplayUtil {
            displayMetrics = DisplayMetrics()
            activity.display?.getRealMetrics(displayMetrics)
            return GetDisplayUtil()
        }
    }

    fun getRealWidth(): Float {
        return displayMetrics.widthPixels.toFloat()
    }

    fun getRealHeight(): Float {
        val navigationHeight = Resources.getSystem().getDimensionPixelSize(
            Resources.getSystem().getIdentifier(
                "navigation_bar_height",
                "dimen",
                "android"
            )
        )
        val statusBarHeight = Resources.getSystem().getDimensionPixelSize(
            Resources.getSystem().getIdentifier(
                "status_bar_height",
                "dimen",
                "android"
            )
        )
        return (displayMetrics.heightPixels - statusBarHeight - navigationHeight).toFloat()
    }
}

val Int.dp
    get() = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        this.toFloat(),
        Resources.getSystem().displayMetrics
    )

4.創建BannerAdapter

banner_item.xml




    

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide


/**
 * Author: FlyWei
 * E-mail: tony91097@gmail.com
 * Date: 2021/4/7
 */

class BannerAdapter(val images: ArrayList, val links: ArrayList) : RecyclerView.Adapter() {

    private lateinit var context: Context

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerHolder {
        context = parent.context
        return BannerHolder(
            LayoutInflater.from(context).inflate(R.layout.banner_item, parent, false)
        )
    }

    override fun getItemCount(): Int {
        return images.size
    }

    override fun onBindViewHolder(holder: BannerHolder, position: Int) {
        holder.setDate(position)
    }

    inner class BannerHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val imageView: ImageView = itemView.findViewById(R.id.imageView)
        fun setDate(position: Int) {
            Glide.with(context)
                .load(images[position])
                .into(imageView)

            imageView.setOnClickListener {
                val intent = Intent(Intent.ACTION_VIEW)
                intent.data = Uri.parse(links[position])
                context.startActivity(intent)
            }
        }
    }
}

5.BannerView

import android.app.Activity
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Outline
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.ViewOutlineProvider
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import fly.com.gittest.GetDisplayUtil
import fly.com.gittest.dp
import java.util.*

/**
 * Author: FlyWei
 * E-mail: tony91097@gmail.com
 * Date: 2021/4/12
 */

class BannerView(private val activity: Activity) {

    private lateinit var viewPagerRecyclerView: ViewPagerRecyclerView
    private lateinit var bgView: View
    private lateinit var previous: ImageView
    private lateinit var next: ImageView
    private lateinit var skip: TextView
    private lateinit var positionBar: LinearLayout
    private var points = arrayListOf()

    //取得手機高度寬度(px)
    private val getDisplayUtil = GetDisplayUtil.getInstance(activity)
    private val realHeight = getDisplayUtil.getRealHeight()
    private val realWidth = getDisplayUtil.getRealWidth()

    //取得背景View
    fun getBgView(): View {
        bgView = View(activity).apply {
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            setBackgroundColor(Color.parseColor("#53000000"))
            setOnClickListener(null)
        }
        return bgView
    }

    //重新計算View大小
    fun changeView(bitmap: Bitmap) {
        viewPagerRecyclerView.apply {
            layoutParams.height = (layoutParams.width.toFloat() / bitmap.width.toFloat() * bitmap.height.toFloat()).toInt()
            y = realHeight / 2 - layoutParams.height / 2
            requestLayout()
            skip.y = y + 9.dp
            positionBar.y = y + layoutParams.height - positionBar.height - 12.dp
        }
    }

    //初始化RecyclerView
    fun getViewPagerRecyclerView(
        bitmap: Bitmap,
        images: ArrayList,
        links: ArrayList
    ): ViewPagerRecyclerView {
        viewPagerRecyclerView = ViewPagerRecyclerView(activity).apply {
            layoutParams = ViewGroup.LayoutParams(
                (realWidth - 82.dp).toInt(),
                ((realWidth - 82.dp) / bitmap.width.toFloat() * bitmap.height.toFloat()).toInt()
            )
            //切圓角
            outlineProvider = object : ViewOutlineProvider() {
                override fun getOutline(view: View, outline: Outline) {
                    outline.setRoundRect(
                        0,
                        0,
                        view.width,
                        view.height,
                        20.dp
                    )
                }
            }
            clipToOutline = true
            adapter = BannerAdapter(images, links)
            x = realWidth / 375f * 41f
            y = realHeight / 2 - layoutParams.height / 2
        }
        return viewPagerRecyclerView
    }

    //判斷最後一張顯示略過
    fun getSkipView(images: ArrayList): TextView {
        val rootView = activity.findViewById(android.R.id.content) as ViewGroup
        skip = TextView(activity).apply {
            layoutParams = ViewGroup.LayoutParams(53.dp.toInt(), 24.dp.toInt())
            text = "略過"
            textSize = 12f
            gravity = Gravity.CENTER
            setTextColor(Color.WHITE)
            visibility = if (viewPagerRecyclerView.position == images.size - 1) {
                View.VISIBLE
            } else {
                View.GONE
            }
            background = ContextCompat.getDrawable(activity, R.drawable.button_corner)
            x = viewPagerRecyclerView.x + viewPagerRecyclerView.layoutParams.width - layoutParams.width - 6.dp
            y = viewPagerRecyclerView.y + 9.dp
            setOnClickListener {
                rootView.removeView(bgView)
                rootView.removeView(viewPagerRecyclerView)
                rootView.removeView(previous)
                rootView.removeView(next)
                rootView.removeView(it)
                rootView.removeView(positionBar)
            }
        }
        return skip
    }

    fun getPreviousView(): ImageView {
        previous = ImageView(activity).apply {
            layoutParams = ViewGroup.LayoutParams(20.dp.toInt(), 20.dp.toInt())
            setImageResource(R.drawable.banner_no_previous)
            x = viewPagerRecyclerView.x + 9
            y =
                viewPagerRecyclerView.y + viewPagerRecyclerView.layoutParams.height / 2 - layoutParams.height / 2
            setOnClickListener {
                if (viewPagerRecyclerView.position < 1) {
                    return@setOnClickListener
                }
                viewPagerRecyclerView.setPagePosition(viewPagerRecyclerView.position - 1)
            }
        }
        return previous
    }

    fun getNextView(images: ArrayList): ImageView {
        next = ImageView(activity).apply {
            layoutParams = ViewGroup.LayoutParams(20.dp.toInt(), 20.dp.toInt())
            if (images.size == 1) {
                setImageResource(R.drawable.banner_no_next)
            } else {
                setImageResource(R.drawable.banner_yes_next)
            }
            x =
                viewPagerRecyclerView.x + viewPagerRecyclerView.layoutParams.width - layoutParams.width - 9
            y =
                viewPagerRecyclerView.y + viewPagerRecyclerView.layoutParams.height / 2 - layoutParams.height / 2
            setOnClickListener {
                if (viewPagerRecyclerView.position > images.size - 2) {
                    return@setOnClickListener
                }
                viewPagerRecyclerView.setPagePosition(viewPagerRecyclerView.position + 1)
            }
        }
        return next
    }

    fun getPositionBarView(images: ArrayList): LinearLayout {
        positionBar = LinearLayout(activity).apply {
            layoutParams = ViewGroup.LayoutParams((20 * images.size).dp.toInt(), 10.dp.toInt())
            gravity = Gravity.CENTER
            for (index in images.indices) {
                val point = ImageView(activity).apply {
                    setPadding(8, 0, 8, 0)
                    if (index == 0) {
                        setImageResource(R.drawable.now_point)
                    } else {
                        setImageResource(R.drawable.no_point)
                    }
                }
                addView(point)
                points.add(point)
            }
            x =
                viewPagerRecyclerView.x + viewPagerRecyclerView.layoutParams.width - layoutParams.width - 18.dp
            y =
                viewPagerRecyclerView.y + viewPagerRecyclerView.layoutParams.height - layoutParams.height - 13.dp
        }
        return positionBar
    }

    fun getPoints() = points

}

6.調用Banner

import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition


class MainActivity : AppCompatActivity() {

    var images = arrayListOf()
    var links = arrayListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //獲取資料
        images.add("https://www.twgreatdaily.com/imgs/image/174/17483365.jpg")
        images.add("https://obs.line-scdn.net/0ha6Hy3DiJPhl1ABRAe6pBTk9WPXZGbC0aETZvGjZuYC0KMi1OSzEkd1YINy4LZXlHGzZyf1kAJShQNilMGTIk/w1200")
        images.add("https://i2.kknews.cc/SIG=cnvpnt/213o00023q071sr823p3.jpg")
        images.add("https://firebasestorage.googleapis.com/v0/b/check-in-4ebce.appspot.com/o/images%2Fgirl.jpg?alt=media&token=f14825f8-a791-407b-a109-89bff5e5f7d7")
        images.add("https://firebasestorage.googleapis.com/v0/b/check-in-4ebce.appspot.com/o/images%2Fgirl2.jpg?alt=media&token=9df39e6f-5420-4044-9b98-189943b0d2ca")

        links.add("https://www.twgreatdaily.com/imgs/image/174/17483365.jpg")
        links.add("https://obs.line-scdn.net/0ha6Hy3DiJPhl1ABRAe6pBTk9WPXZGbC0aETZvGjZuYC0KMi1OSzEkd1YINy4LZXlHGzZyf1kAJShQNilMGTIk/w1200")
        links.add("https://i2.kknews.cc/SIG=cnvpnt/213o00023q071sr823p3.jpg")
        links.add("https://firebasestorage.googleapis.com/v0/b/check-in-4ebce.appspot.com/o/images%2Fgirl.jpg?alt=media&token=f14825f8-a791-407b-a109-89bff5e5f7d7")
        links.add("https://firebasestorage.googleapis.com/v0/b/check-in-4ebce.appspot.com/o/images%2Fgirl2.jpg?alt=media&token=9df39e6f-5420-4044-9b98-189943b0d2ca")
    }

    fun show(view: View) {
        val bannerView = BannerView(this)
        val myView = bannerView.getBgView()
        addContentView(myView, myView.layoutParams)

        //取得第一張圖片寬高
        Glide.with(this)
            .asBitmap()
            .load(images[0]).into(object : CustomTarget() {
                override fun onLoadCleared(placeholder: Drawable?) {}

                override fun onResourceReady(bitmap: Bitmap, transition: Transition?) {
                    val viewPagerRecyclerView = bannerView.getViewPagerRecyclerView(bitmap, images, links)
                    addContentView(viewPagerRecyclerView, viewPagerRecyclerView.layoutParams)

                    val skipView = bannerView.getSkipView(images)
                    addContentView(skipView, skipView.layoutParams)

                    val previousView = bannerView.getPreviousView()
                    addContentView(previousView, previousView.layoutParams)

                    val nextView = bannerView.getNextView(images)
                    addContentView(nextView, nextView.layoutParams)

                    val positionBarView = bannerView.getPositionBarView(images)
                    addContentView(positionBarView, positionBarView.layoutParams)

                    viewPagerRecyclerView.setOnPagerChangeListener(object : ViewPagerRecyclerView.OnPagerChangeListener {
                        override fun onPagerChange(position: Int) {
                            if (position == images.size - 1) {
                                skipView.visibility = View.VISIBLE
                                nextView.setImageResource(R.drawable.banner_no_next)
                            } else {
                                skipView.visibility = View.GONE
                                nextView.setImageResource(R.drawable.banner_yes_next)
                            }
                            if (position != 0) {
                                previousView.setImageResource(R.drawable.banner_yes_previous)
                            } else {
                                previousView.setImageResource(R.drawable.banner_no_previous)
                            }
                            for (index in 0 until bannerView.getPoints().size) {
                                bannerView.getPoints()[position]
                                    .setImageResource(R.drawable.now_point)
                                if (position != index) {
                                    bannerView.getPoints()[index]
                                        .setImageResource(R.drawable.no_point)
                                }
                            }
                            Glide.with(this@MainActivity).asBitmap().load(images[position])
                                .into(object : CustomTarget() {
                                    override fun onLoadCleared(placeholder: Drawable?) {}

                                    override fun onResourceReady(bitmap: Bitmap, transition: Transition?) {
                                        bannerView.changeView(bitmap)
                                    }
                                })
                        }
                    })
                }
            })
    }
}

7.效果展示

發表迴響