Expert knowledge in mobile app development for iOS, Android, and cross-platform solutions
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';
const LoginForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const navigation = useNavigation();
const handleLogin = async () => {
setLoading(true);
try {
// API call for authentication
await loginAPI(email, password);
navigation.navigate('Home');
} catch (error) {
console.error('Login failed:', error);
} finally {
setLoading(false);
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>Login</Text>
<TextInput
style={styles.input}
placeholder="Email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button
title={loading ? "Logging in..." : "Login"}
onPress={handleLogin}
disabled={loading}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 20,
},
input: {
height: 40,
borderColor: 'gray',
borderWidth: 1,
marginBottom: 10,
paddingHorizontal: 10,
},
});
import SwiftUI
struct LoginView: View {
@State private var email = ""
@State private var password = ""
@State private var showingAlert = false
@State private var alertMessage = ""
var body: some View {
VStack(spacing: 20) {
Text("Login")
.font(.largeTitle)
.fontWeight(.bold)
TextField("Email", text: $email)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.emailAddress)
.autocapitalization(.none)
SecureField("Password", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: login) {
Text("Login")
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.disabled(email.isEmpty || password.isEmpty)
}
.padding()
.alert(isPresented: $showingAlert) {
Alert(title: Text("Error"), message: Text(alertMessage))
}
}
private func login() {
// Authentication logic
guard !email.isEmpty, !password.isEmpty else {
alertMessage = "Please fill in all fields"
showingAlert = true
return
}
// API call for authentication
AuthAPI.login(email: email, password: password) { result in
switch result {
case .success:
// Navigate to home screen
break
case .failure(let error):
alertMessage = error.localizedDescription
showingAlert = true
}
}
}
}
import 'package:flutter/material.dart';
class LoginForm extends StatefulWidget {
@override
_LoginFormState createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
bool _isLoading = false;
Future<void> _login() async {
if (_formKey.currentState!.validate()) {
setState(() => _isLoading = true);
try {
await AuthAPI.login(
email: _emailController.text,
password: _passwordController.text,
);
Navigator.pushReplacementNamed(context, '/home');
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Login failed: ${e.toString()}')),
);
} finally {
setState(() => _isLoading = false);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: _emailController,
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
controller: _passwordController,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
return null;
},
),
SizedBox(height: 24),
_isLoading
? CircularProgressIndicator()
: ElevatedButton(
onPressed: _login,
child: Text('Login'),
style: ElevatedButton.styleFrom(
minimumSize: Size(double.infinity, 48),
),
),
],
),
),
),
);
}
}
When developing mobile applications, always consider:
npx skills add tao12345666333/mobile-developer下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer