首页 > 解决方案 > 通过 ListView.Builder Flutter 搜索文本和高亮匹配

问题描述

基本上我有一个阅读应用程序,其中在屏幕上显示巨大的文本,为了优化,我将文本分割为 \n 并显示在 ListView.Builder 中。

用户可以随时更改此文本的字体大小和字体粗细(从 12 到 24,从 w200 到 w900)

所以,目标是实现一个搜索栏,滚动到匹配的文本并突出显示它(就像 chrome 一样)

例子:

import 'package:flutter/material.dart';
import 'package:testtttt/search_bar.dart';

void main() => runApp(MaterialApp(home: App()));

class App extends StatelessWidget {
  App({Key? key}) : super(key: key);

  static const String _lorem =
      "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam rhoncus mauris ac neque interdum porta. Integer rutrum est a velit gravida eleifend. Sed quis eros a eros imperdiet mollis semper sit amet erat. In in gravida nunc. Maecenas id arcu sed sem commodo sodales ut a arcu. Morbi quis nisl varius, vestibulum libero eget, egestas diam. In hac habitasse platea dictumst. Sed ut porta metus. Ut venenatis nibh et leo efficitur, et tempor urna euismod. Maecenas quis quam nec leo egestas tempus.\nDonec dapibus, mi et hendrerit sodales, ligula ex suscipit est, vel varius ex ligula at erat. Duis scelerisque aliquam felis, sed accumsan lacus maximus sit amet. Suspendisse ac nulla purus. Cras diam leo, luctus eu laoreet non, sollicitudin a turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque efficitur auctor fermentum. Nulla non luctus ligula, at sollicitudin nulla. Aliquam pellentesque nisi in blandit condimentum. Etiam vitae felis ac nisl eleifend tristique eget vitae nulla. In rhoncus venenatis tempus. Donec tortor diam, lobortis eu ex vitae, viverra hendrerit nisi.\nPraesent sollicitudin vulputate augue, cursus vestibulum sem volutpat non. Donec efficitur est a erat sodales, et aliquam dui vehicula. Quisque eu purus malesuada augue efficitur fringilla id vitae nunc. Cras eget diam sit amet mi posuere convallis. Nulla facilisi. Maecenas sit amet dapibus nisi. Donec tincidunt dui pulvinar lorem malesuada posuere. Nunc tristique facilisis pretium. Pellentesque tristique purus ipsum, at dapibus magna eleifend sed. Vestibulum lacinia augue sed ipsum facilisis rutrum. Proin feugiat feugiat auctor.\nNunc pellentesque libero lectus, non maximus massa maximus at. Sed elementum metus ac odio fringilla bibendum. Mauris facilisis dictum justo, quis molestie nulla vestibulum quis. Donec in sodales justo, quis pulvinar metus. Nulla id suscipit nisi. Praesent volutpat sollicitudin facilisis. Vivamus risus justo, dignissim vel turpis id, commodo tincidunt ligula.\nSed at purus dui. Suspendisse quis sem eu libero fringilla condimentum nec vitae orci. Sed mi augue, bibendum non consectetur dictum, ultricies eget est. Suspendisse porta arcu sit amet sem interdum laoreet. Nulla facilisi. Vestibulum tincidunt urna tempor, finibus enim sodales, dapibus erat. Curabitur vitae iaculis lectus, a consectetur quam. Donec sed auctor sem. Etiam in metus ut tortor viverra euismod. Sed porta et nisl id consequat. In consequat elit ex, a tristique quam consequat ac. Maecenas euismod sodales consequat.";
  final List<String> _splitLorem = _lorem.split(RegExp('\n'));

  static const FontWeight _userChangeableFontWeight = FontWeight.bold;
  static const double _userChangeableFontSize = 16.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            SearchBar(
              onChanged: (value) {
                // search, scroll to and highlight the matched values
              },
              decoration: InputDecoration(
                hintText: 'Search...',
                counterText: '',
              ),
            ),
            const SizedBox(height: 16),
            Expanded(
              child: ListView.builder(
                padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
                itemCount: _splitLorem.length,
                itemBuilder: (context, index) {
                  return Text(
                    _splitLorem[index],
                    style: TextStyle(
                      fontSize: _userChangeableFontSize,
                      fontWeight: _userChangeableFontWeight,
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

标签: fluttersearchflutter-listview

解决方案


// Assuming you have a search bar, with a listener of some sorts
// e.g.: TextFormField with onChanged that calls setState(){} 
//
// Your search function could be simply
List<String> matches = _splitLorem.where((word) => word == searchTerm);



推荐阅读