공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
커스텀 뷰는 소셜 로그인 같은 레이아웃의 형태는 같지만 들어가는 이미지,
텍스트, 색상이 다를 때 요긴하게 사용할 수 있습니다.
저는 위 아래로 텍스트가 들어가는 막대바가 한 액티비티에 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)
요런 식으로 사용할 수 있습니다.
실제로 사용해보시면 크게 어렵지 않으실 거에요.
이상입니다. 감사합니다.