有一点命名规则:
文件名用小写+_线。
类名用骆驼名字
私类或方法用_开头。

rand_page.dart 文件:

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

class RandPage extends StatefulWidget {
  const RandPage({Key? key}) : super(key: key);
  @override
  State<RandPage> createState() => _RandPageState();
}

class _RandPageState extends State<RandPage> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemBuilder: /*1*/ (context, i) {
          if (i.isOdd) return const Divider(); /*2*/

          final index = i ~/ 2; /*3*/
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10)); /*4*/
          }
          return _buildRow(_suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );
  }
  // #docregion RWS-class-only
}

main.dart 文件:

import 'package:flutter/material.dart';
import 'package:flutter_application_1/rand_page.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Startup Name Generator',
      home: RandPage(),
    );
  }
}

官方例子使用英文名字随机库
在pubspec.yaml中增加库名字和版本号就可以

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  # 增加这行
  english_words: ^4.0.0

并在pubspec.yaml文件右键。下载库就可以。也可以使用命令在工程目录运行:

flutter pub get

增加环境变量

Win下在系统设置环境变量分别增加下面两个变量
PUB_HOSTED_URL=https://mirrors.tuna.tsinghua.edu.cn/dart-pub
FLUTTER_STORAGE_BASE_URL=https://mirrors.tuna.tsinghua.edu.cn/flutter

Linux 或 Mac下增加
export PUB_HOSTED_URL=https://mirrors.tuna.tsinghua.edu.cn/dart-pub
export FLUTTER_STORAGE_BASE_URL=https://mirrors.tuna.tsinghua.edu.cn/flutter

这样使用

Flutter pub get

或者在VSCode下载包时就可能直接下载。不需要VPN

set exe="C:\Program Files\Java\jre1.8.0_231\bin\keytool.exe"
set openssl="C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
set file_name=google_play.der
set password=android

%openssl% sha1 -binary %file_name%| %openssl% base64
pause

下面是将本地证书转:
set exe="C:\Program Files\Java\jre1.8.0_231\bin\keytool.exe"
set openssl="C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
set file_name=key.jks
set password=111111111

%exe% -exportcert -alias username -keystore %file_name% -storepass %password%| %openssl% sha1 -binary | %openssl% base64

pause

主要用:HorizontalScrollView 实现,然后里面放一个LinearLayout 就可以。
为什么用HorizontalScrollView ,如果用其它View窗口。LinearLayout 显示区以外的可能不显示
再使用动画类实现移动跟循环。喜欢封装的可以自己继续然后再用循环做

    for (item in logs) {
        createItem(item)
    }
    createItem(logs[0])

    MainScope().launch(Dispatchers.Main) {
        delay(100)
        loop2()
    }
}

private fun loop2(){
    val width = xxxLine.measuredWidth

    // 第一个多创一下。用于做动画
    var w1 = xxxLine[0].measuredWidth
    val w2 = xxxLine.measuredWidth
    var dx = width - w1 + (w2 - w1).coerceAtMost(0)

    val anim = ObjectAnimator.ofFloat(xxxLine, "translationX", 0.0f, -dx.toFloat())
    anim.duration = width * 10L
    anim.interpolator = LinearInterpolator() // 匀速
    anim.repeatCount = ValueAnimator.INFINITE // 循环
    anim.start()
}

禁掉HorizontalScrollView 的事件和android:scrollbarSize="0dp"就可能完美显示

hsXXX.setOnTouchListener { _, _ -> return@setOnTouchListener true }