728x90
안녕하세요.
이번 포스팅에서는 다른 포스팅에서 구현한 로또 정보 받아오는 소스에 MVVM 패턴을 적용해 보겠습니다.
의존성 주입은 hilt를 사용합니다.
retrofit2, mvvm, hilt 내용은 아래를 참고해 주세요.
https://it-of-fortune.tistory.com/30
https://it-of-fortune.tistory.com/27
https://it-of-fortune.tistory.com/26
언어: 코틀린
sdk vsersion
- compile: 33
- min: 21
- target: 33
ViewModel class를 생성하여 아래와 같이 작성합니다.
Fragment에 작성했던 코드를 이곳으로 옮기고, 데이터 바인딩을 위한 코드를 추가했습니다.
LottoViewModel.kt
@HiltViewModel
class LottoViewModel @Inject constructor() : ViewModel() {
private val _lottoResult = MutableLiveData<LottoData>()
val lottoResult: LiveData<LottoData> get() = _lottoResult
private var inputText: CharSequence = ""
fun onTextInput(text: CharSequence) {
inputText = text
}
fun onSearchClicked() {
if (inputText.isNotEmpty()) {
getDrawingResult()
}
}
private fun getDrawingResult() {
viewModelScope.launch(Dispatchers.IO) {
_lottoResult.postValue(
getLottoService().getDrawingResult(
method = "getLottoNumber",
drwNo = getDrwNo(inputText).toString()
)
)
}
}
private fun getLottoService(): LottoService {
return Retrofit.Builder()
.client(OkHttpClient.Builder().build())
.baseUrl("https://www.dhlottery.co.kr/")
.addConverterFactory(
MoshiConverterFactory.create()
)
.build()
.create(LottoService::class.java)
}
private fun getDrwNo(text: CharSequence): Int{
return text.toString().toInt()
}
}
이번에는 숫자를 입력하고 검색 버튼을 누르면 해당 회차의 결과 정보를 받아옵니다.
getDrwNo에서 처음에 입력된 0을 걸러줍니다(ex: 0729 -> 729)
layout xml에 data binding을 추가합니다.
fragment_lotto.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.example.laboratory.lotto.LottoViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".lotto.LottoFragment">
<EditText
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:inputType="number"
android:maxLength="4"
android:maxLines="1"
android:onTextChanged="@{(s, start, before, count) -> viewModel.onTextInput(s)}"
app:layout_constraintTop_toTopOf="parent"
tools:text="1004" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="검색"
android:onClick="@{() -> viewModel.onSearchClicked()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.lottoResult.toString()}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="result" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
이로 인해 프래그먼트는 코드가 간략해졌습니다.
xml에 viewModel과 lifeCycleOwner를 알려주는 것이 전부입니다.
LottoFragment.kt
@AndroidEntryPoint
class LottoFragment : Fragment() {
private var _binding: FragmentLottoBinding? = null
private val binding get() = _binding!!
private val viewModel: LottoViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentLottoBinding.inflate(layoutInflater, container, false).apply {
viewModel = this@LottoFragment.viewModel
lifecycleOwner = viewLifecycleOwner
}
return binding.root
}
}
에뮬레이터에서 테스트해 보겠습니다.
의도한 대로 잘 동작합니다.
이상 포스팅을 마치겠습니다.
감사합니다.
728x90
'Android Application > 응용 구현' 카테고리의 다른 글
안드로이드 리사이클러뷰 아이템 클릭(recyclerView item click)처리 (0) | 2023.04.04 |
---|---|
안드로이드의 다양한 데이터 바인딩(editText, Progress bar...) (0) | 2023.04.02 |
Android Studio 연습용 어플 구현2 (사용자 입력2) (0) | 2020.05.26 |
Android Studio 연습용 어플 구현1 (사용자 입력) (0) | 2020.05.25 |
Android Studio 연습용 어플 구현 (Activity 전환) (0) | 2020.05.22 |
댓글