Android自定義多圖片適配器(根據圖片的個數展示不同的布局)


一、概述&效果圖

  項目上有一個需求根據不同的圖片個數展示不同的的布局樣式,且圖片個數不能超過四個。要說起來手動寫也挺方便的,就是代碼看起來比較臃腫,考慮了兩秒決定用自定義布局試實現

  思路:

  1.讓布局繼承ViewGroup

  2.利用ViewGroup測量自己以及測量子View的寬高

  3.根據寬高在layout方法中進行手動布局

  廢話不多說,大家可以看下效果圖

  

二、源代碼(主要部分)

  測量自己和測量子View

 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //測量子View
        measureChildren(widthMeasureSpec, heightMeasureSpec)
        //獲取ziView的數量
        val childCount = childCount
        if (childCount > 4) {
            //如果元素超過四個就拋出異常
            throw IndexOutOfBoundsException("元素數量不能超過四個")
        }
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)
        //布局必須是固定寬高的,如果不是就拋出異常
        if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) {
            throw RuntimeException("主布局必須指定寬高")
        }
        //指定布局寬高范圍
        setMeasuredDimension(width, height)
        //以下默認布局都是有固定寬高的
        for (index in 0 until childCount) {
            when (childCount) {
                //當只有一個子元素的時候,布局的寬高就是子元素的寬高
                1 -> {
                    val childView = getChildAt(index)
                    val params = ViewGroup.LayoutParams(width, height)
                    childView.layoutParams = params
                }
                2 -> {
                    for (index in 0 until 2) {
                        val childView = getChildAt(index)
                        val params = ViewGroup.LayoutParams((width - margin) / 2, height)
                        childView.layoutParams = params
                    }
                }
                3 -> {
                    for (index in 0 until 3) {
                        val childView = getChildAt(index)
                        var childWidth = 0
                        var childHeight = 0
                        if (index == 0) {
                            childWidth = (width - margin) / 2
                            childHeight = height
                        } else {
                            childWidth = (width - margin) / 2
                            childHeight = (height - margin) / 2
                        }
                        val params = ViewGroup.LayoutParams(childWidth, childHeight)
                        childView.layoutParams = params
                    }
                }
                4 -> {
                    for (index in 0 until 4) {
                        val childView = getChildAt(index)
                        val params =
                            ViewGroup.LayoutParams((width - margin) / 2, (width - margin) / 2)
                        childView.layoutParams = params
                    }
                }
            }
        }
    }

  布局子View

  /**
     * @description 開始布局
     * @date: 2020/11/6 16:20
     * @author: wei.yang
     * @param
     * @return
     */
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        Log.e("margin:", margin.toString())
        val childCount = childCount
        when (childCount) {
            1 -> {
                val childView = getChildAt(0)
                childView.layout(0, 0, childView.measuredWidth, childView.measuredHeight)
            }
            2 -> {
                val childView1 = getChildAt(0)
                val childWidth = childView1.measuredWidth
                childView1.layout(0, 0, childWidth, childView1.measuredHeight)
                val childView2 = getChildAt(1)
                childView2.layout(
                    childWidth + margin,
                    0,
                    childWidth * 2 + margin,
                    childView2.measuredHeight
                )
            }
            3 -> {
                val childView1 = getChildAt(0)
                val childWidth = childView1.measuredWidth
                childView1.layout(0, 0, childWidth, childView1.measuredHeight)
                val childView2 = getChildAt(1)
                childView2.layout(
                    childWidth + margin,
                    0,
                    childWidth * 2 + margin,
                    childView2.measuredHeight
                )
                val childView3 = getChildAt(2)
                childView3.layout(
                    childWidth + margin,
                    childWidth + margin,
                    childWidth * 2 + margin,
                    childView3.measuredHeight * 2 + margin
                )
            }
            4 -> {
                Log.e("CustomerMusdfj", "布局了四個")
                val childView = getChildAt(0)
                val childWidth = childView.measuredWidth
                val childHeight = childView.measuredHeight
                childView.layout(0, 0, childWidth, childHeight)
                getChildAt(1).layout(childWidth + margin, 0, childWidth * 2 + margin, childHeight)
                getChildAt(2).layout(0, childHeight + margin, childWidth, childHeight * 2 + margin)
                getChildAt(3).layout(
                    childWidth + margin,
                    childHeight + margin,
                    childWidth * 2 + margin,
                    childHeight * 2 + margin
                )
            }
        }

    }

  設置數據源

 /**
     * @description 設置圖片的數據源
     * @date: 2020/11/6 16:39
     * @author: wei.yang
     * @param margin 單位是dp
     * @return
     */
    fun setAdapter(views: ArrayList<View>, margin: Float) {
        removeAllViews()
        this.margin = dp2px(margin)
        views?.apply {
            this.forEach {
                addView(it)
            }
        }
        requestLayout()

    }

 

三、使用方法

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initViews()
    }

    private fun initViews() {
        customMutiImageView.setAdapter(getDataViews(4), 0f)
        customMutiImageView2.setAdapter(getDataViews(4), 5f)
        customMutiImageViewOnLayout.setAdapter(getDataViews(1), 0f)
        customMutiImageViewTwoLayout.setAdapter(getDataViews(2), 5f)
        customMutiImageViewThreeLayout.setAdapter(getDataViews(3), 0f)

        customMutiOtherLayout.setAdapter(getCustomLayout(), 5f)
    }

    private fun getCustomLayout(): ArrayList<View> {
        val views = ArrayList<View>()
        for (index in 0 until 4) {
            val view = LayoutInflater.from(this).inflate(R.layout.item_mutillayout, null)
            val customView =
                view.findViewById<com.yw.custommutilimageadapter.widget.CustomMutiImageView>(R.id.customMutiImageLittle)
            customView.setAdapter(getDataViews(4), 0f)
            views.add(view)
        }

        return views
    }

    private fun getDataViews(size: Int): ArrayList<View> {
        val views = ArrayList<View>()
        val img1 = ImageView(this)
        img1.setImageResource(R.drawable.girl1)
        img1.scaleType = ImageView.ScaleType.CENTER_CROP
        val img2 = ImageView(this)
        img2.setImageResource(R.drawable.girl2)
        img2.scaleType = ImageView.ScaleType.CENTER_CROP
        val img3 = ImageView(this)
        img3.setImageResource(R.drawable.girl3)
        img3.scaleType = ImageView.ScaleType.CENTER_CROP
        val img4 = ImageView(this)
        img4.setImageResource(R.drawable.girl4)
        img4.scaleType = ImageView.ScaleType.CENTER_CROP


        when (size) {
            1 -> {
                views.add(img4)
            }
            2 -> {
                views.add(img3)
                views.add(img4)
            }
            3 -> {
                views.add(img1)
                views.add(img2)
                views.add(img3)
            }
            4 -> {
                views.add(img1)
                views.add(img2)
                views.add(img3)
                views.add(img4)
            }
        }
        return views
    }
}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:context=".MainActivity">
        <!--    四張圖片不帶間距-->
        <com.yw.custommutilimageadapter.widget.CustomMutiImageView
            android:id="@+id/customMutiImageView"
            android:layout_width="200dp"
            android:layout_height="200dp"
            tools:ignore="MissingConstraints" />
        <!--    四張圖片帶間距-->
        <com.yw.custommutilimageadapter.widget.CustomMutiImageView
            android:id="@+id/customMutiImageView2"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            tools:ignore="MissingConstraints" />
        <!--    一張圖片-->
        <com.yw.custommutilimageadapter.widget.CustomMutiImageView
            android:id="@+id/customMutiImageViewOnLayout"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            tools:ignore="MissingConstraints" />
        <!--    兩張圖片-->
        <com.yw.custommutilimageadapter.widget.CustomMutiImageView
            android:id="@+id/customMutiImageViewTwoLayout"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            tools:ignore="MissingConstraints" />
        <!--    三張圖片-->
        <com.yw.custommutilimageadapter.widget.CustomMutiImageView
            android:id="@+id/customMutiImageViewThreeLayout"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            tools:ignore="MissingConstraints" />
        <!--自定義填充其他布局-->
        <com.yw.custommutilimageadapter.widget.CustomMutiImageView
            android:id="@+id/customMutiOtherLayout"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            tools:ignore="MissingConstraints" />
    </LinearLayout>
</ScrollView>

 

如果要下載源代碼,請移步GitHub


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM