Merge branch 'main' into patch-1

pull/2741/head
Eric Windmill 3 weeks ago committed by GitHub
commit 0c01e7dd10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,4 +1,7 @@
{
"context": {
"fileName": "/.prompts/llm.md"
},
"mcpServers": {
"dart": {
"command": "dart",
@ -6,6 +9,5 @@
"mcp-server"
]
}
},
"contextFileName": "/.prompts/llm.md"
}
}
}

@ -0,0 +1,11 @@
{
"mcpServers": {
"dart": {
"command": "dart",
"args": [
"mcp-server"
]
}
},
"contextFileName": "/.prompts/llm.md"
}

@ -17,7 +17,7 @@ Googler's, you can freely add samples to the [flutter/demos] repository.
### Quickstarts
* [`asset_transformation`] - Demonstrates how to transform images' color scales and formats.
* [`asset_transformation`] - Demonstrates how to transform images' color scales and formats.
* [`background_isolate_channels`] - Demonstrates how to use long-lived isolates.
* [`code_sharing`] - Demonstrates how to share business logic between Flutter client and Dart server using [`package:shelf`] )
* [`context_menus`] - This sample shows how to create and customize cross-platform context menus, such as the text selection toolbar on mobile or the right click menu on desktop.
@ -25,7 +25,6 @@ Googler's, you can freely add samples to the [flutter/demos] repository.
* [`dynamic_theme`] - A developer sample demonstrating how to call on-device Flutter APIs based on output from the Gemini API.
* [`form_app`] - A sample demonstrating different types of forms and best practices.
* [`game_template`] - (**note: deprecated!**) A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game.
* [`gemini_tasks`] - A developer sample written in Flutter demonstrating how to interact with a to-do list in natural language using the Gemini API.
* [`google_maps`] - Demonstrates the Google Maps for Flutter plugin.
* [`infinite_list`] - A Flutter sample app that shows an implementation of the "infinite list" UX pattern.
* [`isolate_example`] - A sample application that demonstrate best practices when using [isolates].
@ -78,10 +77,10 @@ Googler's, you can freely add samples to the [flutter/demos] repository.
## Flutter sample code
Samples are **correct and concise code** that developers
can **quickly understand** and **easily reuse** with minimal side effects.
Samples teach developers how to be successful using Flutter and Dart.
They are maintained on an ongoing basis
Samples are **correct and concise code** that developers
can **quickly understand** and **easily reuse** with minimal side effects.
Samples teach developers how to be successful using Flutter and Dart.
They are maintained on an ongoing basis
to reflect changing APIs and best practices.
### Types of samples
@ -90,18 +89,18 @@ There are two types of sample code in this repository:
* **Quickstarts** provide a starting point to extend. They answer the question,
"What is the minimal amount of code needed to implement this feature?"
* **Demo apps** are meant to be built and ran. They demo the _product_,
* **Demo apps** are meant to be built and ran. They demo the _product_,
not how to write code.
A majority of samples in this repository are quickstarts.
## Usage
Every sample in this repo is fully runnable. To run an example,
use `flutter run` inside that example's directory.
Every sample in this repo is fully runnable. To run an example,
use `flutter run` inside that example's directory.
See the [getting started guide] to install the `flutter` tool.
> [!IMPORTANT]
> [!IMPORTANT]
> If you want to run an add-to-app sample, there are additional requirements.
> We suggest reading the [add-to-app documentation].
@ -129,7 +128,6 @@ If you run into a bug in one of the samples, please file an issue in the
[`dynamic_theme`]: ./dynamic_theme
[`form_app`]: ./form_app
[`game_template`]: ./game_template
[`gemini_tasks`]: ./gemini_tasks
[`google_maps`]: ./google_maps
[`infinite_list`]: ./infinite_list
[`isolate_example`]: ./isolate_example

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Include Cleartext traffic for the espresso package -->
<application android:usesCleartextTraffic="true" />
<!-- The network security config is needed for Espresso testing since it
uses http cleartext traffic.
-->
<application android:networkSecurityConfig="@xml/network_security_config">
<meta-data android:name="io.flutter.network-policy"
android:resource="@xml/network_security_config"/>
</application>
</manifest>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!-- Cleartext is needed for Espresso testing. -->
<base-config cleartextTrafficPermitted="true">
</base-config>
</network-security-config>

@ -7,10 +7,9 @@ we don't maintain samples that are tied to events.
This sample has been copied to [another repository](https://github.com/ericwindmill/gemini_recipe_generation). It will not be updated to reflect changes to Gemini.
## Other Gemini resources
## Other Gemini resources
The following resources can assist you in integrating Gemini with Flutter:
* [gemini_tasks sample](https://github.com/flutter/samples/tree/main/gemini_tasks) is a Gemini sample in this repository.
* [google_generative_ai package](https://pub.dev/packages/google_generative_ai) is the package that Flutter apps use to integrate with gemini, and it has additional samples.
* The [google-gemini github](https://github.com/google-gemini) has additional Flutter samples.
* The [google-gemini github](https://github.com/google-gemini) has additional Flutter samples.

@ -49,6 +49,7 @@ class _AnimatedListDemoState extends State<AnimatedListDemo> {
parent: animation,
curve: const Interval(0.0, 1.0),
),
// ignore: deprecated_member_use
axisAlignment: 0.0,
child: _buildItem(user),
),

@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
@ -25,11 +27,11 @@ migrate_working_dir/
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/
# Symbolication related
app.*.symbols

@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "c0f2a1dd60414de7bef59318dc2554a6bb75d4ad"
channel: "beta"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
- platform: android
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
- platform: ios
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
- platform: linux
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
- platform: macos
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
- platform: web
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
- platform: windows
create_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
base_revision: c0f2a1dd60414de7bef59318dc2554a6bb75d4ad
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

@ -0,0 +1,16 @@
# cupertino_gallery
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

@ -5,9 +5,10 @@ gradle-wrapper.jar
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks

@ -0,0 +1,44 @@
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
android {
namespace = "com.example.cupertino_gallery"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.cupertino_gallery"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}
flutter {
source = "../.."
}

@ -1,12 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="gemini_tasks"
android:label="cupertino_gallery"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
@ -31,7 +32,7 @@
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility?hl=en and
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->

@ -0,0 +1,5 @@
package com.example.cupertino_gallery
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity()

@ -0,0 +1,24 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip

@ -0,0 +1,26 @@
pluginManagement {
val flutterSdkPath =
run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.9.1" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
}
include(":app")

@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
<string>13.0</string>
</dict>
</plist>

@ -0,0 +1 @@
#include "Generated.xcconfig"

@ -0,0 +1 @@
#include "Generated.xcconfig"

@ -346,7 +346,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -362,13 +362,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2UUT9AMTS2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiTasks;
PRODUCT_BUNDLE_IDENTIFIER = com.example.cupertinoGallery;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@ -384,7 +385,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiTasks.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.example.cupertinoGallery.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -401,7 +402,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiTasks.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.example.cupertinoGallery.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@ -416,7 +417,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiTasks.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.example.cupertinoGallery.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@ -472,7 +473,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -523,7 +524,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -541,13 +542,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2UUT9AMTS2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiTasks;
PRODUCT_BUNDLE_IDENTIFIER = com.example.cupertinoGallery;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -563,13 +565,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2UUT9AMTS2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiTasks;
PRODUCT_BUNDLE_IDENTIFIER = com.example.cupertinoGallery;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;

@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
@ -54,11 +55,13 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

@ -1,7 +1,7 @@
import UIKit
import Flutter
import UIKit
@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Gemini Tasks</string>
<string>Cupertino Gallery</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@ -13,7 +13,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>gemini_tasks</string>
<string>cupertino_gallery</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

@ -0,0 +1,52 @@
import 'package:flutter/cupertino.dart';
import 'settings_page.dart';
import 'widgets_page.dart';
class GalleryHome extends StatelessWidget {
const GalleryHome({
super.key,
required this.onThemeChange,
required this.isDarkMode,
required this.onTextSizeChange,
required this.textSize,
});
final ValueChanged<bool> onThemeChange;
final bool isDarkMode;
final ValueChanged<double> onTextSizeChange;
final double textSize;
@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.list_bullet),
label: 'Widgets',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.settings),
label: 'Settings',
),
],
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
builder: (BuildContext context) {
return switch (index) {
0 => const WidgetsPage(),
1 => SettingsPage(
onThemeChange: onThemeChange,
isDarkMode: isDarkMode,
onTextSizeChange: onTextSizeChange,
textSize: textSize,
),
_ => const Center(child: Text('Widgets')),
};
},
);
},
);
}
}

@ -0,0 +1,72 @@
// Copyright 2022 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'gallery_home.dart';
void main() {
runApp(const CupertinoGalleryApp());
}
class CupertinoGalleryApp extends StatefulWidget {
const CupertinoGalleryApp({super.key});
@override
State<CupertinoGalleryApp> createState() => _CupertinoGalleryAppState();
}
class _CupertinoGalleryAppState extends State<CupertinoGalleryApp> {
ThemeMode _themeMode = ThemeMode.system;
double _textSize = 1.0;
void _handleThemeChange(bool isDarkMode) {
setState(() {
_themeMode = isDarkMode ? ThemeMode.dark : ThemeMode.light;
});
}
void _handleTextSizeChange(double newTextSize) {
setState(() {
_textSize = newTextSize;
});
}
@override
Widget build(BuildContext context) {
final baseTheme = CupertinoThemeData(
brightness:
_themeMode == ThemeMode.dark ? Brightness.dark : Brightness.light,
);
final textTheme = baseTheme.textTheme.copyWith(
textStyle:
baseTheme.textTheme.textStyle.copyWith(fontSize: 14 * _textSize),
actionTextStyle: baseTheme.textTheme.actionTextStyle
.copyWith(fontSize: 14 * _textSize),
tabLabelTextStyle: baseTheme.textTheme.tabLabelTextStyle
.copyWith(fontSize: 10 * _textSize),
navTitleTextStyle: baseTheme.textTheme.navTitleTextStyle
.copyWith(fontSize: 17 * _textSize),
navLargeTitleTextStyle: baseTheme.textTheme.navLargeTitleTextStyle
.copyWith(fontSize: 34 * _textSize),
navActionTextStyle: baseTheme.textTheme.navActionTextStyle
.copyWith(fontSize: 17 * _textSize),
pickerTextStyle: baseTheme.textTheme.pickerTextStyle
.copyWith(fontSize: 21 * _textSize),
dateTimePickerTextStyle: baseTheme.textTheme.dateTimePickerTextStyle
.copyWith(fontSize: 21 * _textSize),
);
return CupertinoApp(
title: 'Cupertino Gallery',
theme: baseTheme.copyWith(textTheme: textTheme),
home: GalleryHome(
onThemeChange: _handleThemeChange,
isDarkMode: _themeMode == ThemeMode.dark,
onTextSizeChange: _handleTextSizeChange,
textSize: _textSize,
),
);
}
}

@ -0,0 +1,143 @@
import 'package:flutter/cupertino.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({
super.key,
required this.onThemeChange,
required this.isDarkMode,
required this.onTextSizeChange,
required this.textSize,
});
final ValueChanged<bool> onThemeChange;
final bool isDarkMode;
final ValueChanged<double> onTextSizeChange;
final double textSize;
@override
State<SettingsPage> createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
late bool isDarkMode;
late double _textSize;
@override
void initState() {
super.initState();
isDarkMode = widget.isDarkMode;
_textSize = widget.textSize;
}
@override
void didUpdateWidget(SettingsPage oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.isDarkMode != oldWidget.isDarkMode) {
isDarkMode = widget.isDarkMode;
}
if (widget.textSize != oldWidget.textSize) {
_textSize = widget.textSize;
}
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('Settings')),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CupertinoListSection(
header: const Text('Appearance'),
children: [
CupertinoListTile(
title: const Text('Dark Mode'),
trailing: CupertinoSwitch(
value: isDarkMode,
onChanged: (bool isActive) {
setState(() {
isDarkMode = isActive;
widget.onThemeChange(isActive);
});
},
),
),
CupertinoListTile(
title: const Text('Text Size'),
trailing: Text('${(_textSize * 100).toStringAsFixed(0)}%'),
),
CupertinoSlider(
value: _textSize,
min: 0.5,
max: 1.5,
onChanged: (double value) {
setState(() {
_textSize = value;
});
widget.onTextSizeChange(value);
},
),
],
),
CupertinoListSection(
header: const Text('General'),
children: [
CupertinoListTile(
title: const Text('About'),
trailing: const Icon(CupertinoIcons.forward),
onTap: () {},
),
CupertinoListTile(
title: const Text('Privacy'),
trailing: const Icon(CupertinoIcons.forward),
onTap: () {},
),
CupertinoListTile(
title: const Text('Help'),
trailing: const Icon(CupertinoIcons.forward),
onTap: () {},
),
CupertinoListTile(
title: const Text('Reset Settings'),
trailing: const Icon(CupertinoIcons.forward),
onTap: () {
showCupertinoDialog<void>(
context: context,
builder: (BuildContext context) => CupertinoAlertDialog(
title: const Text('Reset Settings'),
content: const Text(
'Are you sure you want to reset all settings?',
),
actions: <CupertinoDialogAction>[
CupertinoDialogAction(
child: const Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoDialogAction(
isDestructiveAction: true,
child: const Text('Reset'),
onPressed: () {
setState(() {
isDarkMode = false;
_textSize = 1.0;
widget.onThemeChange(false);
widget.onTextSizeChange(1.0);
});
Navigator.pop(context);
},
),
],
),
);
},
),
],
),
],
),
);
}
}

@ -0,0 +1,84 @@
import 'package:flutter/cupertino.dart';
import 'widgets/action_sheet_page.dart';
import 'widgets/activity_indicator_page.dart';
import 'widgets/alert_dialog_page.dart';
import 'widgets/button_page.dart';
import 'widgets/checkbox_page.dart';
import 'widgets/context_menu_page.dart';
import 'widgets/date_picker_page.dart';
import 'widgets/list_tile_page.dart';
import 'widgets/picker_page.dart';
import 'widgets/popup_surface_page.dart';
import 'widgets/radio_page.dart';
import 'widgets/scrollbar_page.dart';
import 'widgets/search_text_field_page.dart';
import 'widgets/segmented_control_page.dart';
import 'widgets/sheet_page.dart';
import 'widgets/slider_page.dart';
import 'widgets/sliding_segmented_control_page.dart';
import 'widgets/switch_page.dart';
import 'widgets/text_field_page.dart';
import 'widgets/text_theme_page.dart';
import 'widgets/time_picker_page.dart';
class WidgetDetailPage extends StatelessWidget {
const WidgetDetailPage({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
switch (title) {
case 'Action Sheet':
return const ActionSheetPage();
case 'Activity Indicator':
return const ActivityIndicatorPage();
case 'Alert Dialog':
return const AlertDialogPage();
case 'Button':
return const ButtonPage();
case 'Checkbox':
return const CheckboxPage();
case 'Context Menu':
return const ContextMenuPage();
case 'Date Picker':
return const DatePickerPage();
case 'List Tile':
return const ListTilePage();
case 'Picker':
return const PickerPage();
case 'Popup Surface':
return const PopupSurfacePage();
case 'Radio':
return const RadioPage();
case 'Scrollbar':
return const ScrollbarPage();
case 'Search Text Field':
return const SearchTextFieldPage();
case 'Segmented Control':
return const SegmentedControlPage();
case 'Sheet':
return const SheetPage();
case 'Slider':
return const SliderPage();
case 'Sliding Segmented Control':
return const SlidingSegmentedControlPage();
case 'Switch':
return const SwitchPage();
case 'Text Field':
return const TextFieldPage();
case 'Text Theme':
return const TextThemePage();
case 'Time Picker':
return const TimePickerPage();
default:
return const CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Widget Not Found'),
),
child: Center(child: Text('Widget Not Found')),
);
}
}
}

@ -0,0 +1,49 @@
import 'package:flutter/cupertino.dart';
class ActionSheetPage extends StatelessWidget {
const ActionSheetPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Action Sheet'),
),
child: Center(
child: CupertinoButton(
child: const Text('Show Action Sheet'),
onPressed: () {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => CupertinoActionSheet(
title: const Text('Title'),
message: const Text('Message'),
actions: <CupertinoActionSheetAction>[
CupertinoActionSheetAction(
child: const Text('Action One'),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoActionSheetAction(
child: const Text('Action Two'),
onPressed: () {
Navigator.pop(context);
},
)
],
cancelButton: CupertinoActionSheetAction(
isDefaultAction: true,
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancel'),
),
),
);
},
),
),
);
}
}

@ -0,0 +1,17 @@
import 'package:flutter/cupertino.dart';
class ActivityIndicatorPage extends StatelessWidget {
const ActivityIndicatorPage({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Activity Indicator'),
),
child: Center(
child: CupertinoActivityIndicator(),
),
);
}
}

@ -0,0 +1,41 @@
import 'package:flutter/cupertino.dart';
class AlertDialogPage extends StatelessWidget {
const AlertDialogPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('Alert Dialog')),
child: Center(
child: CupertinoButton(
child: const Text('Show Alert Dialog'),
onPressed: () {
showCupertinoDialog<void>(
context: context,
builder: (BuildContext context) => CupertinoAlertDialog(
title: const Text('Alert'),
content: const Text('This is a sample alert dialog.'),
actions: <CupertinoDialogAction>[
CupertinoDialogAction(
child: const Text('OK'),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoDialogAction(
isDefaultAction: true,
child: const Text('NO'),
onPressed: () {
Navigator.pop(context);
},
),
],
),
);
},
),
),
);
}
}

@ -0,0 +1,42 @@
import 'package:flutter/cupertino.dart';
class ButtonPage extends StatelessWidget {
const ButtonPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('Button')),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'CupertinoButton widget',
style: CupertinoTheme.of(context).textTheme.textStyle,
),
const SizedBox(height: 16),
CupertinoButton(child: const Text('Enabled'), onPressed: () {}),
const SizedBox(height: 16),
const CupertinoButton(onPressed: null, child: Text('Disabled')),
const SizedBox(height: 32),
Text(
'CupertinoButton.filled widget',
style: CupertinoTheme.of(context).textTheme.textStyle,
),
const SizedBox(height: 16),
CupertinoButton.filled(
child: const Text('Enabled'),
onPressed: () {},
),
const SizedBox(height: 16),
const CupertinoButton.filled(
onPressed: null,
child: Text('Disabled'),
),
],
),
),
);
}
}

@ -0,0 +1,31 @@
import 'package:flutter/cupertino.dart';
class CheckboxPage extends StatefulWidget {
const CheckboxPage({super.key});
@override
State<CheckboxPage> createState() => _CheckboxPageState();
}
class _CheckboxPageState extends State<CheckboxPage> {
bool _value = false;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Checkbox'),
),
child: Center(
child: CupertinoCheckbox(
value: _value,
onChanged: (bool? value) {
setState(() {
_value = value!;
});
},
),
),
);
}
}

@ -0,0 +1,42 @@
import 'package:flutter/cupertino.dart';
class ContextMenuPage extends StatelessWidget {
const ContextMenuPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('Context Menu')),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Long press to activate context menu:'),
SizedBox(height: 16),
SizedBox(
width: 100,
height: 100,
child: CupertinoContextMenu(
actions: <Widget>[
CupertinoContextMenuAction(
child: const Text('Action one'),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoContextMenuAction(
child: const Text('Action two'),
onPressed: () {
Navigator.pop(context);
},
),
],
child: Container(color: CupertinoColors.activeBlue),
),
),
],
),
),
);
}
}

@ -0,0 +1,22 @@
import 'package:flutter/cupertino.dart';
class DatePickerPage extends StatelessWidget {
const DatePickerPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Date Picker'),
),
child: Center(
child: SizedBox(
height: 200,
child: CupertinoDatePicker(
onDateTimeChanged: (DateTime newDate) {},
),
),
),
);
}
}

@ -0,0 +1,62 @@
import 'package:flutter/cupertino.dart';
class ListTilePage extends StatelessWidget {
const ListTilePage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('List Tile')),
child: Center(
child: ListView(
children: [
CupertinoListSection.insetGrouped(
children: [
CupertinoListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
leading: Icon(CupertinoIcons.info),
trailing: Icon(CupertinoIcons.forward),
),
CupertinoListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
leading: Icon(CupertinoIcons.person),
trailing: Icon(CupertinoIcons.forward),
),
CupertinoListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
leading: Icon(CupertinoIcons.wifi),
trailing: Icon(CupertinoIcons.forward),
),
],
),
CupertinoListSection(
children: [
CupertinoListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
leading: Icon(CupertinoIcons.search),
trailing: Icon(CupertinoIcons.forward),
),
CupertinoListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
leading: Icon(CupertinoIcons.heart_fill),
trailing: Icon(CupertinoIcons.forward),
),
CupertinoListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
leading: Icon(CupertinoIcons.ant),
trailing: Icon(CupertinoIcons.forward),
),
],
),
],
),
),
);
}
}

@ -0,0 +1,28 @@
import 'package:flutter/cupertino.dart';
class PickerPage extends StatelessWidget {
const PickerPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Picker'),
),
child: Center(
child: SizedBox(
height: 200,
child: CupertinoPicker(
itemExtent: 32,
onSelectedItemChanged: (int index) {},
children: const <Widget>[
Text('One'),
Text('Two'),
Text('Three'),
],
),
),
),
);
}
}

@ -0,0 +1,36 @@
import 'package:flutter/cupertino.dart';
class PopupSurfacePage extends StatelessWidget {
const PopupSurfacePage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Popup Surface'),
),
child: Center(
child: CupertinoButton(
child: const Text('Show Popup Surface'),
onPressed: () {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) {
return CupertinoPopupSurface(
child: Container(
color: CupertinoColors.white,
width: 200,
height: 200,
child: const Center(
child: Text('This is a popup surface.'),
),
),
);
},
);
},
),
),
);
}
}

@ -0,0 +1,46 @@
import 'package:flutter/cupertino.dart';
class RadioPage extends StatefulWidget {
const RadioPage({super.key});
@override
State<RadioPage> createState() => _RadioPageState();
}
class _RadioPageState extends State<RadioPage> {
int _selectedValue = 0;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('Radio')),
child: Center(
child: RadioGroup(
groupValue: _selectedValue,
onChanged: (int? value) {
setState(() {
_selectedValue = value!;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoListTile(
title: const Text('Option 1'),
leading: CupertinoRadio<int>(value: 0),
),
CupertinoListTile(
title: const Text('Option 2'),
leading: CupertinoRadio<int>(value: 1),
),
CupertinoListTile(
title: const Text('Option 3'),
leading: CupertinoRadio<int>(value: 2),
),
],
),
),
),
);
}
}

@ -0,0 +1,26 @@
import 'package:flutter/cupertino.dart';
class ScrollbarPage extends StatelessWidget {
const ScrollbarPage({super.key});
@override
Widget build(BuildContext context) {
final ScrollController controller = ScrollController();
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(middle: Text('Scrollbar')),
child: CupertinoScrollbar(
controller: controller,
child: ListView.separated(
controller: controller,
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return CupertinoListTile(title: Text('Item $index'));
},
separatorBuilder: (BuildContext context, int index) {
return Container(height: 1, color: CupertinoColors.opaqueSeparator);
},
),
),
);
}
}

@ -0,0 +1,20 @@
import 'package:flutter/cupertino.dart';
class SearchTextFieldPage extends StatelessWidget {
const SearchTextFieldPage({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Search Text Field'),
),
child: Center(
child: Padding(
padding: EdgeInsets.all(16.0),
child: CupertinoSearchTextField(),
),
),
);
}
}

@ -0,0 +1,36 @@
import 'package:flutter/cupertino.dart';
class SegmentedControlPage extends StatefulWidget {
const SegmentedControlPage({super.key});
@override
State<SegmentedControlPage> createState() => _SegmentedControlPageState();
}
class _SegmentedControlPageState extends State<SegmentedControlPage> {
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Segmented Control'),
),
child: Center(
child: CupertinoSegmentedControl<int>(
children: <int, Widget>{
0: Text('One'),
1: Text('Two'),
2: Text('Three'),
},
onValueChanged: (int val) {
setState(() {
_selectedIndex = val;
});
},
groupValue: _selectedIndex,
),
),
);
}
}

@ -0,0 +1,39 @@
import 'package:flutter/cupertino.dart';
class SheetPage extends StatelessWidget {
const SheetPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(middle: Text('Sheet')),
child: Center(
child: CupertinoButton.filled(
child: const Text('Show Sheet'),
onPressed: () {
Navigator.of(context).push(
CupertinoSheetRoute<void>(
builder: (BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: const Text('Sheet'),
trailing: GestureDetector(
child: const Icon(CupertinoIcons.xmark),
onTap: () {
Navigator.of(context).pop();
},
),
),
child: const Center(
child: Text('This is a sheet'),
),
);
},
),
);
},
),
),
);
}
}

@ -0,0 +1,31 @@
import 'package:flutter/cupertino.dart';
class SliderPage extends StatefulWidget {
const SliderPage({super.key});
@override
State<SliderPage> createState() => _SliderPageState();
}
class _SliderPageState extends State<SliderPage> {
double _value = 0.5;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Slider'),
),
child: Center(
child: CupertinoSlider(
value: _value,
onChanged: (double value) {
setState(() {
_value = value;
});
},
),
),
);
}
}

@ -0,0 +1,38 @@
import 'package:flutter/cupertino.dart';
class SlidingSegmentedControlPage extends StatefulWidget {
const SlidingSegmentedControlPage({super.key});
@override
State<SlidingSegmentedControlPage> createState() =>
_SlidingSegmentedControlPageState();
}
class _SlidingSegmentedControlPageState
extends State<SlidingSegmentedControlPage> {
int? _groupValue = 0;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Sliding Segmented Control'),
),
child: Center(
child: CupertinoSlidingSegmentedControl<int>(
children: const <int, Widget>{
0: Text('One'),
1: Text('Two'),
2: Text('Three'),
},
onValueChanged: (int? value) {
setState(() {
_groupValue = value;
});
},
groupValue: _groupValue,
),
),
);
}
}

@ -0,0 +1,31 @@
import 'package:flutter/cupertino.dart';
class SwitchPage extends StatefulWidget {
const SwitchPage({super.key});
@override
State<SwitchPage> createState() => _SwitchPageState();
}
class _SwitchPageState extends State<SwitchPage> {
bool _value = true;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Switch'),
),
child: Center(
child: CupertinoSwitch(
value: _value,
onChanged: (bool value) {
setState(() {
_value = value;
});
},
),
),
);
}
}

@ -0,0 +1,22 @@
import 'package:flutter/cupertino.dart';
class TextFieldPage extends StatelessWidget {
const TextFieldPage({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Text Field'),
),
child: Center(
child: Padding(
padding: EdgeInsets.all(16.0),
child: CupertinoTextField(
placeholder: 'Enter text',
),
),
),
);
}
}

@ -0,0 +1,58 @@
import 'package:flutter/cupertino.dart';
class TextThemePage extends StatelessWidget {
const TextThemePage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Text Theme'),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'This is the default text style',
style: CupertinoTheme.of(context).textTheme.textStyle,
),
const SizedBox(height: 16),
Text(
'This is the action text style',
style: CupertinoTheme.of(context).textTheme.actionTextStyle,
),
const SizedBox(height: 16),
Text(
'This is the tab label text style',
style: CupertinoTheme.of(context).textTheme.tabLabelTextStyle,
),
const SizedBox(height: 16),
Text(
'This is the nav title text style',
style: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
),
const SizedBox(height: 16),
Text(
'This is the nav large title text style',
style: CupertinoTheme.of(context)
.textTheme
.navLargeTitleTextStyle,
),
const SizedBox(height: 16),
Text(
'This is the picker text style',
style: CupertinoTheme.of(context).textTheme.pickerTextStyle,
),
const SizedBox(height: 16),
Text(
'This is the date time picker text style',
style:
CupertinoTheme.of(context).textTheme.dateTimePickerTextStyle,
),
],
),
),
);
}
}

@ -0,0 +1,22 @@
import 'package:flutter/cupertino.dart';
class TimePickerPage extends StatelessWidget {
const TimePickerPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Time Picker'),
),
child: Center(
child: SizedBox(
height: 200,
child: CupertinoTimerPicker(
onTimerDurationChanged: (Duration newDuration) {},
),
),
),
);
}
}

@ -0,0 +1,75 @@
import 'package:flutter/cupertino.dart';
import 'widget_detail_page.dart';
class WidgetsPage extends StatelessWidget {
const WidgetsPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: CustomScrollView(
slivers: <Widget>[
CupertinoSliverNavigationBar(largeTitle: Text('Cupertino Gallery')),
SliverFillRemaining(
child: ListView(
children: [
CustomCupertinoListTile(title: 'Action Sheet'),
CustomCupertinoListTile(title: 'Activity Indicator'),
CustomCupertinoListTile(title: 'Alert Dialog'),
CustomCupertinoListTile(title: 'Button'),
CustomCupertinoListTile(title: 'Checkbox'),
CustomCupertinoListTile(title: 'Context Menu'),
CustomCupertinoListTile(title: 'Date Picker'),
CustomCupertinoListTile(title: 'List Tile'),
CustomCupertinoListTile(title: 'Picker'),
CustomCupertinoListTile(title: 'Popup Surface'),
CustomCupertinoListTile(title: 'Radio'),
CustomCupertinoListTile(title: 'Scrollbar'),
CustomCupertinoListTile(title: 'Search Text Field'),
CustomCupertinoListTile(title: 'Segmented Control'),
CustomCupertinoListTile(title: 'Sheet'),
CustomCupertinoListTile(title: 'Slider'),
CustomCupertinoListTile(title: 'Sliding Segmented Control'),
CustomCupertinoListTile(title: 'Switch'),
CustomCupertinoListTile(title: 'Text Field'),
CustomCupertinoListTile(title: 'Text Theme'),
CustomCupertinoListTile(title: 'Time Picker'),
],
),
),
],
),
);
}
}
class CustomCupertinoListTile extends StatelessWidget {
const CustomCupertinoListTile({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
CupertinoPageRoute<void>(
builder: (BuildContext context) {
return WidgetDetailPage(title: title);
},
),
);
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: CupertinoColors.separator)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[Text(title), const Icon(CupertinoIcons.forward)],
),
),
);
}
}

@ -1,13 +1,13 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.13)
project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "gemini_tasks")
set(BINARY_NAME "cupertino_gallery")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.example.gemini_tasks")
set(APPLICATION_ID "com.example.cupertino_gallery")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
@ -54,25 +54,8 @@ add_subdirectory(${FLUTTER_MANAGED_DIR})
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
# Application build; see runner/CMakeLists.txt.
add_subdirectory("runner")
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)

@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save