¿Cómo hago el efecto de "vidrio esmerilado" en Flutter?

99

Estoy escribiendo una aplicación Flutter y me gustaría usar / implementar el efecto de "vidrio esmerilado" que es común en iOS. ¿Cómo hago esto?

Seth Ladd
fuente
1
Escribo un artículo para mostrar cómo hacer un efecto de desenfoque en Flutter usando BackdropFilter & ImageFilter - léelo en Medium
anticafe
Puede utilizar el paquete blurrycontainer .
Jon

Respuestas:

172

Puede utilizar el widget BackdropFilter para lograr este efecto.

captura de pantalla

import 'dart:ui';
import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(home: new FrostedDemo()));
}

class FrostedDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Stack(
        children: <Widget>[
          new ConstrainedBox(
            constraints: const BoxConstraints.expand(),
            child: new FlutterLogo()
          ),
          new Center(
            child: new ClipRect(
              child: new BackdropFilter(
                filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
                child: new Container(
                  width: 200.0,
                  height: 200.0,
                  decoration: new BoxDecoration(
                    color: Colors.grey.shade200.withOpacity(0.5)
                  ),
                  child: new Center(
                    child: new Text(
                      'Frosted',
                      style: Theme.of(context).textTheme.display3
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
Collin Jackson
fuente
¿Cómo haría que el efecto escarchado cubriera todo el ancho / alto de la aplicación?
Pieter
2
o, si está intentando utilizar el efecto de vidrio esmerilado como barrera modal para los diálogos, puede modificar su copia de ModalBarrier para incluir un BackdropFilter. github.com/flutter/flutter/blob/master/packages/flutter/lib/src/…
Collin Jackson
Desafortunadamente, el efecto de desenfoque no funciona en dispositivos iOS: github.com/flutter/flutter/issues/10284
Mark
3
iirc, el problema anterior se ha resuelto y el efecto de desenfoque funciona en dispositivos iOS ahora :)
loganrussell48
12

Creo que no sé el significado exacto de 'Frosted' (si mi ejemplo no funcionó aquí),

import 'package:flutter/material.dart';
import 'dart:ui' as ui;

void main() => runApp(
    MaterialApp(
        title: "Frosted glass",
        home: new HomePage()
    )
);

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Stack(
        fit: StackFit.expand,
        children: <Widget>[
          generateBluredImage(),
          new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              rectShapeContainer(),
            ],
          ),
        ],
      ),
    );
  }

  Widget generateBluredImage() {
    return new Container(
      decoration: new BoxDecoration(
        image: new DecorationImage(
          image: new AssetImage('assets/images/huxley-lsd.png'),
          fit: BoxFit.cover,
        ),
      ),
      //I blured the parent container to blur background image, you can get rid of this part
      child: new BackdropFilter(
        filter: new ui.ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
        child: new Container(
          //you can change opacity with color here(I used black) for background.
          decoration: new BoxDecoration(color: Colors.black.withOpacity(0.2)),
        ),
      ),
    );
  }

  Widget rectShapeContainer() {
    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 40.0, vertical: 10.0),
      padding: const EdgeInsets.all(15.0),
      decoration: new BoxDecoration(
        //you can get rid of below line also
        borderRadius: new BorderRadius.circular(10.0),
        //below line is for rectangular shape
        shape: BoxShape.rectangle,
        //you can change opacity with color here(I used black) for rect
        color: Colors.black.withOpacity(0.5),
        //I added some shadow, but you can remove boxShadow also.
        boxShadow: <BoxShadow>[
          new BoxShadow(
            color: Colors.black26,
            blurRadius: 5.0,
            offset: new Offset(5.0, 5.0),
          ),
        ],
      ),
      child: new Column(
        children: <Widget>[
          new Text(
            'There\'s only one corner of the universe you can be certain of improving and that\'s your own self.',
            style: new TextStyle(
              color: Colors.white,
              fontSize: 20.0,
            ),
          ),
        ],
      ),
    );
  }
}

Salir:

ingrese la descripción de la imagen aquí

Espero que esto ayude a alguien.

Blasanka
fuente
1
totalmente ayudado. Me olvidé por completo de la opción 'Apilar' ... muchas gracias.
AhabLives
¿Cómo se puede hacer que el glaseado siga la forma del recipiente principal? que todavía muestran rectangular cuando se añade dentro de un contenedor de forma circular
Kaki maestro del tiempo
@KakiMasterOfTime Creo que no entendí tu pregunta correctamente. Pero si convierte la forma del contenedor rectShape en un círculo eliminando borderRadius, funcionará.
Blasanka
1
Me gusta la cita :-)
santanu bera
0
BackdropFilter(
  filter: ImageFilter.blur(sigmaX: _sigmaX, sigmaY: _sigmaY),
  child: Container(
    color: Colors.black.withOpacity(_opacity),
  ),
),
Mahmoud Hamdy
fuente