kotlin
@Composable
fun MyComponent(
displayString: String
) {
Text(displayString)
}
@Composable
fun MyComponent(
displayString: String
) {
Text(displayString)
}
class MyComponent extends StatelessWidget {
final String displayString;
MyComponent({required this.displayString});
Widget build(BuildContext context) {
return Text(displayString);
}
}
struct MyComponent: View {
var displayString: String
var body: some View {
Text(displayString)
}
}
@Composable
fun ConditionalComponent(condition: Boolean) {
if (condition) {
Text("Condition is true")
} else {
Text("Condition is false")
}
}
// Usage
ConditionalComponent(condition = true)
class ConditionalComponent extends StatelessWidget {
final bool condition;
ConditionalComponent({required this.condition});
Widget build(BuildContext context) {
if(condition) {
return Text("Condition is true");
} else {
return Text("Condition is false");
}
}
}
// Usage
ConditionalComponent(condition: true)
struct ConditionalComponent: View {
let condition: Bool
var body: some View {
Group {
if condition {
Text("Condition is true")
} else {
Text("Condition is false")
}
}
}
}
// Usage
ConditionalComponent(condition: true)
@Composable
fun Parent(data: String) {
IntermediateComponent(data = data)
}
@Composable
fun IntermediateComponent(data: String) {
ChildComponent(data = data)
}
@Composable
fun ChildComponent(data: String) {
Text("Received data: $data")
}
// Usage
Parent(data = "Some data")
class Parent extends StatelessWidget {
final String data;
Parent({required this.data});
Widget build(BuildContext context) {
return IntermediateComponent(data: data);
}
}
class IntermediateComponent extends StatelessWidget {
final String data;
IntermediateComponent({required this.data});
Widget build(BuildContext context) {
return ChildComponent(data: data);
}
}
class ChildComponent extends StatelessWidget {
final String data;
ChildComponent({required this.data});
Widget build(BuildContext context) {
return Text("Received data: $data");
}
}
// Usage
Parent(data: "Some data")
struct Parent: View {
let data: String
var body: some View {
IntermediateComponent(data: data)
}
}
struct IntermediateComponent: View {
let data: String
var body: some View {
ChildComponent(data: data)
}
}
struct ChildComponent: View {
let data: String
var body: some View {
Text("Received data: \(data)")
}
}
// Usage
Parent(data: "Some data")
@Composable
fun ClickableComponent() {
var clicked by remember { mutableStateOf(false) }
Button(onClick = { clicked = true }) {
Text(if (clicked) "Button clicked" else "Click me")
}
}
class ClickableComponent extends StatefulWidget {
_ClickableComponentState createState() => _ClickableComponentState();
}
class _ClickableComponentState extends State<ClickableComponent> {
bool clicked = false;
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () => setState(() => clicked = true),
child: Text(clicked ? "Button clicked" : "Click me"),
);
}
}
struct ClickableComponent: View {
@State private var clicked = false
var body: some View {
Button(action: {
clicked = true
}) {
Text(clicked ? "Button clicked" : "Click me")
}
}
}
@Composable
fun TextInputComponent() {
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = { newText -> text = newText },
label = { Text("Enter text") }
)
}
class TextInputComponent extends StatefulWidget {
const TextInputComponent({super.key});
State<TextInputComponent> createState() => _TextInputComponentState();
}
class _TextInputComponentState extends State<TextInputComponent> {
late final _controller = TextEditingController(text: "");
void dispose() {
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return TextField(
controller: _controller,
decoration: const InputDecoration(labelText: "Enter text"),
);
}
}
struct TextInputComponent: View {
@State private var text = ""
var body: some View {
TextField("Enter text", text: $text)
}
}
@Composable
fun ExampleComponent() {
Text("Hello, World!")
}
@Preview(showBackground = true)
@Composable
fun ExampleComponentPreview() {
ExampleComponent()
}
Additionally, you can also use Showkase, an open source library by Airbnb that allows you to view themes preview functions in an auto-generated component browser that can be viewed on an Android device.
Flutter doesn't have a built-in preview feature. You can, however, create a separate app or run your app in an emulator or on a device to view your components. Additionally, you can use the Flutter Studio web-based tool to create and preview Flutter widgets in a browser.
struct ExampleComponent: View {
var body: some View {
Text("Hello, World!")
}
}
struct ExampleComponent_Previews: PreviewProvider {
static var previews: some View {
ExampleComponent()
}
}
@Composable
fun ListComponent(items: List<String>) {
LazyColumn {
items(items) { item ->
Text(item)
}
}
}
// Usage
val items = listOf("Item 1", "Item 2", "Item 3")
ListComponent(items = items)
class ListComponent extends StatelessWidget {
final List<String> items;
ListComponent({required this.items});
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
);
}
}
// Usage
final items = ["Item 1", "Item 2", "Item 3"];
ListComponent(items: items)
struct ListComponent: View {
let items: [String]
var body: some View {
List(items, id: \.self) { item in
Text(item)
}
}
}
// Usage
let items = ["Item 1", "Item 2", "Item 3"]
ListComponent(items: items)
data class Person(val name: String, val age: Int, val id: String)
@Composable
fun ItemKeysExample(items: List<Person>) {
LazyColumn {
items(items, key = { person -> person.id }) { person ->
Text("Name: ${person.name}, Age: ${person.age}")
}
}
}
class Person {
final String name;
final int age;
final String id;
Person({required this.name, required this.age, required this.id});
}
class ItemKeysExample extends StatelessWidget {
final List<Person> items;
ItemKeysExample({required this.items});
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final person = items[index];
return ListTile(
key: Key(person.id),
title: Text('Name: ${person.name}, Age: ${person.age}'),
);
},
);
}
}
// Usage
ItemKeysExample(items: [Person(name: 'John', age: 30, id: '1'), Person(name: 'Jane', age: 28, id: '2'), Person(name: 'Bob', age: 25, id: '3')])
struct Person: Identifiable {
let name: String
let age: Int
let id: String
}
struct ItemKeysExample: View {
let items: [Person]
var body: some View {
List(items) { person in
Text("Name: \(person.name), Age: \(person.age)")
}
}
}
// Usage
ItemKeysExample(items: [Person(name: "John", age: 30, id: "1"), Person(name: "Jane", age: 28, id: "2"), Person(name: "Bob", age: 25, id: "3")])
@Composable
fun Parent(
header: @Composable () -> Unit,
content: @Composable () -> Unit
) {
Column {
header()
content()
}
}
// Usage
Parent(
header = { Text("Header") },
content = { Child() }
)
@Composable
fun Child() {
Text("Child Content")
}
class Parent extends StatelessWidget {
final Widget header;
final Widget content;
Parent({required this.header, required this.content});
Widget build(BuildContext context) {
return Column(
children: [
header,
content,
],
);
}
}
// Usage
Parent(
header: Text("Header"),
content: Child(),
)
class Child extends StatelessWidget {
Widget build(BuildContext context) {
return Text("Child Content");
}
}
struct Parent<Header: View, Content: View>: View {
let header: Header
let content: Content
var body: some View {
VStack {
header
content
}
}
}
// Usage
Parent(
header: Text("Header"),
content: Child()
)
struct Child: View {
var body: some View {
Text("Child Content")
}
}
@Composable
fun ModifiersExample() {
Text(
"Hello, World!",
modifier = Modifier
.padding(16.dp)
.background(Color.Blue)
)
}
In Flutter, you can wrap widgets with other widgets to achieve similar effects.
class ModifiersExample extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16.0),
color: Colors.blue,
child: Text('Hello, World!', style: TextStyle(color: Colors.white)),
);
}
}
struct ModifiersExample: View {
var body: some View {
Text("Hello, World!")
.padding(EdgeInsets(top: 16, leading: 16, bottom: 16, trailing: 16))
.background(Color.blue)
}
}
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Button(onClick = { count = count + 1 }) {
Text("Count: $count")
}
}
class Counter extends StatefulWidget {
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () => setState(() => count += 1),
child: Text("Count: $count"),
);
}
}
struct Counter: View {
@State private var count = 0
var body: some View {
Button(action: {
count += 1
}) {
Text("Count: \(count)")
}
}
}
val CustomLocal = compositionLocalOf<String> { "Default data" }
@Composable
fun Parent(data: String) {
CompositionLocalProvider(CustomLocal provides data) {
Intermediate()
}
}
@Composable
fun Intermediate() {
Child()
}
@Composable
fun Child() {
val data = CustomLocal.current
Text("Received data: $data")
}
// Usage
Parent(data = "Some data")
class CustomInheritedWidget extends InheritedWidget {
final String data;
CustomInheritedWidget({required this.data, required Widget child})
: super(child: child);
bool updateShouldNotify(CustomInheritedWidget oldWidget) {
return oldWidget.data != data;
}
static CustomInheritedWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<CustomInheritedWidget>()!;
}
}
class Parent extends StatelessWidget {
final String data;
Parent({required this.data});
Widget build(BuildContext context) {
return CustomInheritedWidget(
data: data,
child: Intermediate(),
);
}
}
class Intermediate extends StatelessWidget {
Widget build(BuildContext context) {
return Child();
}
}
class Child extends StatelessWidget {
Widget build(BuildContext context) {
final data = CustomInheritedWidget.of(context).data;
return Text("Received data: $data");
}
}
// Usage
Parent(data: "Some data")
struct CustomEnvironmentKey: EnvironmentKey {
static let defaultValue: String = ""
}
extension EnvironmentValues {
var customData: String {
get { self[CustomEnvironmentKey.self] }
set { self[CustomEnvironmentKey.self] = newValue }
}
}
struct Parent: View {
let data: String
var body: some View {
Intermediate().environment(\.customData, data)
}
}
struct Intermediate: View {
var body: some View {
Child()
}
}
struct Child: View {
@Environment(\.customData) private var data
var body: some View {
Text("Received data: \(data)")
}
}
// Usage
Parent(data: "Some data")
@Composable
fun SideEffectOnLoadComponent() {
LaunchedEffect(Unit) {
// Perform side effect, e.g. fetch data, update external data source
}
// Other UI components
Text("Hello, World!")
}
class SideEffectOnLoadComponent extends StatefulWidget {
_SideEffectOnLoadComponentState createState() => _SideEffectOnLoadComponentState();
}
class _SideEffectOnLoadComponentState extends State<SideEffectOnLoadComponent> {
void initState() {
super.initState();
// Perform side effect, e.g. fetch data, update external data source
}
Widget build(BuildContext context) {
// Other UI components
return Container();
}
}
struct SideEffectOnLoadComponent: View {
@State private var hasPerformedSideEffect = false
var body: some View {
if !hasPerformedSideEffect {
DispatchQueue.main.async {
// Perform side effect, e.g. fetch data, update external data source
hasPerformedSideEffect = true
}
}
// Other UI components
Text("Hello, World!")
}
}