Làm cách nào để tắt một Nút trong Flutter?


115

Tôi chỉ mới bắt đầu hiểu về Flutter, nhưng tôi đang gặp khó khăn khi tìm cách đặt trạng thái được bật của một nút.

Từ tài liệu, nó cho biết đặt onPressedthành null để tắt một nút và cung cấp cho nó một giá trị để bật nó. Điều này tốt nếu nút tiếp tục ở trạng thái cũ trong vòng đời.

Tôi có ấn tượng rằng tôi cần tạo một tiện ích Stateful tùy chỉnh sẽ cho phép tôi cập nhật trạng thái đã bật của nút (hoặc gọi lại onPressed) bằng cách nào đó.

Vì vậy, câu hỏi của tôi là làm thế nào tôi sẽ làm điều đó? Đây có vẻ như là một yêu cầu khá đơn giản, nhưng tôi không thể tìm thấy bất kỳ điều gì trong tài liệu về cách thực hiện.

Cảm ơn.


Bạn có thể làm rõ ý của bạn bằng cách "Điều này là tốt nếu nút tiếp tục ở trạng thái tương tự trong vòng đời." ?
Seth Ladd

Câu trả lời:


127

Tôi nghĩ rằng bạn có thể muốn giới thiệu một số chức năng trợ giúp cho buildnút của mình cũng như tiện ích Stateful cùng với một số thuộc tính để khóa.

  • Sử dụng StatefulWidget / State và tạo một biến để giữ điều kiện của bạn (ví dụ isButtonDisabled:)
  • Đặt điều này thành true ban đầu (nếu đó là điều bạn mong muốn)
  • Khi hiển thị nút, không đặt trực tiếponPressed giá trị cho một nullhoặc một số chức năngonPressed: () {}
  • Thay vào đó , hãy đặt nó có điều kiện bằng cách sử dụng hàm bậc ba hoặc hàm trợ giúp (ví dụ bên dưới)
  • Kiểm tra isButtonDisablednhư một phần của điều kiện này và trả về một nullhoặc một số hàm.
  • Khi nút được nhấn (hoặc bất cứ khi nào bạn muốn tắt nút) sử dụng setState(() => isButtonDisabled = true)để lật biến điều kiện.
  • Flutter sẽ gọi lại build()phương thức với trạng thái mới và nút sẽ được hiển thị bằng nulltrình xử lý báo chí và bị vô hiệu hóa.

Đây là một số ngữ cảnh khác sử dụng dự án bộ đếm 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,
    );
  }
}

Trong ví dụ này, tôi đang sử dụng một bậc ba nội dòng để đặt có điều kiện TextonPressed, nhưng có thể thích hợp hơn để bạn trích xuất nó thành một hàm (bạn cũng có thể sử dụng cùng một phương pháp này để thay đổi văn bản của nút):

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();
      };
    }
  }

3
Bạn cần thêm hàm fat arrow làm đối số, nếu không hàm _incrementCounter () sẽ được gọi ngay lập tức khi nút được bật. Bằng cách này, nó thực sự sẽ chờ cho đến khi nút được click: Các onPressed sẽ trông như thế này:onPressed: _isButtonDisabled ? null : () => _incrementCounter
Vit Veres

2
@vitVeres thường đúng nhưng _counterButtonPress () đang trả về một hàm return () {}nên điều này là cố ý. Tôi không muốn sử dụng mũi tên béo ở đây vì tôi muốn hàm thực thi và trả về nullvà tắt nút.
Ashton Thomas

@AshtonThomas Vâng, trong phương thức trích xuất _counterButtonPress (), nó chính xác như bạn đã giải thích, nhưng tôi đã tham chiếu đến mã bằng toán tử bậc ba trước khi bạn đề xuất trích xuất. Trong ví dụ đầu tiên của bạn, nó sẽ gây ra việc thực thi phương thức _incrementCounter () khi nút được bật. Lần sau tôi sẽ cố gắng chỉ ra những gì tôi muốn nói chính xác hơn :)
Vit Veres

30
Điều gì đã xảy ra với việc sử dụng một thuộc disabledtính, nhóm Flutter? Điều này không phải là trực quan: - /
Curly

1
cách chính xác là với AbsorbPointer hoặc bỏ quaPointer. Đơn giản là cách widget thay vì logic với việc thiết lập onPressed thành null.
ejdrian313

93

Theo tài liệu:

"Nếu lệnh gọi lại onPressed là null, thì nút này sẽ bị vô hiệu hóa và theo mặc định sẽ giống với một nút phẳng trong màu vô hiệu hóa."

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

Vì vậy, bạn có thể làm điều gì đó như sau:

    RaisedButton(
      onPressed: calculateWhetherDisabledReturnsBool() ? null : () => whatToDoOnPressed,
      child: Text('Button text')
    );

2
Đánh giá từ các tài liệu, đây là cách nó được thực hiện. Với các thuộc tính câu trả lời được chấp nhận như disabledElevation, disabledColorDisabledTextColorsẽ không hoạt động như dự định.
Joel Broström

Pff cảm ơn vì Steve này, đã không có kế hoạch xem qua tất cả các mã của câu trả lời hiện được chấp nhận. @ chris84948, hãy cân nhắc thay đổi câu trả lời này thành câu trả lời được chấp nhận.
CularBytes


17

Cài đặt

onPressed: null // disables click

onPressed: () => yourFunction() // enables click

1
Trong giải pháp này, giá trị của onPressedluôn là một hàm để nút được hiển thị là 'có thể nhấp' mặc dù nó sẽ bỏ qua sự kiện nhấp nếu thuộc isEnabledtính được đặt. Để thực sự vô hiệu hóa nút, hãy sử dụngRaisedButton(onPressed: isEnabled ? _handleClick : null
Curly

15

Đối với một số tiện ích cụ thể và có giới hạn, việc gói chúng trong một widget Bỏ qua điểm chính thực hiện điều này: khi thuộc tính của nó ignoringđược đặt thành true, tiện ích con (thực tế là toàn bộ cây con) không thể nhấp được.

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

Ngược lại, nếu bạn định vô hiệu hóa toàn bộ cây con, hãy xem AbsorbPointer ().


9

Chức năng Bật và Tắt giống nhau đối với hầu hết các tiện ích.

Ví dụ: nút, công tắc, hộp kiểm, v.v.

Chỉ cần đặt thuộc onPressedtính như hình dưới đây

onPressed : nulltrả về tiện ích bị vô hiệu hóa

onPressed : (){}hoặc onPressed : _functionNametrả về tiện ích đã bật


6

Bạn cũng có thể sử dụng AbsorbPointer và bạn có thể sử dụng nó theo cách sau:

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

Nếu bạn muốn biết thêm về tiện ích này, bạn có thể kiểm tra liên kết sau Flutter Docs


2
Bỏ qua- / AbsorbPointer không coi các kiểu bị vô hiệu hóa chỉ là một LỜI NHẮC :-)
Pascal

4

Đây là cách dễ nhất theo ý kiến ​​của tôi:

RaisedButton(
  child: Text("PRESS BUTTON"),
  onPressed: booleanCondition
    ? () => myTapCallback()
    : null
)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.