-:blue_heart: โํ์๊ณผ์ (์๋ฃ:10/17)
1.MainActivity ๋ก๊ทธ์ธ ํ๋ฉด์ ๋ชจ์ต์ด๋ค. ํ์๊ฐ์ ๋ฒํผ์ ๋๋ฅด๋ฉด 2.secondActivity๋ก ๋์ด๊ฐ๋ค. ๋์ด๊ฐ๋๋ intent๋ฅผ ์ฌ์ฉํ๋ค.
2.SecondActivity ํ์ ๊ฐ์ ํ๋ฉด์ผ๋ก SignUpActivity์ด๋ค. EditTextView์์ inputType์ ๋ณํ์ํค๋ฉด password๋ถ๋ถ์ ๊ธ์๊ฐ ์๋ณด์ด๊ฒ ํ ์ ์๋ค. hint์์ฑ์ ์ ์ฉํ๋ฉด ์ ๋ ฅ์ด ์๋ ์ํ์์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ธ์จ๊ฐ ๋ํ๋๋ค.
#๊ธฐ๋ณธํ๋ฉด์ ๋ชจ์ต
ํ๋๋ผ๋ ์ ๋ ฅ์ด ์๋์์ ๋ Toast๋ฉ์ธ์ง๋ก ์ ๋ ฅ๋์ง ์์ ๊ฐ์ด ์์์ ์๋ ค์ค๋ค.
#์คํจ ํ ์คํธ๋ฉ์ธ์ง
๋ชจ๋ input์ด ๋ค์ด์จ๋ค์ ๋ฒํผ์ ๋๋ ์ ๋ ํ์๊ฐ์ ์ฑ๊ณต toast๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ๋ค.
#์ฑ๊ณต ํ ์คํธ ๋ฉ์ธ์ง
(๊ณผ์ ์๋ฃ 10/17)- ๋ณด์ ํ์/readme์ ์ฝ๋๋ธ๋ญ ๋ฃ๋๋ฒ ๋ฐฐ์ฐ๊ธฐ->ํ์ธ
-:tiger: : โ์ฌํ๊ณผ์ 1 (๊ณผ์ ์๋ฃ 10/29) ํ์๊ฐ์ ์ดํ mainํ๋ฉด์ผ๋ก ๋์๊ฐ๋ฉด id์ password๊ฐ ์ ๋ ฅ๋ ์ํ์ด๋ค. startActivityForResult์ ํ์ฉํ์๊ณ , onActivityResult๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ์ฌ ๋ด๋ถ ์ค์ ์ ๋ฐ๊ฟจ๋ค. id์ pw๋ฅผ ์ด์ ํ๋ฉด์์ ๋ฐ์ดํฐ ๊ฐ์ ๋ฐ์์์ setText๋ฅผ ํ๋ค.
-์ฌ์ง ์ฌ์ด์ฆ ์ค์ด๋ ๋ฐฉ๋ฒ์ ๋ค์ ์ฐพ์๋ด์ผํจ-> <img src="" width=""๋ก ๊ฐ๋ฅ
-:tiger: ์ฌํ๊ณผ์ 2 ( ๋ฏธ์: ) sharedPreferences๋ฅผ ์ฌ์ฉํด ์๋๋ก๊ทธ์ธ์ ๊ตฌํํ๋ค. ์๋๋ก๊ทธ์ธ ๋ฒํผ์ ๋ฐ๋ก ์ถ๊ฐํ์๋ค.
-:blue_heart: ํ์๊ณผ์ (๊ณผ์ ์๋ฃ:10/30)
๐ฆ ์๋ฌ์ํฉ >> โ ๋๋ฒ์งธ ์ธ๋ฏธ๋ ํ์ ๊ณผ์ ๋จ๋ ์ผ๋ก๋ ์คํ์ด ๋๋๋ฐ, 1์ฃผ์ฐจ ๊ณผ์ ์ ํจ๊ป ๋ถ์ด๋ฉด (์ ์ฒด ํฉ๋ณธ์์) RecyclerView์์ Recycler_detail๋ก ๋์ด๊ฐ๋ ๊ณผ์ ์์ ์ค๊ฐ์ ๋ฉ์ถ๋ ์ํฉ์ด ๋ฐ์ํ๋ค. ์ด๋ค ์์ธ์ด ๋ฌธ์ ์ธ์ง ํ์ธ์ด ํ์ํจ.
๋๋ฒ์งธ ํ์ ๊ณผ์ ๋จ๋ ์คํ์ https://github.com/NaHui999/2nd_Seminar ์ ์ฌ๋ ค๋์์.
3์ฃผ์ฐจ ๊ณผ์ ๋ฅผ ํ๋ฉฐ Recylcer fragment๋ฅผ ๋ง๋ค๋ appbar๋ฅผ ๋ฐ๋ก ๋ง๋ค ์ ์์ด, ํ๋๊ทธ๋จผํธ์ linear๋ง ๋ฐฐ์นํ์์. grid ์ linear ์ค๊ฐ๋ ์ฌํ๊ณผ์ 1๋ํ ์ ๋งํฌ์์ ํ์ธ ๊ฐ๋ฅํจ.
item_list_recycler.xml์ ๋ฌ์ ๊ณ์ ๋ฐ๋ณต ์ฌ์ฉ๋ ์์ดํ ๋ ์ด์์์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ ์์ดํ ์ ๋ค์ด๊ฐ๋ ๋ฐ์ดํฐ๋ฅผ RecyclerData๋ก ๋์์ผ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ๋ทฐ์ ๋ฃ์ด์ฃผ๋ ์ญํ ์ด RecyclerViewHolder์ด๊ณ , ์์ดํ ๋ณ ๋ทฐ ํ๋๋ฅผ ์์ฑํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ฎ๋ ์ญํ ์ RecyclerAdapter์ด๋ค.
๋์ ํ๋กํ์ Recycler๋ทฐ๋ก ๋ง๋ ๋ค์ Adapter์ intent๋ฅผ ์ถ๊ฐํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๋ณด๋ด์ Recycler_detail ์ฐฝ์ ๋ง๋ค์ด ์์ธํ ๋ด์ฉ์ ํ์ํด์ค๋ค.
class MainActivity : AppCompatActivity() {
private lateinit var RecyclerAdapter: RecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
RecyclerAdapter = RecyclerAdapter(this)
main_rcv.adapter = RecyclerAdapter
main_rcv.layoutManager = LinearLayoutManager(this) //์ด ๋ ์ด์์์ ๊ฒฉ์ํ์ผ๋ก๋ ๋ฐ๊ฟ ์ ์๋ค.
RecyclerAdapter.data = mutableListOf(
RecyclerData("์ด๋ฆ","๋ํฌ์ ","2020/10/1","์ด๋ฆ์ ๋ํ ์์ธํ ์ค๋ช
"),
RecyclerData("๋์ด","22","2020/10/2","๋์ด์ ๋ํ ์์ธํ ์ค๋ช
"),
RecyclerData("ํํธ","์๋๋ก์ด๋","2020/10/3","ํํธ์ ๋ํ ์์ธํ ์ค๋ช
"),
RecyclerData("GitHub","www.github.com/nahui999","2020/10/4","๊นํ์ ๋ํ ์์ธํ ์ค๋ช
"),
RecyclerData("Blog","None","2020/10/5","๋ธ๋ก๊ทธ์ ๋ํ ์์ธํ ์ค๋ช
"),
RecyclerData("Sopt","www.sopt.org","2020/10/6","์ํธ์ ๋ํ ์์ธํ ์ค๋ช
")
)
RecyclerAdapter.notifyDataSetChanged()
}
}
์๋ recycler ์ฐฝ์ ๋ชจ์ต. Adapter๋ฅผ ๋ถ๋ฌ์จ๋ค.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
val view=LayoutInflater.from(context).inflate(R.layout.item_list_recycler,parent,false)
return RecyclerViewHolder(view)
}
override fun getItemCount(): Int {
return data.size
}
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
holder.onBind(data[position])
holder.itemView.setOnClickListener{
val intent=Intent(holder.itemView.context,Activity_Recycler_Detail::class.java)
intent.putExtra("title",data[position].title)
intent.putExtra("subtitle",data[position].subTitle)
intent.putExtra("date",data[position].date)
intent.putExtra("add",data[position].add)
startActivity(holder.itemView.context,intent,null)
}
RecyclerAdapter๋ onCreateViewHolder์ getItemCount, onBindViewHolder๋ฅผ ํ์์ ์ผ๋ก ์ค๋ฒ๋ผ์ด๋ ํด์ผํ๋ค.
class RecyclerViewHolder (itemView:View):RecyclerView.ViewHolder(itemView){//val,varํ๋ฉด ์ ์ธ๊ณผ ๋์์ ์ด๊ธฐํ.
private val title:TextView=itemView.findViewById(R.id.item_title) //๋ฐ์ธ๋ฉ์ํด.
private val subTitle:TextView=itemView.findViewById(R.id.item_subtitle)
fun onBind(data: RecyclerData){//Recyclerdata.kt๊ฐ ๊ฐ์ฒด๋ก ๋ค์ด์ค๊ฒ๋จ.
title.text=data.title
subTitle.text=data.subTitle
}
}
recyclerViewHolder๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ธ๋ฉ์ ์ํค๋ ์ญํ ์ ํ๋ค.
-:tiger: : โ์ฌํ๊ณผ์ 1 ( ์์ฑ: 11/1)
grid์ linear layout์ ์๋ค๊ฐ๋ค ํ ์ ์๋๋ก appbar์ ์ถ๊ฐํ์ฌ ์งํํ์์.
3์ฃผ์ฐจ ๊ณผ์ ๋ฅผ ํ๋ฉฐ appbar๋ฅผ fragment์ ์ถ๊ฐํ๋ ๊ฒ์ ์ด๋ ค์์ ๊ฒช์ด ๋ฐ๋ก ๋ถ๋ฆฌํ์ฌ repository๋ฅผ ์์ฑํจ.
-:tiger: :์ฌํ๊ณผ์ 2 (๋ฏธ์)
-:blue_heart: ํ์๊ณผ์ (์์ฑ: 11/5)
Activity ์์ ์ฌ๋ฌ๊ฐ์ fragment๋ฅผ ๋์ ๊ฐ๋ณ ์๋ํ๊ฒ ๋ง๋ค ์ ์์.
-> ์ค๋ณต ํผํ๊ธฐ์ํ ๋ฐฉ๋ฒ
ํ๋๊ทธ๋จผํธ์ onCreate(), onCreateView(), on ActivityCreated()๊ฐ ์๋ค.
์ฌ๊ธฐ์๋ onCreateView()๋ง ์ฌ์ฉํ๋ค.
๋์์์ด ์ถ๊ฐ๊ฐ ์๋์ด์ ์ฐ์ ์คํฌ๋ฆฐ์ท์ผ๋ก ๋์ฒด
"""
class FirstFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_first, container, false)
return view
}
}
"""
์ด ๊ณผ์ ์์๋ Activity1๊ฐ์, Profile/Recycler/Empty Fragment์
ProfileFragment ๋ด์ Info์ Other Fragment๋ก ์ด๋ฃจ์ด์ง๋ค.
Viewpager๋ฅผ ์ด์ฉํด ์ฌ๋ผ์ด๋ ํ์์ผ๋ก ๋ณด์ฌ์ค์ ์๋๋ฐ, ViewPagerAdapter๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
""""
class ViewPagerAdapter(fm: FragmentManager): FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT){
var fragments= listOf<Fragment>()
override fun getItem(position:Int): Fragment=when(position){
0->FirstFragment()
1->SecondFragment()
else->throw IllegalStateException("Unexpected position &position")
}
override fun getCount():Int =2
//override fun getItem(position: Int): Fragment =fragments[position]
//override fun getCount():Int=fragmets.size
}
"""
์ ๋ฐฉ์์ผ๋ก ๊ฐ์ ๋๊ฒจ์ฃผ๊ฒ ๋๋ฉด ViewPagerAdapter๋ 2๊ฐ ๋ง๋ค์ด์ ธ์ผํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ํฐ๋นํฐ์์ ์๋์ฒ๋ผ Adapter๋ฅผ ํธ์ถํด์ฃผ์ด์ ์ ์ฉํ๋ค.
"""
class ProfileActivity : AppCompatActivity() {
private lateinit var btmViewpageradapter: Btm_ViewPagerAdapter
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)//๋์ค์ activity_profile ๋ก ๋ฐ๊ฟ์ผํจ.
//BTM ViewPager ๋๊ธฐ๊ธฐ
btmViewpageradapter=Btm_ViewPagerAdapter(supportFragmentManager)
btmViewpageradapter.fragments= listOf(
AccountFragment(),
RecyclerFragment(),
EmptyFragment()
)
sample_bottom_viewpager.adapter=btmViewpageradapter
//๋ทฐํ์ด์ ๋ฅผ ์ฌ๋ผ์ด๋ ํ์๋ ๊ทธ์ ๋์๋๋ ํ๋จ ํญ ๋ณ๊ฒฝ
sample_bottom_viewpager.addOnPageChangeListener(object: ViewPager.OnPageChangeListener{
override fun onPageScrollStateChanged(state: Int){
}
override fun onPageScrolled(
position: Int,
positionOffset:Float,
positionOffsetPixels:Int
){}
override fun onPageSelected(position:Int){
sample_bottom_navi.menu.getItem(position).isChecked=true
}
})
//ํ๋จํญ์ ๋๋ ์๋ ๋ทฐํ์ด์ ํ๋ฉด ๋ณ๊ฒฝ
sample_bottom_navi.setOnNavigationItemSelectedListener {
var index by Delegates.notNull<Int>()
when(it.itemId){
R.id.menu_account->index=0 //์ฒซ ํ๋ฉด์ ์ธ๋ฑ์ค ๊ธฐ์ค 0๋ฒ์งธ
R.id.menu_recy->index=1
R.id.menu_msg->index=2
}
sample_bottom_viewpager.currentItem=index
true //๋ถ๋ฆฐ ๋ฐํ
}
}
""""
Profile/Recycler/Empty Fragment ๋ BottomNavigator๋ฅผ ์ฌ์ฉํด ํ๋จํญ์ผ๋ก ์ฌ๋ผ์ด๋๋ ํฐ์น ๋ฐฉ์์ผ๋ก ์ด๋ํ๋ค. ์ ์ฝ๋๋ฅผ ๋ณด๋ฉด,
addOnPageChangeListener์ setOnNavigationItemSelectedListener๊ฐ ๊ทธ ์ญํ ์ ํ๋ค.
ProfileFragment ๋ด์ ํ๋ ๊ทธ๋จผํธ๋ : Tab Layout์ ์ฌ์ฉํ๋ค.
ProfileFragment ๋ด๋ถ์์ ์๋ํ๋ฏ๋ก ProfileFragment.kt์
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewPagerAdapter = ViewPagerAdapter(childFragmentManager)
viewPagerAdapter.fragments = listOf(
FirstFragment(),
SecondFragment()
)
sample_tab_viewpager.adapter=viewPagerAdapter
sample_tab.setupWithViewPager(sample_tab_viewpager)
sample_tab.apply{
getTabAt(0)?.text="INFO"
getTabAt(1)?.text="OTHER"
}
}
๋ฅผ ์ถ๊ฐํ๋ค.
๐ฏ : โ์ฌํ๊ณผ์ _ ์์์.
4๋ฒ์งธ ์ธ๋ฏธ๋_ ๋์์ธ ์ธ๋ฏธ๋
5๋ฒ์งธ ์ธ๋ฏธ๋_ ํด๋ํฉ๋
-:blue_heart: ํ์๊ณผ์ (์์ฑ: 12/4)
postman์ผ๋ก ์๋ฒ ํ์ธ.
[sign-up]
[sign in]
<ํ์ ๊ณผ์ ์ ์ฒด ๋ชจ์ต.gif>
์ฝ๋์ค๋ช
module gradle์ ์ถ๊ฐ
// https://github.com/square/retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// Retrofit ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๋ต์ผ๋ก ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํจ
implementation 'com.squareup.retrofit2:retrofit-mock:2.9.0'
// https://github.com/google/gson
implementation 'com.google.code.gson:gson:2.8.6'
// Retrofit์์ Gson์ ์ฌ์ฉํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
Manifest ํ์ผ์ ์ถ๊ฐ
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:usesCleartextTraffic="true"
์ธํฐํ์ด์ค ์ค๊ณ
Headers๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ , POST์ธ์ง GET์ธ์ง ๋ช ์ํด์ค๋ค.
interface SoptService{
@Headers("Content-Type:application/json")
@POST("/users/signin")
fun postLogin(
@Body body : RequestLoginData
) : Call<ResponseLoginData>
}
Call์ ๋น๋๊ธฐ ํต์ ์ ๋์์ฃผ๋ Retrofit ๊ฐ์ฒด์ด๊ณ , ์๋ฒ์์ ๋ฐ์์ฌ Response๊ฐ์ฒด๋ฅผ ๋ช ์ํด์ค๋ค. ๋ฆฌ์คํธ ๊ฐ์ฒด์ธ๊ฒฝ์ฐ List๋ผ ์ด๋ค
Request์ Response Dataํํ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
JSONํ์ผ์ Kotlin Data Class ํํ๋ก ๋ง๋ค์ด์ฃผ๋ Plugin์ ์ถ๊ฐํ์๋ค.
data class RequestLoginData(
val email : String,
val password :String
)
data class ResponseLoginData(
val data: Data,
@SerializedName("message")
val responseMessage: String,
val status: Int,
val success: Boolean
){
data class Data(
val email:String,
val password: String,
val userName: String
)
}
JSON ๊ฐ์ฒด์ ํค๊ฐ๊ณผ ํ์ ์ ๋ง์ถฐ์ค๋ค. @SerializedName ์ด๋ ธํ ์ด์ ์ ํตํด JSON ๊ฐ์ฒด์ ๊ฐ๊ณผ ๋์์ํฌ์์๋ค. JSON์๋ "message":"๋ก๊ทธ์ธ์ฑ๊ณต."์ฒ๋ผ ๋์์๋ค.
Interface๋ฅผ ์ค์ ๊ตฌํ์ฒด๋ก ๋ง๋ ๋ค.
object SoptServiceImpl {
private const val BASE_URL = "http://15.164.83.210:3000"
private val retrofit : Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
val service : SoptService = retrofit.create(SoptService::class.java)
}
์ฑ๊ธํค ๊ฐ์ฒด์ด๋ฏ๋ก Objectํํ์ด๋ค.
BaseURL์ ์ ์ ๋๋ /๋ฅผ ์กฐ์ฌํด์ผํ๋ค. ์์ ์ธํฐํ์ด์ค๋ฅผ ์ค๊ณํ ๋ /๋ฅผ ์ผ๋ค๋ฉด ์ฌ๊ธฐ์๋ ์ฐ๋ฉด ์๋๋ค. ๊ฒน์น๋ฉด ์ธ์ ๋ชปํจ.
retrofit ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋จ๊ณ๋ก Builder๋ ์์ฑ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ด๊ณ , baseUrl()์ ๋น๋๊ฐ์ฒด์ URL์ ํธ์ถํ๋ค. ์๋ฒ์ main url ์ ๋ฌํ๋ค.
add~ ๋ gson์ ์ฐ๋ํ๋ ์ญํ ์ํ๋ค. (๋ ํธ๋กํ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ฝ๊ฒ), build๋ ๋ฐํํ๋ค.
์๋ Activity์์ Callback ๋ฑ๋กํ์ฌ ํต์ ์์ฒญ
login_btn.setOnClickListener{
id=id_input.text.toString()
pw=pw_input.text.toString()
val call: Call<ResponseLoginData> = SoptServiceImpl.service.postLogin(
RequestLoginData(email = id, password = pw)
)
call.enqueue(object : Callback<ResponseLoginData> {
override fun onFailure(call: Call<ResponseLoginData>, t: Throwable) {
//ํต์ ์คํจ ๋ก์ง
Toast.makeText(this@MainActivity, "๋ก๊ทธ์ธ ์คํจ", Toast.LENGTH_LONG).show()
}
override fun onResponse(
call: Call<ResponseLoginData>,
response: Response<ResponseLoginData>
) {
response.takeIf { it.isSuccessful }
?.body()
?.let { it ->
it.data.let { data ->
Toast.makeText(this@MainActivity,"${data.userName} ๋ ํ์ํฉ๋๋ค.",Toast.LENGTH_LONG).show()
}
} ?: showError(response.errorBody())
}
private fun showError(error: ResponseBody?) {
val e = error ?: return
val ob = JSONObject(e.string())
Toast.makeText(this@MainActivity, ob.getString("message"), Toast.LENGTH_LONG)
.show()
}
})
}
์ฌ๊ธฐ์๋ ๋ก๊ทธ์ธ ๋ฒํผ์ ๋๋ ์ ๋ ์ํํ๋๋ก ํ๊ธฐ ์ํด setonClickListener ์์ call์ ๋ฃ์๋ค.
onFailure๋ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ด ์๋์์ ๋ ๋ฐ์ํ๋ฏ๋ก, ๋คํธ์ํฌ ๊ผญ ํ์ธํ์...^^
onResponse๋ ์ ์์ํ๋ ๊ฒฝ์ฐ๋ก data๋ฅผ ๋ฐ์์์ userName์ Toast๋ฉ์ธ์ง๋ก ์๋ ค์ค๋ค.
ShowError๋ ๋คํธ์ํฌ๋ ์ ์ ์ฐ๊ฒฐ์ด์ง๋ง ์๋ฌ๊ฐ ๋ฐ์ํ ๋ ๋ฌธ์ ์ํฉ์ ์๋ ค์ค๋ค.
-:tiger: : ์ฌํ๊ณผ์ 1 ( ์์ฑ: 12/11)
Reqres - A hosted REST-API ready to respond to your AJAX requests
reqres.in ์ฌ์ดํธ์์ ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์์ ์งํ.
์ ์ฒด์ ์ธ ๊ตฌํ์ ์์ ๊ฐ์ผ๋ฏ๋ก ํท๊ฐ๋ ธ๋ ๋ถ๋ถ๋ง ๋ช ์.( ํ๋ฆฐ ๋ถ๋ถ์ ์๋ ค์ค ๋ค๋น์ธ๋ ๋กํ:blue_heart: )
Glide๋ฅผ ์ฌ์ฉํด avatar, ์ฆ ๊ทธ๋ฆผ์ ๋ฐ์์ฌ ์ ์๋ค.
Glide.with(itemView)
.load(data.avatar)
.placeholder(R.drawable.earth)
.error(R.drawable.earth)
.into(avatar)
placeholder๋ ๋ก๋ฉ์ค ๊ทธ๋ฆผ์ด๊ณ , error๋ ์๋ฌ๋ฐ์์ ๊ทธ๋ฆผ์ด๋ค. avatar๋ผ๋ xml ์ฌ์ง ์นธ์ ๋ค์ด๊ฐ๋ค.
itemView๋ถ๋ถ์ ๊ณ์ this๋ผ๊ณ ์จ์ ์๋ฌ๊ฐ ๋ฌ๋ค.
BaseUrl ์กฐ์ฌํ๊ธฐ
object ReqresServiceImpl {
private const val BASE_URL = "https://reqres.in/"
//๋ค์ ๋ ๋ด์ฉ
}
ReqreAdapter์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ๋, ๋ค์๊ฐ์ฒด๊น์ง ๋๊ฒจ๋ฐ์์์ผํจ.
var data= mutableListOf<ReqresData.DataX>()
ReqresData๋ง ์ง์ด๋ฃ๊ณ , ๊ทธ ๋ค์ ๋ด๋ถ ์ฝ๋์์ .data.dataX๋ก ์ฐ๋ ค๊ณ ํ๋๋ ์๋ํ์ง ์์๋ค.
holder.onBind(data[position])
์ด ๋ถ๋ถ๋ ์๋ํ์ง ์๊ฒ ๋๊ธฐ ๋๋ฌธ์ ์์ฒ๋ผ ์์ฑํด์ผํ๋ค. ReqresData.DataX๋ก