Bagaimana cara menonaktifkan Tombol di Flutter?

116

Saya baru saja mulai memahami Flutter, tetapi saya mengalami masalah dalam mencari tahu cara menyetel status aktif tombol.

Dari dokumen, dikatakan setel onPressedke null untuk menonaktifkan tombol, dan memberinya nilai untuk mengaktifkannya. Ini bagus jika tombol terus berada dalam status yang sama untuk siklus proses.

Saya mendapat kesan bahwa saya perlu membuat widget Stateful khusus yang memungkinkan saya memperbarui status aktif tombol (atau callback onPressed) entah bagaimana.

Jadi pertanyaan saya adalah bagaimana saya melakukannya? Ini sepertinya persyaratan yang cukup mudah, tetapi saya tidak dapat menemukan apa pun di dokumen tentang cara melakukannya.

Terima kasih.

chris84948
sumber
Dapatkah Anda menjelaskan apa yang Anda maksud dengan "Tidak apa-apa jika tombol terus berada dalam status yang sama untuk siklus proses." ?
Seth Ladd

Jawaban:

127

Saya pikir Anda mungkin ingin memperkenalkan beberapa fungsi pembantu ke buildtombol Anda serta widget Stateful bersama dengan beberapa properti untuk dimatikan.

  • Gunakan StatefulWidget / State dan buat variabel untuk menampung kondisi Anda (misalnya isButtonDisabled)
  • Setel ini menjadi benar pada awalnya (jika itu yang Anda inginkan)
  • Saat merender tombol, jangan langsung menyetelonPressed nilainya ke salah satu nullatau beberapa fungsionPressed: () {}
  • Sebaliknya , setel secara kondisional menggunakan terner atau fungsi pembantu (contoh di bawah)
  • Periksa isButtonDisabledsebagai bagian dari kondisional ini dan kembalikan salah satu nullatau beberapa fungsi.
  • Saat tombol ditekan (atau kapan pun Anda ingin menonaktifkan tombol) gunakan setState(() => isButtonDisabled = true)untuk membalik variabel bersyarat.
  • Flutter akan memanggil build()metode lagi dengan status baru dan tombol akan ditampilkan dengan nullpenangan pers dan dinonaktifkan.

Berikut adalah beberapa konteks lainnya menggunakan proyek penghitung Flutter.

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  bool _isButtonDisabled;

  @override
  void initState() {
    _isButtonDisabled = false;
  }

  void _incrementCounter() {
    setState(() {
      _isButtonDisabled = true;
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("The App"),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            _buildCounterButton(),
          ],
        ),
      ),
    );
  }

  Widget _buildCounterButton() {
    return new RaisedButton(
      child: new Text(
        _isButtonDisabled ? "Hold on..." : "Increment"
      ),
      onPressed: _isButtonDisabled ? null : _incrementCounter,
    );
  }
}

Dalam contoh ini saya menggunakan terner sebaris untuk mengatur Textdan secara kondisional onPressed, tetapi mungkin lebih sesuai bagi Anda untuk mengekstrak ini ke dalam fungsi (Anda dapat menggunakan metode yang sama ini untuk mengubah teks tombol juga):

Widget _buildCounterButton() {
    return new RaisedButton(
      child: new Text(
        _isButtonDisabled ? "Hold on..." : "Increment"
      ),
      onPressed: _counterButtonPress(),
    );
  }

  Function _counterButtonPress() {
    if (_isButtonDisabled) {
      return null;
    } else {
      return () {
        // do anything else you may want to here
        _incrementCounter();
      };
    }
  }
Ashton Thomas
sumber
3
Anda perlu menambahkan fungsi panah gemuk sebagai argumen, jika tidak fungsi _incrementCounter () akan langsung dipanggil saat tombol diaktifkan. Dengan cara ini akan benar-benar menunggu sampai tombol diklik: OnPressed akan terlihat seperti ini:onPressed: _isButtonDisabled ? null : () => _incrementCounter
Vit Veres
2
@vitVeres yang biasanya benar tetapi _counterButtonPress () mengembalikan fungsi return () {}jadi ini disengaja. Saya tidak ingin menggunakan panah gemuk di sini karena saya ingin fungsi menjalankan dan mengembalikan nullserta menonaktifkan tombol.
Ashton Thomas
@AshtonThomas Ya, dalam metode yang diekstrak _counterButtonPress () itu persis seperti yang Anda jelaskan, tetapi saya merujuk ke kode dengan operator terner sebelum Anda menyarankan ekstraksi. Dalam contoh pertama Anda, ini akan menyebabkan eksekusi metode _incrementCounter () saat tombol harus diaktifkan. Lain kali saya akan mencoba untuk menunjukkan apa yang saya maksud dengan lebih tepat :)
Vit Veres
30
Apa yang salah dengan menggunakan disabledproperti, tim Flutter? Ini tidak intuitif: - /
Curly
1
cara yang benar adalah dengan AbsorbPointer atau IgnorePointer. Cukup cara widget alih-alih logika dengan menyiapkan onPressed to null.
ejdrian313
95

Menurut dokumen:

"Jika callback onPressed adalah null, maka tombol tersebut akan dinonaktifkan dan secara default akan menyerupai tombol datar di disabledColor."

https://docs.flutter.io/flutter/material/RaisedButton-class.html

Jadi, Anda mungkin melakukan sesuatu seperti ini:

    RaisedButton(
      onPressed: calculateWhetherDisabledReturnsBool() ? null : () => whatToDoOnPressed,
      child: Text('Button text')
    );
Steve Alexander
sumber
2
Dilihat dari dokumentasinya, beginilah cara implementasinya. Dengan properti jawaban yang diterima seperti disabledElevation, disabledColordan DisabledTextColortidak akan berfungsi sebagaimana mestinya.
Joel Broström
Pff terima kasih untuk Steve ini, tidak berencana memeriksa semua kode dari jawaban yang diterima saat ini. @ chris84948, pertimbangkan untuk mengubahnya menjadi jawaban yang diterima.
CularBytes
42

Jawaban sederhananya adalah onPressed : nullmemberikan tombol yang dinonaktifkan.

BINAY THAPA MAGAR
sumber
17

Pengaturan

onPressed: null // disables click

dan

onPressed: () => yourFunction() // enables click
CopsOnRoad
sumber
1
Dalam solusi ini, nilai onPressedselalu berupa fungsi sehingga tombol ditampilkan sebagai 'dapat diklik' meskipun akan mengabaikan peristiwa klik jika isEnabledproperti disetel. Untuk benar-benar menonaktifkan tombol, gunakanRaisedButton(onPressed: isEnabled ? _handleClick : null
Curly
15

Untuk widget dengan jumlah tertentu dan terbatas, menggabungkannya dalam widget IgnorePointer melakukan hal ini: ketika ignoringpropertinya disetel ke true, sub-widget (sebenarnya, seluruh subpohon) tidak dapat diklik.

IgnorePointer(
    ignoring: true, // or false
    child: RaisedButton(
        onPressed: _logInWithFacebook,
        child: Text("Facebook sign-in"),
        ),
),

Jika tidak, jika Anda ingin menonaktifkan seluruh subpohon, lihat AbsorbPointer ().

edmond
sumber
9

Fungsionalitas Aktifkan dan Nonaktifkan sama untuk sebagian besar widget.

Mis, tombol, sakelar, kotak centang, dll.

Cukup atur onPressedproperti seperti yang ditunjukkan di bawah ini

onPressed : nullmengembalikan widget Dinonaktifkan

onPressed : (){}atau onPressed : _functionNamemengembalikan widget yang Diaktifkan

Vicky Salunkhe
sumber
6

Anda juga dapat menggunakan AbsorbPointer, dan Anda dapat menggunakannya dengan cara berikut:

AbsorbPointer(
      absorbing: true, // by default is true
      child: RaisedButton(
        onPressed: (){
          print('pending to implement onPressed function');
        },
        child: Text("Button Click!!!"),
      ),
    ),

Jika Anda ingin tahu lebih banyak tentang widget ini, Anda dapat memeriksa tautan berikut Flutter Docs

Juanes 30
sumber
2
Ignore- / AbsorbPointer tidak menganggap gaya yang dinonaktifkan hanya sebagai PENGINGAT :-)
Pascal
5

Ini cara termudah menurut saya:

RaisedButton(
  child: Text("PRESS BUTTON"),
  onPressed: booleanCondition
    ? () => myTapCallback()
    : null
)
MatPag
sumber