버그 잡이

[안드로이드, Kotlin] 내가 만든 CustomView 모음 #ProgressBar #TimePicker #EditText 본문

안드로이드

[안드로이드, Kotlin] 내가 만든 CustomView 모음 #ProgressBar #TimePicker #EditText

버그잡이 2020. 5. 7. 17:35

오늘 날 잡아서 앱에서 사용될 CustomView들을 만들었습니다.

 

원래는 customView를 안 썼었는데 이렇게 만들어서 쓰니 Activity에서 코드가 확 줄어듭니다.

 

 

 

#ProgressBar

 

 

- 영어 단어를 맞추면 전체 갯수 중 몇개를 맞췄는지 보여주는 TextView가 추가된 progressbar가 필요했습니다.

- 퍼센트 형태가 아니라 "맞힌 단어수 / 전체 단어수" 이기에 매개변수를 두개를 받았습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <ProgressBar
        android:id="@+id/custom_progressbar"
        style="@android:style/Widget.Holo.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:progress="0"
        android:layout_marginTop="10dp"/>

    <TextView
        android:id="@+id/TV_seekBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/skyBlue"
        tools:text="1/5"/>

</LinearLayout>

 

open class CustomProgressBar @JvmOverloads constructor(context: Context, attrs: AttributeSet?=null, defStyleAttr: Int=0)
    : LinearLayout(context, attrs, defStyleAttr){

    init {
        inflate(context, R.layout.custom_seekbar, this)
    }

    fun settingProgress(correctNum : Int, totalNum : Int){

        //progressbar 진행상황 표시
        val percentage = (correctNum * 100)/totalNum
        custom_progressbar.progress = percentage

        //progressbar 아래 진행 상황 숫자로 나타내기
        TV_seekBar.text = "${correctNum}/${totalNum}"

        //텍스트 위치 계산
        val xPosition=  (((custom_progressbar.right - custom_progressbar.left) / custom_progressbar.max) * custom_progressbar.progress ) + custom_progressbar.left
        TV_seekBar.translationX = xPosition.toFloat() - (TV_seekBar.width/2)

    }

}

 

 

 

 

#TimePicker

 

- setTimeExisting 기존에 저장된 Time을 받아서 TimePicker 초기 시간을 설정하는 메서드입니다.

- DB 에 저장한 date 형태를 TimePicker에서 요구하는 형태로 변환해주고 버전 별로 따로 처리해줘야하는 번거로움을 여기서 처리했습니다.

 

open class CustomTimepicker @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TimePicker(context, attrs, defStyleAttr) {

    fun setTimeExisting(item : String){
        //timepicker는 calendar 자료형만 받을 수 있어.
        var calendar = Calendar.getInstance()
        calendar.time = timeFormat(item)

        //초기화
        if (Build.VERSION.SDK_INT < 23) {
            this.currentHour = calendar.get(Calendar.HOUR_OF_DAY)
            this.currentMinute = calendar.get(Calendar.MINUTE)
        } else {
            this.hour = calendar.get(Calendar.HOUR_OF_DAY)
            this.minute = calendar.get(Calendar.MINUTE)
        }
    }


    private fun timeFormat(item: String): Date? {
        val itemTrimed = item.replace(" ", "")
        val format = SimpleDateFormat("hh:mm")
        val time = format.parse(itemTrimed)
        return time
    }

}

 

 

 

 

#EditText

 

- 알파벳만 입력되도록 하는 edittext입니다.

- 알파벳이 아닌 다른 문자가 입력되면 문자가 입력되지 않고 "영단어를 입력해주세요"라는 메시지를 띄운다.

 

open class OnlyAlphabetEditText : AppCompatEditText {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    init {
        onlyAlphabetFilterToEnglishET()
    }

    private fun onlyAlphabetFilterToEnglishET() {
        this.setFilters(arrayOf(
            InputFilter { src, start, end, dst, dstart, dend ->
                if (src == " ") { // for space
                    return@InputFilter src
                }
                if (src == "") { // for backspace
                    return@InputFilter src
                }
                if (src.matches(Regex("[a-zA-Z]+"))) {
                    return@InputFilter src
                }
                Toast.makeText(context, "영단어를 입력해주세요", Toast.LENGTH_LONG).show()
                this.setText("")
                return@InputFilter ""

            }
        ))
    }
}

 

*여기서는 @JvmOverloads 를 사용하지 않았다. TextView와 EditText는 @JvmOverloads를 사용할 경우 style이 초기화 되어 기존 style을 사용할 수 없다. 그래서 @JvmOverloads의 도움을 받지 않고 직접 생성자를 설정해줬다.

반응형
Comments