如何在Flutter应用中仅展示GitHub仓库内的代码内容(类似网站代码展示效果)
Hey there! As someone who's tackled this exact scenario before, let me walk you through the steps to pull only code content from a GitHub repo and display it with that polished, website-like code styling in your Flutter app.
Step 1: Fetch & Filter Code Files via GitHub API
First, you'll need to use the GitHub REST API to get the repo's file structure and filter out non-code files. Here's how:
- Use the
contentsendpoint to list files in a repo (or specific folder):import 'package:http/http.dart' as http; import 'dart:convert'; Future<List<dynamic>> fetchCodeFiles(String owner, String repo, String path) async { final url = Uri.parse('https://api.github.com/repos/$owner/$repo/contents/$path'); final response = await http.get(url); if (response.statusCode == 200) { final files = json.decode(response.body); // Filter for common code file extensions - adjust this list to your needs final codeExtensions = ['.dart', '.js', '.py', '.java', '.cpp', '.html', '.css']; return files.where((file) => file['type'] == 'file' && codeExtensions.contains(Uri.parse(file['name']).pathExtension) ).toList(); } else { throw Exception('Failed to load files'); } } - This function will return only files that match your specified code extensions, ignoring READMEs, licenses, configs, etc.
- Note: If your repo has a lot of files, you might need to handle pagination (check the
Linkheader in the API response for next/prev pages).
Step 2: Fetch Raw Code Content
Once you have the list of code files, use the download_url from each file object to fetch the raw code text:
Future<String> fetchCodeContent(String downloadUrl) async { final response = await http.get(Uri.parse(downloadUrl)); if (response.statusCode == 200) { return response.body; } else { throw Exception('Failed to load code content'); } }
Step 3: Display Code with Syntax Highlighting
To get that familiar website-style code display (syntax coloring, line numbers, clean formatting), use the flutter_highlight package. Here's how to set it up:
Add dependencies to your
pubspec.yaml:dependencies: flutter_highlight: ^0.7.0 flutter_highlight_themes: ^0.1.0 http: ^1.1.0Use the
Highlightwidget to render your code:import 'package:flutter_highlight/flutter_highlight.dart'; import 'package:flutter_highlight/themes/atom-one-dark.dart'; class CodeDisplayWidget extends StatelessWidget { final String code; final String language; // e.g., 'dart', 'javascript', 'python' const CodeDisplayWidget({super.key, required this.code, required this.language}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(16), color: const Color(0xff282c34), // Match the theme background child: HighlightView( code, language: language, theme: atomOneDarkTheme, padding: const EdgeInsets.all(0), textStyle: const TextStyle( fontSize: 14, fontFamily: 'Courier New', ), ), ); } }Add line numbers (optional but common on code sites):
You can wrap theHighlightViewin a row with a line number column. Here's a quick snippet:Widget build(BuildContext context) { final lines = code.split('\n'); return Container( padding: const EdgeInsets.all(16), color: const Color(0xff282c34), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Line numbers column Container( margin: const EdgeInsets.only(right: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: List.generate(lines.length, (index) { return Text( '${index + 1}', style: const TextStyle( color: Colors.grey, fontSize: 14, fontFamily: 'Courier New', ), ); }), ), ), // Highlighted code Expanded( child: HighlightView( code, language: language, theme: atomOneDarkTheme, padding: const EdgeInsets.all(0), textStyle: const TextStyle( fontSize: 14, fontFamily: 'Courier New', ), ), ), ], ), ); }
Bonus Optimizations
- Cache Code Content: Use
shared_preferencesorhiveto cache fetched code so you don't re-request it every time the user opens the screen. - Loading & Error States: Add a progress indicator while fetching, and an error message if something goes wrong.
- Copy Code Button: Use the
clipboardpackage to add a button that copies the code to the user's clipboard.
That's it! With these steps, you'll have a Flutter app that pulls only code from a GitHub repo and displays it just like your favorite code websites.
内容的提问来源于stack exchange,提问作者chiragJKL

