BY ์ตํธ์ค, ๊น์ ๋, ์ํ์
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.android.support:design:29.0.0'
//๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ
implementation 'androidx.recyclerview:recyclerview:1.0.0'
//Retrofit ๋ผ์ด๋ธ๋ฌ๋ฆฌ : https://github.com/square/retrofit
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
//Retrofit ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๋ต์ผ๋ก ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํด
implementation 'com.squareup.retrofit2:retrofit-mock:2.6.2'
//๊ฐ์ฒด ์๋ฆฌ์ผ๋ผ์ด์ฆ๋ฅผ ์ํ Gson ๋ผ์ด๋ธ๋ฌ๋ฆฌ : https://github.com/google/gson
implementation 'com.google.code.gson:gson:2.8.6'
//Retrofit ์์ Gson ์ ์ฌ์ฉํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
//์ด๋ฏธ์ง ๋ก๋ฉ
implementation 'com.github.bumptech.glide:glide:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
//๋๊ทธ๋ ์ด๋ฏธ์ง ์ปค์คํ
๋ทฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ : https://github.com/hdodenhof/CircleImageView
implementation 'de.hdodenhof:circleimageview:3.0.1'
//indecator ํจ๊ณผ
implementation 'com.tbuonomo.andrui:viewpagerdotsindicator:4.1.2'
//multi radiobutton
implementation 'com.yuxingxin.multiradiogroup:library:1.0.0'
//Picaso ๋ผ์ด๋ธ๋ฌ๋ฆฌ (์ด๋ฏธ์ง)
implementation 'com.squareup.picasso:picasso:2.4.0'
//ํ์ด์ค๋ถ ์ฐ๋
implementation 'com.facebook.android:facebook-login:[5,6)'
//socket.io ๋ผ์ด๋ธ๋ฌ๋ฆฌ
implementation('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}
ํ๋ก๊ทธ๋จ ๊ตฌ์กฐ๋ ํฌ๊ฒ data, network, ui๋ก ํจํค์งํ์ฌ ์งํํ์๋ค.
network๋ ๋ค์๊ณผ ์์ ๊ฐ์ด BASE_URL์ ๊ฐ์ง ์ฑ๊ธํค๊ณผ, ํด๋น ๋ถ๋ถ ๊ตฌํ์ ์ด์ฉํ interface,
Kotlin Extension Function์ ์ด์ฉํ enqueue ๋ฉ์๋๊ฐ ์๋ค.
ui๋ ๋๋ฆ๋๋ก ํจํค์ง์ ํ์์ผ๋, ์์ง ๋ทฐ ๊ตฌํ์ด ์งํ์ค์ด๋ผ ๊ตฌ์กฐ๊ฐ ๋ช ํํ์ง๋ ์๋ค. ํ์ง๋ง ๋ก๊ทธ์ธ,ํ์๊ฐ์ ์ ๋ํ ๋ถ๋ถ๊ณผ ํ๋จ ํญ๋ฐ๋ฅผ ๋๋ ์ ๋ ์ ํ๋๋ 5๊ฐ์ง ํ๋๊ทธ๋จผํธ๊ฐ ์๊ณ , ํด๋น ํ๋๊ทธ๋จผํธ์์ ์ฐ๋๋๋ ์กํฐ๋นํฐ๊ฐ์ ๊ฒฝ์ฐ ๊ทธ ํจํค์ง ์์ ๋ถ๋ฅ๋ฅผ ํ์ฌ ์งํํ๊ณ ์๋ค.
์ดํ ์คํ์ ๋ฐฐ๊ฒฝ์ ๋ณํ, ๋ก๊ทธ์ธ / ํ์๊ฐ์ ์ EditText๋ณํ ๋ฑ์ ์ ๋๋งค์ด์ ์ ์ ์ฉํ์๋ค. ObjectAnimator์ ALPHA, TRANSLATE ์์ฑ ๋ฑ์ ์ด์ฉํ์๋ค.
kotlin extension์ ์ด์ฉํ์ฌ ์์ฑ๋ enqueue๋ฉ์๋์ sendToast๋ผ๋ ๋ฉ์๋๋ฅผ ์ ์ฉํ์๋ค. ์ ์ด๋ฏธ์ง์์๋ ์ด๋ฉ์ผ ์ค๋ณต ์ฒดํฌ, ๋ก๊ทธ์ธ ์์ฒญ์ enqueue ํจ์๋ฅผ ์ด์ฉํ์๊ณ , ์ด๋ฉ์ผ ์ค๋ณต์ฒดํฌ ๊ฒฐ๊ณผ๋ฅผ ๋์ฐ๋ ํ ์คํธ ๋ํ Toast์ ํจ์๋ฅผ ํ์ฅ์์ผ sendToast๋ฅผ ์ด์ฉํ์๋ค. (๊ธฐ์กด ์ฝ๋์ ๋ฐ๋ณต๋๋ ์์๋ค์ ์ค์ผ ์ ์์๋ค.)
ex 1) ํ ์คํธ๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๋ ๊ฒฝ์ฐ val toast = Toast.makeText(this,"๋ฉํธ",Toast.LENTH_SHORT) toast.show()
๋ฅผ kotlin extension ์ ์ด์ฉํ์ฌ ์์ฑํ ํจ์ sendToast()๋ฅผ ์ด์ฉํ์ฌ sendToast("๋ฉํธ") ๋ฅผ ์์ฑํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
ex 2) enqueue ๋ฉ์๋
ex 3) textview ๊ฐ๊ฒฉ์ 1000์ -> 1,000์ ์ผ๋ก ๋ฐ๊พธ์ด์ฃผ์๋ค.
ex 4) editText ๊ฐ๊ฒฉ ์ ๋ ฅ์ ์๋์ผ๋ก ,(์ฝค๋ง) ๋ฃ์ด์ฃผ์๋ค.
๊ฐ๋ ์ฑ์ ๋์ด๊ธฐ ์ํด ์์ ๊ฐ์ด ๋๋ค์์ ํ์ฉํ์๋ค.
implementation 'com.tbuonomo.andrui:viewpagerdotsindicator:4.1.2' ์ ์ด์ฉํด ์ถ๊ฐํ Indicator๋ฅผ ๋ทฐํ์ด์ ธ์ ์ฐ๋์์ผ ์ ํ ํจ๊ณผ๋ฅผ ์ ์ฉ์์ผฐ๋ค.
๋ํ ๋งค๊ฑฐ์ง์ ์ธ๋ก ์คํฌ๋กค ๊ธฐ๋ฅ ๋ํ Vertical ViewPager ๊ฒ์์ ํตํด ๊ธฐ์กด์ ๋ทฐํ์ด์ ๋ฅผ ๋ณํํ ์ปค์คํ ์ ์ ์ฉ์์ผฐ๋ค.
์์ ์ฌ์ฉ๋ ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ๋ ์ธ๋ฏธ๋๋ ๋ฐฐ์ด ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์ ์ฉ๋์๋ค.
-
ํํ๋ฉด์ ์๋จ ๋ทฐํ์ด์ ธ๋ฅผ ์ ์ธํ ๋ชฉ๋ก๋ค
-
๋ง์ดํ์ด์ง์ ์ต๊ทผ ๋ณธ ์ํ, ์ข์์/ํ๋ก์ฐ ๋ฆฌ์คํธ
https://re-build.tistory.com/11 ํด๋น ์ฌ์ดํธ ๋ฐ facebook developer ์ฌ์ดํธ๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ํ์ด์ค๋ถ ๋ก๊ทธ์ธ ์ฐ๋์ ํ์๋ค. ์ด์ ๋๋ถ์ด SharedPreferences๋ฅผ ํ์ฉํด ์๋๋ก๊ทธ์ธ ๋ฐ ๋ก๊ทธ์์์ ๋ํ ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์๋ค. ์๋๋ ํด๋น ํ๋ฉด์ด๋ค.
๊ตฌ๊ธ ๋จธํฐ๋ฆฌ์ผ ๋์์ธ ๊ฐ์ด๋์ ๊ตฌ๊ธ๋ง์ ํตํด recyclerview์ ์์ดํ ํด๋ฆญ์ ์กํฐ๋นํฐ๋ก ์ ํ๋ ๋ ์ ๋๋งค์ด์ ์ ๊ตฌํํ์๋ค. ์๋๋ ํด๋น ํ๋ฉด๊ณผ ์ฝ๋์ด๋ค.
์ท์ ์ ํํ ๋๋ RadioButton์ ์ด์ฉํ์๋ค. ์ด ๊ณผ์ ์์ RadioGroup์ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ ์ํ๋ก๋ ๋ ์ค๋ก ๋์ด ํ ์ ์์๊ธฐ์ implementation 'com.yuxingxin.multiradiogroup:library:1.0.0' ์ ํตํด ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด ์ฃผ์๋ค. Bottom sheet Behavior ์์ฑ ์ค hideable="true"๋ฅผ ํตํด ๋๋๊ทธํด์ ํํฐ ๋ทฐ๋ฅผ ๋ด๋ฆด ์ ์๋๋ก ๊ตฌํํด์ฃผ์๋ค.
8. ๊ฐค๋ฌ๋ฆฌ ์ฐ๋ํ๊ธฐ - ๋นํฐ์ง ์ต์ ๋ฑ๋กํ๊ธฐ ์ํด ์ฌ์ง์ ์ฌ๋ฆด ํ์๊ฐ ์๋๋ฐ ์ด๋ฅผ ์ํด ๋ด ํฐ์ ๊ฐค๋ฌ๋ฆฌ๋ฅผ ์ฐ๋ํ ์ ์๋๋ก ํ์๋ค.
์๋ ์ฌ์ง์ ๋ณด๋ฉด 3๊ฐ์ ๋ ์ด์์ ์์ดํ ์ด ์๋ ๊ฒฝ์ฐ +3๊ณผ ๊ฐ์ ์์ฝ ํ์๋ฅผ ํด์ค์ผ ํ ํ์๊ฐ ์์๋ค. ํด๋น ๊ธฐ๋ฅ์ ๋ํด kotlin์ collection ๊ธฐ๋ฅ์ ์ด์ฉํ์๊ณ , ์ด์ ๋ํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
๊ฒฝ๋งค๊ฐ ๋๋๋ ์๊ฐ์ ์๋ฒ์ ๋ฐ์์จ ๋ค ๊ฒฝ๋งค๋ฅผ ์งํ ์ค์ธ ์๊ฐ์ ๊ณ์ฐํ์ฌ ํด๋น ๊ฒฝ๋งค ์์ดํ ๋ทฐ์ ํ๋ฌ๊ฐ๋ ์๊ฐ์ ํ์ํ๋ค. ํด๋น ๊ธฐ๋ฅ์ ๋ํด kotlin์ ์กด์ฌํ๋ CountDownTimer ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ 1์ด๋ง๋ค ์๊ฐ์ด ์ค์ด๊ฐ๋ ๊ฒ์ ํ์ํ๋ค. ์ด์ ๋ํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
fun countDownTimer(long: Long)
{
var countDownTimer = object : CountDownTimer(long*1000, 1000)
{
override fun onFinish() {
tv_auction_detail_extra_time.text = "๊ฒฝ๋งค๊ฐ ๋ง๊ฐ๋์์ต๋๋ค."
tv_auction_detail_extra_text.text = ""
// sendToast("๊ฒฝ๋งค๊ฐ ๋ง๊ฐ๋์์ต๋๋ค.")
}
override fun onTick(p0: Long) {
val hours = p0.div(3600000)
var temp = p0/1000 - hours*3600
val min = p0.div(60000).toInt() - p0.div(3600000)*60
val seconds = temp - min*60
if ( hours < 10)
{
tv_auction_detail_extra_time.text = "0" + hours.toString()+ " : "+ min.toString() + " : " + seconds.toString()
if( min < 10)
{
tv_auction_detail_extra_time.text = "0" + hours.toString()+ " : "+ "0" + min.toString() + " : " + seconds.toString()
}
}
else
{
if(min < 10)
{
tv_auction_detail_extra_time.text = hours.toString()+ " : "+ "0" + min.toString() + " : " + seconds.toString()
}
tv_auction_detail_extra_time.text = hours.toString()+ " : "+ min.toString() + " : " + seconds.toString()
}
}
}
countDownTimer.start()
}
์ํ์ ์ฅ๋ฐ๊ตฌ๋์ ๋ด์ผ๋ฉด ์ํ์ด ์ฅ๋ฐ๊ตฌ๋์ ๋ด๊ธฐ๊ฒ ๋๊ณ , ์ฅ๋ฐ๊ตฌ๋ ๋ทฐ์์ ์ํ์ ์ญ์ ํ๋ฉด ์ฅ๋ฐ๊ตฌ๋์์ ์ํ์ด ์ญ์ ๋๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค. ๋ํ ์ฅ๋ฐ๊ตฌ๋์์ ์ ์ฒด์ ํ ์ฒดํฌ๋ฐ์ค๋ฅผ ํตํด ์ํ๋ค์ ๋ชจ๋ ๋ค ์ ํ ํ๊ธฐ๋ฅผ ์ํ ์ ์ ์ฒด ์ ํ์ด ๋๊ณ , ๋ง์ฝ ํ๋๋ผ๋ ์ํ์ ์ฒดํฌ๋ฐ์ค๊ฐ ์ฒดํฌ๊ฐ ํ๋ฆด ์ ์ ์ฒด์ ํ์ด ํ๋ฆฌ๊ฒ ๊ตฌํํ์๋ค.
//์กํฐ๋นํฐ ๋ด์ ์ฝ๋
cb_cart_check_all.setOnClickListener{
if(cb_cart_check_all.isChecked){
cartGoodsAdapter.isAllSelected = true
cartGoodsAdapter.notifyDataSetChanged()
}else{
cartGoodsAdapter.isAllSelected = false
cartGoodsAdapter.notifyDataSetChanged()
}
}
//์ฒดํฌ๋ฐ์ค ๋ค์ด์๋ RecyclerView์ ๋ทฐํ๋์ ํด๋นํ๋ ๋ถ๋ถ
if(isAllCheck){
cb_cart_goods.isChecked = true
}else{
cb_cart_goods.isChecked = false
}
cb_cart_goods.setOnCheckedChangeListener{
buttonView, isChecked ->
if(isChecked){
ctx.count++
ctx.checkItem()
ctx.selected_cart_list!!.add(goodsData)
}else{
ctx.count--
ctx.checkItem()
ctx.selected_cart_list!!.remove(goodsData)
ctx.cb_cart_check_all.isChecked = false
}
}
ํ์๊ฐ์ ์ฑ๊ณต ํ, ๊ฐ๊ฐ์ ์ ์ ์ ์ทจํฅ์ ๋ฐ๋ฅธ ์ํ์ ์ถ์ฒํด์ฃผ๊ธฐ ์ํด, ์ ์ ๊ฐ ๋ง์์ ๋๋ ์ฌ์ง์ 3๊ฐ ์ด์ ์ ํํ๊ฒ ํ๋ค. ์ ์ ์ ์ทจํฅ์ด ์๋ฒ๋ฅผ ํตํด ๋ถ์์ด ๋์ด์ง๋ฉด, ๊ทธ์ ๋ง๋ ํค์๋๋ฅผ ๊ฐ์ง ์ ๋ฌ(ํ๋ฝ)์ ์ถ์ฒํด์ฃผ๊ณ , ์ทจํฅ์ ๋ง๋ ์คํ์ผ์ ์ท๋ค์ด ํํ๋ฉด์ ๋์ค๊ฒ ๋๋ค.
์ ์ ์ทจํฅ์ ๋ฐ๋ฅธ ์ท๋ค์ด ์ต์ ์์ผ๋ก ๋๋ฌ๋ณด๊ธฐ ํ๋ฉด์ ๋์ค๊ฒ ๋๊ณ , ํํฐ ์์ด์ฝ์ ์ ํํ์ฌ ์ท์ ์ข ๋ฅ, ์๊น, ์คํ์ผ, ์ฌ์ด์ฆ,๋ฑ ์ ์ ํํ๊ฒ ๋๋ฉด ์ํ DB์ ์กด์ฌํ๋ ๋ชจ๋ ์ท๋ค ์ค ์ ์ ๊ฐ ๊ณ ๋ฅธ ํํฐ์ ๋ฐ๋ฅธ ์ท๋ค๋ง ํ๋ฉด์ ์กด์ฌํ๊ฒ ๋๋ค.
์ ์ ๊ฐ ๋ง์์ ๋๋ ์ฌ์ง์ ํด๋ฆญ์ customToast๋ฅผ ํตํด ํํธ ์ด๋ฏธ์ง๊ฐ ํ๋ฉด ์ค์์ ๋จ๊ฒ ๋๊ณ ํด๋น ์ํ์ ํ๋จ ํํธ ๋ฒํผ์ด ์ฑ์์ง๊ฒ ๋๋ค.
class MySharedPreferences(context: Context) {
val PREFS_FILENAME = "prefs"
val PREF_KEY_MY_LOCAL_LOGIN_TOKEN = "local_login"
val PREF_KEY_MY_LOCAL_LOGIN_ID = "local_login_id"
val prefs: SharedPreferences = context.getSharedPreferences(PREFS_FILENAME,0)
val editor = prefs.edit()
/* ํ์ผ ์ด๋ฆ๊ณผ EditText๋ฅผ ์ ์ฅํ Key ๊ฐ์ ๋ง๋ค๊ณ prefs ์ธ์คํด์ค ์ด๊ธฐํ */
/* get/set ํจ์ ์์ ์ค์ . get ์คํ ์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ๋ฉฐ default ๊ฐ์ false
* set(value) ์คํ ์ value๋ก ๊ฐ์ ๋์ฒดํ ํ ์ ์ฅ */
var local_login_token : String?
get() = prefs.getString(PREF_KEY_MY_LOCAL_LOGIN_TOKEN,null)
set(value) = editor.putString(PREF_KEY_MY_LOCAL_LOGIN_TOKEN,value).apply()
}
IO.Option์์ query์ต์
: url์ ์ง์ ์ฟผ๋ฆฌ ๋งค๊ฐ ๋ณ์๋ฅผ ์ ๊ณตํ๋ค.
bid ์ด๋ฒคํธ๋ฅผ ํตํด ์๋ฒ์ ํต์ ํ๋ค.