secure_text_widget 0.1.1
secure_text_widget: ^0.1.1 copied to clipboard
A Flutter text widget that stays invisible in iOS screenshots, screen recordings, AirPlay mirroring and the App Switcher, while looking like a normal Text.
import 'package:flutter/material.dart';
import 'package:secure_text_widget/secure_text_widget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'SecureText demo',
home: DemoScreen(),
);
}
}
class DemoScreen extends StatefulWidget {
const DemoScreen({super.key});
@override
State<DemoScreen> createState() => _DemoScreenState();
}
class _DemoScreenState extends State<DemoScreen> {
String _text = '4242 4242 4242 4242';
double _fontSize = 22;
Color _color = Colors.black;
FontWeight _weight = FontWeight.w600;
void _cycleColor() {
const palette = [Colors.black, Colors.red, Colors.blue, Colors.green];
setState(() {
_color = palette[(palette.indexOf(_color) + 1) % palette.length];
});
}
void _cycleWeight() {
const weights = [
FontWeight.w300,
FontWeight.w400,
FontWeight.w600,
FontWeight.w800
];
setState(() {
_weight = weights[(weights.indexOf(_weight) + 1) % weights.length];
});
}
@override
Widget build(BuildContext context) {
final style = TextStyle(
fontSize: _fontSize,
fontWeight: _weight,
color: _color,
);
return Scaffold(
appBar: AppBar(title: const Text('SecureText demo')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Regular Text (visible on screenshot):',
style: TextStyle(color: Colors.grey),
),
const SizedBox(height: 8),
Text(_text, style: style),
const SizedBox(height: 32),
const Text(
'SecureText (hidden on screenshot / recording / AirPlay):',
style: TextStyle(color: Colors.grey),
),
const SizedBox(height: 8),
SecureText(_text, style: style),
const Spacer(),
Wrap(
spacing: 12,
runSpacing: 12,
children: [
ElevatedButton(
onPressed: () => setState(() {
_text = _text == '4242 4242 4242 4242'
? 'CVV 123 · 12/28'
: '4242 4242 4242 4242';
}),
child: const Text('Change text'),
),
ElevatedButton(
onPressed: () => setState(() {
_fontSize = _fontSize == 22 ? 32 : 22;
}),
child: const Text('Toggle size'),
),
ElevatedButton(
onPressed: _cycleColor,
child: const Text('Cycle color'),
),
ElevatedButton(
onPressed: _cycleWeight,
child: const Text('Cycle weight'),
),
],
),
const SizedBox(height: 16),
const Text(
'Try: take a screenshot, start a screen recording, or swipe up to the App Switcher. '
'The SecureText line should disappear while the regular Text stays visible.',
style: TextStyle(color: Colors.grey, fontSize: 12),
),
],
),
),
);
}
}