Flutter开发Instagram克隆:点击底部导航Profile项触发API请求方法咨询
Flutter + Spring Boot 实现点击Profile导航栏触发API请求方案
一、Flutter 前端实现
1. 监听底部导航栏点击事件
通过BottomNavigationBar的onTap回调判断点击项,触发数据请求:
int _currentIndex = 0; final PageController _pageController = PageController(); // 底部导航栏组件 BottomNavigationBar( currentIndex: _currentIndex, onTap: (index) { setState(() => _currentIndex = index); _pageController.jumpToPage(index); // 假设Profile项索引为2,根据实际布局调整 if (index == 2) { _loadUserProfile(); } }, items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.search), label: '搜索'), BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'), ], )
2. 实现API请求逻辑
使用http包发起GET请求,先在pubspec.yaml添加依赖:
dependencies: http: ^1.1.0 shared_preferences: ^2.2.2 # 用于存储当前用户ID
编写请求方法与数据模型:
import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; // 用户Profile数据模型 class UserProfile { final String username; final int postsCount; final int followers; final int following; final String avatarUrl; UserProfile({ required this.username, required this.postsCount, required this.followers, required this.following, required this.avatarUrl, }); factory UserProfile.fromJson(Map<String, dynamic> json) { return UserProfile( username: json['username'], postsCount: json['postsCount'], followers: json['followers'], following: json['following'], avatarUrl: json['avatarUrl'], ); } } // 加载用户Profile数据 bool _isLoading = false; UserProfile? _currentProfile; String? _errorMsg; Future<void> _loadUserProfile() async { setState(() { _isLoading = true; _errorMsg = null; }); try { // 从本地存储获取当前登录用户ID final prefs = await SharedPreferences.getInstance(); final userId = prefs.getString('user_id') ?? ''; if (userId.isEmpty) return; // 发起API请求 final response = await http.get( Uri.parse('http://你的后端地址/api/profile/$userId'), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { final data = json.decode(response.body); setState(() => _currentProfile = UserProfile.fromJson(data)); } else { setState(() => _errorMsg = '加载失败,请重试'); } } catch (e) { setState(() => _errorMsg = '网络错误:${e.toString()}'); } finally { setState(() => _isLoading = false); } }
3. 渲染Profile页面
根据状态展示加载、错误或正常数据:
Widget _buildProfilePage() { if (_isLoading) { return const Center(child: CircularProgressIndicator()); } if (_errorMsg != null) { return Center(child: Text(_errorMsg!)); } if (_currentProfile == null) { return const Center(child: Text('点击底部"我的"加载数据')); } return Column( children: [ const SizedBox(height: 30), CircleAvatar( radius: 50, backgroundImage: NetworkImage(_currentProfile!.avatarUrl), ), const SizedBox(height: 15), Text(_currentProfile!.username, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Column(children: [Text('${_currentProfile!.postsCount}'), const Text('帖子')]), Column(children: [Text('${_currentProfile!.followers}'), const Text('粉丝')]), Column(children: [Text('${_currentProfile!.following}'), const Text('关注')]), ], ), // 其他Profile内容(如发布的帖子列表) ], ); }
二、Spring Boot 后端实现
1. 定义实体类与Repository
对应MySQL的用户表(假设表名为user_profile):
import jakarta.persistence.*; import lombok.Data; @Entity @Table(name = "user_profile") @Data public class UserProfile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private int postsCount; private int followers; private int following; private String avatarUrl; }
编写JPA Repository:
import org.springframework.data.jpa.repository.JpaRepository; public interface UserProfileRepository extends JpaRepository<UserProfile, Long> { }
2. 编写REST接口
创建Controller处理前端请求:
import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/profile") public class ProfileController { private final UserProfileRepository profileRepository; // 构造函数注入Repository public ProfileController(UserProfileRepository profileRepository) { this.profileRepository = profileRepository; } @GetMapping("/{userId}") public ResponseEntity<UserProfile> getProfile(@PathVariable Long userId) { return profileRepository.findById(userId) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } }
3. 配置跨域(本地调试必备)
如果前后端不在同一域名,添加CORS配置:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://localhost:5555") // Flutter本地调试地址 .allowedMethods("GET", "POST") .allowedHeaders("*"); } }
内容的提问来源于stack exchange,提问作者cruxi5
相关产品推荐
相关产品推荐

