PagingSourceã¯ã©ã¹ã®èªä½ãå¿ è¦ï¼1ï¼
ãæ¬é£è¼ã¯ãAndroid Jetpackãç´¹ä»ãã¦ãã¾ããä»åã¯ã大éã®ãã¼ã¿ãå¹çããæ±ãããã¼ã¸ã³ã°ã©ã¤ãã©ãªãå©ç¨ãã¦ããããä¸ã«ãããªã¹ããã¼ã¿ããã¼ã¸ã³ã°ããæ¹æ³ã解説ãã¾ãã
ããªããä»åã®ãµã³ãã«ãã¼ã¿ã¯ãGitHubããåç §ã§ãã¾ãããã ãããµã³ãã«å ã®ã³ã¼ãã§ã¯å®éã«ãããã«ã¢ã¯ã»ã¹ãã¦ãã¼ã¿ãåå¾ããã³ã¼ãã¯è¨è¼ãããããã¼ã§ãã¼ã¿ãçæããã³ã¼ãã¨ãªã£ã¦ããç¹ã¯ããããããäºæ¿ãã ããã
PagingSourceã¯ã©ã¹ã¯PagingSourceãç¶æ¿
ãååç´¹ä»ããã®ã¯ã大éã®ãªã¹ããã¼ã¿ããã¼ã¸ã«åå²ãããã®å¶å¾¡ãè¡ãPagingSourceãªãã¸ã§ã¯ãããRoomã«ãã£ã¦èªåçæãã¦ãããã¨ãã£ãå 容ã§ããã大éã®ãªã¹ããã¼ã¿ããã¼ã¿ãã¼ã¹å ã«æ ¼ç´ããã¦ãããªãã°ããã®æ¹æ³ãæé©ã¨ããã¾ãã
ã䏿¹ããã¼ã¿ããããä¸ã«ããå ´åãå½ç¶ã§ããRoomã«ããèªåçæã¯ä½¿ãããPagingSourceã¯ã©ã¹ãèªä½ãããã®ä¸ã§ããããããã¼ã¿ãåå¾ããã³ã¼ããè¨è¿°ããå¿ è¦ãããã¾ãããã®éª¨æ ¼ã¯ãä¾ãã°ããªã¹ã1ã®ã³ã¼ãã«ãªãã¾ãããã®ã³ã¼ãã¯ãååã®å³1åæ§ã«ãé»è©±çªå·ã¨ãã®ä¸»ãã¼ã表示ããã¢ããªãæ³å®ãã¦ãã¾ãããã®ãããã¯ã©ã¹åãPhonePagingSourceã¨ãã¦ãã¾ãã
class PhonePagingSource : PagingSource<Int, Phone>() { // (1)
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Phone> { // (2)
:
}
override fun getRefreshKey(state: PagingState<Int, Phone>): Int? { // (3)
:
}
}
ãPagingSourceã¯ã©ã¹ä½æã®ãã¤ã³ãã¯ãï¼1ï¼ã«ããããã«ãPagingSourceã¯ã©ã¹ãç¶æ¿ãããã¨ã§ãããã®éãã¸ã§ããªã¯ã¹ã¨ãã¦ãRoomã®DAOã¤ã³ã¿ã¼ãã§ã¼ã¹ã®ãªã¹ããã¼ã¿ãåå¾ããã¡ã½ããã®æ»ãå¤ã®PagingSourceã«å®ç¾©ããã¸ã§ããªã¯ã¹ã¨åæ§ã®ãã®ãæå®ãã¾ããããªãã¡ãã¸ã§ããªã¯ã¹ã®ã²ã¨ã¤ãã¯ãåãã¼ã¸ãåºå¥ããããã®ãã¼ã¿ã®ãã¼ã¿åãããµãã¤ãã¯ãªã¹ããã¼ã¿ã®åã¢ã¤ãã ã表ãã¯ã©ã¹ãæå®ãã¾ãã
ããã®PagingSourceã¯ã©ã¹ã¯æ½è±¡ã¯ã©ã¹ã¨ãªã£ã¦ããã®ã§ãæ½è±¡ã¡ã½ããããªã¼ãã¼ã©ã¤ããã¦ããå¿ è¦ãããã¾ãããããããªã¹ã1ã®ï¼2ï¼ã®load()ã¨ï¼3ï¼ã®getRefreshKey()ã§ãã
load()ã¡ã½ããã®å®è£ æ¹æ³
ããªã¼ãã¼ã©ã¤ããå¿ è¦ãª2åã®æ½è±¡ã¡ã½ããã®ãã¡ãload()ã¡ã½ããã¯ãã¼ã¸ã³ã°ã®èã¨ãªãã¡ã½ããã§ãããã®å¼æ°ã§ããLoadParamsã«ã¯ã表1ã®3åã®ããããã£ãå«ã¾ãã¦ãã¾ãããªãã表ä¸ã®ãã¼ã¿åKeyã¯ã¸ã§ããªã¯ã¹ã§æå®ãããã¼ã¿åã§ãã
| ããããã£å | ãã¼ã¿å | å 容 |
| key | Key? | 次ã«èªã¿è¾¼ãã¹ããªã¹ãã®ãã¼ã¨ãªãå¤ãååæã¯null |
| loadSize | Int | 1ãã¼ã¸åã®ã¢ã¤ãã æ° |
| placeholdersEnabled | Boolean | PagingConfig.enablePlaceholdersã§è¨å®ããå¤ |
ããããã®å¤ãå ã«ãããããªã©ããå¿ è¦ãªãªã¹ããã¼ã¿ãåå¾ãããã®ãªã¹ããã¼ã¿ãå ã«ãã¼ã¸ãã¼ã¿ãçæãã¦ãªã¿ã¼ã³ãã¾ãããã®æ»ãå¤ã¨ãã¦ã¯ãç¡äºãªã¹ããã¼ã¿ãç¨æã§ããå ´åã¯LoadResult.Pageãã失æããå ´åã¯LoadResult.Errorã¨ãã¾ãã
ãããã¯ãä¾ãã°ããªã¹ã2ã®ã³ã¼ãã¨ãªãã¾ãããªããï¼2ï¼ã®fetchPhoneListSize()ã¯ããããä¸ã«ãããªã¹ããã¼ã¿ã®ç·ä»¶æ°ãåå¾ããsuspend颿°ã§ããåæ§ã«ãfetchPhoneList()ã¯ããããä¸ãããªã¹ããã¼ã¿ãåå¾ããsuspend颿°ã§ãã弿°ã¨ãã¦ã¯åãåºããªã¹ãã®éå§idã¨çµäºidãåãåãããã«ãã¦ãã¾ãã
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Phone> {
var returnVal: LoadResult<Int, Phone> // (1)
try {
val phoneListSize = fetchPhoneListSize() // (2)
val startKey = params.key ?: 1 // (3)
var endKey = startKey + params.loadSize - 1 // (4)
if(endKey > phoneListSize) { // (4)
endKey = phoneListSize
}
val fetchedPhoneList = fetchPhoneList(startKey, endKey) // (5)
val prevKey = if(startKey - params.loadSize <= 0) { // (6)
null
}
else {
startKey - params.loadSize
}
val nextKey = if(endKey + 1 >= phoneListSize) { // (7)
null
}
else {
endKey + 1
}
returnVal = LoadResult.Page(fetchedPhoneList, prevKey, nextKey) // (8)
}
catch(ex: Exception) {
returnVal = LoadResult.Error(ex) // (9)
}
return returnVal
}
ããªã¹ã2ã®å¤§ããªæµãã¨ãã¦ã¯ãï¼1ï¼ã§æ»ãå¤å¤æ°ã¨ãã¦LoadResult<Int, Phone>åã®returnValãç¨æãããã®å¾ãå¦çå ¨ä½ãtryãããã¯ã§å²ã¿ãä¾å¤å¦çãè¡ã£ã¦ãã¾ãããããä¸ãããã¼ã¿ãåå¾ãããããªå¦çã§ã¯å¿ é ã®ã³ã¼ããã¿ã¼ã³ã¨ããã¾ãã
ããã®ä¾å¤å¦çã®catchãããã¯ãå¦ç失æã¨è¨ããã®ã§ãï¼9ï¼ã§LoadResult.Errorã¤ã³ã¹ã¿ã³ã¹ãçæããæ»ãå¤ã®returnValã¨ãã¦ãã¾ãããã®éã弿°ã¨ãã¦ä¾å¤ã¤ã³ã¹ã¿ã³ã¹ã渡ãã¦ãã¾ãã
ã䏿¹ãtryãããã¯ã®æçµè¡ã§ããï¼8ï¼ãå¦çãæåããå ´åã§ãã®ã§ãããã§LoadResult.Pageã¤ã³ã¹ã¿ã³ã¹ãçæãã¦ãã¾ãããã®éã弿°ã¨ãã¦è¡¨2ã®3åã®å¤ã渡ãå¿ è¦ããããããããäºåã«tryãããã¯å ã§ç¨æãã¦ãã¾ãããªãã表ä¸ã®ãã¼ã¿åKeyã¨Valueã¯ã¸ã§ããªã¯ã¹ã§æå®ãããã¼ã¿åã§ãã
| 弿°å | ãã¼ã¿å | å 容 | |
| 1 | data | List<Value> | ç¾å¨ã®ãã¼ã¸ã®ãªã¹ããã¼ã¿ |
| 2 | prevKey | Key? | åãã¼ã¸ã®éå§ãã¼ã®å¤ãåãã¼ã¸ããªãå ´åã¯null |
| 3 | nextKey | Key? | 次ãã¼ã¸ã®éå§ãã¼ã®å¤ã次ãã¼ã¸ããªãå ´åã¯null |
ãã¾ããï¼3ï¼ï½ï¼5ï¼ã§ãããä¸ãããªã¹ããã¼ã¿ãåå¾ãã¦ãã¾ããï¼3ï¼ãéå§ãã¼ãããªãã¡ããããä¸ã«ãããªã¹ããã¼ã¿ããåãåºããªã¹ããã¼ã¿ã®éå§idãã夿°startKeyã¨ãã¦çæãã¦ãã¾ãããã®éã弿°paramsã®keyããããã£ã®å¤ãå©ç¨ãã表1ã®éãããã®å¤ãnullã®å ´åã¯1ã¨ãã¦ãã¾ãã
ãï¼4ï¼ã¯ãçµäºãã¼ãendKeyã¨ãã¦çæãã¦ãã¾ãããã®éã表1ã®å¼æ°paramsã®loadSizeããããã£ãå©ç¨ãã¦ãã¾ããããã«ï¼2ï¼ã§åå¾ããå ¨ãªã¹ããµã¤ãºãå ã«endKeyããªã¹ããµã¤ãºãè¶ ãã¦ããå ´åã¯ãendKeyããªã¹ããµã¤ãºã¨ãã¦ãã¾ãã
ããã®ããã«ãã¦çæããstartKeyã¨endKeyãå ã«ãããä¸ãããªã¹ããã¼ã¿ãåå¾ãã¦ããã®ãï¼5ï¼ã§ããããã¦ãããããã®ã¾ã¾ï¼8ï¼ã§LoadResult.Pageã¤ã³ã¹ã¿ã³ã¹ãçæããéã®ç¬¬1弿°ã¨ãªã£ã¦ãã¾ãã
ãæ¬¡ã«ã第2弿°ã®prevKeyã¨ç¬¬3弿°ã®nextKeyãçæãã¦ããå¿ è¦ãããã¾ãããããï¼6ï¼ã¨ï¼7ï¼ã§ãããããã®ã³ã¼ãã¯ãåç´ã«startKeyãendKeyã¨params.loadSizeãå ã«ç®åºããå¦çã«éãã¾ããããã ãã表2ã®éããprevKeyã®å ´åã¯ãç®åºããçµæã0以ä¸ã®å ´åã¯åãã¼ã¸ããªãã®ã§nullã¨ããå¿ è¦ãããã¾ããåæ§ã«ãnextKeyã¯å ¨ãªã¹ããµã¤ãºãã大ãããã°nullã¨ããå¿ è¦ãããã¾ãã
