📌  相关文章
📜  Android Jetpack Compose 中的 Lazy Composables – 列、行、网格

📅  最后修改于: 2022-05-13 01:54:42.167000             🧑  作者: Mango

Android Jetpack Compose 中的 Lazy Composables – 列、行、网格

在 Jetpack compose 中,我们有像ColumnRow这样的可组合项,但是当应用程序需要在一行或几列中显示大量项目时,如果通过 RowColumn Composable 来完成,则效率不高。因此,我们在 Jetpack Compose 中有 Lazy Composables。我们主要有三种 Lazy Composables Row、Column 和 Grid。在本文中,我们将研究所有三个 Lazy Composable。我们将构建一个简单的应用程序来演示所有三个可组合的操作。

先决条件:

  • 对 Kotlin 的了解。
  • Jetpack Compose 的知识。

分步实施

第 1 步:创建一个新项目(或在现有 Compose 项目中使用它)

要在 Android Studio Canary 版本中创建新项目,请参阅文章如何使用 Jetpack Compose 在 Android Studio Canary 版本中创建新项目。



第 2 步:添加颜色(可选)

打开ui > 主题 > Colors.kt并添加

第 3 步:创建要显示的行和列项

打开MainActivity.kt并创建两个可组合项,一个用于行项,一个用于列项

Kotlin
// Row Item with item Number 
@Composable
fun RowItem(number: Int) {
  
    // Simple Row Composable
    Row(
        modifier = Modifier
            .size(100.dp) // Size 100 dp
            .background(Color.White) // Background White
            .border(1.dp, GreenGfg), // Border color green
  
        // Align Items in Center
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center
  
    ) {
        // Text Composable which displays some 
        // kind of message , text color is green
        Text(text = "This Is Item Number $number", color = GreenGfg)
    }
}
  
// Similar to row composable created above
@Composable
fun ColumnItem(number: Int) {
  
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .height(30.dp)
            .background(Color.White)
            .border(1.dp, GreenGfg),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
  
    ) {
        Text(text = "This Is Item Number $number", color = GreenGfg)
    }
}


Kotlin
@Composable
fun LazyRowExample(numbers: Array) {
  
    // Place A lazy Row
    LazyRow(
        contentPadding = PaddingValues(8.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
  
        // item places one item on the LazyScope
        item {
            RowItem(number = 0)
        }
  
        // items(count) places number of items supplied
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            RowItem(number = currentCount)
        }
  
        // items(list/array) places number of items same as
        // the size of list/array and gives current list/array
        // item in the lazyItemScope
        items(numbers) {arrayItem-> // Here numbers is Array so we 
                                      // get Int in the scope.
            RowItem(number = arrayItem)
        }
  
        // items(list/array) places number of items same 
        // as the size of list/array and gives current list/array 
        // item and currentIndex in the lazyItemScope
        itemsIndexed(numbers) { index: Int, item: Int ->
            RowItem(number = index)
        }
    }
}


Kotlin
@Composable
fun ColumnExample(numbers: Array) {
  
    LazyColumn(
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        // item places one item on the LazyScope
        item {
            ColumnItem(number = 0)
        }
  
        // items(count) places number of items supplied 
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            ColumnItem(number = currentCount)
        }
  
        // items(list/array) places number of items same
        // as the size of list/array and gives current 
        // list/array item in the lazyItemScope
        items(numbers) {arrayItem->
            ColumnItem(number = arrayItem)
        }
  
        // items(list/array) places number of items 
        // same as the size of list/array and gives
        // current list/array item and currentIndex 
        // in the lazyItemScope
        itemsIndexed(numbers) { index, item ->
            ColumnItem(number = index)
        }
    }
}


Kotlin
// add the annotation, 
// since [LazyVerticalGrid] is Experimental Api
@ExperimentalFoundationApi
@Composable
fun GridExample(numbers: Array) {
    // Lazy Vertical grid
    LazyVerticalGrid(
        // fix the item in one row to be 2.
        cells = GridCells.Fixed(2),
  
        contentPadding = PaddingValues(8.dp),
  
        ) {
        item {
            RowItem(number = 0)
        }
        items(10) {
            RowItem(number = it)
        }
        items(numbers) {
            RowItem(number = it)
        }
        itemsIndexed(numbers) { index, item ->
            RowItem(number = index)
        }
    }
}


Kotlin
class MainActivity : ComponentActivity() {
  
    // Creates array as [0,1,2,3,4,5,.....99]
    private val numbers: Array = Array(100) { it + 1 }
  
    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LazyComponentsTheme {
  
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color.White)
                ) {
                    // Place the row and column 
                    // to take 50% height of screen
                    Column(Modifier.fillMaxHeight(0.5f)) {
                          
                        // Heading
                        Text(
                            text = "Row",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                          
                        // Lazy Row, pass the numbers array
                        LazyRowExample(numbers = numbers)
                          
                        // Heading
                        Text(
                            text = "Column",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                        // Lazy Column, Pass the numbers array
                        LazyColumnExample(numbers = numbers)
                    }
                      
                    Column(Modifier.fillMaxHeight()) {
                          
                        // Heading
                        Text(
                            text = "Grid",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                          
                        // Lazy Grid
                        GridExample(numbers = numbers)
                    }
                }
            }
        }
    }
}


Kotlin
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.gfg.lazycomponents.ui.theme.GreenGfg
import com.gfg.lazycomponents.ui.theme.LazyComponentsTheme
  
class MainActivity : ComponentActivity() {
  
    // Creates array as [0,1,2,3,4,5,.....99]
    private val numbers: Array = Array(100) { it + 1 }
  
    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LazyComponentsTheme {
  
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color.White)
                ) {
                    // Place the row and column
                    // to take 50% height of screen
                    Column(Modifier.fillMaxHeight(0.5f)) {
  
                        // Heading
                        Text(
                            text = "Row",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
  
                        // Lazy Row,pass the numbers array
                        LazyRowExample(numbers = numbers)
  
                        // Heading
                        Text(
                            text = "Column",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                        // Lazy Column, Pass the numbers array
                        LazyColumnExample(numbers = numbers)
                    }
  
                    Column(Modifier.fillMaxHeight()) {
  
                        // Heading
                        Text(
                            text = "Grid",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
  
                        // Lazy Grid
                        GridExample(numbers = numbers)
                    }
                }
            }
        }
    }
}
  
  
@Composable
fun LazyRowExample(numbers: Array) {
    // Place A lazy Row
    LazyRow(
        contentPadding = PaddingValues(8.dp),
          
        // Each Item in LazyRow have a 8.dp margin
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
  
        // item places one item on the LazyScope
        item {
            RowItem(number = 0)
        }
  
        // items(count) places number of items supplied
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            RowItem(number = currentCount)
        }
  
        // items(list/array) places number of items 
        // same as the size of list/array and gives 
        // current list/array item in the lazyItemScope
        items(numbers) {arrayItem-> // Here numbers is Array so we 
                                      // get Int in the scope.
            RowItem(number = arrayItem)
        }
  
        // items(list/array) places number of items 
        // same as the size of list/array and gives
        // current list/array item and currentIndex
        // in the lazyItemScope
        itemsIndexed(numbers) { index: Int, item: Int ->
            RowItem(number = index)
        }
    }
}
  
  
@Composable
fun RowItem(number: Int) {
    // Simple Row Composable
    Row(
        modifier = Modifier
            .size(100.dp) // Size 100 dp
            .background(Color.White) // Background White
            .border(1.dp, GreenGfg), // Border color green
  
        // Align Items in Center
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center
    ) {
        // Text Composable which displays some 
        // kind of message , text color is green
        Text(text = "This Is Item Number $number", color = GreenGfg)
    }
}
  
@Composable
fun ColumnItem(number: Int) {
  
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .height(30.dp)
            .background(Color.White)
            .border(1.dp, GreenGfg),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
  
    ) {
        Text(text = "This Is Item Number $number", color = GreenGfg)
    }
}
  
@Composable
fun LazyColumnExample(numbers: Array) {
    LazyColumn(
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        // item places one item on the LazyScope
        item {
            ColumnItem(number = 0)
        }
  
        // items(count) places number of items supplied 
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            ColumnItem(number = currentCount)
        }
  
        // items(list/array) places number of items
        // same as the size of list/array and gives 
        // current list/array item in the lazyItemScope
        items(numbers) {arrayItem->
            ColumnItem(number = arrayItem)
        }
  
        // items(list/array) places number of 
        // items same as the size of list/array 
        // and gives current list/array item and 
        // currentIndex in the lazyItemScope
        itemsIndexed(numbers) { index, item ->
            ColumnItem(number = index)
        }
    }
}
  
  
// add the annotation, 
// since [LazyVerticalGrid] is Experimental Api
@ExperimentalFoundationApi
@Composable
fun GridExample(numbers: Array) {
    // Lazy Vertical grid
    LazyVerticalGrid(
        
        // fix the item in one row to be 2.
        cells = GridCells.Fixed(2),
  
        contentPadding = PaddingValues(8.dp),
  
        ) {
        item {
            RowItem(number = 0)
        }
        items(10) {
            RowItem(number = it)
        }
        items(numbers) {
            RowItem(number = it)
        }
        itemsIndexed(numbers) { index, item ->
            RowItem(number = index)
        }
    }
}


第 4 步:使用 Lazy Composables

Unline ColumnRow Composable 我们不能将可组合直接放在Lazy Composable 中。 Lazy Composables 提供了在 LazyScope 中放置项目的功能。主要有五个重载函数。

Function



Parameter

Functionality

itemComposablePlaces one item in the LazyScope
itemscount,key(optional),ComposablePlaces count items in the LazyScope
itemsList, ComposablePlaces number of items present same as the size of List,
itemsArray, ComposablePlaces number of items present same as the size of Array,
itemsIndexedArray/List,Composable

Places number of items present same as the size of Array,

and provides item(in list) and index of current Item.

步骤 4.1:懒惰行

在MainActivity.kt中创建一个Composable,这里我们放置Lazy row来演示Lazy Row

科特林

@Composable
fun LazyRowExample(numbers: Array) {
  
    // Place A lazy Row
    LazyRow(
        contentPadding = PaddingValues(8.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
  
        // item places one item on the LazyScope
        item {
            RowItem(number = 0)
        }
  
        // items(count) places number of items supplied
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            RowItem(number = currentCount)
        }
  
        // items(list/array) places number of items same as
        // the size of list/array and gives current list/array
        // item in the lazyItemScope
        items(numbers) {arrayItem-> // Here numbers is Array so we 
                                      // get Int in the scope.
            RowItem(number = arrayItem)
        }
  
        // items(list/array) places number of items same 
        // as the size of list/array and gives current list/array 
        // item and currentIndex in the lazyItemScope
        itemsIndexed(numbers) { index: Int, item: Int ->
            RowItem(number = index)
        }
    }
}

步骤 4.2:惰性列

在MainActivity.kt中创建一个Composable,这里我们将放置Lazy Column来演示Lazy Column

科特林



@Composable
fun ColumnExample(numbers: Array) {
  
    LazyColumn(
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        // item places one item on the LazyScope
        item {
            ColumnItem(number = 0)
        }
  
        // items(count) places number of items supplied 
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            ColumnItem(number = currentCount)
        }
  
        // items(list/array) places number of items same
        // as the size of list/array and gives current 
        // list/array item in the lazyItemScope
        items(numbers) {arrayItem->
            ColumnItem(number = arrayItem)
        }
  
        // items(list/array) places number of items 
        // same as the size of list/array and gives
        // current list/array item and currentIndex 
        // in the lazyItemScope
        itemsIndexed(numbers) { index, item ->
            ColumnItem(number = index)
        }
    }
}

步骤 4.3:懒惰网格

在 MainActivity.kt 中创建一个 Composable,这里我们将放置 LazyVerticalGrid。它与其他惰性可组合几乎相同,但它需要一个额外的参数单元格,即一行中的网格项数/一项的最小宽度。单元格可以是GridCells.Fixed(count) ,它固定显示在一个网格行中的项目。它接受的另一个值是GridCells.Adaptive(minWidth),它设置每个网格项的 minWidth。

科特林

// add the annotation, 
// since [LazyVerticalGrid] is Experimental Api
@ExperimentalFoundationApi
@Composable
fun GridExample(numbers: Array) {
    // Lazy Vertical grid
    LazyVerticalGrid(
        // fix the item in one row to be 2.
        cells = GridCells.Fixed(2),
  
        contentPadding = PaddingValues(8.dp),
  
        ) {
        item {
            RowItem(number = 0)
        }
        items(10) {
            RowItem(number = it)
        }
        items(numbers) {
            RowItem(number = it)
        }
        itemsIndexed(numbers) { index, item ->
            RowItem(number = index)
        }
    }
}

第 5 步:将可组合物放在屏幕上

现在将所有三个示例都放在MainActivity Class 的 setContentView 中。

科特林

class MainActivity : ComponentActivity() {
  
    // Creates array as [0,1,2,3,4,5,.....99]
    private val numbers: Array = Array(100) { it + 1 }
  
    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LazyComponentsTheme {
  
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color.White)
                ) {
                    // Place the row and column 
                    // to take 50% height of screen
                    Column(Modifier.fillMaxHeight(0.5f)) {
                          
                        // Heading
                        Text(
                            text = "Row",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                          
                        // Lazy Row, pass the numbers array
                        LazyRowExample(numbers = numbers)
                          
                        // Heading
                        Text(
                            text = "Column",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                        // Lazy Column, Pass the numbers array
                        LazyColumnExample(numbers = numbers)
                    }
                      
                    Column(Modifier.fillMaxHeight()) {
                          
                        // Heading
                        Text(
                            text = "Grid",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                          
                        // Lazy Grid
                        GridExample(numbers = numbers)
                    }
                }
            }
        }
    }
}

完整代码:

科特林

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.gfg.lazycomponents.ui.theme.GreenGfg
import com.gfg.lazycomponents.ui.theme.LazyComponentsTheme
  
class MainActivity : ComponentActivity() {
  
    // Creates array as [0,1,2,3,4,5,.....99]
    private val numbers: Array = Array(100) { it + 1 }
  
    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LazyComponentsTheme {
  
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color.White)
                ) {
                    // Place the row and column
                    // to take 50% height of screen
                    Column(Modifier.fillMaxHeight(0.5f)) {
  
                        // Heading
                        Text(
                            text = "Row",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
  
                        // Lazy Row,pass the numbers array
                        LazyRowExample(numbers = numbers)
  
                        // Heading
                        Text(
                            text = "Column",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
                        // Lazy Column, Pass the numbers array
                        LazyColumnExample(numbers = numbers)
                    }
  
                    Column(Modifier.fillMaxHeight()) {
  
                        // Heading
                        Text(
                            text = "Grid",
                            color = Color.Black,
                            modifier = Modifier.padding(start = 8.dp)
                        )
  
                        // Lazy Grid
                        GridExample(numbers = numbers)
                    }
                }
            }
        }
    }
}
  
  
@Composable
fun LazyRowExample(numbers: Array) {
    // Place A lazy Row
    LazyRow(
        contentPadding = PaddingValues(8.dp),
          
        // Each Item in LazyRow have a 8.dp margin
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
  
        // item places one item on the LazyScope
        item {
            RowItem(number = 0)
        }
  
        // items(count) places number of items supplied
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            RowItem(number = currentCount)
        }
  
        // items(list/array) places number of items 
        // same as the size of list/array and gives 
        // current list/array item in the lazyItemScope
        items(numbers) {arrayItem-> // Here numbers is Array so we 
                                      // get Int in the scope.
            RowItem(number = arrayItem)
        }
  
        // items(list/array) places number of items 
        // same as the size of list/array and gives
        // current list/array item and currentIndex
        // in the lazyItemScope
        itemsIndexed(numbers) { index: Int, item: Int ->
            RowItem(number = index)
        }
    }
}
  
  
@Composable
fun RowItem(number: Int) {
    // Simple Row Composable
    Row(
        modifier = Modifier
            .size(100.dp) // Size 100 dp
            .background(Color.White) // Background White
            .border(1.dp, GreenGfg), // Border color green
  
        // Align Items in Center
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center
    ) {
        // Text Composable which displays some 
        // kind of message , text color is green
        Text(text = "This Is Item Number $number", color = GreenGfg)
    }
}
  
@Composable
fun ColumnItem(number: Int) {
  
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .height(30.dp)
            .background(Color.White)
            .border(1.dp, GreenGfg),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
  
    ) {
        Text(text = "This Is Item Number $number", color = GreenGfg)
    }
}
  
@Composable
fun LazyColumnExample(numbers: Array) {
    LazyColumn(
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        // item places one item on the LazyScope
        item {
            ColumnItem(number = 0)
        }
  
        // items(count) places number of items supplied 
        // as count and gives current count in the lazyItemScope
        items(10) {currentCount->
            ColumnItem(number = currentCount)
        }
  
        // items(list/array) places number of items
        // same as the size of list/array and gives 
        // current list/array item in the lazyItemScope
        items(numbers) {arrayItem->
            ColumnItem(number = arrayItem)
        }
  
        // items(list/array) places number of 
        // items same as the size of list/array 
        // and gives current list/array item and 
        // currentIndex in the lazyItemScope
        itemsIndexed(numbers) { index, item ->
            ColumnItem(number = index)
        }
    }
}
  
  
// add the annotation, 
// since [LazyVerticalGrid] is Experimental Api
@ExperimentalFoundationApi
@Composable
fun GridExample(numbers: Array) {
    // Lazy Vertical grid
    LazyVerticalGrid(
        
        // fix the item in one row to be 2.
        cells = GridCells.Fixed(2),
  
        contentPadding = PaddingValues(8.dp),
  
        ) {
        item {
            RowItem(number = 0)
        }
        items(10) {
            RowItem(number = it)
        }
        items(numbers) {
            RowItem(number = it)
        }
        itemsIndexed(numbers) { index, item ->
            RowItem(number = index)
        }
    }
}

现在在模拟器或手机上运行该应用程序。

输出:

从 GitHub 获取完整代码。

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!