안드로이드

안드로이드 커스텀뷰 만들기 android customView

알통몬_ 2019. 2. 7. 11:18
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 


이번 포스팅에서는 안드로이드 커스텀 뷰를 만드는 방법에 대해 공부합니다.


커스텀 뷰는 소셜 로그인 같은 레이아웃의 형태는 같지만 들어가는 이미지,

텍스트, 색상이 다를 때 요긴하게 사용할 수 있습니다.

저는 위 아래로 텍스트가 들어가는 막대바가 한 액티비티에 21개가 들어가야 해서

커스텀 뷰를 만들어 봤습니다.

 

필요한 것들

커스텀 뷰 클래스, 커스텀 뷰xml, attrs.xml


1. 커스텀 뷰 .xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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.support.v7.widget.AppCompatTextView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/view"
app:layout_constraintVertical_weight="1.1"
tools:text="50%"
android:id="@+id/mealVolumeTxtView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
/>
<View
android:id="@+id/lView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/barImgView"
app:layout_constraintHorizontal_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<View
app:layout_constraintTop_toBottomOf="@+id/mealVolumeTxtView"
app:layout_constraintBottom_toTopOf="@+id/mealDayTxtView"
app:layout_constraintVertical_weight="7.8"
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="0dp"/>
<ImageView
android:contentDescription="@string/app_name"
app:layout_constraintTop_toBottomOf="@+id/mealVolumeTxtView"
app:layout_constraintBottom_toTopOf="@+id/mealDayTxtView"
app:layout_constraintStart_toEndOf="@+id/lView"
app:layout_constraintEnd_toStartOf="@+id/rView"
app:layout_constraintVertical_weight="7.8"
app:layout_constraintHorizontal_weight="3.5"
android:scaleType="fitXY"
android:id="@+id/barImgView"
android:layout_width="0dp"
android:layout_height="0dp">
</ImageView>
<View
android:id="@+id/rView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/barImgView"
app:layout_constraintHorizontal_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<android.support.v7.widget.AppCompatTextView
app:layout_constraintTop_toBottomOf="@+id/view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_weight="1.1"
android:id="@+id/mealDayTxtView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
/>
</android.support.constraint.ConstraintLayout>

  이런 형태의 커스텀 뷰 입니다.

커스텀 할 부분은 위 아래로 들어가는 텍스트와 가운데 들어가는 이미지 입니다.


2. attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MealVolumeBarView">
<attr name="dayText" format="reference|string"/>
<attr name="volumeText" format="reference|string"/>
<attr name="barImage" format="reference|integer"/>
</declare-styleable>
</resources>

name에는 커스텀뷰 클래스의 이름을 넣어주면 됩니다.

dayText, volumeText는 문자열을 참조하고, barIamge는 이미지를 참조합니다.


[ 광고 보고 가시죠! ]



[ 감사합니다! ]

3. 커스텀 뷰 클래스 - 저는 ConstraintLayout을 상속받는 클래스를 만들었습니다.

코틀린으로 작성되었습니다.

import android.content.Context
import android.content.res.TypedArray
import android.support.constraint.ConstraintLayout
import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ImageView

class MealVolumeBarView : ConstraintLayout {

// view_mealvolumebar.xml 에 있는 컴포넌트들을 참조하기 위한 변수
private lateinit var mealVolumeTxtView: AppCompatTextView
private lateinit var mealDayTxtView: AppCompatTextView
private lateinit var barImgView: ImageView

constructor(context: Context) : this(context, null) {
init()
}

constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {
init()
getAttrs(attrs)
}

constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
getAttrs(attrs, defStyleAttr)
}

// 레이아웃 초기화, 액티비티에서 setContentView 하는 것과 동일하다고 보면 됩니다.
private fun init() {
val layoutInflateService = Context.LAYOUT_INFLATER_SERVICE
val layoutInflater = context.getSystemService(layoutInflateService) as LayoutInflater
val view = layoutInflater.inflate(R.layout.view_mealvolumebar, this, false)
addView(view)

//초기화
mealVolumeTxtView = findViewById(R.id.mealVolumeTxtView)
mealDayTxtView = findViewById(R.id.mealDayTxtView)
barImgView = findViewById(R.id.barImgView)

}

// 만들어 놓은 attrs을 참조합니다.
private fun getAttrs(attrs: AttributeSet?) {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MealVolumeBarView)
setTypeArray(typedArray)
}

// 만들어 놓은 attrs을 참조합니다.
private fun getAttrs(attrs: AttributeSet?, defStyleAttr: Int) {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MealVolumeBarView, defStyleAttr, 0)
setTypeArray(typedArray)
}

// 여기서 값을 세팅해줍니다.
private fun setTypeArray(typedArray: TypedArray) {

val dayTxtResID = typedArray.getString(R.styleable.MealVolumeBarView_dayText)
val volumeTxtResID = typedArray.getString(R.styleable.MealVolumeBarView_volumeText)

val barImageResID = typedArray.getResourceId(R.styleable.MealVolumeBarView_barImage, R.drawable.zero)


mealDayTxtView.text = dayTxtResID
mealVolumeTxtView.text = volumeTxtResID
barImgView.setImageResource(barImageResID)
typedArray.recycle()

}

//TextView에 setText가 있는 것처럼
//메소드를 만듭니다.
fun setVolumeText(text: String) {
mealVolumeTxtView.text = text
}

fun setVolumeText(text_resID: Int) {
mealVolumeTxtView.text = context.getString(text_resID)
}

fun setDayText(text: String) {
mealDayTxtView.text = text
}

fun setDayText(text_resID: Int) {
mealDayTxtView.text = context.getString(text_resID)
}

//이미지 적용
fun setBarImage(image_ResID: Int) {
barImgView.setImageResource(image_ResID)
}

}


실제 사용.
<superbrain.rowan.com.rowancareadmin.MealVolumeBarView
app:layout_constraintStart_toEndOf="@+id/mealTueView"
app:layout_constraintEnd_toStartOf="@+id/mealThuView"
android:id="@+id/mealWedView"
android:layout_width="0dp"
android:layout_height="match_parent"
app:barImage="@drawable/half"
app:volumeText="50%"
app:dayText="@string/text_wed"/>

attrs.xml에 만든 dayText,  volumeText, barImage를 

app:에 붙여서 사용할 수 있습니다.

그리고 커스텀뷰 클래스에 만들어놓은 메소드들은

textViews[i].setVolumeText(volume)
textViews[i].setBarImage(image)

요런 식으로 사용할 수 있습니다.


실제로 사용해보시면 크게 어렵지 않으실 거에요.

이상입니다. 감사합니다.

반응형