画像を参考に次のコードを追加してください
TextEditingController nameController = TextEditingController();
TextEditingController priceController = TextEditingController();

作成した2つのcontrollerをそれぞれのTextFieldにセットします。
次のコードを画像のように追加してください
controller: nameController,
controller: priceController,
これでTextFieldをcontrollerの支配下に置くことができました。
今回のアプリで管理したいデータは、欲しいものの
「名前」と「金額」
の二つです。今から「名前」と「金額」をワンセットで保存していくためのユニットを作成します。
(ユニット=ひとかたまり、最小単位)
次のコードはGoodsInfoクラスの定義です。このコードを画像の場所に追加してGoodsInfoクラスを作成してください。
class GoodsInfo {
GoodsInfo(this.name, this.price);
String name;
int price;
}

Class(クラス)について説明します!
クラスとは、変数(ここでは、名前や金額のこと、このアプリで扱うデータたち)や、
メソッド(機能のこと、変数に対して行う処理)をひとまとめにしたものです。
まずはここについて

その前に、前提知識として変数とデータ型の確認をします
文字や数字などを入れておくための箱。入れ物、容器。
数学の変数とは全く別物なので頭を新しくしてください。
変数に入る値がどんな値か定義するためのもの。
例)
String型=文字列
int型=数字
String name;
このコードが意味するのは、
「文字列(String)が入る箱をつくった。その箱のことをnameと呼ぶ」ということです。
「String型の変数nameを定義した」とも言います。
int price;
この一文も同じように考えて、
「数字(int)が入る箱を作った。その箱のことはpriceと呼ぶ。」
ということです。
つまりGoodsInfoクラスは、nameとpriceという二つの変数をもったクラスということになります。
クラスというまとまりの中に2つの名前の付いた引き出しがあるようなイメージです!

次はこの一文について
この一文はコンストラクタと呼ばれる処理で、このクラスの初期化をしている部分になります。
今日は、この一文は「アプリに必要なもの」くらいに考えてもらえば大丈夫です。
ここからの行程を説明します。
欲しい物のデータ(GoodsInfoクラス)をListに保存し、そのListをUI作成で作った
リスト部分に反映させます。
List(配列)とは、データの保存庫の様なものです。
上の図のように、データを保存することのできる小部屋がいくつも並んだものがListになります。
この小部屋には番号がついています。先頭の部屋から
0, 1, 2, 3, 4, ・・・
となっていて、この番号のことをindexと言います。
完成時のイメージとしては、この小部屋ひとつひとつにGoodsInfoを収納していく感じです。
ほしいものひとつ分 = 小部屋に収納されたGoodsInfoとなるからです。

このListでは、0番目の部屋に入っているGoodsInfoと2番目の部屋に入っているGoodsInfoは、中の引き出し(変数)のデータが違っていることがあると思います。
例えば、0番目のGoodsInfoクラスは、nameがApple Watchで、priceが25000
しかし、2番めのGoodsInfoクラスは、nameがサンダルで、priceが3000
といった具合です。
これは、先程作成したGoodsInfoクラスのコピーを作成して使うことで可能になります。そのコピーの中の変数であるnameとpriceに欲しいものの値を当てはめてみましょう。
画像を参考に次のコードを追加してください。
GoodsInfo _goodsInfo = GoodsInfo(
nameController.text,
priceController.text,
);
これでGoodsInfoクラスから、_goodsInfoというコピーを作成しました。この行程のことを「クラスをインスタンス(オブジェクト)化する」と言います。
このインスタンス化の考え方は、プログラミングを学ぶ中で、悩むことが多いポイントと言われています。ここでは、はっきりと理解できなくても大丈夫です。
実はクラスというのは設計図のようなもので、実体化(コピーを作る)しないと使えないのです。
おや?
priceController.text,
に赤い波線が出ています。エラーですね。
これは、「int型の変数priceに、String型の値であるpriceController.textを代入しようとしている」ことが原因です。
ここで、前に説明したデータ型が関係してきます。
int型(数字型)の変数には、intのデータしか格納することができません。
TextFieldに入力された値はそれが数字であってもString型として扱われる仕様になっているので、そのまま代入するとデータ型が違いますというエラーが出ます。
データ型を変換させます。
エラーの出ている行を次のように書き換えてください。
このように書くとString型をint型に変換することができます!
int.parse(priceController.text),
これで、保存ボタンがタップされた時に
「その時TextFieldに入力されているnameとpriceを初期値として_goodsInfoを作成する」
ということが行われます。
ここまでの工程で、「名前」と「金額」の情報を持つ_goodsInfoを作成することができました。欲しいものと金額をTextFieldに入力し保存ボタンをタップすると新しい_goodsInfoが作成されます。
_goodsInfoたちが入るListを作成してデータを管理しましょう。
画像を参考に次のコードを追加してください。GoodsInfo型が入る配列goodsInfoListを作成するコードです。
List<GoodsInfo> goodsInfoList = [];
次は、保存ボタンを押したらgoodsInfoListに_goodsInfoが追加される様にします。
保存ボタンの { } 内に
「_goodsInfoをgoodsInfoListに追加する処理」を書きます。
こうすることにより、保存ボタンが押されるたびに_goodsInfoがgoodsInfoListに追加されます。
goodsInfoList.add(_goodsInfo);
入力した情報をListに保存することができるようになりました。
はじめにUI(見た目)を作成したときは、リスト部分の表示内容を
で固定にしていました。なので今からgoodsInfoListのデータで欲しい物リストが表示されるように変更します。
ListViewが入力されているところを見てください。
まずは画像のところを書き換えます。itemCountはリストに何件表示するのかを設定する場所です。
今は20で固定になっています。

itemCountを画像のように変更してください。
lengthは長さという意味ですが、 この場合はListが持っている要素の数を表しています。
Listの小部屋が何個埋まっているか教えてくれるイメージです。
goodsInfoList.length

次はここです。ここは名前と金額を表示している部分です。
今はSwitchと25000で固定になっています。

それぞれ画像を参考に書き換えてください。このように指定することで、goodsInfoListの要素の数だけリストを出力してくれます。
goodsInfoList[index].name
goodsInfoList[index].price.toString()
これで、goodInfoListの内容でリスト部分が表示されるようになりました!
次に保存ボタンElevatedButtonのonPressedの中に次のコードを追加してください。
setState(() {
});
これはsetStateと言い、「現在の状態で画面を再描画する」という処理を行います。
今表示されている画面は、goodsInfoListに新しい_goodsInfoが追加される「前」のものです。
なので、空のgoodsInfoListでリスト部分が作られているため何も表示されません。
_goodsInfoをgoodsInfoListに追加した後に画面を再描画することで、
新たに追加した_goodsInfoが反映されたリストを表示することができます。

では、なんでもいいので欲しいものを入力して保存ボタンを押してみましょう。
保存されました!
でも、保存ボタンを押したのにTextFieldに値が残っていて使いにくいですね。
次は保存を押したタイミングでTextFieldの中身をクリアになるようにします。
「保存ボタンがタップされた時にTextFieldの中身をクリアにする」が実現したいことです。
保存ボタンがタップされた時の処理はonPressedの{ }の中に記述するんでしたね。
{ } 内に、TextFieldの中身をクリアにするという処理を書きます。
次のコードを追加してください。
nameController.clear();
priceController.clear();

ホットリロードで反映させてからシミュレーターで動きを確認しましょう。
保存ボタンを押したあとに、TextFieldがクリアになりましたね。

最後に、合計金額を表示させる処理を作ります。 あと少しです!頑張りましょう💪
まずは合計金額を入れておくための変数を用意します。
画像を参考にint型の変数totalを定義してください。初期値として0を入れておきます。
int total = 0;

次に一番下の合計金額表示の部分を変更します。今は100で固定になっていますね。

作成した変数totalの値が表示されるようにするため、下の画像のように書き換えます。
totalはint型の変数なので、Textで表示するためには .toStirng()でString型に変換する必要があります。
total.toString()
ホットリロードで反映してみましょう。0円になりました!

ただ、totalの中身が初期値の0になっていますね。
保存ボタンが押されたタイミングで金額が加算されていくようにします。
保存ボタンが押された時の処理なので、ElevantedButtonのonPressedの { } 内に書きます。
画像を参考に一行コードを書いてください。
total = total + _goodsInfo.price;
このコードは「totalにtotal + _goodsInfo.priceを代入する」という意味です。
このような書き方をすることで、合計金額に欲しいものの金額が追加されていきます。
ホットリロードでシミュレーターに反映して動きを確かめてください。
おお!ちゃんと合計金額が計算されて動的に表示されています!感動!
TextFieldにフォーカスを当ててcommand + kを押してください。
キーボードが出てきましたね。

ただ、金額のTextFieldにフォーカスが当たっている時でも言語のキーボードが表示されてしまっています。

金額の方は数字キーボードを表示したいので今からそれをやります。 画像を参考に以下のコードを追加してください。
keyboardType: TextInputType.number,

ホットリロードでシミュレーターに反映して、動きを確かめてください。 おお!数字のキーボードが表示されていますね!
以上で欲しいもの記録アプリは完成です🎉 ボタンのレイアウトを変えたり、背景に色をつけたり、色々と遊んでみてください!