Flutter滚动定位列表支持rtl方向?

zdwk9cvp  于 2023-03-19  发布在  Flutter
关注(0)|答案(1)|浏览(158)

我在下面的代码中使用scrollable positioned package通过索引在元素之间移动,它在LTR的情况下工作得很好,但是当转换到RTL时,出现了一些问题,转换不正确!!我试图找出问题所在,但没有成功。
如何解决这个问题?

LTR:

RTL:

代码:

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int currentIndex = 0;
  TextDirection textDirection = TextDirection.ltr;

  late final ItemScrollController itemScrollController;

  @override
  void initState() {
    itemScrollController = ItemScrollController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: textDirection,
      child: Scaffold(
        appBar: AppBar(title: const Text('Scrollable positioned list')),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              height: 100,
              child: ScrollablePositionedList.separated(
                itemCount: 10,
                scrollDirection: Axis.horizontal,
                itemScrollController: itemScrollController,
                padding: const EdgeInsets.symmetric(horizontal: 16),
                separatorBuilder: (context, index) => const SizedBox(width: 10),
                itemBuilder: (context, index) => Container(
                  width: 100,
                  height: 50,
                  alignment: AlignmentDirectional.center,
                  decoration: BoxDecoration(
                    color: Colors.red,
                    border: currentIndex == index ? Border.all(color: Colors.black, width: 4) : null,
                  ),
                  child:
                      Text(index.toString(), style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w800)),
                ),
              ),
            ),
            const SizedBox(height: 40),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  if (textDirection == TextDirection.ltr) {
                    textDirection = TextDirection.rtl;
                  } else {
                    textDirection = TextDirection.ltr;
                  }
                });
              },
              child: Text(textDirection.toString()),
            )
          ],
        ),
        floatingActionButton: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            FloatingActionButton(
              onPressed: () {
                setState(() {
                  if (currentIndex != 0) {
                    currentIndex--;
                    itemScrollController.scrollTo(index: currentIndex, duration: const Duration(microseconds: 500), alignment: 0.10);
                  }
                });
              },
              child: const Icon(Icons.arrow_back),
            ),
            FloatingActionButton(
              onPressed: () {
                setState(() {
                  if (currentIndex < 9) {
                    currentIndex++;
                    itemScrollController.scrollTo(index: currentIndex, duration: const Duration(microseconds: 500), alignment: 0.10);
                  }
                });
              },
              child: const Icon(Icons.arrow_forward),
            ),
          ],
        ),
      ),
    );
  }
}
emeijp43

emeijp431#

看起来这可能是scrollable positioned package库或Directionality小部件中的一个错误。一个简单的解决方案是根据方向切换reverse参数来反转List小部件。
List控件的Reverse属性仅以相反顺序显示数据,但功能保持不变,因此您需要相应地更改按钮功能。

import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

void main() => runApp(
      const MyApp(), // Wrap your app
    );

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int currentIndex = 0;
  TextDirection textDirection = TextDirection.ltr;

  late final ItemScrollController itemScrollController;

  @override
  void initState() {
    itemScrollController = ItemScrollController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              height: 100,
              child: ScrollablePositionedList.separated(
                reverse: textDirection == TextDirection.ltr ? false : true, // reverse the list
                itemCount: 10,
                scrollDirection: Axis.horizontal,
                itemScrollController: itemScrollController,
                padding: const EdgeInsets.symmetric(horizontal: 16),
                separatorBuilder: (context, index) => const SizedBox(width: 10),
                itemBuilder: (context, index) => Container(
                  width: 100,
                  height: 50,
                  alignment: AlignmentDirectional.center,
                  decoration: BoxDecoration(
                    color: Colors.red,
                    border: currentIndex == index
                        ? Border.all(color: Colors.black, width: 4)
                        : null,
                  ),
                  child: Text(index.toString(),
                      style: const TextStyle(
                          color: Colors.white, fontWeight: FontWeight.w800)),
                ),
              ),
            ),
            const SizedBox(height: 40),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  if (textDirection == TextDirection.ltr) {
                    textDirection = TextDirection.rtl;
                  } else {
                    textDirection = TextDirection.ltr;
                  }
                });
              },
              child: Text(textDirection.toString()),
            )
          ],
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        floatingActionButton: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            FloatingActionButton(
              onPressed: () {
                setState(() {
                  if (textDirection == TextDirection.ltr) {
                    if (currentIndex != 0) {
                      currentIndex--;
                      itemScrollController.scrollTo(
                          index: currentIndex,
                          duration: const Duration(microseconds: 500),
                          alignment: 0.10);
                    }
                  } else {
                    if (currentIndex < 9) {
                      currentIndex++;
                      itemScrollController.scrollTo(
                          index: currentIndex,
                          duration: const Duration(microseconds: 500),
                          alignment: 0.10);
                    }
                  }
                });
              },
              child: const Icon(Icons.arrow_back),
            ),
            FloatingActionButton(
              onPressed: () {
                setState(() {
                  if (textDirection == TextDirection.ltr) {
                    if (currentIndex < 9) {
                      currentIndex++;
                      itemScrollController.scrollTo(
                          index: currentIndex,
                          duration: const Duration(microseconds: 500),
                          alignment: 0.10);
                    }
                  } else {
                    if (currentIndex != 0) {
                      currentIndex--;
                      itemScrollController.scrollTo(
                          index: currentIndex,
                          duration: const Duration(microseconds: 500),
                          alignment: 0.10);
                    }
                  }
                });
              },
              child: const Icon(Icons.arrow_forward),
            ),
          ],
        ),
      ),
    );
  }
}

相关问题