SOPT 27๊ธฐ 17th APP-JAM : Apophis ๐
๋งค์ผ ์ ๋ 7์ 30๋ถ
https://www.notion.so/b562e3c34a9e4641b5025506546260a0
https://github.com/Apophis-AppJam/ApophisAndroid/projects/1
- Android Studio
- Zeplin
- Figma
- Notion
- Slack
- Gather
- Zoom
-
feature : ๊ธฐ๋ฅ ๊ฐ๋ฐํ๋ ๋ธ๋์น
feature/[์ด์๋ฒํธ] _ [๊ธฐ๋ฅ] _ [layout/inflate]
ex) [Add] ํ ํ๋ฉด Layout ์์ฑ ์๋ฃ
1. ์ค๋ช
1
2. ์ค๋ช
2
[Add] ๊ธฐ๋ฅ์ถ๊ฐ
[Delete] ์ญ์
[Update] ๊ธฐ๋ฅ์์
[Fix] ๋ฒ๊ทธ์์
[Docs] ๋ฌธ์์ ๋ฆฌ
[Chore] ์ก์ผ
/* retrofit */
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'
/* gson */
implementation 'com.google.code.gson:gson:2.8.6'
/* glide */
implementation "com.github.bumptech.glide:glide:4.10.0"
kapt "com.github.bumptech.glide:compiler:4.10.0"
//lottie
implementation 'com.airbnb.android:lottie:3.4.0'
/* recyclerview */
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
/* kakao */
implementation 'com.kakao.sdk:usermgmt:1.28.0'
implementation platform('com.google.firebase:firebase-bom:26.2.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-auth:19.1.0'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
compileOnly 'com.google.android.wearable:wearable:2.8.1'
/* camera */
def camerax_version = "1.0.0-beta07"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:1.0.0-alpha14"
๐ apophis_android
โฃ ๐data
โ โฃ ๐entity
โ โ ๐remote
โ โฃ ๐request
โ โ ๐response
โ ๐ui
โฃ ๐firstDay
โ โ ๐adapter
โฃ ๐login
โฃ ๐main
โ โฃ ๐letter
โ ๐onboarding
โ โ ๐adapter
โฃ ๐secondDay
โ โฃ ๐adapter
โ โฃ ๐findMe
โ โฃ ๐time
โ โ ๐value
โฃ ๐seventhDay
โ โฃ ๐adapter
โ โ ๐tarot
โฃ ๐sixthDay
โ โ ๐adapter
โ ๐ChipFactory.kt
- ์นด๋ฉ๋ผ ์ด๋ฏธ์ง ์บก์ฒ
imageCapture.takePicture(
ContextCompat.getMainExecutor(this),
object : ImageCapture.OnImageCapturedCallback() {
@SuppressLint("UnsafeExperimentalUsageError")
override fun onCaptureSuccess(imageProxy: ImageProxy) {
imageProxy.image?.let {
val rotationDegrees = imageProxy.imageInfo.rotationDegrees
previewPicture = it.toBitmap(rotationDegrees)
iv_camera_capture.setImageBitmap(previewPicture)
super.onCaptureSuccess(imageProxy)
previewMode()
}
}
override fun onError(exception: ImageCaptureException) {
val msg = "Photo capture failed: ${exception.message}"
}
})
imageProxy๋ก ๋ฐ์์ ์ํ๋ ํํ๋ก ๋ณํํด์ ์ฌ์ฉ ๊ฐ๋ฅ
- ๋์นจ๋ฐ ์ผ์ ๋ฉ์๋
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor === accelerometer) {
lowPass(event.values, lastAccelerometer)
lastAccelerometerSet = true
} else if (event.sensor === magnetometer) {
lowPass(event.values, lastMagnetometer)
lastMagnetometerSet = true
}
if (lastAccelerometerSet && lastMagnetometerSet) {
val r = FloatArray(9)
if (SensorManager.getRotationMatrix(r, null, lastAccelerometer, lastMagnetometer)) {
val orientation = FloatArray(3)
SensorManager.getOrientation(r, orientation)
val degree = (Math.toDegrees(orientation[0].toDouble()) + 360).toFloat() % 360
var rotateAnimation = RotateAnimation(
currentDegree,
-degree,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f)
rotateAnimation.duration = 200
rotateAnimation.fillAfter = true
image.startAnimation(rotateAnimation)
currentDegree = -degree
if (degree > 80 && degree < 100) {
Timer().schedule(1500) {
runOnUiThread {
iv_compass_arrow.setImageResource(R.drawable.img_compass_arrow_bold)
sensorManager.unregisterListener(this@CompassActivity, accelerometer)
sensorManager.unregisterListener(this@CompassActivity, magnetometer)
rotateAnimation = RotateAnimation(
-90.toFloat(), (-90).toFloat(), Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f
)
rotateAnimation.duration = 210
rotateAnimation.fillAfter = true
currentDegree = -degree
iv_compass.startAnimation(rotateAnimation)
Thread.currentThread().interrupt()
Timer().schedule(1500){
finish()
}
}
}
} else {
iv_compass.setImageResource(R.drawable.img_compass)
}
}
}
}
๊ฐ์๋ ์ผ์(TYPE_ACCELEROMETER), ์๊ธฐ์ฅ ์ผ์(TYPE_ACCELEROMETER)๋ฅผ ํ์ฉํ์ฌ ๊ฐ์ ์ง์์ ์ผ๋ก ๋ฐ์์ ๋ฐฉํฅ์ ์ธ์ํ๊ณ ์ผ์๊ฐ์ด ๋ฐ๋ ๋๋ง๋ค ๋ฆฌ์ค๋ ์ค๋ธ์ ํธ์ onSensorChanged() ๋ฉ์๋๊ฐ ํธ์ถ๋จ
- ์ผ์ฐจ๋ณ ์ฑํ
class SecondDayChatActivity : AppCompatActivity() {
private lateinit var chatAdapter: SecondDayChatAdapter
private val apophisService = ApophisService
private val jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWR4Ijo2LCJpYXQiOjE2MTAxNjM5NjIsImV4cCI6MTYxMDc2ODc2MiwiaXNzIjoiYXBvcGhpcyJ9.gM5avYDIhGybMsXqlvaWwqJCsTfkAjo1lYD2tvxZAdw"
private var chatDetailsIdx = 23 // 2์ผ์ฐจ ์์ ์ธ๋ฑ์ค 23
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second_day_chat)
initRcv()
getAponymousChatFromServer(jwt, chatDetailsIdx)
btn_second_back.setOnClickListener { onBackPressed() }
constraintLayout_second.setOnClickListener { hideKeyboard() }
et_second_chat_message.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
btn_chat_send.setImageResource(R.drawable.btn_send_act)
}
override fun afterTextChanged(s: Editable?) {}
})
/* chip click listener ์ฌ์ ์ */
chatAdapter.setOnItemClickListener(object : SecondDayChatAdapter.OnItemClickListener {
override fun onItemClick(data: String) {
// override fun onItemClick(data: MutableList<String>) {
et_second_chat_message.setText(data)
et_second_chat_message.setTextColor(Color.parseColor("#FFFFFF"))
btn_chat_send.setImageResource(R.drawable.btn_send_act)
/*for (i in dataList.indices) {
et_second_chat_message.setText(dataList[i])
et_second_chat_message.setTextColor(Color.parseColor("#FFFFFF"))
btn_chat_send.setImageResource(R.drawable.btn_send_act)
}*/
}
})
}
private fun initRcv() {
chatAdapter = SecondDayChatAdapter(this)
rcv_second_chat.adapter = chatAdapter
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SecondDayChatAdapter.TIMER_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
val text = data?.getStringExtra("text")
et_second_chat_message.setText(text)
}
}
}
private fun getAponymousChatFromServer(jwt: String, chatDetailsIdx: Int) {
apophisService.getInstance()
.requestAponymousChat(
jwt = jwt,
chatDetailsIdx = chatDetailsIdx
).enqueue(object : Callback<BaseResponse<AponymousChatResponse>> {
override fun onFailure(
call: Call<BaseResponse<AponymousChatResponse>>,
t: Throwable
) { //ํต์ ์คํจ
Log.d("fail", t.message)
}
override fun onResponse(
call: Call<BaseResponse<AponymousChatResponse>>,
response: Response<BaseResponse<AponymousChatResponse>>
) {
//ํต์ ์ฑ๊ณต
if (response.isSuccessful) {
if (response.body()!!.success) {
var tag: Int
for (i in response.body()!!.data.chat.indices) {
tag = 0
val nextAction = response.body()!!.data.chat[i].nextAction
if (nextAction == "์ฑํ
์ด๋ฏธ์ง") {
tag = 1
} else if (nextAction == "๋ฐฑ๊ทธ๋ผ์ด๋ ์ด๋ฏธ์ง - ๋๊ธธ ๋ทฐ"){
snowBackground()
} else if(nextAction == "์์ฑ์ก์ถ1"){
tag = 2
}
val aponymousChatData = OurUserChat(mutableListOf(response.body()!!.data.chat[i].text), tag)
chatAdapter.addChat(aponymousChatData)
}
val replyType = response.body()!!.data.postInfo.replyType
tag = if (replyType == "๋จ์ผ ๋ณด๊ธฐ ์ ํ" || replyType == "๋ค์ค ๋ณด๊ธฐ ์ ํ" || replyType == "์นดํ
๊ณ ๋ฆฌ ์ ํ") { //chip_choice
4
} else if (replyType == "๋จ๋ตํ ํ
์คํธ ์
๋ ฅ") { //short answer
5
} else if (replyType == "๊ธฐ๋ฅ ์ก์
๋ฒํผ - ์๊ฐ๋ ์ค์ ") { //timer
6
} else if (replyType == "๊ธฐ๋ฅ ์ก์
๋ฒํผ - ๋๊ฐ์ ๋ ") { //find_me
7
} else if (replyType == "๊ธฐ๋ฅ ์ก์
๋ฒํผ - ๊ฐ์น ์ ํ") { //value
8
} else if(replyType == "์ฅ๋ฌธํ ํ
์คํธ ์
๋ ฅ") { // long answer
9
} else if (replyType == "์ผ์ฐจ ์ข
๋ฃ (reply ์์)") { //end
10
} else {
3 //chat_user
}
when (tag) {
0, 1, 3, 4 -> {
getChoiceChatFromServer(jwt, chatDetailsIdx, tag)
btn_chat_send.setOnClickListener {
chatAdapter.removeChat()
val userChoice = et_second_chat_message.text.toString()
val chat = OurUserChat(mutableListOf(userChoice), 3)
chatAdapter.addChat(chat)
et_second_chat_message.setText("")
postReplyOneToServer(jwt, chatDetailsIdx, 1, userChoice)
}
}
5 -> { //short answer
getChoiceChatFromServer(jwt, chatDetailsIdx, tag)
btn_chat_send.setOnClickListener(null)
chatAdapter.setCallbackListener(object : SecondDayChatAdapter.CallbackListener{
override fun callBack(inputTextList: MutableList<String>) {
postReplyFourToServer(jwt, chatDetailsIdx, 4, inputTextList)
}
})
}
9 -> { //long answer
btn_chat_send.setOnClickListener {
val userChoice = et_second_chat_message.text.toString()
val chat = OurUserChat(mutableListOf(userChoice), 3)
chatAdapter.addChat(chat)
et_second_chat_message.setText("")
postReplyOneToServer(jwt, chatDetailsIdx, 1, userChoice)
}
}
10 -> {
val user = ""
val chat = OurUserChat(mutableListOf(user), 10)
chatAdapter.addChat(chat)
btn_chat_send.setOnClickListener(null)
}
else -> {
getChoiceChatFromServer(jwt, chatDetailsIdx, tag)
btn_chat_send.setOnClickListener {
chatAdapter.removeChat()
val userChoice = et_second_chat_message.text.toString()
val chat = OurUserChat(mutableListOf(userChoice), 3)
chatAdapter.addChat(chat)
et_second_chat_message.setText("")
postReplyOneToServer(jwt, chatDetailsIdx, 1, userChoice)
}
}
}
}
}
}
})
}
private fun getChoiceChatFromServer(jwt: String, chatDetailsIdx: Int, tag: Int) {
apophisService.getInstance()
.requestChoiceChat(
jwt = jwt,
chatDetailsIdx = chatDetailsIdx
).enqueue(object : Callback<BaseResponse<ChoiceChatResponse>> {
override fun onFailure(
call: Call<BaseResponse<ChoiceChatResponse>>,
t: Throwable
) { //ํต์ ์คํจ
Log.d("fail", t.message)
}
override fun onResponse(
call: Call<BaseResponse<ChoiceChatResponse>>,
response: Response<BaseResponse<ChoiceChatResponse>>
) {
//ํต์ ์ฑ๊ณต
if (response.isSuccessful) {
if (response.body()!!.success) {
val replyNum = response.body()!!.data.replyNum
val list = mutableListOf<String>()
for (i in response.body()!!.data.choiceWords.indices) {
list.add(response.body()!!.data.choiceWords[i].choiceWords)
}
val choiceChatData = OurUserChat(list, tag)
chatAdapter.addChat(choiceChatData)
}
}
}
})
}
private fun postReplyOneToServer(jwt: String, chatDetailsIdx: Int, replyNum: Int, replyString: String) {
apophisService.getInstance()
.requestOneReply(
jwt = jwt,
chatDetailsIdx = chatDetailsIdx,
replyNum = replyNum,
body = ReplyOneRequest(replyString)
).enqueue(object : Callback<BaseResponse<Unit>> {
override fun onFailure(
call: Call<BaseResponse<Unit>>,
t: Throwable
) { //ํต์ ์คํจ
Log.d("fail", t.message)
}
override fun onResponse(
call: Call<BaseResponse<Unit>>,
response: Response<BaseResponse<Unit>>
) {
if (response.isSuccessful) {
if (response.body()!!.success) {
if (chatDetailsIdx < 41) {
getAponymousChatFromServer(jwt, chatDetailsIdx + 1)
btn_chat_send.setImageResource(R.drawable.btn_send_unact)
}
}
}
}
})
}
private fun postReplyFourToServer(jwt: String, chatDetailsIdx: Int, replyNum: Int, reply: MutableList<String>) {
apophisService.getInstance()
.requestFourReply(
jwt = jwt,
chatDetailsIdx = chatDetailsIdx,
replyNum = replyNum,
body = ReplyFourRequest(reply[0], reply[1], reply[2], reply[3])
) .enqueue(object : Callback<BaseResponse<Unit>> {
override fun onFailure(
call: Call<BaseResponse<Unit>>,
t: Throwable
) { //ํต์ ์คํจ
Log.d("fail", t.message)
}
override fun onResponse(
call: Call<BaseResponse<Unit>>,
response: Response<BaseResponse<Unit>>
) {
if (response.isSuccessful) {
if (response.body()!!.success) {
if (chatDetailsIdx < 41) {
getAponymousChatFromServer(jwt, chatDetailsIdx + 1)
btn_chat_send.setImageResource(R.drawable.btn_send_unact)
}
}
}
}
})
}
private fun hideKeyboard() {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(et_second_chat_message.windowToken, 0)
}
private fun snowBackground() {
rcv_second_chat.setBackgroundResource(R.color.transparency00FF)
cl_second_chat_bottom.setBackgroundResource(R.color.transparency00FF)
cl_second_chat_header.setBackgroundResource(R.color.transparency00FF)
constraintLayout_second.setBackgroundResource(R.drawable.bg_snowroadxx)
Handler().postDelayed({
rcv_second_chat.setBackgroundResource(R.color.black262627)
cl_second_chat_bottom.setBackgroundResource(R.color.black2C2C2D)
cl_second_chat_header.setBackgroundResource(R.color.black2C2C2D)
constraintLayout_second.setBackgroundResource(R.color.black262627)
}, 40000)
}
}
class SecondDayChatAdapter(private val context: Context): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val userChatList: MutableList<OurUserChat> = mutableListOf()
override fun getItemViewType(position: Int): Int {
return when (userChatList[position].tag) {
0 -> R.layout.item_chat_aponymous
1 -> R.layout.item_chat_aponymous_image
2 -> R.layout.item_aponymous_sound
3, 9 -> R.layout.item_chat_user //9 ์ฅ๋ฌธํ
4 -> R.layout.item_chip_choice
5 -> R.layout.item_chat_short_answer
6 -> R.layout.item_chat_time
7 -> R.layout.item_chat_find_me
10 -> R.layout.item_chat_ending
else -> R.layout.item_chat_value
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return when (viewType) {
R.layout.item_chat_aponymous -> {
val view = layoutInflater.inflate(R.layout.item_chat_aponymous, parent, false)
AponymousViewHolder(view)
}
R.layout.item_chat_aponymous_image -> {
val view = layoutInflater.inflate(R.layout.item_chat_aponymous_image, parent, false)
AponymousImageViewHolder(view)
}
R.layout.item_aponymous_sound -> {
val view = layoutInflater.inflate(R.layout.item_aponymous_sound, parent, false)
AponymousSoundViewHolder(view)
}
R.layout.item_chat_user -> {
val view = layoutInflater.inflate(R.layout.item_chat_user, parent, false)
UserViewHolder(view)
}
R.layout.item_chip_choice -> {
val view = layoutInflater.inflate(R.layout.item_chip_choice, parent, false)
ChoiceChatViewHolder(view, layoutInflater)
}
R.layout.item_chat_short_answer -> {
val view = layoutInflater.inflate(R.layout.item_chat_short_answer, parent, false)
UserShortAnswerViewHolder(view, callbackListener)
}
R.layout.item_chat_time -> {
val view = layoutInflater.inflate(R.layout.item_chat_time, parent, false)
TimerActionViewHolder(view)
}
R.layout.item_chat_find_me -> {
val view = layoutInflater.inflate(R.layout.item_chat_find_me, parent, false)
FindMeActionViewHolder(view)
}
R.layout.item_chat_value -> {
val view = layoutInflater.inflate(R.layout.item_chat_value, parent, false)
ValueActionViewHolder(view)
}
R.layout.item_chat_ending -> {
val view = layoutInflater.inflate(R.layout.item_chat_ending, parent, false)
EndingViewHolder(view)
}
else ->
throw IllegalArgumentException("ViewType [$viewType] is unexpected")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is AponymousViewHolder) {
holder.bind(userChatList[position].content)
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is AponymousImageViewHolder) {
holder.bind(userChatList[position].content)
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is AponymousSoundViewHolder) {
holder.bind(userChatList[position].content)
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is UserViewHolder) {
holder.bind(userChatList[position].content)
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is ChoiceChatViewHolder) {
holder.bind(userChatList[position].content)
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is UserShortAnswerViewHolder) {
holder.bind(callbackListener)
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is TimerActionViewHolder) {
holder.bind()
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is FindMeActionViewHolder) {
holder.bind()
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is ValueActionViewHolder) {
holder.bind()
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
if (holder is EndingViewHolder) {
holder.bind()
holder.itemView.animation = AnimationUtils.loadAnimation(context, R.anim.translate_up)
}
}
inner class AponymousViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val content = itemView.findViewById<TextView>(R.id.tv_aponymous_chat)
fun bind(text: MutableList<String>) {
text.forEach {
content.text = it
}
}
}
inner class AponymousImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val image = itemView.findViewById<ImageView>(R.id.img_chat_aponymous)
fun bind(imageUrl: MutableList<String>) {
imageUrl.forEach {
Glide.with(itemView).load(it).into(image)
}
image.background = context.getDrawable(R.drawable.round_rectangle_black_23dp)
image.clipToOutline = true
}
}
inner class AponymousSoundViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(text: MutableList<String>) {
}
}
inner class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val content = itemView.findViewById<TextView>(R.id.tv_user_chat)
fun bind(chatDataList: MutableList<String>) {
chatDataList.forEach {
content.text = it
}
}
}
inner class ChoiceChatViewHolder(itemView: View, inflater: LayoutInflater) : RecyclerView.ViewHolder(itemView) {
private var chipGroup: ChipGroup = itemView.findViewById(R.id.chipgroup_choice)
private val chipTextList: MutableList<String> = mutableListOf()
private val inflater: LayoutInflater = inflater
fun bind(chipItem: MutableList<String>) {
chipGroup.removeAllViews()
chipTextList.clear()
chipItem.forEach {
val chip = ChipFactory.newInstance(inflater)
chip.text = it
chip.isClickable = true
chipGroup.addView(chip)
chipTextList.add(it)
chip.setOnClickListener {
itemClickListener.onItemClick(chip.text.toString())
// itemClickListener.onItemClick(chipTextList)
}
}
}
}
inner class UserShortAnswerViewHolder(itemView: View, callbackListener: CallbackListener) : RecyclerView.ViewHolder(itemView) {
private var num1: TextView = itemView.findViewById(R.id.tv_user_input_1)
private var num2: TextView = itemView.findViewById(R.id.tv_user_input_2)
private var num3: TextView = itemView.findViewById(R.id.tv_user_input_3)
private var input: TextView = itemView.findViewById(R.id.tv_user_input)
private var input1: TextView = itemView.findViewById(R.id.et_user_input_1)
private var input2: TextView = itemView.findViewById(R.id.et_user_input_2)
private var input3: TextView = itemView.findViewById(R.id.et_user_input_3)
private var btnComplete: TextView = itemView.findViewById(R.id.btn_user_input_complete)
private val inputTextList: MutableList<String> = mutableListOf()
fun bind(callbackListener: CallbackListener) {
input1.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
num1.setTextColor(Color.parseColor("#AB70F5"))
}
override fun afterTextChanged(s: Editable?) {}
})
input2.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
num2.setTextColor(Color.parseColor("#AB70F5"))
}
override fun afterTextChanged(s: Editable?) {}
})
input3.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
num3.setTextColor(Color.parseColor("#AB70F5"))
}
override fun afterTextChanged(s: Editable?) {}
})
btnComplete.setOnClickListener {
removeChat()
inputTextList.add(input.text.toString())
inputTextList.add("์ฒซ ๋ฒ์งธ๋ " + input1.text.toString())
inputTextList.add("๋ ๋ฒ์งธ๋ " + input2.text.toString())
inputTextList.add("์ธ ๋ฒ์งธ๋ " + input3.text.toString())
for (i in inputTextList.indices) {
val chatRight = OurUserChat(mutableListOf(inputTextList[i]), 3)
addChat(chatRight)
}
callbackListener.callBack(inputTextList)
}
}
}
inner class TimerActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val btnAction = itemView.findViewById<ImageView>(R.id.btn_timer)
fun bind() {
btnAction.setOnClickListener {
val intent = Intent(context, SecondDayTimepickerActivity::class.java)
(context as Activity).startActivityForResult(intent, TIMER_ACTIVITY_REQUEST_CODE
)
}
}
}
inner class FindMeActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val btnAction = itemView.findViewById<ImageView>(R.id.btn_find_me)
fun bind() {
btnAction.setOnClickListener {
itemClickListener.onItemClick("์ด๋ฐ ๋ชจ์ต๋ค์ด ์๋ ๊ฒ ๊ฐ์.")
val intent = Intent(context, SecondDayFindLightMeActivity::class.java)
context.startActivity(intent)
}
}
}
inner class ValueActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val btnAction = itemView.findViewById<ImageView>(R.id.btn_value)
fun bind() {
btnAction.setOnClickListener {
itemClickListener.onItemClick("ํ์ด.")
val intent = Intent(context, SecondDayValueActivity::class.java)
context.startActivity(intent)
}
}
}
inner class EndingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val btnAction = itemView.findViewById<View>(R.id.btn_ending_okay)
fun bind() {
btnAction.setOnClickListener {
val intent = Intent(context, SecondDayChatEndingActivity::class.java)
context.startActivity(intent)
}
}
}
override fun getItemCount(): Int {
return userChatList.size
}
fun addChat(userChatItem: OurUserChat) {
userChatList.add(userChatItem)
notifyItemInserted(userChatList.size)
}
fun removeChat() {
userChatList.removeAt(userChatList.size-1)
notifyItemRemoved(userChatList.size)
}
/* chip click listener */
interface OnItemClickListener {
fun onItemClick(data: String)
// fun onItemClick(dataList: MutableList<String>)
}
private lateinit var itemClickListener: OnItemClickListener
fun setOnItemClickListener(listener: OnItemClickListener) {
this.itemClickListener = listener
}
/* callback listener */
interface CallbackListener {
fun callBack(inputTextList: MutableList<String>)
}
private lateinit var callbackListener: CallbackListener
fun setCallbackListener(callbackListener: CallbackListener) {
this.callbackListener = callbackListener
}
companion object {
const val TIMER_ACTIVITY_REQUEST_CODE = 26
// 26 = 2์ผ์ฐจ viewType 6
const val FIND_ME_ACTIVITY_REQUEST_CODE = 27
const val VALUE_ACTIVITY_REQUEST_CODE = 28
}
}
drawble : ์ฑ์ ํต์ฌ ๊ธฐ๋ฅ์ธ ์ฑํ ๊ตฌํ ๋ก์ง ์ ๋ฒํผ ํ์ฑํ, ๋นํ์ฑํ ๊ธฐ์ค์ด ๋ทฐํ์ ๋ง๋ค ๋ฌ๋ผ์ง๋ ๊ด๊ณ๋ก ๊ฐ๋ณ drawable์ ์ฌ์ฉํ์ต๋๋ค.
๐ฉ ๊น๋คํ | ๐จ ํ์ฌํ | ๐ฉ ์กฐ์ฑ๋ฆผ |
---|---|---|
์คํ๋์ฌ ์์ ์ฌ์ ๋ฉ์ธ ํธ์ง ๋ฐ๊ธฐ/์ฐ๊ธฐ |
์จ๋ณด๋ฉ | ์ํฌํผ์ค ๋ทฐ ํ์ด๋จธ ์์ฑ ์ก์ถ |
์ฑํ
์ ์ฒด ๋ก์ง ๊ตฌํ ์ฑํ ์๋ฉ ๋ทฐ 2์ผ์ฐจ - ์ฑํ ๊ตฌํ 2์ผ์ฐจ - ์๊ฐ ์ค์ 2์ผ์ฐจ - Find me |
1์ผ์ฐจ - ์ฑํ
๊ตฌํ 1์ผ์ฐจ - ๋์นจ๋ฐ 1์ผ์ฐจ - ์นด๋ฉ๋ผ ์ดฌ์ 1์ผ์ฐจ / 2์ผ์ฐจ - ๋ฐฑ๊ทธ๋ผ์ด๋ ์ด๋ฏธ์ง ์ ํ |
2์ผ์ฐจ - ๊ฐ์น๊ด 7์ผ์ฐจ - ์ฑํ ๊ตฌํ 7์ผ์ฐจ - ์ ์ ์ฐ๊ธฐ |