Skip to content

Instantly share code, notes, and snippets.

@martinbonnin
Last active September 11, 2018 09:36
Show Gist options
  • Select an option

  • Save martinbonnin/7a6cb5f1845ac64df215a89e3fd8210d to your computer and use it in GitHub Desktop.

Select an option

Save martinbonnin/7a6cb5f1845ac64df215a89e3fd8210d to your computer and use it in GitHub Desktop.
class SegmentedControl @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) {
val rect = Rect()
val paint = Paint()
init {
val p = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4f, context.resources.displayMetrics).toInt()
//setPadding(p, p, p, p)
//clipChildren = false
//setWillNotDraw(true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
elevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4f, context.resources.displayMetrics)
outlineProvider = ViewOutlineProvider.BOUNDS
}
}
fun setOptions(optionList: List<String>, callback: (Int) -> Unit) {
removeAllViews()
optionList.forEachIndexed { index, s ->
val optionView = OptionView(context)
val layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
optionView.setText(s)
addView(optionView, layoutParams)
optionView.setOnClickListener {
setSelectedOption(index)
callback(index)
}
}
invalidate()
}
fun setSelectedOption(index: Int) {
children.forEachIndexed { index2, view ->
view.isSelected = index == index2
(view as OptionView).setTextColor(if(view.isSelected) Color.WHITE else Color.parseColor("#7f7f7f"))
}
}
override fun onDraw(canvas: Canvas) {
paint.color = Color.parseColor("#efefef")
paint.style = Paint.Style.STROKE
paint.strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, context.resources.displayMetrics)
children.forEach {
rect.left = it.left
rect.top = it.top
rect.right = it.right
rect.bottom = it.bottom
canvas.drawRect(rect, paint)
}
super.onDraw(canvas)
}
companion object {
const val NO_SELECTION = -1
}
}
class OptionView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextView(context, attrs, defStyleAttr) {
val rect = Rect()
val paint = Paint()
init {
typeface = ResourcesCompat.getFont(context, R.font.retinabook)
gravity = Gravity.CENTER
maxLines = 1
ellipsize = TextUtils.TruncateAt.END
val p = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 9f, context.resources.displayMetrics).toInt()
setPadding(p, p, p, p)
val attrs = intArrayOf(R.attr.selectableItemBackground)
val ta = context.obtainStyledAttributes(attrs)
val drawable = ta.getDrawable(0)
ta.recycle()
background = drawable
}
override fun onDraw(canvas: Canvas) {
rect.left = 0
rect.top = 0
rect.bottom = height
rect.right = width
paint.color = Color.parseColor("#ffffff")
paint.style = Paint.Style.FILL
canvas.drawRect(rect, paint)
paint.color = Color.parseColor("#efefef")
paint.style = Paint.Style.STROKE
paint.strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, context.resources.displayMetrics)
canvas.drawRect(rect, paint)
if (isSelected || isPressed) {
paint.color = Color.parseColor("#00aaff")
paint.style = Paint.Style.FILL
canvas.drawRect(rect, paint)
}
super.onDraw(canvas)
// this is slightly hackhish but this way we don't have to forward the hot spot to the ripple :)
background.draw(canvas)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment