You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:25:08