-
Notifications
You must be signed in to change notification settings - Fork 70
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
[Team-04][Android][Linus_Jay][3주차 금요일 여섯번째 PR] #285
base: team-04
Are you sure you want to change the base?
Conversation
- 필터된 이슈 목록 리스트가 빈값이 아닐 때만 이슈 목록이 갱신되도록 수정
1. 네트워크 O -> 리모트에서 로컬에 캐시해줌, 로컬에서 내려주기 2. 네트워크 X -> 로컬에서 내려주기
- sealed class 를 생성하여 실제 issue 와 progress bar 구분 - ProgressBar ViewType 타입 할당 - Is 연산자를 활용하여 sealed class 구분 - firebase의 limit 과 startAfter 메서드를 활용하여 페이징 처리
- 코루틴 수정 : Coroutine() -> suspend 함수인 coroutine() 으로 수정하고 .join() 을 삭제 - suspend 함수가 아닌 Coroutine 에서 선언된 launch 실행문들은 무시되고 함수를 리턴 함 , 최초에는 join 이 있어서 문제가 없었음 - 컨벤션에 맞게 변수이름 수정
- 맨 마지막 스크롤까지 가면 page 숫자 증가 - page 숫자를 가지고 페이징 처리 구현
caching 적용 및 네트워크상태 관리
페이징 처리를 하여 이슈 목록 화면 표시 구현
[Team-04][Linus_Jay] Upstream에 마지막 PR 요청을 위한 PR
질문 답변
안녕하세요 ~ // line: 70
// 데이터를 추가하는 코드
// fireStore.collection(FIREBASE_COLLECTION_ISSUE_PATH).document().set(it1)
lastVisibleDocument = issueData.documents.last()
Log.d("reno", "[loadNextPageIssues] last visible document id: ${lastVisibleDocument?.id}")
Log.d("reno", "[loadNextPageIssues] last visible document id: ${(list.last() as Issue).title}")
Log.d("reno", "[loadNextPageIssues] last visible document id: ${(list.last() as Issue).description}")
------------------------------------------------ Log ------------------------------------------------
//첫번째 loadNextPageIssues 함수가 호출되었을 때 결과
9799-9799/com.example.issu_tracker D/reno: [loadNextPageIssues] last visible document id: 1PM0sqRmEzgwngIKNdV4
9799-9799/com.example.issu_tracker D/reno: [loadNextPageIssues] last visible document id: 제이 야근 그만
9799-9799/com.example.issu_tracker D/reno: [loadNextPageIssues] last visible document id: 테스트입니다 |
sealed class IssueList : Serializable { | ||
|
||
object IssueProgressBar : IssueList() | ||
|
||
@Entity | ||
data class Issue( | ||
@ColumnInfo(name = "issue_id") | ||
var id: String, | ||
val comments: List<Comment>, | ||
val description: String, | ||
val label: List<Label>, | ||
val mileStone: String, | ||
val state: Boolean, | ||
val title: String, | ||
@Embedded | ||
val user: User | ||
) : IssueList(), Serializable { | ||
@PrimaryKey(autoGenerate = true) | ||
var idx: Int = 0 | ||
} | ||
} |
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.
sealed class
로 구현하셨던 이유가 무엇일까요?
class Error<T : Any>(val code: Int = EMPTY) : NetworkResult<T>() | ||
class Exception<T : Any>(val e: Throwable) : NetworkResult<T>() |
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.
Error
와 Exception
을 구분하셨던 이유가 있나요?? (궁금해서요 ㅎㅎ)
friendData.forEach { | ||
val user = | ||
User( | ||
it["uid"] ?: "", it["name"] ?: "", | ||
it["userPhoto"] ?: "" | ||
) | ||
friendList.add(user) | ||
} |
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.
map
연산자를 사용하면 좀더 깔끔하겠네요~ ㅎㅎ
issueData.documents.forEach { | ||
val issueObj = it.toObject(IssueDto::class.java) | ||
issueObj?.id = it.id | ||
issueObj?.let { issueDto -> | ||
issueDto.toIssue()?.let { issue -> | ||
list.add(issue) | ||
} | ||
} | ||
} | ||
|
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.
여기도 map
연산자와 toList
연산자를 잘 사용한다면 가독성있는 코드를 만들 수 있겠네요~
@Database(entities = [User::class , IssueList.Issue::class ], version = 2,exportSchema = false) | ||
@TypeConverters(Converters::class) | ||
abstract class IssueTrackerDatabase : RoomDatabase() { | ||
abstract fun userDao(): UserDao | ||
abstract fun issueDao(): IssueDao | ||
} |
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.
Use
, Issue
정보를 Disk 에 저장하는 이유가 있나용?
Memory 에 저장해도 되지 않았나 싶네요 ㅎㅎ
if (issueListResponse is NetworkResult.Success) { | ||
val issueList = issueListResponse.data.toMutableList() | ||
issueList.removeLast() | ||
issueList.addAll(repository.loadNextPageIssues(currentPage)) | ||
issueList.add(IssueList.IssueProgressBar) | ||
_issueListStateFlow.value = NetworkResult.Success(issueList) | ||
} |
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.
NetworkResult.Success
를 제외한 나머지 경우들은 처리 안하는 이유가 있나요?
.filter { | ||
if (condition.state.isNotEmpty() && it is IssueList.Issue) { | ||
it.state | ||
} else { | ||
true | ||
} | ||
}.filter { | ||
if (condition.writer.isNotEmpty() && it is IssueList.Issue) { | ||
it.user.name == condition.writer | ||
} else { | ||
true | ||
} | ||
} | ||
.filter { | ||
if (it is IssueList.Issue) { | ||
it.label.any { label -> | ||
if (condition.label.isNotEmpty()) { | ||
label.content == condition.label | ||
} else { | ||
true | ||
} | ||
} | ||
} |
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.
하나의 filter
연산자에서 처리할 수 있지 않나용?
나눠서 처리하는 이유가 있나요??
고생 많았어요~ |
🤷♂️ Description
📷 Screenshots
캐싱 구현 영상
2022-07-01.9.07.05.mov
무한 스크롤 구현 영상
2022-07-01.9.08.39.mov
🎉 질문 사항
안녕하세요 레노! 페이징 처리를 위해 firebase 의 limit 과 startAfter 메서드를 사용하고 있습니다. (참고자료)
첫번째 페이징 처리로 10개의 데이터를 먼저 불러오고 맨 마지막으로 스크롤할 때
loadNextPageIssues
가 호출되는 구조입니다.첫번째로 데이터를 불러오고 10번째의 데이터를
lastVisibleDocument
에 저장하고loadNextPageIssues
가 호출될 때,startAfter(lastVisibleDocument)
를 사용하여 11번째 데이터부터 다시 10개의 데이터를 불러오도록 구현을 원했습니다.하지만 어찌된 일인지,
lastVisibleDocument
값은 정상적으로 존재하는데, 자꾸issueData
가 빈 리스트로 값이 반환됩니다. (밑에 에러 코드 첨부)원인을 도저히 찾지 못해 어쩔 수 없이, page 번호를 fragment -> ViewModel -> repository 까지 불러와
lastVisibleDoc
에서 볼 수 있듯이 10번째 데이터 값(20번째, 30번째, 40번째 등등)을 다시 할당하고 이를 startAfter() 인자로 넘겨주는 방식으로 구현을 완료했습니다. 하지만 이 경우, 페이지 번호가 높을수록 불러오는 데이터양이 많아져 성능이 저하될 수 밖에 없는 단점이 있습니다. (즉, 지금은 그냥 임시방편으로 페이징을 구현하고 있습니다.)혹시 이에 대해 조언이 있을까요?
🎃 기타