Flutter未知功能插件tenor_flutter的探索使用
Flutter未知功能插件tenor_flutter的探索使用
Tenor Flutter
tenor_flutter
是一个将 Tenor GIF 搜索 集成到 Flutter 的插件。该插件通过使用 tenor_dart 包直接与 Tenor API V2 进行通信。
目前,该插件提供了一个可定制的 UI 体验,用于从 Tenor GIF 搜索 API 中搜索和选择 GIF 或贴纸。
如果你喜欢这个插件,请给它点个星来支持我们。
使用须知
- 要开始使用
tenor_flutter
,你需要在 Tenor 注册项目并获取 API 密钥。 - Tenor 要求使用其 API 的项目进行适当的 归因。此插件默认启用 “Powered By Tenor” 和 “Search Tenor”。你只需要其中一个即可。
获取 Tenor API v2 密钥
- 登录 Google Cloud Console
- 创建一个 新项目
- 进入 Google Cloud Marketplace 并找到 Tenor API
- 点击
Enable
以激活它 - 在导航菜单中,进入
APIs & Services
标签页并选择 Credentials - 点击
+ Create Credentials
并选择API key
- 复制生成的 API 密钥
- 将此 API 密钥作为参数传递给
Tenor(apiKey: 'YOUR_API_KEY')
使用方法
安装
flutter pub add tenor_flutter
遇到问题?请阅读 pub.dev 的 安装页面。
导入
在需要使用的 Dart 文件中导入包:
import 'package:tenor_flutter/tenor_flutter.dart';
初始化
必须传递由 Tenor 提供的有效 apiKey
。强烈建议同时传递 clientKey
,这将帮助你区分哪个项目正在发出请求。
final tenorClient = Tenor(apiKey: 'YOUR_API_KEY', clientKey: 'YOUR_PROJECT_NAME');
示例
更多详细的示例请参阅 example/lib/main.dart。
以下是如何显示 UI 作为底部弹出框,然后打印用户的选择。如果返回 null
,则表示用户在未选择 GIF 的情况下关闭了弹出框。
final tenorClient = Tenor(apiKey: 'YOUR_API_KEY', clientKey: 'YOUR_PROJECT_NAME');
final TenorResult? result = await tenorClient.showAsBottomSheet(context: context);
print(result?.media.tinyGif?.url);
不需要 UI?
如果你希望完全自定义而不依赖于任何依赖项,可以考虑使用 Tenor Dart。
赞助商
Flyclops 是一家独立的移动游戏工作室,专注于休闲多人游戏,包括异步回合制和实时游戏。Flyclops 的游戏已在全球范围内被数百万人玩过。 |
Domino! 是一款超级上瘾、节奏快速的多人多米诺游戏,适用于 iOS 和 Android。这款易于学习但难以掌握的策略游戏设计精美,令人爱不释手! |
下一步计划
- 文档
- 测试(欢迎 贡献)
- 进一步改进
贡献
如果你看到这里,那你真是太棒了!你可以通过多种方式 贡献:
- 拾取任何标记为 “good first issue” 的问题
- 提出任何功能或增强建议
- 报告 bug
- 修复 bug
- 编写和改进文档
- 发送 Pull Request 🙏
示例代码
import 'package:flutter/material.dart';
import 'package:flutter_config/flutter_config.dart';
import 'package:tenor_flutter/tenor_flutter.dart';
import 'package:tenor_flutter_example/examples/dark_theme.dart';
import 'package:tenor_flutter_example/examples/localization.dart';
void main() async {
// 仅用于从 .env 文件加载 API 密钥,不是必需的
WidgetsFlutterBinding.ensureInitialized();
await FlutterConfig.loadEnvVariables();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tenor Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// 替换 apiKey 为你从 Tenor 获取的 API 密钥 > https://developers.google.com/tenor/guides/quickstart
var tenor = Tenor(apiKey: FlutterConfig.get('TENOR_API_KEY'));
// 定义一个结果以便稍后显示
TenorResult? selectedResult;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Tenor Flutter Demo'),
),
body: _exampleBody(),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// 默认实现 tenor flutter。显示 GIF 选择器作为底部弹出框,并更新状态中的 selectedResult。
FloatingActionButton(
onPressed: () async {
final result = await tenor.showAsBottomSheet(context: context);
setState(() {
selectedResult = result;
});
},
tooltip: 'Default',
child: const Icon(Icons.add),
),
],
),
);
}
// 更多示例,见:https://github.com/Flyclops/tenor_flutter/tree/main/example/lib/examples
Widget _exampleBody() {
final selectedGif = selectedResult?.media.tinyGif ??
selectedResult?.media.tinyGifTransparent;
return Center(
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.topCenter,
child: Column(
children: [
const SizedBox(height: 8),
const Text('Additional Examples'),
const SizedBox(height: 8),
Wrap(
alignment: WrapAlignment.center,
spacing: 8,
children: [
// https://github.com/Flyclops/tenor_flutter/tree/main/example/lib/examples/dark_theme.dart
ElevatedButton(
onPressed: () => push(const DarkTheme()),
child: const Text('Dark Theme'),
),
// https://github.com/Flyclops/tenor_flutter/tree/main/example/lib/examples/localization.dart
ElevatedButton(
onPressed: () => push(const Localization()),
child: const Text('Localization'),
),
],
),
],
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
selectedResult != null && selectedGif != null
? Image.network(
selectedGif.url,
width: selectedGif.dimensions.width,
height: selectedGif.dimensions.height,
)
: const Text('No GIF selected'),
],
),
],
),
);
}
void push(Widget page) {
Navigator.of(context).push(
MaterialPageRoute<String>(
builder: (BuildContext context) {
return page;
},
),
);
}
}
更多关于Flutter未知功能插件tenor_flutter的探索使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter未知功能插件tenor_flutter的探索使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
探索和使用Flutter中的未知功能插件tenor_flutter
时,了解其核心功能和API是非常重要的。虽然具体文档和详细API信息可能有限(因为是“未知功能插件”),但通常可以通过查看插件的官方仓库、示例代码或源代码来获取关键信息。以下是一个假设性的代码案例,展示如何使用tenor_flutter
插件(注意:实际API和方法可能有所不同,这里仅为示例)。
首先,确保你已经在pubspec.yaml
文件中添加了tenor_flutter
依赖项:
dependencies:
flutter:
sdk: flutter
tenor_flutter: ^x.y.z # 替换为实际的版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以尝试如下方式使用tenor_flutter
插件:
import 'package:flutter/material.dart';
import 'package:tenor_flutter/tenor_flutter.dart'; // 假设插件提供了这个import路径
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<GifResult> _gifs = [];
final TenorClient _tenorClient = TenorClient(apiKey: 'YOUR_TENOR_API_KEY'); // 替换为你的Tenor API密钥
@override
void initState() {
super.initState();
_fetchGifs();
}
Future<void> _fetchGifs() async {
try {
final SearchResult searchResult = await _tenorClient.searchGifs(query: 'happy');
setState(() {
_gifs = searchResult.gifs;
});
} catch (e) {
print('Error fetching GIFs: $e');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Tenor Flutter Example'),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 4.0,
mainAxisSpacing: 4.0,
),
itemCount: _gifs.length,
itemBuilder: (context, index) {
final GifResult gif = _gifs[index];
return GestureDetector(
onTap: () {
// 可以在这里添加点击GIF后的处理逻辑,比如全屏显示
print('GIF tapped: ${gif.url}');
},
child: Image.network(gif.url),
);
},
),
),
);
}
}
// 假设的TenorClient类和返回类型
class TenorClient {
final String apiKey;
TenorClient({required this.apiKey});
Future<SearchResult> searchGifs({required String query}) async {
// 这里应该是一个网络请求,使用dio、http等库
// 示例代码,实际API调用和响应解析会有所不同
final response = await http.get(
Uri.parse('https://api.tenor.com/v1/search', {
'q': query,
'key': apiKey,
'limit': '10', // 限制返回结果数量
}),
);
if (response.statusCode == 200) {
// 解析响应数据,这里假设响应数据已经被序列化为Map<String, dynamic>
final Map<String, dynamic> data = jsonDecode(response.body);
return SearchResult.fromJson(data);
} else {
throw Exception('Failed to fetch GIFs: ${response.statusCode}');
}
}
}
class SearchResult {
List<GifResult> gifs;
SearchResult({required this.gifs});
factory SearchResult.fromJson(Map<String, dynamic> json) {
return SearchResult(
gifs: List<GifResult>.from(json['results'].map((x) => GifResult.fromJson(x))),
);
}
}
class GifResult {
String url;
GifResult({required this.url});
factory GifResult.fromJson(Map<String, dynamic> json) {
return GifResult(
url: json['media'][0]['gif']['url'], // 假设URL的解析路径是这样的
);
}
}
注意:
- 上述代码中的
TenorClient
类、SearchResult
类和GifResult
类是基于假设的API响应结构创建的。实际使用时,你需要根据tenor_flutter
插件提供的API文档和响应数据结构来调整这些类。 YOUR_TENOR_API_KEY
需要替换为你从Tenor获取的API密钥。- 网络请求部分使用了
http
库,你可能需要在pubspec.yaml
中添加http: ^x.y.z
依赖项,并运行flutter pub get
来安装它。 - 由于
tenor_flutter
是一个假设的插件,上述代码可能需要根据实际插件的API进行调整。
务必查阅tenor_flutter
插件的官方文档和示例代码,以确保正确使用其功能。