Flutter实现仿微信分享功能的示例代码怎么写

发布时间:2022-01-15 15:55:12 作者:柒染
来源:亿速云 阅读:327
# Flutter实现仿微信分享功能的示例代码详解

本文将全面讲解如何使用Flutter实现仿微信的分享功能,包含UI构建、平台交互、多端适配等完整实现方案。

## 一、功能需求分析

微信分享功能主要包含以下核心要素:

1. **分享入口**:
   - 右上角"..."菜单触发
   - 长按内容触发
   - 特定按钮点击触发

2. **分享面板UI**:
   - 半透明模态弹窗
   - 应用图标网格布局
   - 取消按钮

3. **分享目标**:
   - 微信好友
   - 朋友圈
   - QQ
   - 微博
   - 复制链接
   - 更多...

4. **平台能力**:
   - 调用原生分享API
   - 处理分享回调
   - 未安装应用处理

## 二、项目结构与依赖配置

### 1. 创建Flutter项目

```bash
flutter create wechat_share_demo

2. 添加必要依赖

pubspec.yaml 配置:

dependencies:
  flutter:
    sdk: flutter
  # 分享插件
  share_plus: ^7.0.2
  # 平台设备信息
  device_info_plus: ^9.0.3
  # 权限处理
  permission_handler: ^10.4.0
  # 图标库
  font_awesome_flutter: ^10.5.0
  # 路由管理
  go_router: ^12.0.0

三、核心代码实现

1. 分享面板UI组件

share_sheet.dart:

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class ShareSheet extends StatelessWidget {
  final VoidCallback onCancel;
  final Function(String) onShare;

  const ShareSheet({
    super.key,
    required this.onCancel,
    required this.onShare,
  });

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.2),
              blurRadius: 10,
              spreadRadius: 0,
            )
          ],
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            _buildHeader(),
            _buildPlatformGrid(),
            _buildActionRow(),
            _buildCancelButton(),
          ],
        ),
      ),
    );
  }

  Widget _buildHeader() {
    return const Padding(
      padding: EdgeInsets.symmetric(vertical: 16),
      child: Text(
        '分享到',
        style: TextStyle(
          fontSize: 16,
          fontWeight: FontWeight.bold,
          color: Colors.black87,
        ),
      ),
    );
  }

  Widget _buildPlatformGrid() {
    const platforms = [
      {'name': '微信好友', 'icon': FontAwesomeIcons.weixin, 'color': Colors.green},
      {'name': '朋友圈', 'icon': FontAwesomeIcons.users, 'color': Colors.green},
      {'name': 'QQ', 'icon': FontAwesomeIcons.qq, 'color': Colors.blue},
      {'name': '微博', 'icon': FontAwesomeIcons.weibo, 'color': Colors.orange},
      {'name': '复制链接', 'icon': Icons.link, 'color': Colors.grey},
      {'name': '更多', 'icon': Icons.more_horiz, 'color': Colors.grey},
    ];

    return GridView.count(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      crossAxisCount: 4,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      children: platforms.map((platform) {
        return _buildPlatformItem(
          platform['icon'] as IconData,
          platform['name'] as String,
          platform['color'] as Color,
        );
      }).toList(),
    );
  }

  Widget _buildPlatformItem(IconData icon, String name, Color color) {
    return GestureDetector(
      onTap: () => onShare(name),
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 12),
        child: Column(
          children: [
            Container(
              width: 50,
              height: 50,
              decoration: BoxDecoration(
                color: color.withOpacity(0.1),
                shape: BoxShape.circle,
              ),
              child: Icon(icon, color: color, size: 24),
            ),
            const SizedBox(height: 8),
            Text(
              name,
              style: const TextStyle(fontSize: 12),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildActionRow() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
      child: Row(
        children: [
          Expanded(
            child: OutlinedButton(
              style: OutlinedButton.styleFrom(
                foregroundColor: Colors.grey,
                side: const BorderSide(color: Colors.grey),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20),
                ),
              ),
              onPressed: () => onShare('收藏'),
              child: const Text('收藏'),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: OutlinedButton(
              style: OutlinedButton.styleFrom(
                foregroundColor: Colors.grey,
                side: const BorderSide(color: Colors.grey),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20),
              ),
              onPressed: () => onShare('保存图片'),
              child: const Text('保存图片'),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildCancelButton() {
    return Container(
      decoration: const BoxDecoration(
        border: Border(top: BorderSide(color: Colors.grey, width: 0.5)),
      ),
      child: ListTile(
        title: const Center(
          child: Text(
            '取消',
            style: TextStyle(fontSize: 16),
          ),
        ),
        onTap: onCancel,
      ),
    );
  }
}

2. 分享功能服务类

share_service.dart:

import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/services.dart';
import 'package:share_plus/share_plus.dart';

class ShareService {
  static Future<void> shareToWeChat(String content) async {
    try {
      // 检测是否安装微信
      final deviceInfo = await DeviceInfoPlugin().androidInfo;
      if (deviceInfo is AndroidDeviceInfo) {
        // Android平台处理
        const platform = MethodChannel('com.example/share');
        await platform.invokeMethod('shareToWeChat', {'text': content});
      } else {
        // iOS平台处理
        await Share.share(content, subject: '微信分享');
      }
    } on PlatformException catch (e) {
      print('分享失败: ${e.message}');
      // 处理未安装微信的情况
      await Share.share(content);
    }
  }

  static Future<void> shareToWeChatMoments(String content) async {
    // 类似微信好友的实现,调用不同平台方法
  }

  static Future<void> shareToQQ(String content) async {
    // QQ分享实现
  }

  static Future<void> copyLink(String link) async {
    await Clipboard.setData(ClipboardData(text: link));
  }

  static Future<void> saveImage(String imageUrl) async {
    // 图片保存实现
  }
}

3. 平台通道配置

Android配置

android/app/src/main/kotlin/com/example/wechat_share_demo/MainActivity.kt:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example/share"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "shareToWeChat" -> {
                    val text = call.argument<String>("text")
                    // 调用微信SDK分享
                    shareToWeChat(text ?: "", result)
                }
                else -> result.notImplemented()
            }
        }
    }

    private fun shareToWeChat(text: String, result: MethodChannel.Result) {
        try {
            // 实际调用微信SDK的代码
            result.success(true)
        } catch (e: Exception) {
            result.error("UNAVLABLE", "微信未安装", null)
        }
    }
}

iOS配置

ios/Runner/AppDelegate.swift:

import Flutter
import UIKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let shareChannel = FlutterMethodChannel(name: "com.example/share",
                                              binaryMessenger: controller.binaryMessenger)
    shareChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
      guard call.method == "shareToWeChat" else {
        result(FlutterMethodNotImplemented)
        return
      }
      self.shareToWeChat(arguments: call.arguments, result: result)
    })
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  private func shareToWeChat(arguments: Any?, result: FlutterResult) {
    // 调用微信SDK分享
    result(true)
  }
}

四、完整使用示例

1. 主页面实现

main_page.dart:

import 'package:flutter/material.dart';
import 'package:wechat_share_demo/share_sheet.dart';
import 'package:wechat_share_demo/share_service.dart';

class MainPage extends StatelessWidget {
  const MainPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('微信分享示例'),
        actions: [
          IconButton(
            icon: const Icon(Icons.share),
            onPressed: () => _showShareSheet(context),
          ),
        ],
      ),
      body: Center(
        child: ElevatedButton(
          child: const Text('分享内容'),
          onPressed: () => _showShareSheet(context),
        ),
      ),
    );
  }

  void _showShareSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      isScrollControlled: true,
      builder: (context) => ShareSheet(
        onCancel: () => Navigator.pop(context),
        onShare: (platform) => _handleShare(platform, context),
      ),
    );
  }

  Future<void> _handleShare(String platform, BuildContext context) async {
    Navigator.pop(context);
    
    const shareContent = '这是要分享的内容\nhttps://example.com';
    const shareImage = 'https://example.com/image.jpg';

    switch (platform) {
      case '微信好友':
        await ShareService.shareToWeChat(shareContent);
        break;
      case '朋友圈':
        await ShareService.shareToWeChatMoments(shareContent);
        break;
      case 'QQ':
        await ShareService.shareToQQ(shareContent);
        break;
      case '微博':
        // 微博分享实现
        break;
      case '复制链接':
        await ShareService.copyLink('https://example.com');
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('链接已复制')),
        );
        break;
      case '保存图片':
        await ShareService.saveImage(shareImage);
        break;
      default:
        await Share.share(shareContent);
    }
  }
}

2. 应用入口

main.dart:

import 'package:flutter/material.dart';
import 'package:wechat_share_demo/main_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '微信分享示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MainPage(),
    );
  }
}

五、高级功能扩展

1. 分享内容预览组件

class SharePreview extends StatelessWidget {
  final String title;
  final String description;
  final String imageUrl;
  final String url;

  const SharePreview({
    super.key,
    required this.title,
    required this.description,
    required this.imageUrl,
    required this.url,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.grey[100],
        borderRadius: BorderRadius.circular(8),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          if (imageUrl.isNotEmpty)
            ClipRRect(
              borderRadius: BorderRadius.circular(4),
              child: Image.network(
                imageUrl,
                height: 120,
                width: double.infinity,
                fit: BoxFit.cover,
              ),
            ),
          const SizedBox(height: 12),
          Text(
            title,
            style: const TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 16,
            ),
          ),
          const SizedBox(height: 4),
          Text(
            description,
            style: TextStyle(
              color: Colors.grey[600],
              fontSize: 14,
            ),
          ),
          const SizedBox(height: 8),
          Text(
            url,
            style: TextStyle(
              color: Colors.blue[400],
              fontSize: 12,
            ),
          ),
        ],
      ),
    );
  }
}

2. 分享统计与埋点

class ShareAnalytics {
  static void logShareEvent({
    required String platform,
    required String contentType,
    required bool success,
  }) {
    // 实际项目中调用埋点SDK
    debugPrint('''
      分享事件记录:
      平台: $platform
      类型: $contentType
      成功: $success
    ''');
  }
}

// 使用示例
ShareAnalytics.logShareEvent(
  platform: '微信好友',
  contentType: '链接',
  success: true,
);

3. 多语言支持

class ShareLocalizations {
  final Locale locale;

  ShareLocalizations(this.locale);

  static ShareLocalizations of(BuildContext context) {
    return Localizations.of<ShareLocalizations>(context, ShareLocalizations)!;
  }

  static const Map<String, Map<String, String>> _localizedValues = {
    'en': {
      'shareTo': 'Share to',
      'wechat': 'WeChat',
      'moments': 'Moments',
      'cancel': 'Cancel',
    },
    'zh': {
      'shareTo': '分享到',
      'wechat': '微信好友',
      'moments': '朋友圈',
      'cancel': '取消',
    },
  };

  String get shareTo => _localizedValues[locale.languageCode]!['shareTo']!;
  String get wechat => _localizedValues[locale.languageCode]!['wechat']!;
  String get moments => _localizedValues[locale.languageCode]!['moments']!;
  String get cancel => _localizedValues[locale.languageCode]!['cancel']!;
}

六、性能优化与测试

1. 分享面板性能优化

class OptimizedShareSheet extends StatefulWidget {
  // ...参数相同
  
  @override
  State<OptimizedShareSheet> createState() => _OptimizedShareSheetState();
}

class _OptimizedShareSheetState extends State<OptimizedShareSheet> {
  late final List<Map<String, dynamic>> _platforms;
  
  @override
  void initState() {
    super.initState();
    // 提前初始化数据,避免重复构建
    _platforms = const [
      {'name': '微信好友', 'icon': FontAwesomeIcons.weixin, 'color': Colors.green},
      // ...其他平台数据
    ];
  }
  
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          // 使用ListView.builder优化长列表
          GridView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 4,
              childAspectRatio: 0.8,
            ),
            itemCount: _platforms.length,
            itemBuilder: (context, index) {
              final platform = _platforms[index];
              return _buildPlatformItem(
                platform['icon'] as IconData,
                platform['name'] as String,
                platform['color'] as Color,
              );
            },
          ),
          // ...其他组件
        ],
      ),
    );
  }
}

2. 自动化测试

share_sheet_test.dart:

”`dart import ‘package:flutter/material.dart’; import ‘package:flutter_test/flutter_test.dart’; import ‘package:wechat_share_demo/share_sheet.dart’;

void main() { testWidgets(‘分享面板显示测试’, (WidgetTester tester) async { bool canceled = false; String? sharedPlatform;

await tester.pumpWidget(MaterialApp(
  home: Scaffold(
    body: ShareSheet(
      onCancel: () => canceled = true,
      onShare: (platform) => sharedPlatform = platform,
    ),
  ),
));

// 验证标题显示
expect(find.text('分享到'), finds
推荐阅读:
  1. 如何实现flutter仿微信底部图标渐变功能
  2. Flutter 实现下拉刷新上拉加载的示例代码

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

flutter

上一篇:普通填报表单元格如何实现数据二次筛选

下一篇:springboot整合quartz定时任务框架的方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》