패키지, 저장소 및 앱 카테고리 검색

chips_input 표지
패키지 상세v0.1.0

chips_input

제안에서 선택할 수 있는 여러 칩을 가진 입력을 생성하는 Flutter 위젯입니다.

30일 다운로드
215
좋아요
41
Pub 점수
70

패키지 설치

flutter pub add chips_input

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

ChipsInput은 실시간 제안과 함께 상호작용 가능한 칩을 통해 사용자가 여러 값을 입력할 수 있도록 해주는 Flutter 위젯입니다. 동적 칩 생성, 입력 기반 제안 필터링, 사용자 정의 스타일링을 지원합니다. 태그 지정, 옵션 선택 또는 깔끔하고 직관적인 인터페이스에서 항목 목록을 입력하는 데 이상적입니다. 이 위젯은 양식 및 데이터 입력 흐름에 원활하게 통합되어 즉각적인 피드백과 시각적 명확성을 제공하여 사용자 경험을 향상시킵니다.

사용 사례

  • 태그 시스템
  • 다중 선택 입력
  • 양식 데이터 입력
  • 검색 가능한 칩 선택
  • 사용자 선호도 수집
  • 동적 목록 생성

주요 기능

  • 실시간 제안 필터링
  • 사용자 정의 가능한 칩 외관
  • 키보드 탐색을 지원합니다
  • 폼 필드와의 간편한 통합
  • 중복 칩 방지
  • 사용자 정의 입력 검증

적합한 대상

  • 양식 빌더
  • 태그 기반 인터페이스
  • 사용자 선호도 선택기
  • 여러 값이 포함된 데이터 입력
  • 인터랙티브 검색 구성 요소

고려 사항

  • 제한된 플랫폼별 동작
  • 중복 외에는 내장 검증이 없습니다
  • 칩 제거를 수동으로 처리해야 합니다
  • 복잡한 테마를 위해 사용자 정의 스타일링이 필요할 수 있습니다
  • 매우 큰 제안 세트에 최적화되지 않음

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

chips_input

Flutter library for building input fields with InputChips as input options.

Pub Version GitHub Workflow Status

Usage

Import
import 'package:chips_input/chips_input.dart';
Example

ChipsInput

First create some sort of Class that holds the data. You could also use a simple String.

class AppProfile {
  final String name;
  final String email;
  final String imageUrl;

  const AppProfile(this.name, this.email, this.imageUrl);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is AppProfile &&
          runtimeType == other.runtimeType &&
          name == other.name;

  @override
  int get hashCode => name.hashCode;

  @override
  String toString() {
    return name;
  }
}

Initialize some data and implement the ChipsInput Widget to your liking.

const mockResults = <AppProfile>[
    AppProfile('John Doe', 'jdoe@flutter.io',
        'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
    AppProfile('Paul', 'paul@google.com',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Fred', 'fred@google.com',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Brian', 'brian@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('John', 'john@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Thomas', 'thomas@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Nelly', 'nelly@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Marie', 'marie@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Charlie', 'charlie@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Diana', 'diana@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Ernie', 'ernie@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Gina', 'fred@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
];

ChipsInput(
    maxChips: 3, // remove, if you like infinity number of chips
    initialValue: [mockResults[1]],
    findSuggestions: (String query) {
        if (query.isNotEmpty) {
            var lowercaseQuery = query.toLowerCase();
            final results = mockResults.where((profile) {
            return profile.name
                    .toLowerCase()
                    .contains(query.toLowerCase()) ||
                profile.email
                    .toLowerCase()
                    .contains(query.toLowerCase());
            }).toList(growable: false)
            ..sort((a, b) => a.name
                .toLowerCase()
                .indexOf(lowercaseQuery)
                .compareTo(
                    b.name.toLowerCase().indexOf(lowercaseQuery)));
            return results;
        }
        return mockResults;
    },
    onChanged: (data) {
        print(data);
    },
    chipBuilder: (context, state, AppProfile profile) {
        return InputChip(
            key: ObjectKey(profile),
            label: Text(profile.name),
            avatar: CircleAvatar(
            backgroundImage: NetworkImage(profile.imageUrl),
            ),
            onDeleted: () => state.deleteChip(profile),
            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        );
    },
    suggestionBuilder: (context, AppProfile profile) {
        return ListTile(
            key: ObjectKey(profile),
            leading: CircleAvatar(
            backgroundImage: NetworkImage(profile.imageUrl),
            ),
            title: Text(profile.name),
            subtitle: Text(profile.email),
        );
    },
)

Instead of the suggestionBuilder you can also pass an optionsViewBuilder for more customization:

//...
optionsViewBuilder: (context, onSelected, options) {
    return Align(
        alignment: Alignment.topLeft,
        child: Material(
            elevation: 4.0,
            child: Container(
                height: 200.0,
                child: ListView.builder(
                    padding: EdgeInsets.all(8.0),
                    itemCount: options.length,
                    itemBuilder: (BuildContext context, int index) {
                        final option = options.elementAt(index);
                        return GestureDetector(
                            onTap: () {
                                onSelected(option);
                            },
                            child: ListTile(
                                key: ObjectKey(option),
                                leading: CircleAvatar(
                                    backgroundImage: NetworkImage(option.imageUrl),
                                ),
                                title: Text(option.name),
                                subtitle: Text(option.email),
                            ),
                        );
                    },
                ),
            ),
        ),
    );
},
//...

Credit

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.