Skip to content

Instantly share code, notes, and snippets.

@fathonyfath
Created October 4, 2020 04:23
Show Gist options
  • Save fathonyfath/4c5387884003195a96744e9412fe80ae to your computer and use it in GitHub Desktop.
Save fathonyfath/4c5387884003195a96744e9412fe80ae to your computer and use it in GitHub Desktop.
Simple FrameLayout implementation
package id.thony.customview
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
class SimpleFrameLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
companion object {
private val TAG = SimpleFrameLayout::class.java.simpleName
private fun d(message: String, throwable: Throwable? = null) = if (throwable == null) {
Log.d(TAG, message)
} else {
Log.d(TAG, message, throwable)
}
}
override fun generateDefaultLayoutParams(): LayoutParams {
return MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
}
override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
return MarginLayoutParams(context, attrs)
}
override fun generateLayoutParams(p: LayoutParams?): LayoutParams {
return MarginLayoutParams(p)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
setMeasuredDimension(widthSize, heightSize)
children.forEach { child ->
if (child.visibility == View.GONE) return@forEach
measureChildWithMargins(
child,
widthMeasureSpec,
0,
heightMeasureSpec,
0
)
}
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
children.forEach { child ->
if (child.visibility == View.GONE) return@forEach
val childParams = child.layoutParams as MarginLayoutParams
child.layout(
paddingLeft + childParams.leftMargin,
paddingTop + childParams.topMargin,
paddingLeft + childParams.leftMargin + child.measuredWidth,
paddingTop + childParams.topMargin + child.measuredHeight
)
}
}
}
@fathonyfath
Copy link
Author

While mostly works, it doesn't support WRAP_CONTENT on height or width. To make it work, update the onMeasure implementation to setMeasuredDimension based on max bottom or max right that is used by the child views.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment