Android разработка, переход с View на Compose
Переделка проекта на Jetpack Compose может значительно упростить работу с пользовательским интерфейсом, но требует изменения подхода к архитектуре, так как Compose работает декларативно. Если у вас есть Fragment и Adapter (например, для RecyclerView
), их можно адаптировать под Compose. Вот пошаговая инструкция:
1. Замена Fragment
на Composable
Fragment обычно используется для управления частью пользовательского интерфейса. В Compose вместо фрагментов используются функции-компоненты @Composable
.
Пример:
Ваш существующий фрагмент:
class ExampleFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_example, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Инициализация элементов
}
}
Переделка:
-
Создайте
@Composable
-функцию для экрана:
@Composable
fun ExampleScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Text(
text = "Hello from Compose!",
style = MaterialTheme.typography.h5
)
Button(onClick = { /* Handle click */ }) {
Text(text = "Click Me")
}
}
}
-
В
Activity
замените вызовFragmentTransaction
на вызовsetContent
:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ExampleScreen()
}
}
}
Теперь ExampleScreen
заменяет ваш Fragment
.
2. Замена RecyclerView.Adapter
на LazyColumn
Compose предоставляет компонент LazyColumn
для создания списков. Он заменяет RecyclerView
.
Существующий адаптер:
class ExampleAdapter(private val items: List<String>) : RecyclerView.Adapter<ExampleAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.textView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_example, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.text = items[position]
}
override fun getItemCount(): Int = items.size
}
Переделка в LazyColumn
:
-
Удалите адаптер.
-
Создайте
@Composable
-функцию для отображения списка:
@Composable
fun ExampleList(items: List<String>) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items) { item ->
ExampleListItem(item = item)
}
}
}
@Composable
fun ExampleListItem(item: String) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
elevation = 4.dp
) {
Text(
text = item,
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.body1
)
}
}
-
Вызовите
ExampleList
из вашего экрана:
@Composable
fun ExampleScreen(items: List<String>) {
Column(modifier = Modifier.fillMaxSize()) {
Text(
text = "Items List",
style = MaterialTheme.typography.h4,
modifier = Modifier.padding(16.dp)
)
ExampleList(items = items)
}
}
3. Передача данных в Compose
Compose использует ViewModel для работы с данными. Если в Fragment
использовался ViewModel
, он интегрируется с Compose через viewModel()
.
Пример:
-
ViewModel для списка:
class ExampleViewModel : ViewModel() {
private val _items = MutableLiveData<List<String>>(listOf("Item 1", "Item 2", "Item 3"))
val items: LiveData<List<String>> = _items
}
-
Подключение ViewModel в Compose:
@Composable
fun ExampleScreen(viewModel: ExampleViewModel = viewModel()) {
val items by viewModel.items.observeAsState(emptyList())
ExampleList(items = items)
}
4. Управление состоянием через Compose
Compose поддерживает управление состоянием через State. Например:
@Composable
fun ExampleScreen() {
var searchText by remember { mutableStateOf("") }
val items = listOf("Apple", "Banana", "Cherry")
val filteredItems = items.filter { it.contains(searchText, ignoreCase = true) }
Column {
TextField(
value = searchText,
onValueChange = { searchText = it },
modifier = Modifier.fillMaxWidth(),
placeholder = { Text("Search") }
)
ExampleList(items = filteredItems)
}
}
5. Интеграция Jetpack Compose с существующим проектом
Если вы не хотите полностью удалять XML и Fragment
, можно использовать ComposeView
в существующем макете.
Пример использования ComposeView
в XML:
<androidx.compose.ui.platform.ComposeView
android:id="@+id/composeView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
В Fragment
или Activity
добавьте содержимое для ComposeView
:
class ExampleFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val composeView = view.findViewById<ComposeView>(R.id.composeView)
composeView.setContent {
ExampleScreen()
}
}
Итоговый порядок действий для переделки:
-
Удалите XML-разметки и замените их
@Composable
функциями. -
Удалите
Fragment
и используйте Composable вместо них. -
Замените
RecyclerView
наLazyColumn
илиLazyRow
. -
Настройте управление состоянием через
State
или ViewModel. -
Интегрируйте Compose через
setContent
вActivity
или используйтеComposeView
в существующих макетах. -
Добавьте анимации и стили для улучшения UX (опционально).
© LazarovStudio 2017 - 20252022>
Есть что-то, что не любит ограждений ©