天天看點

譯文----- JetpackCompose List清單(下)

Many apps need to react and listen to scroll position and item layout changes. The lazy components support this use-case by hoisting the <code>LazyListState</code>:

很多app需要根據item的滑動做出相應的變化. 可以通過懶加載元件(<code>LazyColumn</code>和<code>LazyRow</code>)的<code>LazyListState</code>來實作該功能

For simple use-cases, apps commonly only need to know information about the first visible item. For this <code>LazyListState</code> provides the <code>firstVisibleItemIndex</code> and <code>firstVisibleItemScrollOffset</code> properties.

常見的應用場景, app僅僅需要知道關于第一個可見的<code>item</code>的資訊. 這些資訊可以通過<code>LazyListState</code>的<code>firstVisibleItemIndex</code>和<code>firstVisibleItemScrollOffset</code>擷取到

If we use the example of a showing and hiding a button based on if the user has scrolled past the first item:

以下示例, 展示了如何一個<code>button</code>根據使用者的滑動操作來動态的顯示和隐藏的效果實作

Note: The example above uses <code>derivedStateOf()</code> to minimize unnecessary compositions. For more information, see the Side Effects documentation.

上面的例子通過 <code>derivedStateOf()</code> 來優化計算量, 更多資訊請閱讀 <code>副作用文檔</code>

(百度翻譯為--&gt;注意:上面的例子使用<code>derivedStateOf()</code>來最小化不必要的合成。有關更多資訊,請參閱副作用文檔, 讀着不順, 看了下<code>derivedStateOf()</code>的文檔大概可了解為(還沒看源碼實作,是以可能了解不準确), 這個函數會儲存一個狀态值在緩存中, 當狀态不改變時, 不會導緻重複的計算狀态值)

Reading the state directly in composition is useful when you need to update other UI composables, but there are also scenarios where the event does not need to be handled in the same composition. A common example of this is sending an analytics event once the user has scrolled past a certain point. To handle this efficiently, we can use a <code>snapshotFlow()</code>:

當你想要更新UI元件時, 直接在元件中讀取狀态會更有效(useful原意有用的, 但感覺翻譯稱"有效"會更好). 但也有一些不需要在相同的元件中處理事件, 一個常見的例子是: 一旦使用者滾動過某個點, 就發送一個事件. 為了有效地處理這個問題,我們可以使用<code>snapshotFlow()</code>

<code>LazyListState</code> also provides information about all of the items currently being displayed and their bounds on screen, via the <code>layoutInfo</code> property. See the <code>LazyListLayoutInfo</code> class for more information. <code>LazyListState</code>還通過<code>layoutInfo</code>屬性提供有關目前顯示的所有item及其在螢幕上的界限的資訊. 有關詳細資訊,請閱讀<code>LazyListLayoutInfo</code>類.
As well as reacting to scroll position, it’s also useful for apps to be able to control the scroll position too. <code>LazyListState</code> supports this via the <code>scrollToItem()</code> function, which ‘immediately’ snaps the scroll position, and <code>animateScrollToItem()</code> which scrolls using an animation (also known as a smooth scroll):

對于一個app來說, 控制滾動位置和擷取滑動事件一樣的有用. 可以通過<code>LazyListState</code>的<code>scrollToItem()</code>函數來控制item立即滾動到某個索引. <code>animateScrollToItem()</code>則會通過動畫效果來平滑過渡

Note: Both <code>scrollToItem()</code> and <code>animateScrollToItem()</code> are suspending functions, which means that we need to invoke them in a coroutine. See our coroutines documentation for more information on how to do that in Compose.

注意:<code>scrollToItem()</code> 和 <code>animateScrollToItem()</code> 都是挂起函數,這意味着我們需要在協同例程中調用它們。有關如何在Compose中實作這一點的更多資訊,請參閱我們的coroutines文檔。

The Paging library enables apps to support large lists of items, loading and displaying small chunks of the list as necessary. Paging 3.0 and later provides Compose support through the androidx.paging:paging-compose library

<code>Paging library</code>元件能夠支援使用小量的開銷, 來加載和展示大量資料list清單, <code>Compose</code>需要使用<code>Paging3.0</code> 及更高版本的<code>androidx.paging:paging-compose</code>庫

Note: Compose support is provided only for Paging 3.0 and later. If you're using an earlier version of the Paging library, you need to migrate to 3.0 first.

注意: <code>Compose</code>需要使用<code>Paging3.0</code>或更高版本, 如果你使用的<code>Paging</code>庫的版本比較低(version &lt; 3.0 )則需要先遷移到3.0(或以上)

To display a list of paged content, we can use the collectAsLazyPagingItems() extension function, and then pass in the returned LazyPagingItems to items() in our LazyColumn. Similar to Paging support in views, you can display placeholders while data loads by checking if the item is null:

要分頁顯示内容清單, 可以使用<code>collectAsLazyPagingItems()</code>函數,然後将傳回的<code>LazyPagingItems</code>傳入<code>LazyColumn</code>中的<code>items()</code>. 與<code>View</code>(應該指的是原生view元件) 中的分頁類似,通過檢查項是否為空,可以在加載資料時顯示placeholders(占位符):

警告:如果使用<code>RemoteMediator</code>從網絡服務擷取資料,請確定提供實際大小的placeholder(占位符)。如果您使用<code>RemoteMediator</code>, 它将被反複調用以擷取新資料, 直到螢幕上充滿内容為止。如果提供了小的placeholder(占位符)(或者根本沒有占位符), 螢幕可能永遠不會被填滿, 應用程式将擷取許多頁的資料.

By default, each item's state is keyed against the position of the item in the list. However, this can cause issues if the data set changes, since items which change position effectively lose any remembered state. If you imagine the scenario of <code>LazyRow</code> within a <code>LazyColumn</code>, if the row changes item position, the user would then lose their scroll position within the row.

預設情況下, 每個item的狀态都是根據item在list中的位置設定的. 然而, 如果資料集發生了改變就會導緻一系列問題, 因為item 會因為更改位置而丢失所記錄的狀态. 設想一下<code>LazyRow</code>在<code>LazyColumn</code>中使用的場景, 如果row改變了item的位置, 那麼使用者将丢失其在行中的滾動位置(這部分沒完全了解, 是以暫時用的百度翻譯)

(個人注釋: 關于這一段我是這麼了解的, 比如說一個縱向滑動(<code>LazyColumn</code>)嵌套了一個橫向滑動(<code>LazyRow</code>), 然後橫向滑動到了任意一位置上, 假設為第三個, 此時通過<code>remember</code>記錄相應狀态, 那麼如果此時再進行縱向滑動, 那麼就會失去橫向滑動的索引坐标, ,不過還沒測試是否正确)

Note: For more information on how Compose remembers state, see the State documentation

注意:有關<code>Compose</code>如何記住狀态的更多資訊,請參閱<code>State</code>文檔

To combat this, you can provide a stable and unique key for each item, providing a block to the key parameter. Providing a stable key enables item state to be consistent across data-set changes:

如果要解決上述問題, 你可以為每個item綁定一個唯一的key, 提供一個穩定的key可以使狀态在資料集中更改中保持一直

Note: Any key provided must be able to be stored within a <code>Bundle</code>. See that class for information on what types can be stored.

注意: 任何一個被設定的key必須能夠存儲到<code>Bundle</code>中. 有關可以存儲哪些類型的資訊,請參見該類.(Android中<code>Bundle</code>能存的也就是實作序列化(<code>Serializable</code>或<code>Parcelable</code>)的類和基本資料類型)