-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
손영준 Assignment3 제출 #64
base: assignment3
Are you sure you want to change the base?
Changes from all commits
adfbc47
658317b
af5e276
58c5f0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
package com.jutak.assignment3 | ||
|
||
import android.app.Activity | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.util.Log | ||
import android.view.View | ||
import android.widget.TextView | ||
import android.widget.Toast | ||
import androidx.activity.result.ActivityResult | ||
import androidx.activity.result.contract.ActivityResultContracts | ||
import androidx.activity.viewModels | ||
import androidx.appcompat.app.AlertDialog | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.core.view.isVisible | ||
import androidx.lifecycle.lifecycleScope | ||
import androidx.recyclerview.widget.LinearLayoutManager | ||
import androidx.recyclerview.widget.RecyclerView.LayoutManager | ||
import com.jutak.assignment3.databinding.ActivityDetailBinding | ||
import com.jutak.assignment3.databinding.CustomTitleLayoutBinding | ||
import com.jutak.assignment3.databinding.EditDialogLayoutBinding | ||
import com.jutak.assignment3.databinding.PostDialogLayoutBinding | ||
import com.jutak.assignment3.databinding.WordAddDialogLayoutBinding | ||
import dagger.hilt.android.AndroidEntryPoint | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.launch | ||
import kotlinx.coroutines.withContext | ||
|
||
@AndroidEntryPoint | ||
class DetailActivity : AppCompatActivity(), OnItemClickListener<Int> { | ||
|
||
private lateinit var binding: ActivityDetailBinding | ||
private val viewModel: MainViewModel by viewModels() | ||
// valid 인증 받은 password 및 permission을 단어 삭제와 추가에도 계속 써야 하므로, DetailActivity 내 전역변수 선언 | ||
private var password = "" | ||
private var wordInfos = emptyList<MyData.WordInfo>() | ||
|
||
|
||
override fun onItemClick(itemId: Int) { | ||
|
||
} | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
binding = ActivityDetailBinding.inflate(layoutInflater) | ||
setContentView(binding.root) | ||
|
||
|
||
|
||
// Intent로 전달된 데이터 가져오기 | ||
val itemId = intent.getIntExtra("itemId", 1) | ||
|
||
lifecycleScope.launch(Dispatchers.IO) { | ||
// 비동기 작업을 수행할 코루틴 블록 | ||
val result = viewModel.fetchWordList(itemId) | ||
withContext(Dispatchers.Main) { | ||
// 메인 스레드에서 수행할 작업 | ||
if (result != "SUCCESS") { | ||
Toast.makeText(this@DetailActivity, result, Toast.LENGTH_SHORT).show() | ||
} | ||
} | ||
wordInfos = viewModel.getWordList(itemId) | ||
withContext(Dispatchers.Main) { | ||
// 메인 스레드에서 수행할 작업 | ||
if (result == "SUCCESS") { | ||
val recAdapter = WordListAdapter(this@DetailActivity, wordInfos.toMutableList(), this@DetailActivity) | ||
binding.wordInfo.adapter = recAdapter | ||
binding.wordInfo.layoutManager = LinearLayoutManager(this@DetailActivity) | ||
|
||
viewModel.wordListData.observe(this@DetailActivity) { wordList -> | ||
// LiveData를 관찰하여 데이터를 얻고, adapter를 업데이트 | ||
Log.d("DetailActivity", "Word list size: ${wordList.size}") // 디버그 로그 추가 | ||
recAdapter.setItems(wordList) | ||
recAdapter.notifyDataSetChanged() | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
val backButton = binding.backButton | ||
backButton.setOnClickListener() { | ||
val intent = Intent(this@DetailActivity, MainActivity::class.java) | ||
startActivity(intent) | ||
} | ||
|
||
val editButton = binding.detailEditBtn | ||
editButton.setOnClickListener() { | ||
showVerifyDialog(itemId) | ||
viewModel.permission.observe(this@DetailActivity) { permission -> | ||
// LiveData를 관찰하여 데이터를 얻고, adapter를 업데이트 | ||
if (permission) { | ||
editButton.visibility = View.GONE | ||
binding.detailRemoveBtn.visibility = View.VISIBLE | ||
binding.detailAddBtn.visibility = View.VISIBLE | ||
} | ||
} | ||
|
||
} | ||
|
||
val detailRemoveButton = binding.detailRemoveBtn | ||
detailRemoveButton.setOnClickListener() { | ||
lifecycleScope.launch(Dispatchers.IO) { | ||
// 비동기 작업을 수행할 코루틴 블록 | ||
val result = viewModel.deleteWordList(itemId, password) | ||
withContext(Dispatchers.Main) { | ||
// 메인 스레드에서 수행할 작업 | ||
if (result != "SUCCESS") { | ||
Toast.makeText(this@DetailActivity, result, Toast.LENGTH_SHORT).show() | ||
} | ||
// 요청 성공 시 메인화면으로 <- 요청 성공/실패 체크] | ||
val intent = Intent(this@DetailActivity, MainActivity::class.java) | ||
startActivity(intent) | ||
Comment on lines
+112
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 하면 메인화면으로 "되돌아가는 것" 이 아니라, MainActivity화면을 새로 만들어서 위에 쌓는 구조가 됩니다. (단어장 삭제하고 나서 뒤로가기를 눌러보면, 스택처럼 두 개의 MainActivity가 쌓여있는 것을 볼 수 있습니다) 그래서 삭제를 했을 때 MainActivity가 그걸 activityResultListener로 전달받은 게 아니라 (챌린지 스펙의 내용), 그냥 새 MainActivitty가 떠서 다시 fetch list를 한 상황입니다. |
||
} | ||
} | ||
} | ||
|
||
val detailAddButton = binding.detailAddBtn | ||
detailAddButton.setOnClickListener() { | ||
// 다이얼로그 생성 후 해당 입력값들로 MyData.WordInfo 인스턴스 생성 및 viewModel.putWord() | ||
showWordAddDialog(itemId) | ||
} | ||
|
||
|
||
|
||
|
||
} | ||
// Dialog abstract class를 만들어도 될듯...? itemId와 Binding 받아서... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋은 생각입니다 Dialog를 상속해서 자신의 앱에서 쭉 사용할 커스텀 다이얼로그를 만들어서 사용하는 게 일반적입니다. 레이아웃을 설정하고, 등장/퇴장 및 애니메이션까지 커스텀해서 사용하면 편하죠 |
||
private fun showVerifyDialog(itemId: Int) { | ||
val dialogBinding = EditDialogLayoutBinding.inflate(layoutInflater) | ||
val customTitleLayoutBinding = CustomTitleLayoutBinding.inflate(layoutInflater) | ||
|
||
val dialog = AlertDialog.Builder(this) | ||
.setView(dialogBinding.root) | ||
.setCustomTitle(customTitleLayoutBinding.root) | ||
.setTitle("수정 권한 확인하기") | ||
.setPositiveButton("Submit") { dialog, _ -> | ||
val inputPassword = dialogBinding.inputPassword.text.toString() | ||
password = inputPassword | ||
// 비밀번호 검증 (뷰모델로 password 전송하고, 뷰모델은 모델로 password 전송. | ||
lifecycleScope.launch(Dispatchers.IO) { | ||
// 비동기 작업을 수행할 코루틴 블록 | ||
val result = viewModel.pushPassword(itemId, inputPassword) | ||
|
||
withContext(Dispatchers.Main) { | ||
// 메인 스레드에서 수행할 작업 | ||
if (result != "SUCCESS") { | ||
// 왜 text가 안 뜨지? | ||
Toast.makeText(this@DetailActivity, result, Toast.LENGTH_SHORT).show() | ||
|
||
} | ||
dialog.dismiss() | ||
} | ||
} | ||
} | ||
.setNegativeButton("Cancel") { dialog, _ -> | ||
dialog.dismiss() | ||
} | ||
.create() | ||
|
||
dialog.show() | ||
} | ||
|
||
private fun showWordAddDialog(itemId: Int) { | ||
val dialogBinding = WordAddDialogLayoutBinding.inflate(layoutInflater) | ||
val customTitleLayoutBinding = CustomTitleLayoutBinding.inflate(layoutInflater) | ||
|
||
val dialog = AlertDialog.Builder(this) | ||
.setView(dialogBinding.root) | ||
.setCustomTitle(customTitleLayoutBinding.root) | ||
.setTitle("단어 추가하기") | ||
.setPositiveButton("Submit") { dialog, _ -> | ||
val spell = dialogBinding.dialogWordSpell.text.toString() | ||
val meaning = dialogBinding.dialogWordMeaning.text.toString() | ||
val synonym = dialogBinding.dialogWordSynonym.text?.toString() ?: null | ||
val antonym = dialogBinding.dialogWordAntonym.text?.toString() ?: null | ||
val sentence = dialogBinding.dialogWordSentence.text?.toString() ?: null | ||
val wordDetail = MyData.WordInfo(spell, meaning, synonym, antonym, sentence) | ||
val word = MyData.WordPutInfo(password, wordDetail) | ||
lifecycleScope.launch(Dispatchers.IO) { | ||
// 비동기 작업을 수행할 코루틴 블록 | ||
val result = viewModel.putWord(itemId, word) | ||
withContext(Dispatchers.Main) { | ||
// 메인 스레드에서 수행할 작업 | ||
if (result != "SUCCESS") { | ||
Toast.makeText(this@DetailActivity, result, Toast.LENGTH_SHORT).show() | ||
} | ||
} | ||
} | ||
|
||
dialog.dismiss() | ||
} | ||
.setNegativeButton("Cancel") { dialog, _ -> | ||
dialog.dismiss() | ||
} | ||
.create() | ||
|
||
dialog.show() | ||
} | ||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서 return 해야되지 않나요? ㅎㅎ