روش دریافت مقدار از TextFormField
دریافت مقدار از ویجت TextFormField یکی از موارد پر کاربرد در طول برنامه نویسی شما می باشد . در لحظه فشرده شدن یک دکمه ، شما باید قادر باشید مقادیر ثبت شده در ویجت های TextFormField را خوانده و مورد استفاده قرار دهید . برای این منظور سه روش در ویجت TextFormField وجود دارد :
- استفاده از خصوصیت onChanged و پاس دادن یک متغییر یا یک CallBack Function
- استفاده از کنترلر از نوع TextEditingController
- استفاده از خصوصیت onSave
روش اول : استفاده از خصوصیت onChanged
در این روش شما می توانید یک CallBack Function در بیرون از ویجت ایجاد و آن را به داخل ویجت پاس دهید و سپس به خصوصیت onChanged ویجت متصل نمایید ، تا در لحظه تحریک رویداد ، شما بتوانید کدهای مورد نظر خود را اجرا و به این وسیله مقدار ثبت شده کاربر را دریافت نمایید . قطعه کد زیر نمونه ای از این روش پیاده سازی را به نمایش گذاشته است :
class MyText extends StatelessWidget { final onChangeValue; MyText({this.onChangeValue}); @override Widget build(BuildContext context) { return TextFormField( onChanged : onChangeValue, ); } } // استفاده از ویجت تعریف شده در بالا var _passwordValue; // تعریف یک کال بک فانکشن جهت دریافت مقدار ثبت شده ویجت MyText(onChangeValue : (String value){ _passwordValue = value; })
روش دوم : استفاده از کنترلر از نوع TextEditingController
جهت دریافت مقدار از ویجت TextFormField به این روش ، باید ابتدا یک کنترلر از نوع TextEditingController تعریف کنید و سپس این کنترلر را به خصوصیت controller ویجت TextFormField متصل نمایید . حال در هر جا که نیاز دارید مقدار ویجت را دریافت نمایید فقط کافیست از خصوصیت text کنترلر استفاده نمایید . قطعه کد زیر روش پیاده سازی این کار را نمایش می دهد :
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); /// This Widget is the main application widget. class MyApp extends StatelessWidget { static const String _title = 'دریافت مقدار از TextFormField'; @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: _title, home: Directionality( textDirection: TextDirection.rtl, child: MyStatefulWidget()), ); } } class MyStatefulWidget extends StatefulWidget { @override _MyStatefulWidgetState createState() => _MyStatefulWidgetState(); } class _MyStatefulWidgetState extends State<MyStatefulWidget> { // تعریف کنترلر TextEditingController _controller = TextEditingController(); // تعریف کلید اختصاصی var _scaffoldKey = GlobalKey<ScaffoldState>(); void dispose() { // جهت مدیریت حافظه بهتر است در لحظه اتمام کار ویجت ، کنترلر نیز آزاد شود _controller.dispose(); super.dispose(); } Widget build(BuildContext context) { return Scaffold( // استفاده از کلید اختصاصی key: _scaffoldKey, appBar: AppBar( title: Text('دریافت مقدار از TextField'), ), body: Center( child: Padding( padding: const EdgeInsets.all(40), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ TextFormField( // اتصال کنترلر به خصوصیت کنترلر controller: _controller, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(8))), ), SizedBox(height: 40,), RaisedButton( onPressed: () { setState(() { _scaffoldKey.currentState.showSnackBar(SnackBar( content: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Icon(Icons.favorite_border,size: 30,), Text('مقدار ثبت شده : ${_controller.text}',style: TextStyle(fontSize: 20),), ], ), )); }); }, child: Text('دریافت اطلاعات'), ) ], ), ), ), ); } }
خروجی کد فوق در تصویر زیر قابل مشاهده است :
حالا که به ویجت TextFormField یک controller متصل کرده اید ، در صورت نیاز می توانید از یک شنونده (listener) نیز استفاده نمایید . شنونده به شما این امکان را می دهد تا در لحظه فشرده شدن هر کلید مقدار ورودی را دریافت و نسبت به آن تصمیم گیری نمایید . ( به عنوان مثال از درج کاراکترهای خاص جلوگیری نمایید )
در این رابطه می توانید در مقاله زیر مطالب مفیدی را مطالعه نمایید :
روش سوم : استفاده از خصوصیت onSave
در این روش شما می توانید یک CallBack Function در بیرون از ویجت ایجاد و آن را به داخل ویجت پاس دهید و سپس به خصوصیت onSave ویجت TextFormField متصل نمایید ، تا در لحظه تحریک رویداد ، شما بتوانید کدهای مورد نظر خود را اجرا و به این وسیله مقدار ثبت شده کاربر را دریافت نمایید . قطعه کد زیر نمونه ای از این روش پیاده سازی را به نمایش گذاشته است :
class MyText extends StatelessWidget { final onSaveValue; MyText({this.onSaveValue}); @override Widget build(BuildContext context) { return TextFormField( onSaved: onSaveValue, ); } } // استفاده از ویجت تعریف شده در بالا var _passwordValue; // تعریف یک کال بک فانکشن جهت دریافت مقدار ثبت شده ویجت MyText(onSaveValue : (String value){ _passwordValue = value; })
جهت کسب اطلاعات بیشتر از این آدرس به سایت اصلی فلاتر مراجعه نمایید .
امیدوارم این مطلب برای شما مفید باشد .
4 نظر
سلام. ممنون از بابت مقالتون. من اصلا درست متوجه نشدم این مواری که برای استفاده از خصوصیت onSave رو نوشتید
یعنی این متد اصلا چیکار میکنه یعنی چی که فرم رو ذخیره میکنه. کجا ذخیره میشه؟ چطوری ذخیره میشه؟ من اگه یه فرم داشته باشم باید با این متد هر چی وارد کرده رو بتونم دریافت کنم که مثلا کاری با اونها انجام بدم؟
با سلام و احترام
خصوصیت onSave قرار نیست چیزی را ذخیره کند . ( گرچه ممکن است اسم این خصوصیت قدری غلط انداز باشد )
این خصوصیت تابعی را که ما بیرون ویجت تعریف کردیم فراخوانی و مقدار موجود در ویجت TextFormField را به آن تابع پاس می دهد ، که در آن تابع شما با مقدار دریافتی هر کاری می توانید بکنید ، در یک فیلد ذخیره کنید و یا به سمت سرور پاس دهید .
امیدوارم توضیح من ابهام شما را بر طرف کرده باشد .
خیلی ممنون از توضیحاتتون، با این تفاسیر فرق onChanged با onSaved چیه؟
با سلام و احترام
رویداد onChanged با هر بار فشرده شدن دکمه از صفحه کلید ، یکبار فراخوانی می شود و معمولا در زمانی که مایلید در حین تایپ کردن کاربر ، کنترلی رو مقدار ورودی داشته باشید کاربرد دارد .
در حالی که رویداد onSaved در انتهای تکمیل فرم ، فراخوانی می شود و مقدار کامل داخل ویجت را برمی گرداند . همچنین با فراخوانی رویداد onSaved مربوط به فرم می توانید مقادیر تمام ویجت های روی فرم را در یک حرکت دریافت نمایید . ( یعنی رویداد onSaved تمام ویجت ها تحریک شده و مقدارشان را به تابعی که به آنها متصل است ارسال می کنند )