Skip to content
This repository was archived by the owner on Jul 18, 2026. It is now read-only.

Commit 1f778f9

Browse files
authored
Merge pull request #93 from misaka10032w/develop
修复横向滚动列表位置返回重置的问题
2 parents 8924c75 + bce42ea commit 1f778f9

4 files changed

Lines changed: 118 additions & 39 deletions

File tree

app/src/main/java/com/yenaly/han1meviewer/ui/fragment/home/HomePageFragment.kt

Lines changed: 100 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.navigation.ui.onNavDestinationSelected
3232
import androidx.palette.graphics.Palette
3333
import androidx.recyclerview.widget.ConcatAdapter
3434
import androidx.recyclerview.widget.LinearLayoutManager
35+
import androidx.recyclerview.widget.RecyclerView
3536
import coil.load
3637
import com.google.android.material.dialog.MaterialAlertDialogBuilder
3738
import com.yenaly.han1meviewer.ADVANCED_SEARCH_MAP
@@ -86,76 +87,140 @@ class HomePageFragment : YenalyFragment<FragmentHomePageBinding>(),
8687
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.GENRE to "裏番"))
8788
}
8889
},
89-
latestHanimeAdapter.wrappedWith {
90-
LinearLayoutManager(
91-
context, LinearLayoutManager.HORIZONTAL, false
92-
)
90+
latestHanimeAdapter
91+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
92+
.apply {
93+
doOnWrap {
94+
val key = "latestHanime"
95+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
96+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
97+
post { lm.scrollToPositionWithOffset(pos, 0) }
98+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
99+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
100+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
101+
}
102+
})
103+
}
93104
},
94105
VideoColumnTitleAdapter(R.string.latest_release).apply {
95106
onMoreHanimeListener = {
96107
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.SORT to "最新上市"))
97108
}
98109
},
99-
latestReleaseAdapter.wrappedWith {
100-
LinearLayoutManager(
101-
context, LinearLayoutManager.HORIZONTAL, false
102-
)
110+
latestReleaseAdapter
111+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
112+
.apply {
113+
doOnWrap {
114+
val key = "latestRelease"
115+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
116+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
117+
post { lm.scrollToPositionWithOffset(pos, 0) }
118+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
119+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
120+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
121+
}
122+
})
123+
}
103124
},
104125
VideoColumnTitleAdapter(R.string.latest_upload).apply {
105126
onMoreHanimeListener = {
106127
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.SORT to "最新上傳"))
107128
}
108129
},
109-
latestUploadAdapter.wrappedWith {
110-
LinearLayoutManager(
111-
context, LinearLayoutManager.HORIZONTAL, false
112-
)
130+
latestUploadAdapter
131+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
132+
.apply {
133+
doOnWrap {
134+
val key = "latestUpload"
135+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
136+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
137+
post { lm.scrollToPositionWithOffset(pos, 0) }
138+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
139+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
140+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
141+
}
142+
})
143+
}
113144
},
114145
VideoColumnTitleAdapter(R.string.chinese_subtitle).apply {
115146
onMoreHanimeListener = {
116-
showSearchFragment(
117-
advancedSearchMapOf(
118-
HAdvancedSearch.TAGS to hashMapOf(
119-
"video_attributes" to "中文字幕"
120-
)
121-
)
122-
)
147+
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.TAGS to hashMapOf("video_attributes" to "中文字幕")))
123148
}
124149
},
125-
chineseSubtitleAdapter.wrappedWith {
126-
LinearLayoutManager(
127-
context, LinearLayoutManager.HORIZONTAL, false
128-
)
150+
chineseSubtitleAdapter
151+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
152+
.apply {
153+
doOnWrap {
154+
val key = "chineseSubtitle"
155+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
156+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
157+
post { lm.scrollToPositionWithOffset(pos, 0) }
158+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
159+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
160+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
161+
}
162+
})
163+
}
129164
},
130165
VideoColumnTitleAdapter(R.string.they_watched).apply {
131166
onMoreHanimeListener = {
132167
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.SORT to "他們在看"))
133168
}
134169
},
135-
hanimeTheyWatchedAdapter.wrappedWith {
136-
LinearLayoutManager(
137-
context, LinearLayoutManager.HORIZONTAL, false
138-
)
170+
hanimeTheyWatchedAdapter
171+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
172+
.apply {
173+
doOnWrap {
174+
val key = "hanimeTheyWatched"
175+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
176+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
177+
post { lm.scrollToPositionWithOffset(pos, 0) }
178+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
179+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
180+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
181+
}
182+
})
183+
}
139184
},
140185
VideoColumnTitleAdapter(R.string.ranking_today).apply {
141186
onMoreHanimeListener = {
142187
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.SORT to "本日排行"))
143188
}
144189
},
145-
hanimeCurrentAdapter.wrappedWith {
146-
LinearLayoutManager(
147-
context, LinearLayoutManager.HORIZONTAL, false
148-
)
190+
hanimeCurrentAdapter
191+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
192+
.apply {
193+
doOnWrap {
194+
val key = "hanimeCurrent"
195+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
196+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
197+
post { lm.scrollToPositionWithOffset(pos, 0) }
198+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
199+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
200+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
201+
}
202+
})
203+
}
149204
},
150205
VideoColumnTitleAdapter(R.string.ranking_this_month).apply {
151206
onMoreHanimeListener = {
152207
showSearchFragment(advancedSearchMapOf(HAdvancedSearch.SORT to "本月排行"))
153208
}
154209
},
155-
hotHanimeMonthlyAdapter.wrappedWith {
156-
LinearLayoutManager(
157-
context, LinearLayoutManager.HORIZONTAL, false
158-
)
210+
hotHanimeMonthlyAdapter
211+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)}
212+
.apply {
213+
doOnWrap {
214+
val key = "hotHanimeMonthly"
215+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
216+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
217+
post { lm.scrollToPositionWithOffset(pos, 0) }
218+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
219+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
220+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
221+
}
222+
})
223+
}
159224
}
160225
)
161226

app/src/main/java/com/yenaly/han1meviewer/ui/fragment/video/VideoIntroductionFragment.kt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,22 @@ class VideoIntroductionFragment : YenalyFragment<FragmentVideoIntroductionBindin
128128
private val playlistTitleAdapter =
129129
VideoColumnTitleAdapter(title = R.string.series_video, notifyWhenSet = true)
130130
private val playlistAdapter = HanimeVideoRvAdapter(VIDEO_LAYOUT_WRAP_CONTENT)
131-
private val playlistWrapper = playlistAdapter.wrappedWith {
132-
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
133-
}
131+
private val playlistWrapper = playlistAdapter
132+
.wrappedWith { LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) }
133+
.apply {
134+
doOnWrap {
135+
val key = viewModel.videoCode
136+
val lm = layoutManager as? LinearLayoutManager ?: return@doOnWrap
137+
val pos = viewModel.horizontalScrollPositions[key] ?: 0
138+
post { lm.scrollToPositionWithOffset(pos, 0) }
139+
addOnScrollListener(object : RecyclerView.OnScrollListener() {
140+
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
141+
viewModel.horizontalScrollPositions[key] = lm.findFirstVisibleItemPosition()
142+
}
143+
})
144+
}
145+
}
146+
134147
private val relatedTitleAdapter =
135148
VideoColumnTitleAdapter(title = R.string.related_video)
136149
private val relatedAdapter = HanimeVideoRvAdapter(VIDEO_LAYOUT_MATCH_PARENT)

app/src/main/java/com/yenaly/han1meviewer/ui/viewmodel/MainViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class MainViewModel(application: Application) : YenalyViewModel(application) {
3030
private val _homePageFlow =
3131
MutableStateFlow<WebsiteState<HomePage>>(WebsiteState.Loading)
3232
val homePageFlow = _homePageFlow.asStateFlow()
33+
val horizontalScrollPositions = mutableMapOf<String, Int>()
3334

3435
fun getHomePage() {
3536
viewModelScope.launch {

app/src/main/java/com/yenaly/han1meviewer/ui/viewmodel/VideoViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class VideoViewModel(application: Application) : YenalyViewModel(application) {
4545
*/
4646
const val MIN_H_KEYFRAME_SAVE_INTERVAL = 5_000 // ms
4747
}
48-
48+
val horizontalScrollPositions = mutableMapOf<String, Int>()
4949
var videoCode: String = EMPTY_STRING
5050
set(value) {
5151
field = value

0 commit comments

Comments
 (0)