Android Combine Two Images| HOW TO COMBINE MULTIPLE IMAGES TO A SINGLE IMAGE IN ANDROID
Published March 23, 2020In this post we are going to learn how to display multiple images like facebook.
Let's start
Step 1: Create Android Application with Kotlin Enable
Step 2: Create Custom MultiIimageView class and add below code
package com.rrtutors.multiimageview
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import java.util.ArrayList
class MultiImageView<T> : ViewGroup{
private var mContext: Context? = null
private var mGap: Int = 0//Spacing
private var mSingleImgSize: Int = 0//Image Size
private var mMaxSize = 3//Max Images
private val mImageViewList = ArrayList<ImageView>()
private var mImgDataList: List<Any>? = null
private var mImageSize: Int = 0//Total Images
private var mRowCount: Int = 0//No Of Rows
private var mColumnCount: Int = 0//No Of Columns
private var textView: TextView? = null
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init(context,attrs)
}
private fun init(context: Context, attrs: AttributeSet?) {
this.mContext = context
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ThreeImageView)
this.mGap = typedArray.getDimension(R.styleable.ThreeImageView_imgGap, 0f).toInt()
this.mSingleImgSize = typedArray.getDimensionPixelSize(R.styleable.ThreeImageView_singleImgSize, -1)
this.mMaxSize = typedArray.getInteger(R.styleable.ThreeImageView_maxSize, 3)
typedArray.recycle()
}
private fun layoutChildrenView() {
if (mImgDataList == null) return
val showChildrenCount = getNeedShowCount(mImgDataList!!.size)
layoutMaxCountChildrenView(showChildrenCount)
}
protected override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
layoutChildrenView()
}
protected override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = View.MeasureSpec.getSize(widthMeasureSpec)
var height = View.MeasureSpec.getSize(heightMeasureSpec)
val totalWidth = width - getPaddingLeft() - getPaddingRight()
if (mImgDataList != null && mImgDataList!!.size > 0) {
if (mImgDataList!!.size == 1 && mSingleImgSize != -1) {
mImageSize = if (mSingleImgSize > totalWidth) totalWidth else mSingleImgSize
} else {
mImageSize = (totalWidth - mGap * (mColumnCount - 1)) / mColumnCount
}
height = mImageSize * mRowCount + mGap * (mRowCount - 1) + getPaddingTop() + getPaddingBottom()
}
setMeasuredDimension(width, height)
}
private fun layoutMaxCountChildrenView(childrenCount: Int) {
var left = 0
var top = 0
var right = 0
var bottom = 0
for (i in 0 until childrenCount) {
val childrenView = getChildAt(i) as ImageView
childrenView.scaleType = ImageView.ScaleType.CENTER_CROP
childrenView.setBackgroundResource(R.drawable.shape)
left = getPaddingLeft() + i % 3 * mImageSize + i % 3 * mGap
top = getPaddingTop() + i / 3 * mImageSize + i / 3 * mGap
right = left + mImageSize
bottom = top + mImageSize
childrenView.layout(left, top, right, bottom)
childrenView.setPadding(2,2,2,2)
mContext?.let { Glide.with(it).load(mImgDataList?.get(i)).into(childrenView) };
}
showImageAndText(left, top, right, bottom)
}
private fun showImageAndText(left: Int, top: Int, right: Int, bottom: Int) {
if (mImgDataList!!.size > mMaxSize) {
if (textView != null) {
textView!!.bringToFront()
val k=(mImgDataList!!.size)
val text = "+ " +( k.minus(mMaxSize)) + ""
val textSize = px2sp(mContext!!, (mImageSize / 6).toFloat())
textView!!.textSize = textSize.toFloat()
textView!!.text = text
textView!!.setTextColor(Color.WHITE)
textView!!.setBackgroundColor(-0x80000000)
val fontMetricsInt = textView!!.paint.fontMetricsInt
val textHeight = fontMetricsInt.bottom - fontMetricsInt.top
val paddingTop = (mImageSize - textHeight) / 2
textView!!.setPadding(0, paddingTop, 0, paddingTop)
textView!!.gravity = Gravity.CENTER
textView!!.layout(left, top, right, bottom)
}
}
}
/**
*
*
* @param size
* @return
*/
private fun getNeedShowCount(size: Int): Int {
return if (mMaxSize > 0 && size > mMaxSize) {
mMaxSize
} else {
size
}
}
/**
*
*
* @param list
*/
fun setImagesData(list: List<Any>?) {
mImgDataList = list
removeAllViews()
if (list == null || list.size == 0) {
this.setVisibility(View.GONE)
} else {
this.setVisibility(View.VISIBLE)
}
val showCount = getNeedShowCount(list!!.size)
val params = calculateParam(showCount)
mRowCount = params[0]
mColumnCount = params[1]
for (i in 0 until showCount) {
val iv = getImageView(i) ?: return
addView(iv, generateDefaultLayoutParams())
if (i == mMaxSize - 1 && list.size > mMaxSize) {
textView = TextView(mContext)
addView(textView, generateDefaultLayoutParams())
}
}
requestLayout()
}
protected fun calculateParam(imageSize: Int): IntArray {
val params = IntArray(2)
params[0] = imageSize / 3 + if (imageSize % 3 == 0) 0 else 1
params[1] = 3
return params
}
private fun getImageView(position: Int): ImageView? {
if (position < mImageViewList.size) {
return mImageViewList[position]
} else {
val imageView = ImageView(mContext)
mImageViewList.add(imageView)
return imageView
}
}
fun setGap(gap: Int) {
this.mGap = gap
}
fun getGap(): Int {
return mGap
}
/**
*
*
* @param singleImgSize
*/
fun setSingleImgSize(singleImgSize: Int) {
mSingleImgSize = singleImgSize
}
/**
*
*
* @param maxSize
*/
fun setMaxSize(maxSize: Int) {
mMaxSize = maxSize
}
private fun px2sp(context: Context, pxValue: Float): Int {
val fontScale = context.resources.displayMetrics.scaledDensity
return (pxValue / fontScale + 0.5f).toInt()
}
}
|
Step 3: Add resourses
attrs.xml file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ThreeImageView">
<attr name="singleImgSize" format="dimension"/>
<attr name="imgGap" format="dimension"/>
<attr name="maxSize" format="integer"/>
</declare-styleable>
</resources>
|
Step 4: Update activity_main.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FAFAFA"
tools:context=".MainActivity">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#F30556"
android:layout_margin="16dp"
android:text="List oF imgaes Like Facebook"
/>
<com.rrtutors.multiimageview.MultiImageView
android:id="@+id/image_three"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:imgGap="10dp"
app:maxSize="3"
android:layout_gravity="center"
android:paddingLeft="10dp"
android:paddingRight="10dp"
app:singleImgSize="50dp"
android:paddingBottom="10dp"
tools:ignore="MissingConstraints"/>
</LinearLayout>
|
Step 5: Update MainActivity file
package com.rrtutors.multiimageview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.ComponentActivity
import androidx.core.app.ComponentActivity.ExtraData
import androidx.core.content.ContextCompat.getSystemService
import android.icu.lang.UCharacter.GraphemeClusterBreak.T
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mList:ArrayList<Int>?= ArrayList<Int>()
mList?.add(R.drawable.images)
mList?.add(R.drawable.images)
mList?.add(R.drawable.images)
mList?.add(R.drawable.images)
mList?.add(R.drawable.images)
mList?.add(R.drawable.images)
mList?.add(R.drawable.images)
image_three.setImagesData(mList)
}
}
|
Step 6: Run Application
Article Contributed By :
|
|
|
|
4769 Views |