오늘도 삽질중

Android Frame Rounding Custom View 본문

안드로이드

Android Frame Rounding Custom View

Choi3950 2021. 1. 26. 19:28
반응형

결과화면부터 보시겠습니다.




모서리 끝 부분만 둥글게 라운드 처리된 커스텀뷰 입니다.

저의 경우에는 카메라로 바코드 인식 기능을 구현하면서  디자인 요구사항에 해당 이미지가 있었습니다.


구현 당시에는 정사각형만 대응이 됬는데, 

이번에 수정하면서 직사각형도 문제 없이 모든 테두리가 나오도록 수정해봤습니다.


해당 디자인이 필요하신분은 유용하게 쓰시길 바랍니다.



*기본적으로 커스텀뷰를 만들고 세팅하는 것을 안다는 전제하에 상세한 설명은 생략합니다.




FrameRoundView.kt

class FrameRoundView @JvmOverloads constructor(
context: Context,
attr: AttributeSet,
defStyleInt: Int = 0
) : View(context, attr, defStyleInt) {


private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
private var path: Path = Path()
private var width = 0f
private var height = 0f
private var borderlineWidth = 0f
private var borderlineHeight = 0f
private var borderSize = 0f
private var borderColor = 0

private var translateValue = 0f

init {
val a = context.obtainStyledAttributes(attr, R.styleable.FrameRoundView, defStyleInt, 0)
borderSize = a.getDimensionPixelSize(R.styleable.FrameRoundView_borderWidth, 2).toFloat()
borderColor = a.getColor(R.styleable.FrameRoundView_borderColor, Color.TRANSPARENT)
a.recycle()

paint.apply {
color = borderColor
style = Paint.Style.STROKE
isAntiAlias = true
strokeWidth = borderSize
strokeCap = Paint.Cap.ROUND
strokeJoin = Paint.Join.ROUND
}

}


override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
width = w.toFloat()
height = h.toFloat()
borderlineWidth = w * 0.12f
borderlineHeight = h * 0.12f

translateValue = (height / 2) - (width / 2)

setMeasuredDimension(
MeasureSpec.getSize(width.toInt()),
MeasureSpec.getSize(height.toInt())
)
}

@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
for (i in 0..3) {
canvas.drawLine(
dpToPx(context, 4),
borderlineWidth,
dpToPx(context, 4),
borderlineWidth / 2.0f,
paint
)
path.reset()
path.moveTo(dpToPx(context, 4), borderlineWidth / 2.0f)
path.quadTo(
dpToPx(context, 4),
dpToPx(context, 4),
borderlineWidth / 2.0f,
dpToPx(context, 4)
)
canvas.drawLine(
borderlineWidth / 2.0f,
dpToPx(context, 4),
borderlineWidth,
dpToPx(context, 4),
paint
)
canvas.drawPath(path, paint)
canvas.rotate(90f, width / 2.0f, height / 2.0f)


when (i) {
0 -> {
canvas.translate(-translateValue, translateValue)
}
1 -> {
canvas.translate(-translateValue, -translateValue)
}
2 -> {
canvas.translate(-translateValue, translateValue)
}
}

}
super.onDraw(canvas)
}

fun dpToPx(context: Context, dp: Int): Float {
val resources = context.resources
val metrics = resources.displayMetrics
return dp * (metrics.densityDpi / 160f)
}
}







attrs.xml

<declare-styleable name="FrameRoundView" >
<attr name="borderWidth" format="dimension"/>
<attr name="borderColor" format="color"/>
</declare-styleable>







xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.example.test_gen.widgets.FrameRoundView
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
app:borderColor="#f0f"
app:borderWidth="4dp" />

<com.example.test_gen.widgets.FrameRoundView
android:layout_width="140dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
app:borderColor="#00f"
app:borderWidth="6dp" />

<com.example.test_gen.widgets.FrameRoundView
android:layout_width="260dp"
android:layout_height="140dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
app:borderColor="#f00"
app:borderWidth="8dp" >



</com.example.test_gen.widgets.FrameRoundView>


</RelativeLayout>


반응형
Comments