Flutter_TextField_Variable_Width

Created with Sketch.

Flutter_TextField_Variable_Width

こんにちはEveryDaySoft代表の永田です。

最近はFlutter案件をしつつ、3Dのビジュアルエフェクトデザインを学んでいます。ビジュアルエフェクトデザインも公式の言っていることが専門用語が多く何言っているのかわからない状態から、わからない専門用語を調べて、専門用語の解説がわからないので、さまざまに調べて理解するまで調べているような状態です。ツールの操作は運動に似ていると思っています。何度も繰り返すことによって感覚と考えが一致してきてインプットが効率的になってくるので、何度も量をこなす必要があると考えています。ここ2ヶ月ぐらいの進捗は最新のOSVersionでiOSとAndroidで簡単なテンプレートの3Dアニメーション、エフェクトをFlutterのUI、UX表示、操作などです。

挙動

Flutter最新VersionでFlutterのUIでUnityを操作

Unity、Houdini、BlenderでExport、Flutter最新VersionでiOS、Androidの最新Versionで表示

今後(数年単位)、オリジナルのエフェクト、アニメーションを拡張していこうと思います。アプリを演出する上で、効果的な表現、体験という観点から展開していこうと思います。

昔からiOSのMetal、openCVを実施したりしてビジュアルエフェクトデザインについてプログラミングで学んでいました。しかし昔はPCもMobileも今ほどパワーがなかったので、技術を拡張していくことはしませんでしたが、

Flutterが登場しiOS、Androidを同時開発ができるので、サービスを始めていくにはそろそろかなと考えている次第です。

Flutterは表面的にとても開発しやすいのですが、内部のrebuild回数、bindingの影響範囲など、パフォーマンスに通じる部分を考慮して作らないと効率的な内部ロジックではなくなる可能性もネイティブアプリに比べ高い傾向にあります。

僕は内部パフォーマンスの最適化することが好きなので、尚更良い言語、良いプラットフォームが現れたなという気持ちでいます。

今回記事にした本題に入ります。

Flutter_TextField_Variable_WidthはTextFieldの横幅を可変するです。

ネットで見てもTextFildの横幅を可変する情報がなかったので作りました。

GitHub

https://gist.github.com/daisukenagata/e563b634ee269a4702f694838d390125

挙動の一部

ソースコードの一部

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter EveryDaySoft',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(
        title: "Example",
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Size size = Size.zero;
  Size size2 = Size.zero;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              _textField(true),
              SizedBox(
                width: 24,
              ),
              _textField(false),
            ],
          ),
        ),
      ),
    );
  }

  Widget _textField(bool flg) {
    var length = flg ? size : size2;
    return Container(
      height: 50,
      width: 60 < length.width ? length.width * 1.2 : 70,
      child: TextFormField(
        scrollPhysics: NeverScrollableScrollPhysics(),
        decoration: const InputDecoration(hintText: 'TextFormField'),
        onChanged: (value) {
          setState(() {
            if (flg) {
              size = _sizeWith(value);
            } else {
              size2 = _sizeWith(value);
            }
          });
        },
      ),
    );
  }

  Size _sizeWith(String text) {
    return (TextPainter(
            text: TextSpan(
              text: text,
            ),
            maxLines: 1,
            textScaleFactor: MediaQuery.of(context).textScaleFactor,
            textDirection: TextDirection.ltr)
          ..layout())
        .size;
  }
}

TextPainterの文字数でSizeを取得する機能です。

メソッドのパラメーター

text: TextSpanを必要とします。TextSpanは指定文字の色を設定します。

maxLines: 行数を指定

textScaleFactor:文字サイズを指定

textDirection:左or右から開始を指定

設定したlayout()のサイズを呼び出し箇所に付与

  Size _sizeWith(String text) {
    return (TextPainter(
            text: TextSpan(
              text: text,
            ),
            maxLines:
            1,
            textScaleFactor:
            MediaQuery.of(context).textScaleFactor,
            textDirection:
            TextDirection.ltr)
          ..layout()).size;
  }

デザインに応じて、なんとなく3項演算子で適当に設定

      return Container(
      height: 50, // デザイン挙動で変更してください
      width: 60 < length.width ? length.width * 1.2 : 70,
      child: TextFormField(
      scrollPhysics: NeverScrollableScrollPhysics(),
      decoration:const InputDecoration(hintText:'TextFormField'),

以上、貴重なお時間お読みくださいまして、誠にありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です