azlistview

repository·master·Indexed 22 days ago

https://github.com/flutterchina/azlistview

A Flutter plugin for creating high-performance ListView interfaces with sticky headers and A-Z index bars, ideal for contact or city selection lists. Built upon scrollable_positioned_list, it provides core components including AzListView, SuspensionView, and IndexBar. Key features include automatic A-Z grouping via the ISuspensionBean interface, custom IndexBar styling with haptic feedback, and programmatic scrolling to specific items using ItemScrollController.

Tokens
3.6K
Snippets
10
Records
15
Agent score
77%

What's inside azlistview

  1. Overview of azlistview features

    master

    azlistview is a Flutter package designed for creating interfaces like city lists or contact lists. It is built upon scrollable_positioned_list and provides the following capabilities:

    • A-Z Grouping: Automatically group list items by their first letter.
    • Sticky Headers: Implement floating headers that stay at the top during scrolling.
    • Customization: Support for custom headers and custom IndexBar styles.
    • Index Linkage: Connect the IndexBar to the list for quick navigation.
    • IndexBar Support: The IndexBar can use local images and supports custom styling.
    • Specific Item Scrolling: Allows the application to scroll directly to a specific item in the list.

    Core components include AzListView, SuspensionView, and IndexBar.

  2. Customize the iOS launch screen assets

    master

    To change the image displayed during the app's launch on iOS, you can either replace the image files directly in the example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode for a more visual approach.

    Using Xcode:

    1. Open the iOS workspace using the command: open ios/Runner.xcworkspace.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace
  3. Listen to IndexBar drag events

    master

    To react to user interaction on the IndexBar, implement the IndexBarDragListener and use its dragDetails stream. This allows you to sync the index bar's state with your main list.

    IndexBarDragDetails provides the following information:

    • action: An integer representing the drag state:
      • 0: actionDown (Touch started)
      • 1: actionUp (Touch released)
      • 2: actionUpdate (Dragging/Moving)
      • 3: actionEnd (Drag finished)
      • 4: actionCancel (Drag cancelled)
    • index: The current integer index being touched.
    • tag: The string label (e.g., 'A') at the current index.
    • localPositionY / globalPositionY: The vertical position of the touch.
    // 1. Create the listener
    final IndexBarDragListener dragListener = IndexBarDragListener.create();
    
    // 2. Add a listener to the dragDetails ValueListenable
    dragListener.dragDetails.addListener(() {
      final details = dragListener.dragDetails.value;
      print('Current tag: ${details.tag}, Action: ${details.action}');
    });
    
    // 3. Pass it to the IndexBar
    IndexBar(
      indexBarDragListener: dragListener,
      // ... other properties
    )
  4. How AzListView handles suspension and indexing

    master

    The AzListView works by combining a SuspensionView and an IndexBar inside a Stack.

    1. Suspension Logic: As the user scrolls, the SuspensionView identifies the current active group based on the ISuspensionBean.getSuspensionTag() and renders a sticky header using the susItemBuilder.
    2. Index Bar Navigation: The IndexBar provides a vertical list of tags. Dragging on the index bar triggers IndexBarDragDetails, which causes the itemScrollController to jumpTo the index corresponding to the dragged tag.
    3. Syncing Scroll and Index: If indexBarOptions.selectItemDecoration is set, the widget listens to itemPositionsListener. When the scroll position changes, it calculates the current active tag and calls indexBarController.updateTagIndex(tag) to ensure the index bar highlights the correct letter/tag currently visible in the list.
  5. Use the IndexBar widget for alphabet navigation

    master

    The IndexBar widget provides a vertical list of characters (or custom data) that users can drag to navigate through a list. It supports custom styling, index hints (popups showing the current character), and drag event listening.

    Key features:

    • Custom Data: Pass a List<String> to data to define the index labels.
    • Index Hint: A popup widget that appears during dragging. You can customize its appearance via indexHintBuilder or options.
    • Drag Listening: Use IndexBarDragNotifier to listen to drag actions and respond to index changes.
    • Styling: Extensive customization via IndexBarOptions for colors, decorations, and text styles.
    IndexBar(
      data: ['A', 'B', 'C', 'D'],
      indexHintBuilder: (context, tag) {
        return Text(tag, style: TextStyle(fontSize: 24));
      },
      options: IndexBarOptions(
        hapticFeedback: true,
        indexHintDecoration: BoxDecoration(
          color: Colors.black87,
          borderRadius: BorderRadius.circular(6),
        ),
      ),
    )
  6. Configure the IndexBar via IndexBarOptions

    master
    The AzListView accepts an indexBarOptions parameter of type IndexBarOptions. This allows you to customize the appearance and behavior of the index bar, specifically regarding how selected items are decorated. If selectItemDecoration is provided in the options, the AzListView will automatically update the index bar's highlighted tag as the user scrolls through the list using the itemPositionsListener.
  7. Configure IndexBarOptions

    master

    The IndexBarOptions class allows for deep customization of the IndexBar appearance and behavior. Use this to control the index hint, text styles, and background decorations.

    Key Configuration Properties:

    • needRebuild: If true, the IndexBar widget will call setState on every drag update.
    • ignoreDragCancel: If true, actionCancel events will not trigger a rebuild.
    • hapticFeedback: Enables vibration during drag updates.
    • indexHintWidth / indexHintHeight: Dimensions of the popup hint.
    • indexHintDecoration: The decoration for the hint popup.
    • indexHintTextStyle: The text style for the character inside the hint.
    • localImages: A list of strings (asset paths). If a tag in data matches a path in localImages, the hint will display an Image.asset instead of text.
  8. Use the AzListView widget

    master

    The AzListView widget is the primary entry point for creating a list with sticky headers (suspension views) and an index bar for quick navigation. It requires a list of data implementing ISuspensionBean, the total item count, and an item builder.

    Key Parameters

    • data: A List<ISuspensionBean> containing the data items. Each bean must provide a suspension tag via getSuspensionTag().
    • itemCount: The total number of items in the list.
    • itemBuilder: A function to build the list items.
    • susItemBuilder: (Optional) A function to build the sticky suspension header widget.
    • itemScrollController: (Optional) An ItemScrollController to programmatically jump or scroll to specific items.
    • itemPositionsListener: (Optional) An ItemPositionsListener to track the position of items as they are laid out.
    • indexBarOptions: Configuration for the index bar, such as item decoration.
    AzListView(
      data: myDataList, // List<ISuspensionBean>
      itemCount: myDataList.length,
      itemBuilder: (context, index) {
        return ListTile(title: Text(myDataList[index].name));
      },
      susItemBuilder: (context, index) {
        return Container(
          color: Colors.grey,
          child: Text(myDataList[index].getSuspensionTag()),
        );
      },
    )
  9. Use SuspensionView to display floating headers

    master

    The SuspensionView widget is used to create a list with floating (suspension) headers. It utilizes ScrollablePositionedList internally to manage scrolling and item positioning. To use it, you must provide a list of data implementing ISuspensionBean, an itemCount, and an itemBuilder for the main list items. You can also provide a susItemBuilder to define how the floating headers look.

    SuspensionView(
      data: mySuspensionBeans, // List<ISuspensionBean>
      itemCount: mySuspensionBeans.length,
      itemBuilder: (context, index) {
        return ListTile(title: Text('Item $index'));
      },
      susItemBuilder: (context, index) {
        return Container(
          color: Colors.blue,
          child: Text('Header $index'),
        );
      },
    )
  10. Use SuspensionUtil to manage suspension data

    master

    The SuspensionUtil class provides static helper methods to process lists of ISuspensionBean objects for use with the list view components.

    • sortListBySuspensionTag(List<ISuspensionBean>? list): Sorts the list based on the tags returned by getSuspensionTag(). It handles special characters like @ and # to ensure they appear at the start/end as intended.
    • getTagIndexList(List<ISuspensionBean>? list): Extracts a unique list of all tags present in the list, which is typically used to build the side index bar.
    • setShowSuspensionStatus(List<ISuspensionBean>? list): Iterates through the list and updates the isShowSuspension property of each item. This is necessary to tell the UI which items in the list are currently the active headers.
    // 1. Sort the list
    SuspensionUtil.sortListBySuspensionTag(myList);
    
    // 2. Get the tags for the side index bar
    List<String> tags = SuspensionUtil.getTagIndexList(myList);
    
    // 3. Update the suspension status for rendering
    SuspensionUtil.setShowSuspensionStatus(myList);
  11. Control IndexBar via IndexBarController

    master

    The IndexBarController allows you to programmatically update the selected tag in the IndexBar from outside the widget.

    Use controller.updateTag(String tag) to force the IndexBar to highlight a specific character.

    final IndexBarController _controller = IndexBarController();
    
    // In your build method
    IndexBar(
      controller: _controller,
      // ...
    )
    
    // Later, to jump to 'Z'
    _controller.updateTag('Z');