Skip to content
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

Feat/#5 week2 xml 필수과제 구현 #7

Merged
merged 31 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
119c260
feat/#5: 메뉴바 생성
hyeeum Apr 10, 2024
c872be5
feat/#5: 프래그먼트 생성
hyeeum Apr 10, 2024
39cc771
feat/#5: 메뉴와 프래그먼트 연결
hyeeum Apr 10, 2024
03a21c4
feat/#5: 리싸이클러뷰 연결
hyeeum Apr 10, 2024
8f52e11
feat/#5: 유저의 상태메세지가 길거나 이름이 길때 말줄임표
hyeeum Apr 10, 2024
131ba88
mod/#5: 마이페이지<->홈 변경
hyeeum Apr 11, 2024
3205e16
del/#5 user 데이터 클래스 삭제
hyeeum Apr 11, 2024
40c4f30
feat/#5: 멀티뷰 리싸이클러뷰 생성
hyeeum Apr 13, 2024
f6a8a70
fix/#5:공백 로그인 성공 오류 해결
hyeeum Apr 13, 2024
b379d72
fix/#5: 마이페이지 데이터 미전달 해결
hyeeum Apr 14, 2024
69ccff0
mod/#5: 뷰홀더 분리 데이터 분리
hyeeum Apr 14, 2024
d712b65
mod/#5: 1주차 피드백 반영
hyeeum Apr 14, 2024
5012ed1
mod/#5: 회원가입 조건 상수화
hyeeum Apr 14, 2024
b27970a
mod/#5: scope 함수 사용해보기
hyeeum Apr 18, 2024
5bc08ee
rename/#5: 홈에 있는 rc 관련 파일 이름 변경
hyeeum Apr 18, 2024
2420f0b
chore/#5: 리스트 데이터 추가
hyeeum Apr 18, 2024
4dd9b1b
delete/#5: 주석 삭제
hyeeum Apr 18, 2024
12e8ccc
chore/#5: 코드 정렬 및 함수명 변경
hyeeum Apr 18, 2024
b1a4e75
delete/#5: 쓸모없는 코드 삭제
hyeeum Apr 18, 2024
e2e4d11
Update README.md
hyeeum Apr 18, 2024
d8003c2
Merge branch 'main-xml' into feat/#5-week2_xml
hyeeum Apr 19, 2024
d0f0261
feat/#5: fragment notnull 처리
hyeeum Apr 26, 2024
9169ea0
mod/#5: PR 적용 - getOrNull
hyeeum Apr 26, 2024
db71fd8
mod/#5: PR 적용 - with
hyeeum Apr 26, 2024
fa0ef19
mod/#5: PR 적용 - isBlank
hyeeum Apr 26, 2024
fd905d6
Merge branch 'feat/#5-week2_xml' of https://github.com/NOW-SOPT-ANDRO…
hyeeum Apr 26, 2024
3d31950
mod/#5: PR 적용 - 숫자 대신 타입상수화
hyeeum Apr 26, 2024
ed096f8
mod/#5: PR 적용 - ViewHolder
hyeeum Apr 26, 2024
480c147
mod/#5: PR 적용 - tools
hyeeum Apr 26, 2024
3c26a27
mod/#5: PR 적용 - scope
hyeeum Apr 26, 2024
9d4ddfb
feat/#5: RC 뷰모델 적용
hyeeum Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Now Sopt Android
feat/#5-week2_xml

- **[FEAT]** : 새로운 기능 구현
- **[MOD]** : 코드 수정 및 내부 파일 수정
Expand Down
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

//viewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
implementation "androidx.fragment:fragment-ktx:1.6.1"
implementation "androidx.activity:activity-ktx:1.8.0"
}
41 changes: 41 additions & 0 deletions app/src/main/java/com/sopt/now/HomeFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.sopt.now

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.sopt.now.databinding.FragmentHomeBinding

class HomeFragment : Fragment() {
private val binding:FragmentHomeBinding
get()= requireNotNull(_binding){"_binding이 null이 아닌 경우만 _binding 반환"}
private var _binding: FragmentHomeBinding ?= null
private val viewModel by viewModels<HomeViewModel>()

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater,container,false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val homeListAdapter = HomeListAdapter()
binding.rvFriends.run {
adapter = homeListAdapter
layoutManager = LinearLayoutManager(requireContext())
}
homeListAdapter.setHomeList(viewModel.homeListData)
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

}
15 changes: 15 additions & 0 deletions app/src/main/java/com/sopt/now/HomeList.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sopt.now

import androidx.annotation.DrawableRes

data class HomeList(
@DrawableRes val profileImage: Int,
val name: String,
val selfDescription: String,
val viewType: Int
) {
companion object {
const val VIEW_TYPE_USER = 0
const val VIEW_TYPE_FRIEND = 1
}
}
44 changes: 44 additions & 0 deletions app/src/main/java/com/sopt/now/HomeListAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.sopt.now

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.sopt.now.databinding.ItemFriendBinding
import com.sopt.now.databinding.ItemUserBinding

class HomeListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var homeListList: List<HomeList> = emptyList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val bindingUser = ItemUserBinding.inflate(inflater, parent, false)
val bindingFriend = ItemFriendBinding.inflate(inflater, parent, false)
return when(viewType){
HomeList.VIEW_TYPE_USER -> {
UserViewHolder(bindingUser)
}
else -> {
FriendViewHolder(bindingFriend)
}
}
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(homeListList.getOrNull(position)?.viewType){
HomeList.VIEW_TYPE_USER -> {
(holder as UserViewHolder).onBind(homeListList[position])
}
else -> {
(holder as FriendViewHolder).onBind(homeListList[position])
}
}
}

override fun getItemCount() = homeListList.size
override fun getItemViewType(position: Int): Int {
return homeListList[position].viewType
}
fun setHomeList(homeListList: List<HomeList>) {
this.homeListList = homeListList.toList()
notifyDataSetChanged()
}
}
25 changes: 25 additions & 0 deletions app/src/main/java/com/sopt/now/HomeListViewHolder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.sopt.now

import androidx.recyclerview.widget.RecyclerView
import com.sopt.now.databinding.ItemFriendBinding
import com.sopt.now.databinding.ItemUserBinding

class FriendViewHolder(private val binding:ItemFriendBinding) : RecyclerView.ViewHolder(binding.root) {
fun onBind(friendData: HomeList) {
binding.run {
ivProfile.setImageResource(friendData.profileImage)
tvName.text = friendData.name
tvSelfDescription.text = friendData.selfDescription
}
Comment on lines +9 to +13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구우우우웃!!!

}
}

class UserViewHolder(private val binding:ItemUserBinding) : RecyclerView.ViewHolder(binding.root) {
fun onBind(friendData: HomeList) {
binding.run {
ivProfile.setImageResource(friendData.profileImage)
tvName.text = friendData.name
tvSelfDescription.text = friendData.selfDescription
}
}
}
86 changes: 86 additions & 0 deletions app/src/main/java/com/sopt/now/HomeViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.sopt.now

import androidx.lifecycle.ViewModel

class HomeViewModel : ViewModel() {
val homeListData = listOf(
HomeList(
profileImage = R.drawable.main,
name = "송혜음",
selfDescription = "멀티 뷰 리싸이클러뷰!",
HomeList.VIEW_TYPE_USER
),
HomeList(
profileImage = R.drawable.main,
name = "박동민",
selfDescription = "곽의진...얼굴 재치 실력 모든걸 다 가진 남자... 하지만 밀양박씨 36대손인 나 박동민은 가지지 못했지",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "이석준",
selfDescription = "죄송합니다 저 도핑했습니다... 안드-로이더 \uD83D\uDC89",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "박유진",
selfDescription = "(ง˙∇˙)ว 에라 모르겠다",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "이의경",
selfDescription = "다들 빨리 끝내고 뒤풀이 가고 싶지? ㅎㅎ 아직 반도 안왔어 ^&^",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "우상욱",
selfDescription = "나보다 안드 잘하는 사람 있으면 나와봐",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "배지현",
selfDescription = "표정 풀자 ^^",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "이의경",
selfDescription = "다들 빨리 끝내고 뒤풀이 가고 싶지? ㅎㅎ 아직 반도 안왔어 ^&^",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "우상욱",
selfDescription = "나보다 안드 잘하는 사람 있으면 나와봐",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "배지현",
selfDescription = "표정 풀자 ^^",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "이의경",
selfDescription = "다들 빨리 끝내고 뒤풀이 가고 싶지? ㅎㅎ 아직 반도 안왔어 ^&^",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "우상욱",
selfDescription = "나보다 안드 잘하는 사람 있으면 나와봐",
HomeList.VIEW_TYPE_FRIEND
),
HomeList(
profileImage = R.drawable.main,
name = "배지현",
selfDescription = "표정 풀자 ^^",
HomeList.VIEW_TYPE_FRIEND
)
)
}
48 changes: 28 additions & 20 deletions app/src/main/java/com/sopt/now/LoginActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,57 +16,65 @@ class LoginActivity : AppCompatActivity() {
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)

//회원가입에서 사용자 정보 받아옴
getUser()
getUserInfo()

//회원가입 페이지로 넘어가기
moveToSignUp()

}
private fun getUser() { // 아쉬운 부분
private fun getUserInfo() {
var id = ""
var pw = ""
var nick = ""
resultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
id = result.data?.getStringExtra("id") ?: ""
pw = result.data?.getStringExtra("pw") ?: ""
nick = result.data?.getStringExtra("nick") ?: ""
result.data?.let { data ->
id = data.getStringExtra("id") ?: ""
pw = data.getStringExtra("pw") ?: ""
nick = data.getStringExtra("nick") ?: ""
}
}
}
binding.btnLogin.setOnClickListener {
sendData(id,pw,nick)
moveToMain(id,pw,nick)
}
}
private fun moveToSignUp(){
binding.btnLoginSignIn.setOnClickListener {
val intent = Intent(this, SignUpActivity::class.java)
//회원가입 데이터를 받아오기 위해 startActivity가 아닌 resultLauncher사용
resultLauncher.launch(intent)
}
}
private fun moveToMain(id:String,pw:String,nick:String){
if (isLoginAvailable(id, pw)) {
val intent = Intent(this, MainActivity::class.java).apply {
saveUserInfo(id, pw, nick)
}
Comment on lines +50 to +52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

객체를 생성하지 않고도 가능하답니당!

startActivity(intent)
}
}
private fun saveUserInfo(id:String,pw:String,nick:String) {
val sharedPreferences = getSharedPreferences("userInfo", MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor
.putString("userId", id)
.putString("userPw", pw)
.putString("userNick", nick)
.apply()
}
Comment on lines +56 to +64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 sharedPreference 너무 좋아요!!
그런데 데이터를 가져오는 과정은 View보다는 ViewModel에 적합한 코드 같네요!! 수정해볼까용~

private fun isLoginAvailable(id: String, pw: String) :Boolean {
var loginBool = false
val userId = binding.etvLoginId.text.toString()
val userPw = binding.etvLoginPw.text.toString()
val message = when{
userId != id || userPw != pw -> "아이디 혹은 비밀번호가 일치하지 않습니다."
userId.isBlank() || userPw.isBlank() -> getString(R.string.login_error_blank)
userId != id || userPw != pw -> getString(R.string.login_error_different)
else -> {
loginBool = true
"로그인에 성공했습니다."
getString(R.string.login_success)
}
}
Toast.makeText(this,message,Toast.LENGTH_SHORT).show()
return loginBool
}
private fun sendData(id:String,pw:String,nick:String){
if (isLoginAvailable(id, pw)) {
val intent = Intent(this, MainActivity::class.java)
//메인 액티비티로 데이터를 보냄
intent.putExtra("id", id).putExtra("pw", pw).putExtra("nick", nick)
startActivity(intent)
}
}
}
45 changes: 38 additions & 7 deletions app/src/main/java/com/sopt/now/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,52 @@ package com.sopt.now

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.sopt.now.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding= ActivityMainBinding.inflate(layoutInflater)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

//로그인화면에서 받아온 id/pw 화면에 출력
getUserInfo()
val currentFragment = supportFragmentManager.findFragmentById(binding.fcvHome.id)
if (currentFragment == null) {
supportFragmentManager.beginTransaction()
.add(R.id.fcv_home, HomeFragment())
.commit()
}

clickBottomNavigation()
}
private fun getUserInfo() {
binding.tvMainNick.text = intent.getStringExtra("nick")
binding.tvMainId.text = intent.getStringExtra("id")
binding.tvMainPw.text = intent.getStringExtra("pw")

private fun clickBottomNavigation() {
binding.bnvHome.setOnItemSelectedListener {
when (it.itemId) {
R.id.menu_home -> {
replaceFragment(HomeFragment())
true
}

R.id.menu_search -> {
replaceFragment(SearchFragment())
true
}

R.id.menu_mypage -> {
replaceFragment(MyPageFragment())
true
}

else -> false
}
}
}

private fun replaceFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction()
.replace(R.id.fcv_home, fragment)
.commit()
}
}
Loading