1659562380
Na maioria das vezes, preencher formulários com muitos campos pode ser trabalhoso, e isso pode desencorajar os usuários a concluir o processo. É aqui que entra em jogo um formulário de várias etapas.
Os formulários de várias etapas são exatamente como o nome indica: um formulário de várias etapas é um formulário longo dividido em partes curtas. Eles fornecem uma experiência menos assustadora para os usuários do seu aplicativo.
O Flutter vem pré-empacotado com um widget Stepper que nos dá a capacidade de dividir nosso formulário em uma lista de etapas. Neste artigo, exploraremos o que realmente é um widget Stepper e como aplicá-lo na criação de um formulário de várias etapas no Flutter para aprimorar a experiência do usuário. Você também aprenderá a personalizar um widget Stepper para atender às especificações do seu aplicativo móvel.
Estas são algumas das propriedades essenciais do widget Stepper. Também os mostraremos em ação por meio da demonstração, mas você pode revisá-los aqui antes de começarmos:
StepperType.horizontal
ou StepperType.vertical
) — Isso determina a orientação e como cada etapa seria colocada, uma em relação à outracurrentStep
— O valor de índice do passo (0, 1, 2, etc.). Define a etapa ativa no formulárioonStepContinue()
— Um botão de retorno de chamada quando continuar, para passar para a próxima etapaonStepCancel()
— Um botão de retorno de chamada ao cancelar, para ir para a etapa anterioronStepTapped
(int index) — Um retorno de chamada para quando o usuário toca nas etapas, para mover para a etapa selecionada em andamento. O retorno de chamada também nos fornece o índice da etapa em que o usuário clicaList<Step>
— Os passos de um stepper cujo título e conteúdo são mostrados quando o respectivo passo éActive
Para detalhar ainda mais, as propriedades de uma etapa em si são:
title
— Use esta propriedade para dar título à etapa. Esta propriedade é obrigatória e aceita um widget como valor, geralmente um widget de textosubtitle
— Use esta propriedade para adicionar uma legenda à etapa. Ele aceita um widget como valor, geralmente um widget de textocontent
— Usaremos essa propriedade para fornecer conteúdo para a etapa. É uma propriedade obrigatória e aceita qualquer widget como valorstate
— Use esta propriedade para definir o estado da etapa como completed
, disabled
, editing
, indexed
ou error
. Com base no estado, os ícones das etapas serão alteradosisActive
— Use esta propriedade para indicar se a etapa está ativa ou inativa. Aceita um booleano como valorAgora, vamos criar um novo projeto Flutter que mostra como aplicar o widget Stepper.
O estado inicial do nosso formulário seria algo como a imagem que temos abaixo. No entanto, usaremos o widget Stepper para dividir isso em várias etapas, para que o usuário não fique sobrecarregado com o número de campos que precisam preencher.
Temos os widgets personalizados reutilizáveis, que criamos.
Temos o nosso main.dart file
, que tem o seguinte conteúdo:
import 'package:flutter/material.dart';
import 'package:stepper_widget/form_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const FormPage(),
);
}
}
Nosso FormPage
widget abriga estes conteúdos:
import 'package:flutter/material.dart';
import 'package:stepper_widget/widgets/custom_button.dart';
import 'package:stepper_widget/widgets/custom_input.dart';
class FormPage extends StatefulWidget {
const FormPage({Key? key}) : super(key: key);
@override
_FormPageState createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(
"Stepper Widget ",
),
centerTitle: true,
),
body: Container(
padding: const EdgeInsets.all(20),
child: ListView(
children: [
const CustomInput(
hint: "First Name",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Last Name",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Address",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "City and State",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
CustomBtn(
title: const Text(
"Save",
style: TextStyle(color: Colors.white),
),
callback: () {},
)
],
),
),
),
);
}
}
Nosso CustomInput
:
import 'package:flutter/material.dart';
class CustomInput extends StatelessWidget {
final ValueChanged<String>? onChanged;
final String? hint;
final InputBorder? inputBorder;
const CustomInput({Key? key, this.onChanged, this.hint, this.inputBorder})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
child: TextField(
onChanged: (v) => onChanged!(v),
decoration: InputDecoration(hintText: hint!, border: inputBorder),
),
);
}
}
E por último é o nosso botão personalizado, CustomBtn
:
import 'package:flutter/material.dart';
class CustomBtn extends StatelessWidget {
final Function? callback;
final Widget? title;
CustomBtn({Key? key, this.title, this.callback}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
child: SizedBox(
width: double.infinity,
child: Container(
color: Colors.blue,
child: TextButton(
onPressed: () => callback!(),
child: title!,
),
),
),
);
}
}
Para usar nosso widget Stepper, começaremos criando uma lista de etapas.
Como já definimos alguns dos recursos importantes de um widget de Stepper, não vamos nos aprofundar muito nisso aqui. Podemos pular direto:
List<Step> getSteps() {
return <Step>[
Step(
state: currentStep > 0 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 0,
title: const Text("Account Info"),
content: Column(
children: const [
CustomInput(
hint: "First Name",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Last Name",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 1 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 1,
title: const Text("Address"),
content: Column(
children: const [
CustomInput(
hint: "City and State",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Postal Code",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 2 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 2,
title: const Text("Misc"),
content: Column(
children: const [
CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
],
),
),
];
}
Depois de criar as etapas necessárias para nosso widget Stepper, agora podemos substituir o ListView
em nosso formpage.dart
. Mas antes disso, vamos ver o que cada campo de nossa única etapa representa.
A primeira propriedade que temos para um único passo é state
: você deve se lembrar que isso define o ícone principal no passo, conforme mostrado na imagem abaixo. Quando um usuário termina de editar os campos em uma etapa específica e passa para a próxima etapa, a etapa anterior é marcada como concluída na state
propriedade e a etapa atual é marcada indexed
, o que significa simplesmente que o usuário está editando ativamente essa etapa.
A isActive
propriedade é simplesmente usada para mostrar qual das etapas está sendo visualizada no momento pelo usuário. O title
pega um widget e o mostra no topo de cada uma das etapas, enquanto o conteúdo de cada etapa são os widgets de formulário reais com os quais queremos que o usuário interaja.
Depois de substituir nosso Listview
widget anterior pelo Stepper
, é assim que nosso código se parece:
import 'package:flutter/material.dart';
import 'package:stepper_widget/widgets/custom_input.dart';
class FormPage extends StatefulWidget {
const FormPage({Key? key}) : super(key: key);
@override
_FormPageState createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
int currentStep = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(
"Stepper Widget ",
),
centerTitle: true,
),
body: Container(
padding: const EdgeInsets.all(20),
child: Stepper(
type: StepperType.horizontal,
currentStep: currentStep,
onStepCancel: () => currentStep == 0
? null
: setState(() {
currentStep -= 1;
}),
onStepContinue: () {
bool isLastStep = (currentStep == getSteps().length - 1);
if (isLastStep) {
//Do something with this information
} else {
setState(() {
currentStep += 1;
});
}
},
onStepTapped: (step) => setState(() {
currentStep = step;
}),
steps: getSteps(),
)),
),
);
}
List<Step> getSteps() {
return <Step>[
Step(
state: currentStep > 0 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 0,
title: const Text("Account Info"),
content: Column(
children: const [
CustomInput(
hint: "First Name",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Last Name",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 1 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 1,
title: const Text("Address"),
content: Column(
children: const [
CustomInput(
hint: "City and State",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Postal Code",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 2 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 2,
title: const Text("Misc"),
content: Column(
children: const [
CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
],
),
),
];
}
}
Agora vamos percorrer cada uma das propriedades que definimos em nosso widget Stepper.
Começando com o type
, definimos como o conteúdo do nosso widget Stepper deve ser disposto dentro do stepper. Para os tipos de etapas verticais e horizontais, é assim que nosso widget Stepper se pareceria:
CurrentStep
simplesmente recebe o valor do índice da etapa que está atualmente visível para o usuário.
OnStepCancel
é o retorno de chamada implementado sempre que um usuário do nosso formulário clica no botão Voltar, e no momento estamos fazendo uma verificação para evitar que o botão fique ativo na primeira etapa.
onStepContinue
é o retorno de chamada em nosso botão continuar. Aqui também temos uma verificação para saber quando o usuário está na última etapa, e aqui podemos realizar a ação necessária usando as informações que nos são fornecidas.
OnStepTapped
retorna a etapa em que o usuário clica, e podemos ativá-la definindo-a como o valor da etapa atual.
Outras coisas que podem ser feitas em nosso widget Stepper para fornecer mais personalizações incluem adicionar um tema personalizado ou implementar nossos próprios botões de controle personalizados, que são os botões Avançar e Continuar atuais que temos. Para isso, basta usar a theme
propriedade e a controlsBuilder
propriedade do nosso widget Stepper.
O uso de um formulário de várias etapas pode melhorar significativamente a experiência do usuário e aumentar o apelo visual de nossos designs.
O widget Stepper no Flutter vem em socorro em situações em que isso é necessário e nos fornece muitas personalizações úteis para obter os resultados que desejamos sem depender de bibliotecas de terceiros.
Fonte: https://blog.logrocket.com/creating-multistep-form-flutter-stepper-widget/
1597014000
Flutter Google cross-platform UI framework has released a new version 1.20 stable.
Flutter is Google’s UI framework to make apps for Android, iOS, Web, Windows, Mac, Linux, and Fuchsia OS. Since the last 2 years, the flutter Framework has already achieved popularity among mobile developers to develop Android and iOS apps. In the last few releases, Flutter also added the support of making web applications and desktop applications.
Last month they introduced the support of the Linux desktop app that can be distributed through Canonical Snap Store(Snapcraft), this enables the developers to publish there Linux desktop app for their users and publish on Snap Store. If you want to learn how to Publish Flutter Desktop app in Snap Store that here is the tutorial.
Flutter 1.20 Framework is built on Google’s made Dart programming language that is a cross-platform language providing native performance, new UI widgets, and other more features for the developer usage.
Here are the few key points of this release:
In this release, they have got multiple performance improvements in the Dart language itself. A new improvement is to reduce the app size in the release versions of the app. Another performance improvement is to reduce junk in the display of app animation by using the warm-up phase.
If your app is junk information during the first run then the Skia Shading Language shader provides for pre-compilation as part of your app’s build. This can speed it up by more than 2x.
Added a better support of mouse cursors for web and desktop flutter app,. Now many widgets will show cursor on top of them or you can specify the type of supported cursor you want.
Autofill was already supported in native applications now its been added to the Flutter SDK. Now prefilled information stored by your OS can be used for autofill in the application. This feature will be available soon on the flutter web.
A new widget for interaction
InteractiveViewer
is a new widget design for common interactions in your app like pan, zoom drag and drop for resizing the widget. Informations on this you can check more on this API documentation where you can try this widget on the DartPad. In this release, drag-drop has more features added like you can know precisely where the drop happened and get the position.
In this new release, there are many pre-existing widgets that were updated to match the latest material guidelines, these updates include better interaction with Slider
and RangeSlider
, DatePicker
with support for date range and time picker with the new style.
pubspec.yaml
formatOther than these widget updates there is some update within the project also like in pubspec.yaml
file format. If you are a flutter plugin publisher then your old pubspec.yaml
is no longer supported to publish a plugin as the older format does not specify for which platform plugin you are making. All existing plugin will continue to work with flutter apps but you should make a plugin update as soon as possible.
Visual Studio code flutter extension got an update in this release. You get a preview of new features where you can analyze that Dev tools in your coding workspace. Enable this feature in your vs code by _dart.previewEmbeddedDevTools_
setting. Dart DevTools menu you can choose your favorite page embed on your code workspace.
The updated the Dev tools comes with the network page that enables network profiling. You can track the timings and other information like status and content type of your** network calls** within your app. You can also monitor gRPC traffic.
Pigeon is a command-line tool that will generate types of safe platform channels without adding additional dependencies. With this instead of manually matching method strings on platform channel and serializing arguments, you can invoke native class and pass nonprimitive data objects by directly calling the Dart
method.
There is still a long list of updates in the new version of Flutter 1.2 that we cannot cover in this blog. You can get more details you can visit the official site to know more. Also, you can subscribe to the Navoki newsletter to get updates on these features and upcoming new updates and lessons. In upcoming new versions, we might see more new features and improvements.
You can get more free Flutter tutorials you can follow these courses:
#dart #developers #flutter #app developed #dart devtools in visual studio code #firebase local emulator suite in flutter #flutter autofill #flutter date picker #flutter desktop linux app build and publish on snapcraft store #flutter pigeon #flutter range slider #flutter slider #flutter time picker #flutter tutorial #flutter widget #google flutter #linux #navoki #pubspec format #setup flutter desktop on windows
1598396940
Flutter is an open-source UI toolkit for mobile developers, so they can use it to build native-looking** Android and iOS** applications from the same code base for both platforms. Flutter is also working to make Flutter apps for Web, PWA (progressive Web-App) and Desktop platform (Windows,macOS,Linux).
Flutter was officially released in December 2018. Since then, it has gone a much stronger flutter community.
There has been much increase in flutter developers, flutter packages, youtube tutorials, blogs, flutter examples apps, official and private events, and more. Flutter is now on top software repos based and trending on GitHub.
What is Flutter? this question comes to many new developer’s mind.
Flutter means flying wings quickly, and lightly but obviously, this doesn’t apply in our SDK.
So Flutter was one of the companies that were acquired by **Google **for around $40 million. That company was based on providing gesture detection and recognition from a standard webcam. But later when the Flutter was going to release in alpha version for developer it’s name was Sky, but since Google already owned Flutter name, so they rename it to Flutter.
Flutter is used in many startup companies nowadays, and even some MNCs are also adopting Flutter as a mobile development framework. Many top famous companies are using their apps in Flutter. Some of them here are
and many more other apps. Mobile development companies also adopted Flutter as a service for their clients. Even I was one of them who developed flutter apps as a freelancer and later as an IT company for mobile apps.
#dart #flutter #uncategorized #flutter framework #flutter jobs #flutter language #flutter meaning #flutter meaning in hindi #google flutter #how does flutter work #what is flutter
1657107416
The era of mobile app development has completely changed the scenario for businesses in regions like Abu Dhabi. Restaurants and food delivery businesses are experiencing huge benefits via smart business applications. The invention and development of the food ordering app have helped all-scale businesses reach new customers and boost sales and profit.
As a result, many business owners are searching for the best restaurant mobile app development company in Abu Dhabi. If you are also searching for the same, this article is helpful for you. It will let you know the step-by-step process to hire the right team of restaurant mobile app developers.
Searching for the top mobile app development company in Abu Dhabi? Don't know the best way to search for professionals? Don't panic! Here is the step-by-step process to hire the best professionals.
#Step 1 – Know the Company's Culture
Knowing the organization's culture is very crucial before finalizing a food ordering app development company in Abu Dhabi. An organization's personality is shaped by its common beliefs, goals, practices, or company culture. So, digging into the company culture reveals the core beliefs of the organization, its objectives, and its development team.
Now, you might be wondering, how will you identify the company's culture? Well, you can take reference from the following sources –
#Step 2 - Refer to Clients' Reviews
Another best way to choose the On-demand app development firm for your restaurant business is to refer to the clients' reviews. Reviews are frequently available on the organization's website with a tag of "Reviews" or "Testimonials." It's important to read the reviews as they will help you determine how happy customers are with the company's app development process.
You can also assess a company's abilities through reviews and customer testimonials. They can let you know if the mobile app developers create a valuable app or not.
#Step 3 – Analyze the App Development Process
Regardless of the company's size or scope, adhering to the restaurant delivery app development process will ensure the success of your business application. Knowing the processes an app developer follows in designing and producing a top-notch app will help you know the working process. Organizations follow different app development approaches, so getting well-versed in the process is essential before finalizing any mobile app development company.
#Step 4 – Consider Previous Experience
Besides considering other factors, considering the previous experience of the developers is a must. You can obtain a broad sense of the developer's capacity to assist you in creating a unique mobile application for a restaurant business.
You can also find out if the developers' have contributed to the creation of other successful applications or not. It will help you know the working capacity of a particular developer or organization. Prior experience is essential to evaluating their work. For instance, whether they haven't previously produced an app similar to yours or not.
#Step 5 – Check for Their Technical Support
As you expect a working and successful restaurant mobile app for your business, checking on this factor is a must. A well-established organization is nothing without a good technical support team. So, ensure whatever restaurant mobile app development company you choose they must be well-equipped with a team of dedicated developers, designers, and testers.
Strong tech support from your mobile app developers will help you identify new bugs and fix them bugs on time. All this will ensure the application's success.
#Step 6 – Analyze Design Standards
Besides focusing on an organization's development, testing, and technical support, you should check the design standards. An appealing design is crucial in attracting new users and keeping the existing ones stick to your services. So, spend some time analyzing the design standards of an organization. Now, you might be wondering, how will you do it? Simple! By looking at the organization's portfolio.
Whether hiring an iPhone app development company or any other, these steps apply to all. So, don't miss these steps.
#Step 7 – Know Their Location
Finally, the last yet very crucial factor that will not only help you finalize the right person for your restaurant mobile app development but will also decide the mobile app development cost. So, you have to choose the location of the developers wisely, as it is a crucial factor in defining the cost.
Summing Up!!!
Restaurant mobile applications have taken the food industry to heights none have ever considered. As a result, the demand for restaurant mobile app development companies has risen greatly, which is why businesses find it difficult to finalize the right person. But, we hope that after referring to this article, it will now be easier to hire dedicated developers under the desired budget. So, begin the hiring process now and get a well-craft food ordering app in hand.
1659562380
Na maioria das vezes, preencher formulários com muitos campos pode ser trabalhoso, e isso pode desencorajar os usuários a concluir o processo. É aqui que entra em jogo um formulário de várias etapas.
Os formulários de várias etapas são exatamente como o nome indica: um formulário de várias etapas é um formulário longo dividido em partes curtas. Eles fornecem uma experiência menos assustadora para os usuários do seu aplicativo.
O Flutter vem pré-empacotado com um widget Stepper que nos dá a capacidade de dividir nosso formulário em uma lista de etapas. Neste artigo, exploraremos o que realmente é um widget Stepper e como aplicá-lo na criação de um formulário de várias etapas no Flutter para aprimorar a experiência do usuário. Você também aprenderá a personalizar um widget Stepper para atender às especificações do seu aplicativo móvel.
Estas são algumas das propriedades essenciais do widget Stepper. Também os mostraremos em ação por meio da demonstração, mas você pode revisá-los aqui antes de começarmos:
StepperType.horizontal
ou StepperType.vertical
) — Isso determina a orientação e como cada etapa seria colocada, uma em relação à outracurrentStep
— O valor de índice do passo (0, 1, 2, etc.). Define a etapa ativa no formulárioonStepContinue()
— Um botão de retorno de chamada quando continuar, para passar para a próxima etapaonStepCancel()
— Um botão de retorno de chamada ao cancelar, para ir para a etapa anterioronStepTapped
(int index) — Um retorno de chamada para quando o usuário toca nas etapas, para mover para a etapa selecionada em andamento. O retorno de chamada também nos fornece o índice da etapa em que o usuário clicaList<Step>
— Os passos de um stepper cujo título e conteúdo são mostrados quando o respectivo passo éActive
Para detalhar ainda mais, as propriedades de uma etapa em si são:
title
— Use esta propriedade para dar título à etapa. Esta propriedade é obrigatória e aceita um widget como valor, geralmente um widget de textosubtitle
— Use esta propriedade para adicionar uma legenda à etapa. Ele aceita um widget como valor, geralmente um widget de textocontent
— Usaremos essa propriedade para fornecer conteúdo para a etapa. É uma propriedade obrigatória e aceita qualquer widget como valorstate
— Use esta propriedade para definir o estado da etapa como completed
, disabled
, editing
, indexed
ou error
. Com base no estado, os ícones das etapas serão alteradosisActive
— Use esta propriedade para indicar se a etapa está ativa ou inativa. Aceita um booleano como valorAgora, vamos criar um novo projeto Flutter que mostra como aplicar o widget Stepper.
O estado inicial do nosso formulário seria algo como a imagem que temos abaixo. No entanto, usaremos o widget Stepper para dividir isso em várias etapas, para que o usuário não fique sobrecarregado com o número de campos que precisam preencher.
Temos os widgets personalizados reutilizáveis, que criamos.
Temos o nosso main.dart file
, que tem o seguinte conteúdo:
import 'package:flutter/material.dart';
import 'package:stepper_widget/form_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const FormPage(),
);
}
}
Nosso FormPage
widget abriga estes conteúdos:
import 'package:flutter/material.dart';
import 'package:stepper_widget/widgets/custom_button.dart';
import 'package:stepper_widget/widgets/custom_input.dart';
class FormPage extends StatefulWidget {
const FormPage({Key? key}) : super(key: key);
@override
_FormPageState createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(
"Stepper Widget ",
),
centerTitle: true,
),
body: Container(
padding: const EdgeInsets.all(20),
child: ListView(
children: [
const CustomInput(
hint: "First Name",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Last Name",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Address",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "City and State",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
const CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
CustomBtn(
title: const Text(
"Save",
style: TextStyle(color: Colors.white),
),
callback: () {},
)
],
),
),
),
);
}
}
Nosso CustomInput
:
import 'package:flutter/material.dart';
class CustomInput extends StatelessWidget {
final ValueChanged<String>? onChanged;
final String? hint;
final InputBorder? inputBorder;
const CustomInput({Key? key, this.onChanged, this.hint, this.inputBorder})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
child: TextField(
onChanged: (v) => onChanged!(v),
decoration: InputDecoration(hintText: hint!, border: inputBorder),
),
);
}
}
E por último é o nosso botão personalizado, CustomBtn
:
import 'package:flutter/material.dart';
class CustomBtn extends StatelessWidget {
final Function? callback;
final Widget? title;
CustomBtn({Key? key, this.title, this.callback}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
child: SizedBox(
width: double.infinity,
child: Container(
color: Colors.blue,
child: TextButton(
onPressed: () => callback!(),
child: title!,
),
),
),
);
}
}
Para usar nosso widget Stepper, começaremos criando uma lista de etapas.
Como já definimos alguns dos recursos importantes de um widget de Stepper, não vamos nos aprofundar muito nisso aqui. Podemos pular direto:
List<Step> getSteps() {
return <Step>[
Step(
state: currentStep > 0 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 0,
title: const Text("Account Info"),
content: Column(
children: const [
CustomInput(
hint: "First Name",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Last Name",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 1 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 1,
title: const Text("Address"),
content: Column(
children: const [
CustomInput(
hint: "City and State",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Postal Code",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 2 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 2,
title: const Text("Misc"),
content: Column(
children: const [
CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
],
),
),
];
}
Depois de criar as etapas necessárias para nosso widget Stepper, agora podemos substituir o ListView
em nosso formpage.dart
. Mas antes disso, vamos ver o que cada campo de nossa única etapa representa.
A primeira propriedade que temos para um único passo é state
: você deve se lembrar que isso define o ícone principal no passo, conforme mostrado na imagem abaixo. Quando um usuário termina de editar os campos em uma etapa específica e passa para a próxima etapa, a etapa anterior é marcada como concluída na state
propriedade e a etapa atual é marcada indexed
, o que significa simplesmente que o usuário está editando ativamente essa etapa.
A isActive
propriedade é simplesmente usada para mostrar qual das etapas está sendo visualizada no momento pelo usuário. O title
pega um widget e o mostra no topo de cada uma das etapas, enquanto o conteúdo de cada etapa são os widgets de formulário reais com os quais queremos que o usuário interaja.
Depois de substituir nosso Listview
widget anterior pelo Stepper
, é assim que nosso código se parece:
import 'package:flutter/material.dart';
import 'package:stepper_widget/widgets/custom_input.dart';
class FormPage extends StatefulWidget {
const FormPage({Key? key}) : super(key: key);
@override
_FormPageState createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
int currentStep = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(
"Stepper Widget ",
),
centerTitle: true,
),
body: Container(
padding: const EdgeInsets.all(20),
child: Stepper(
type: StepperType.horizontal,
currentStep: currentStep,
onStepCancel: () => currentStep == 0
? null
: setState(() {
currentStep -= 1;
}),
onStepContinue: () {
bool isLastStep = (currentStep == getSteps().length - 1);
if (isLastStep) {
//Do something with this information
} else {
setState(() {
currentStep += 1;
});
}
},
onStepTapped: (step) => setState(() {
currentStep = step;
}),
steps: getSteps(),
)),
),
);
}
List<Step> getSteps() {
return <Step>[
Step(
state: currentStep > 0 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 0,
title: const Text("Account Info"),
content: Column(
children: const [
CustomInput(
hint: "First Name",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Last Name",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 1 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 1,
title: const Text("Address"),
content: Column(
children: const [
CustomInput(
hint: "City and State",
inputBorder: OutlineInputBorder(),
),
CustomInput(
hint: "Postal Code",
inputBorder: OutlineInputBorder(),
),
],
),
),
Step(
state: currentStep > 2 ? StepState.complete : StepState.indexed,
isActive: currentStep >= 2,
title: const Text("Misc"),
content: Column(
children: const [
CustomInput(
hint: "Bio",
inputBorder: OutlineInputBorder(),
),
],
),
),
];
}
}
Agora vamos percorrer cada uma das propriedades que definimos em nosso widget Stepper.
Começando com o type
, definimos como o conteúdo do nosso widget Stepper deve ser disposto dentro do stepper. Para os tipos de etapas verticais e horizontais, é assim que nosso widget Stepper se pareceria:
CurrentStep
simplesmente recebe o valor do índice da etapa que está atualmente visível para o usuário.
OnStepCancel
é o retorno de chamada implementado sempre que um usuário do nosso formulário clica no botão Voltar, e no momento estamos fazendo uma verificação para evitar que o botão fique ativo na primeira etapa.
onStepContinue
é o retorno de chamada em nosso botão continuar. Aqui também temos uma verificação para saber quando o usuário está na última etapa, e aqui podemos realizar a ação necessária usando as informações que nos são fornecidas.
OnStepTapped
retorna a etapa em que o usuário clica, e podemos ativá-la definindo-a como o valor da etapa atual.
Outras coisas que podem ser feitas em nosso widget Stepper para fornecer mais personalizações incluem adicionar um tema personalizado ou implementar nossos próprios botões de controle personalizados, que são os botões Avançar e Continuar atuais que temos. Para isso, basta usar a theme
propriedade e a controlsBuilder
propriedade do nosso widget Stepper.
O uso de um formulário de várias etapas pode melhorar significativamente a experiência do usuário e aumentar o apelo visual de nossos designs.
O widget Stepper no Flutter vem em socorro em situações em que isso é necessário e nos fornece muitas personalizações úteis para obter os resultados que desejamos sem depender de bibliotecas de terceiros.
Fonte: https://blog.logrocket.com/creating-multistep-form-flutter-stepper-widget/
1561523460
This Matplotlib cheat sheet introduces you to the basics that you need to plot your data with Python and includes code samples.
Data visualization and storytelling with your data are essential skills that every data scientist needs to communicate insights gained from analyses effectively to any audience out there.
For most beginners, the first package that they use to get in touch with data visualization and storytelling is, naturally, Matplotlib: it is a Python 2D plotting library that enables users to make publication-quality figures. But, what might be even more convincing is the fact that other packages, such as Pandas, intend to build more plotting integration with Matplotlib as time goes on.
However, what might slow down beginners is the fact that this package is pretty extensive. There is so much that you can do with it and it might be hard to still keep a structure when you're learning how to work with Matplotlib.
DataCamp has created a Matplotlib cheat sheet for those who might already know how to use the package to their advantage to make beautiful plots in Python, but that still want to keep a one-page reference handy. Of course, for those who don't know how to work with Matplotlib, this might be the extra push be convinced and to finally get started with data visualization in Python.
You'll see that this cheat sheet presents you with the six basic steps that you can go through to make beautiful plots.
Check out the infographic by clicking on the button below:
With this handy reference, you'll familiarize yourself in no time with the basics of Matplotlib: you'll learn how you can prepare your data, create a new plot, use some basic plotting routines to your advantage, add customizations to your plots, and save, show and close the plots that you make.
What might have looked difficult before will definitely be more clear once you start using this cheat sheet! Use it in combination with the Matplotlib Gallery, the documentation.
Matplotlib
Matplotlib is a Python 2D plotting library which produces publication-quality figures in a variety of hardcopy formats and interactive environments across platforms.
>>> import numpy as np
>>> x = np.linspace(0, 10, 100)
>>> y = np.cos(x)
>>> z = np.sin(x)
>>> data = 2 * np.random.random((10, 10))
>>> data2 = 3 * np.random.random((10, 10))
>>> Y, X = np.mgrid[-3:3:100j, -3:3:100j]
>>> U = 1 X** 2 + Y
>>> V = 1 + X Y**2
>>> from matplotlib.cbook import get_sample_data
>>> img = np.load(get_sample_data('axes_grid/bivariate_normal.npy'))
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> fig2 = plt.figure(figsize=plt.figaspect(2.0))
>>> fig.add_axes()
>>> ax1 = fig.add_subplot(221) #row-col-num
>>> ax3 = fig.add_subplot(212)
>>> fig3, axes = plt.subplots(nrows=2,ncols=2)
>>> fig4, axes2 = plt.subplots(ncols=3)
>>> plt.savefig('foo.png') #Save figures
>>> plt.savefig('foo.png', transparent=True) #Save transparent figures
>>> plt.show()
>>> fig, ax = plt.subplots()
>>> lines = ax.plot(x,y) #Draw points with lines or markers connecting them
>>> ax.scatter(x,y) #Draw unconnected points, scaled or colored
>>> axes[0,0].bar([1,2,3],[3,4,5]) #Plot vertical rectangles (constant width)
>>> axes[1,0].barh([0.5,1,2.5],[0,1,2]) #Plot horiontal rectangles (constant height)
>>> axes[1,1].axhline(0.45) #Draw a horizontal line across axes
>>> axes[0,1].axvline(0.65) #Draw a vertical line across axes
>>> ax.fill(x,y,color='blue') #Draw filled polygons
>>> ax.fill_between(x,y,color='yellow') #Fill between y values and 0
>>> fig, ax = plt.subplots()
>>> im = ax.imshow(img, #Colormapped or RGB arrays
cmap= 'gist_earth',
interpolation= 'nearest',
vmin=-2,
vmax=2)
>>> axes2[0].pcolor(data2) #Pseudocolor plot of 2D array
>>> axes2[0].pcolormesh(data) #Pseudocolor plot of 2D array
>>> CS = plt.contour(Y,X,U) #Plot contours
>>> axes2[2].contourf(data1) #Plot filled contours
>>> axes2[2]= ax.clabel(CS) #Label a contour plot
>>> axes[0,1].arrow(0,0,0.5,0.5) #Add an arrow to the axes
>>> axes[1,1].quiver(y,z) #Plot a 2D field of arrows
>>> axes[0,1].streamplot(X,Y,U,V) #Plot a 2D field of arrows
>>> ax1.hist(y) #Plot a histogram
>>> ax3.boxplot(y) #Make a box and whisker plot
>>> ax3.violinplot(z) #Make a violin plot
y-axis
x-axis
The basic steps to creating plots with matplotlib are:
1 Prepare Data
2 Create Plot
3 Plot
4 Customized Plot
5 Save Plot
6 Show Plot
>>> import matplotlib.pyplot as plt
>>> x = [1,2,3,4] #Step 1
>>> y = [10,20,25,30]
>>> fig = plt.figure() #Step 2
>>> ax = fig.add_subplot(111) #Step 3
>>> ax.plot(x, y, color= 'lightblue', linewidth=3) #Step 3, 4
>>> ax.scatter([2,4,6],
[5,15,25],
color= 'darkgreen',
marker= '^' )
>>> ax.set_xlim(1, 6.5)
>>> plt.savefig('foo.png' ) #Step 5
>>> plt.show() #Step 6
>>> plt.cla() #Clear an axis
>>> plt.clf(). #Clear the entire figure
>>> plt.close(). #Close a window
>>> plt.plot(x, x, x, x**2, x, x** 3)
>>> ax.plot(x, y, alpha = 0.4)
>>> ax.plot(x, y, c= 'k')
>>> fig.colorbar(im, orientation= 'horizontal')
>>> im = ax.imshow(img,
cmap= 'seismic' )
>>> fig, ax = plt.subplots()
>>> ax.scatter(x,y,marker= ".")
>>> ax.plot(x,y,marker= "o")
>>> plt.plot(x,y,linewidth=4.0)
>>> plt.plot(x,y,ls= 'solid')
>>> plt.plot(x,y,ls= '--')
>>> plt.plot(x,y,'--' ,x**2,y**2,'-.' )
>>> plt.setp(lines,color= 'r',linewidth=4.0)
>>> ax.text(1,
-2.1,
'Example Graph',
style= 'italic' )
>>> ax.annotate("Sine",
xy=(8, 0),
xycoords= 'data',
xytext=(10.5, 0),
textcoords= 'data',
arrowprops=dict(arrowstyle= "->",
connectionstyle="arc3"),)
>>> plt.title(r '$sigma_i=15$', fontsize=20)
Limits & Autoscaling
>>> ax.margins(x=0.0,y=0.1) #Add padding to a plot
>>> ax.axis('equal') #Set the aspect ratio of the plot to 1
>>> ax.set(xlim=[0,10.5],ylim=[-1.5,1.5]) #Set limits for x-and y-axis
>>> ax.set_xlim(0,10.5) #Set limits for x-axis
Legends
>>> ax.set(title= 'An Example Axes', #Set a title and x-and y-axis labels
ylabel= 'Y-Axis',
xlabel= 'X-Axis')
>>> ax.legend(loc= 'best') #No overlapping plot elements
Ticks
>>> ax.xaxis.set(ticks=range(1,5), #Manually set x-ticks
ticklabels=[3,100, 12,"foo" ])
>>> ax.tick_params(axis= 'y', #Make y-ticks longer and go in and out
direction= 'inout',
length=10)
Subplot Spacing
>>> fig3.subplots_adjust(wspace=0.5, #Adjust the spacing between subplots
hspace=0.3,
left=0.125,
right=0.9,
top=0.9,
bottom=0.1)
>>> fig.tight_layout() #Fit subplot(s) in to the figure area
Axis Spines
>>> ax1.spines[ 'top'].set_visible(False) #Make the top axis line for a plot invisible
>>> ax1.spines['bottom' ].set_position(( 'outward',10)) #Move the bottom axis line outward
Have this Cheat Sheet at your fingertips
Original article source at https://www.datacamp.com
#matplotlib #cheatsheet #python