SlideShare a Scribd company logo
Dominando o Data Binding

no Android
+Nelson Glauber
@nglauber
www.nglauber.com.br
@nglauber
+NelsonGlauber
www.nglauber.com.br
Por que Data Binding?
Dominando o Data Binding no Android
Estudo de caso
public class Book {
private String id;
private String title;
private String author;
private String coverUrl;
private int pages;
private int year;
private Publisher publisher;
private boolean available;
private MediaType mediaType;
private float rating;
// Getters and setters...
}
Book book = (Book)getIntent().getSerializableExtra(EXTRA_LIVRO);
ImageView imgCover = (ImageView) findViewById(R.id.image_cover);
TextView txtTitle = (TextView) findViewById(R.id.text_title);
TextView txtAuthor = (TextView) findViewById(R.id.text_author);
TextView txtPages = (TextView) findViewById(R.id.text_pages);
TextView txtYear = (TextView) findViewById(R.id.text_year);
TextView txtPublisher = (TextView) findViewById(R.id.text_publisher);
TextView txtAvailable = (TextView) findViewById(R.id.text_available);
TextView txtMediaType = (TextView) findViewById(R.id.text_media_type);
RatingBar ratingBook = (RatingBar) findViewById(R.id.rating_book);
Glide.with(this).load(book.getCoverUrl()).into(imgCover);
txtTitle.setText(book.getTitle());
txtAuthor.setText(book.getAuthor());
txtPages.setText(getString(R.string.text_format_book_pages, book.getPages()));
txtYear.setText(getString(R.string.text_format_book_year, book.getYear()));
txtPublisher.setText(book.getPublisher().getName());
txtAvailable.setText(book.isAvailable() ?
R.string.text_book_available : R.string.text_book_unavailable);
txtMediaType.setText(book.getMediaType().toString());
ratingBook.setNumStars(book.getRating());
book.setCoverUrl(imageFile.getAbsolutePath());
book.setTitle(editPages.getText().toString());
book.setAuthor(editAuthor.getText().toString());
book.setPages(Integer.parseInt(editPages.getText().toString()));
book.setYear(Integer.parseInt(editYear.getText().toString()));
book.setPublisher((Publisher) spinnerPublisher.getSelectedItem());
book.setAvailable(checkAvailable.isChecked());
book.setMediaTypeValue(radioMediaEbook.isChecked() ?

MediaType.EBOOK : MediaType.PAPER);
book.setRating(ratingBook.getRating());
saveBook(book);
Book book = (Book)getIntent().getSerializableExtra(EXTRA_BOOK);
ActivityDetailViewBinding mBinding =

DataBindingUtil.setContentView(this, R.layout.activity_detail_view);
mBinding.setBook(book);
Conceitos básicos
Configuração
Passo 1
Não tem passo 2 o/
android {
...
dataBinding {
enabled true
}
}
res/layout/activity_main.xml
activity_main.xml
ActivityMainBinding
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout ...>
<TextView ...
android:id=“@+id/text_view_name”
android:text="Hello World!" />
</LinearLayout>
</layout>
public class MainActivity extends AppCompatActivity {
ActivityMainBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mBinding.textViewName.setText(“DataBinding is cool!!!”);
}
}
MainActivity.java
camelCase
Dominando o Data Binding no Android
Se não gostar do nome da classe…
MainActivity.java
res/layout/activity_main.xml
<layout ...>
<data class="AwsomeBinding">
...
</data>
public class MainActivity extends AppCompatActivity {
AwsomeBinding binding;
...
Mapeando objetos na UI
Book book = (Book)getIntent().getSerializableExtra(EXTRA_LIVRO);
ImageView imgCover = (ImageView) findViewById(R.id.image_cover);
TextView txtTitle = (TextView) findViewById(R.id.text_title);
TextView txtAuthor = (TextView) findViewById(R.id.text_author);
TextView txtPages = (TextView) findViewById(R.id.text_pages);
TextView txtYear = (TextView) findViewById(R.id.text_year);
TextView txtPublisher = (TextView) findViewById(R.id.text_publisher);
TextView txtAvailable = (TextView) findViewById(R.id.text_available);
TextView txtMediaType = (TextView) findViewById(R.id.text_media_type);
RatingBar ratingBook = (RatingBar) findViewById(R.id.rating_book);
Glide.with(this).load(book.getCoverUrl()).into(imgCover);
txtTitle.setText(book.getTitle());
txtAuthor.setText(book.getAuthor());
txtPages.setText(getString(R.string.text_format_book_pages, book.getPages()));
txtYear.setText(getString(R.string.text_format_book_year, book.getYear()));
txtPublisher.setText(book.getPublisher().getName());
txtAvailable.setText(book.isAvailable() ?
R.string.text_book_available : R.string.text_book_unavailable);
txtMediaType.setText(book.getMediaType().toString());
ratingBook.setNumStars(book.getRating());
Book book = (Book)getIntent().getSerializableExtra(EXTRA_BOOK);
ActivityDetailViewBinding mBinding =

DataBindingUtil.setContentView(this, R.layout.activity_detail_view);
mBinding.setBook(book);
<layout xmlns:android="http://schemas.android.com/apk/res/android" ...>
<data>
<variable
name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<LinearLayout ... >
<ImageView android:src="@{book.coverUrl}" ... />
<TextView android:text="@{book.title}" ... />
<TextView android:text="@{book.author}" ... />
<TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... />
<TextView android:text="@{@string/text_format_book_year(book.year)}" ... />
<TextView android:text="@{book.publisher.name}" ... />
<TextView android:text="@{book.available ?
@string/text_book_available :
@string/text_book_unavailable}" ... />
<TextView android:text="@{book.mediaTypeValue}" ... />
<RatingBar android:rating="@{book.rating}" ... />
</LinearLayout>
</layout>
<layout xmlns:android="http://schemas.android.com/apk/res/android" ...>
<data>
<variable
name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<LinearLayout ... >
<ImageView android:src="@{book.coverUrl}" ... />
<TextView android:text="@{book.title}" ... />
<TextView android:text="@{book.author}" ... />
<TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... />
<TextView android:text="@{@string/text_format_book_year(book.year)}" ... />
<TextView android:text="@{book.publisher.name}" ... />
<TextView android:text="@{book.available ?
@string/text_book_available :
@string/text_book_unavailable}" ... />
<TextView android:text="@{book.mediaTypeValue}" ... />
<RatingBar android:progress="@{book.rating}" ... />
</LinearLayout>
</layout>
<!-- strings.xml -->
<string name="text_format_book_pages">Número de páginas: %1$d</string>
<string name="text_format_book_year">Ano de publicação: %1$d</string>
<layout xmlns:android="http://schemas.android.com/apk/res/android" ...>
<data>
<variable
name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<LinearLayout ... >
<ImageView android:src="@{book.coverUrl}" ... />
<TextView android:text="@{book.title}" ... />
<TextView android:text="@{book.author}" ... />
<TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... />
<TextView android:text="@{@string/text_format_book_year(book.year)}" ... />
<TextView android:text="@{book.publisher.name}" ... />
<TextView android:text="@{book.available ?
@string/text_book_available :
@string/text_book_unavailable}" ... />
<TextView android:text="@{book.mediaType}" ... />
<RatingBar android:progress="@{book.rating}" ... />
</LinearLayout>
</layout>
Tá pronto? Pode
rodar???
NÃO!
<layout xmlns:android="http://schemas.android.com/apk/res/android" ...>
<data>
<variable
name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<LinearLayout ... >
<ImageView android:src="@{book.coverUrl}" ... />
<TextView android:text="@{book.title}" ... />
<TextView android:text="@{book.author}" ... />
<TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... />
<TextView android:text="@{@string/text_format_book_year(book.year)}" ... />
<TextView android:text="@{book.publisher.name}" ... />
<TextView android:text="@{book.available ?
@string/text_book_available :
@string/text_book_unavailable}" ... />
<TextView android:text="@{book.mediaTypeValue}" ... />
<RatingBar android:progress="@{book.rating}" ... />
</LinearLayout>
</layout>
Binding Adapters #1
public class TextBinding {
@BindingAdapter({"android:text"})
public static void setMediaTypeText(TextView textView, MediaType mediaType){
Context context = textView.getContext();
switch (mediaType) {
case EBOOK:
textView.setText(context.getString(R.string.text_book_media_ebook));
break;
case PAPER:
textView.setText(context.getString(R.string.text_book_media_paper));
break;
default:
textView.setText(null);
}
}
}
TextBinding.java
<ImageView
android:id="@+id/image_cover"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:background="#CCC"
android:scaleType="centerCrop"
android:src="@{book.coverUrl}"
app:placeHolder=“@{@drawable/ic_photo}”/>
res/values/attrs.xml
<attr name="placeHolder" format="reference"/>
public class ImageBinding {
@BindingAdapter({"android:src"})
public static void setImageUrl(ImageView imageView, String url){
Glide.with(imageView.getContext())
.load(url)
.into(imageView);
}
@BindingAdapter({"android:src", "placeHolder"})
public static void setImageUrl(ImageView imageView, String url,
Drawable placeholder){
Glide.with(imageView.getContext())
.load(url)
.placeholder(placeholder)
.into(imageView);
}
}
ImageBinding.java
Dominando o Data Binding no Android
E se os dados mudarem?
public class Book extends BaseObservable {
// Atributos...
@Bindable
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
notifyPropertyChanged(BR.title);
}
@Bindable
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
notifyPropertyChanged(BR.author);
}
// Demais getters/setters
Book.java
public class Book implements Observable {
private PropertyChangeRegistry mCallbacks;
// Copia as coisas do BaseObservable :)
}
public class BaseObservable implements Observable {
private transient PropertyChangeRegistry mCallbacks;
public BaseObservable() {
}
@Override
public synchronized void addOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
if (mCallbacks == null) {
mCallbacks = new PropertyChangeRegistry();
}
mCallbacks.add(callback);
}
@Override
public synchronized void removeOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
if (mCallbacks != null) {
mCallbacks.remove(callback);
}
}
public synchronized void notifyChange() {
if (mCallbacks != null) {
mCallbacks.notifyCallbacks(this, 0, null);
}
}
public void notifyPropertyChanged(int fieldId) {
if (mCallbacks != null) {
mCallbacks.notifyCallbacks(this, fieldId, null);
}
}
}
import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
public class Book {
//...
private final ObservableField<String> title;
private final ObservableInt year;
private final ObservableBoolean available;
public Book() {
//...
this.title = new ObservableField<>();
this.year = new ObservableInt(2016);
this.available = new ObservableBoolean(false);
}
public ObservableField<String> getTitle() { return title; }
public void setTitle(String title) { this.title.set(title); }
public ObservableInt getYear() { return year; }
public void setYear(double year) { this.year.set(year); }
public ObservableBoolean isAvailable() { return available; }
public void setAvailable(boolean available) { this.available.set(available); }
}
Fragments e Adapters
BookFragment.java
private FragmentBookBinding mBinding;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
mBinding = DataBindingUtil.inflate(inflater,
R.layout.fragment_book,
container, false);
...
return mBinding.getRoot();
}
res/layout/item_book.xml
<layout ...>
<data>
<variable
name="book"
type="br.com.nglauber.livrosfirebase.model.Book"/>
</data>
<android.support.v7.widget.CardView ...>
<RelativeLayout ...>
<ImageView android:src="@{book.coverUrl}" ... />
<TextView android:text="@{book.title}" ... />
<TextView android:text="@{book.author}" ... />
</RelativeLayout>
</android.support.v7.widget.CardView>
</layout>
BookViewHolder.java
public static class BookViewHolder extends RecyclerView.ViewHolder {
ItemBookBinding binding;
public BookViewHolder(ItemBookBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
@Override
public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ItemBookBinding binding = DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()),
R.layout.item_book,
parent,
false);
final BookViewHolder vh = new BookViewHolder(binding);
vh.itemView.setOnClickListener(...);
return vh;
}
@Override
public void onBindViewHolder(BookViewHolder holder, int pos) {
Book book = mBooksList.get(pos);
holder.binding.setBook(book);
holder.binding.executePendingBindings();
}
BookAdapter.java
Dominando o Data Binding no Android
Two-way Data Binding
<layout ...>
<data>
<variable name="texto" type="String"/>
</data>
<LinearLayout ... >
<TextView ...
android:id="@+id/textViewNome"
android:text="@{texto}" />
<EditText ...
android:id="@+id/editTextNome"
android:text="@={texto}"/>
</LinearLayout>
</layout>
Dominando o Data Binding no Android
<layout ...>
<data>
...
<import type="br.com.nglauber.livrosfirebase.model.MediaType" />
<variable name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<LinearLayout ...>
<ImageView android:src="@{book.coverUrl}" ... />
<EditText android:text="@={book.title}" ... />
<EditText android:text="@={book.author}" ... />
<EditText android:text="@={book.pages}" ... />
<EditText android:text="@={book.year}" ... />
<Spinner ...> <!-- trataremos desse em breve. -->
<CheckBox android:checked="@={book.available}" ... />
<RadioGroup ...>
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" ... />
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.PAPER}" ... />
</RadioGroup>
<RatingBar
android:rating="@={book.rating}" ... />
...
</LinearLayout>
</layout>
<layout ...>
<data>
...
<import type="br.com.nglauber.livrosfirebase.model.MediaType" />
<variable name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<LinearLayout ...>
<ImageView android:src="@{book.coverUrl}" ... />
<EditText android:text="@={book.title}" ... />
<EditText android:text="@={book.author}" ... />
<EditText android:text="@={book.pages}" ... />
<EditText android:text="@={book.year}" ... />
<Spinner ...> <!-- trataremos desse em breve. -->
<CheckBox android:checked="@={book.available}" ... />
<RadioGroup ...>
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" ... />
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.PAPER}" ... />
</RadioGroup>
<RatingBar
android:progress="@={book.rating}" ... />
...
</LinearLayout>
</layout>
Binding Adapters #2
Cuidado com loops!
EditText

android:text="@={book.title}"
public class Book extends BaseObservable {
// Atributos...
@Bindable
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
notifyPropertyChanged(BR.title);
}
// Demais getters/setters
public class EditTextBindingAdapters {
@InverseBindingAdapter(attribute = "android:text")
public static int getTextAsInt(EditText editText) {
try {
return Integer.parseInt(editText.getText().toString());
} catch (Exception e){
return 0;
}
}
@BindingAdapter({"android:text"})
public static void setTextFromInt(EditText editText, int value){
if (getTextAsInt(editText) != value) {
editText.setText(String.valueOf(value));
}
}
}
EditTextBindingAdapters.java
Tratamento de eventos
<layout ...>
<data>
...
<variable
name="presenter"
type=“br.com.nglauber.livrosfirebase.DetailEditActivity"/>
</data>
<LinearLayout ...>
...
<TextView ...
android:onLongClick="@{presenter::longClick}" />
<Button ...
android:onClick=“@{presenter::clickSaveBook}”/>
<EditText ...
android:onFocusChange="@{presenter::focusChanged}"/>
</LinearLayout>
</layout>
res/layout/activity_detail_edit.xml
@Override
protected void onCreate(Bundle savedInstanceState) {
...
binding.setBook(book);
binding.setPresenter(this);
}
public void clickSaveBook(View view) {
Toast.makeText(this, book.toString(), Toast.LENGTH_SHORT).show();
}
public boolean longClick(View view){
book.setRating(book.getRating() + 1);
return true;
}
public void focusChanged(View v, boolean focus){
if (!focus) showProduct(v);
}
DetailEditActivity.java
Respeite a
assinatura do
método
<layout ...>
<data>
<import type="br.com.nglauber.livrosfirebase.model.MediaType" />
...
<variable
name="presenter"
type="br.com.nglauber.livrosfirebase.DetailEditActivity" />
</data>
<LinearLayout ...>
...
<RadioGroup ...>
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.EBOOK}"
android:onCheckedChanged="@{presenter::onMediaTypeChanged}" />
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.PAPER}"
android:onCheckedChanged="@{presenter::onMediaTypeChanged}" />
</RadioGroup>
...
</LinearLayout>
</layout>
public void onMediaTypeChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
if (buttonView == mBinding.radioMediaEbook) {
mBinding.getBook().setMediaTypeValue(MediaType.EBOOK);
} else if (buttonView == mBinding.radioMediaPaper) {
mBinding.getBook().setMediaTypeValue(MediaType.PAPER);
}
}
}
public class Publisher {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class Book extends BaseObservable {
private Publisher publisher;
...
@Bindable
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
notifyPropertyChanged(BR.publisher);
}
}
<layout ...>
<data>
<import type="java.util.List"/>
<variable name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
<variable name="presenter"
type="br.com.nglauber.livrosfirebase.DetailEditActivity" />
<variable name="publishers"
type="java.util.List&lt;br.com.nglauber.livrosfirebase.model.Publisher&gt;" />
</data>

<LinearLayout ...>
<Spinner ...
android:entries="@{publishers}"
android:selection="@{publishers.indexOf(book.publisher)}"
android:onItemSelected="@{(p, v, pos, id)->book.setPublisher(publishers[pos])}" />
</LinearLayout>
</layout>
DetailEditActivity.java
ObservableList<Publisher> publishers = loadListFromSomewhere();
mBinding.setPublishers(publishers);
<layout ...>
<data>
<variable
name="book"
type="br.com.nglauber.livrosfirebase.model.Book"/>
<variable
name="presenter"
type=“br.com.nglauber.livrosfirebase.DetailEditActivity"/>
</data>
<LinearLayout ...>
...
<Button ...
android:onClick="@{()->presenter.saveBook(book)}"/>
</LinearLayout>
</layout>
Pronto!
http://jakewharton.github.io/butterknife/
Binding Adapters #3
https://github.com/lisawray/fontbinding
public class TextViewBinderAdapter {
@BindingAdapter({"font"})
public static void setFont(TextView textView,String font){
AssetManager assets = textView.getContext().getAssets();
Typeface typeface = Typeface.createFromAsset(assets, font);
textView.setTypeface(typeface);
}
}
<TextView app:font="@{`FunnyKid.ttf`}" .../>
Mas se tiver um “set” pode usar!
<android.support.v4.widget.DrawerLayout ...
app:scrimColor="@{@color/scrim}"
app:drawerListener="@{fragment.drawerListener}"/>
Miscellaneous
Expression Language
<TextView ...
android:text="@{user.displayName ?? user.lastName}"/>
<TextView ...
android:text="@{`User: ` + user.name}”/>
<LinearLayout ...
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"/>
res/values/colors.xml
<color name="red">#F00</color>
<color name="black">#000</color>
<TextView ...
android:id="@+id/text_title"
android:textColor="@{book.available ? @color/black : @color/red}"
android:text="@{book.title}" />
res/values/strings.xml
<string name="price_format">$ %1$.2f</string>
<TextView ...
android:id="@+id/text_price"
android:text="@{@string/price_format(book.price)}" />
getString(R.string.price_format, product.price);
Include
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="book" type=“...Book”/>
<variable name=“presenter" type=“...DetailEditActivity" />
</data>
<LinearLayout ...>
<include
android:id="@+id/content"
layout="@layout/content_detail_edit"
app:presenter="@{presenter}"
app:book="@{book}" />
</LinearLayout>
</layout>
Include
ActivityDetailEditBinding mBinding =
DataBindingUtil.setContentView(this, R.layout.activity_detail_edit);
mBinding.setBook(book);
mBinding.setPresenter(this);
mBinding.content.setPublishers(new ObservableArrayList<Publisher>());
Expression Chain
<layout ...>
<data>
<import type="android.view.View" />
...
</data>
<LinearLayout ...>
<ImageView ...
android:id="@+id/image_cover"
android:visibility="@{book.available ? View.VISIBLE : View.INVISIBLE}" />
<RadioGroup ...
android:id="@+id/radio_group_media_type"
android:visibility="@{imageCover.visibility}" />
<RatingBar
android:visibility="@{radioGroupMediaType.visibility}"
android:id=“@+id/rating_book">
<CheckBox ...
android:id="@+id/check_available"
android:checked="@={book.available}" />
Ouvindo coisas… :)
binding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable observable, int i) {
if (i == br.com.nglauber.uidemo.BR.name){
Product p = (Product)observable;
Log.d("NGVL", p.getName());
}
}
});
Ouvindo coisas… :)
Use para
animações
binding.addOnRebindCallback(new OnRebindCallback() {
@Override
public boolean onPreBind(ViewDataBinding binding) {
return super.onPreBind(binding);
}
@Override
public void onCanceled(ViewDataBinding binding) {
super.onCanceled(binding);
}
@Override
public void onBound(ViewDataBinding binding) {
super.onBound(binding);
}
});
Aplicando no seu projeto
1. Remova os findViewById’s :)
2. Faça o Binding dos seus objetos.
3. Use os callbacks (eventos) de UI.
4. Aproveite os objetos observáveis.
5. Two-way Data Binding é vida! ♥
Boas práticas
• Não coloque lógica de negócios na tela. Apenas lógica de tela.
• Os eventos disparados executarão na UI Thread.
• Simplifique a lógica de UI (não coloque expressões complicadas,
crie métodos para isso.
• Considere utilizar um ViewModel.
• Leve os BinderAdapters com você :) Você só vai precisar escrevê-
los uma vez. // TODO: Fazer uma lib para isso :p
Referências
• Data Binding -- Write Apps Faster (Android Dev Summit 2015)

https://www.youtube.com/watch?v=NBbeQMOcnZ0
• Data Binding Documentation (pode melhorar né…?)

http://developer.android.com/tools/data-binding/guide.html
• Nelson Glauber Blog

http://www.nglauber.com.br/2016/05/android-data-binding.html
• Advanced Data Binding (Google I/O 2016)

https://www.youtube.com/watch?v=DAmMN7m3wLU
Dúvidas?
@nglauber
+NelsonGlauber
www.nglauber.com.br
Obrigado!

More Related Content

What's hot

Responsive mobile design
Responsive mobile designResponsive mobile design
Responsive mobile design
Kirill Grouchnikov
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
Jeado Ko
 
22 j query1
22 j query122 j query1
22 j query1
Fajar Baskoro
 
Responsive mobile design in practice
Responsive mobile design in practiceResponsive mobile design in practice
Responsive mobile design in practice
Kirill Grouchnikov
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
Scott Gardner
 
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle StudiosAngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
Learnimtactics
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 
Guia de Sobrevivência JS no mundo Open Source
Guia de Sobrevivência JS no mundo Open SourceGuia de Sobrevivência JS no mundo Open Source
Guia de Sobrevivência JS no mundo Open Source
Leonardo Balter
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJS
Zhang Xiaoxue
 
MVVM with SwiftUI and Combine
MVVM with SwiftUI and CombineMVVM with SwiftUI and Combine
MVVM with SwiftUI and Combine
Tai Lun Tseng
 
React 소개 및 구현방법 Demo
React 소개 및 구현방법 DemoReact 소개 및 구현방법 Demo
React 소개 및 구현방법 Demo
Daesung Kim
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
Rob Bontekoe
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
Siva Arunachalam
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
Pierre Sudron
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery Presentation
Rod Johnson
 
Jquery ui
Jquery uiJquery ui
Jquery ui
adm_exoplatform
 
AngularJS: an introduction
AngularJS: an introductionAngularJS: an introduction
AngularJS: an introduction
Luigi De Russis
 
A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020
A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020
A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020
Rob Ousbey
 
Dom selecting & jQuery
Dom selecting & jQueryDom selecting & jQuery
Dom selecting & jQuery
Kim Hunmin
 
Angular js
Angular jsAngular js
Angular js
prasaddammalapati
 

What's hot (20)

Responsive mobile design
Responsive mobile designResponsive mobile design
Responsive mobile design
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
 
22 j query1
22 j query122 j query1
22 j query1
 
Responsive mobile design in practice
Responsive mobile design in practiceResponsive mobile design in practice
Responsive mobile design in practice
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
 
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle StudiosAngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
Guia de Sobrevivência JS no mundo Open Source
Guia de Sobrevivência JS no mundo Open SourceGuia de Sobrevivência JS no mundo Open Source
Guia de Sobrevivência JS no mundo Open Source
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJS
 
MVVM with SwiftUI and Combine
MVVM with SwiftUI and CombineMVVM with SwiftUI and Combine
MVVM with SwiftUI and Combine
 
React 소개 및 구현방법 Demo
React 소개 및 구현방법 DemoReact 소개 및 구현방법 Demo
React 소개 및 구현방법 Demo
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery Presentation
 
Jquery ui
Jquery uiJquery ui
Jquery ui
 
AngularJS: an introduction
AngularJS: an introductionAngularJS: an introduction
AngularJS: an introduction
 
A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020
A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020
A Novel Approach to Scraping Websites - Rob Ousbey, MozCon 2020
 
Dom selecting & jQuery
Dom selecting & jQueryDom selecting & jQuery
Dom selecting & jQuery
 
Angular js
Angular jsAngular js
Angular js
 

Viewers also liked

Deep dive into Android Data Binding
Deep dive into Android Data BindingDeep dive into Android Data Binding
Deep dive into Android Data Binding
Radek Piekarz
 
Android Wear DevFest Sudeste 2015
Android Wear DevFest Sudeste 2015Android Wear DevFest Sudeste 2015
Android Wear DevFest Sudeste 2015
Nelson Glauber Leal
 
Google Play Services Rocks!!!
Google Play Services Rocks!!!Google Play Services Rocks!!!
Google Play Services Rocks!!!
Nelson Glauber Leal
 
Android Libs - AndroidDevConf
Android Libs - AndroidDevConfAndroid Libs - AndroidDevConf
Android Libs - AndroidDevConf
Nelson Glauber Leal
 
Android FREETEC
Android FREETECAndroid FREETEC
Android FREETEC
Nelson Glauber Leal
 
Aumentando a produtividade com Android Libs
Aumentando a produtividade com Android LibsAumentando a produtividade com Android Libs
Aumentando a produtividade com Android Libs
Nelson Glauber Leal
 
Android Wear Androidos 2015
Android Wear Androidos 2015Android Wear Androidos 2015
Android Wear Androidos 2015
Nelson Glauber Leal
 
Android data binding
Android data bindingAndroid data binding
Android data binding
Sergi Martínez
 
Conhecendo o Android Wear
Conhecendo o Android WearConhecendo o Android Wear
Conhecendo o Android Wear
Nelson Glauber Leal
 
MVVM & Data Binding Library
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library
10Clouds
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
Fabio Collini
 
MVVM with DataBinding on android
MVVM with DataBinding on androidMVVM with DataBinding on android
MVVM with DataBinding on android
Rodrigo Bressan
 
Android DevConference - Data Binding: Código limpo, manutenção garantida
Android DevConference - Data Binding: Código limpo, manutenção garantidaAndroid DevConference - Data Binding: Código limpo, manutenção garantida
Android DevConference - Data Binding: Código limpo, manutenção garantida
iMasters
 
Data binding
Data bindingData binding
Data binding
Yonatan Levin
 
Android L e Android Wear
Android L e Android WearAndroid L e Android Wear
Android L e Android Wear
Nelson Glauber Leal
 
Android e iOS: Por que eles são diferentes... ou não.
Android e iOS: Por que eles são diferentes... ou não.Android e iOS: Por que eles são diferentes... ou não.
Android e iOS: Por que eles são diferentes... ou não.
Nelson Glauber Leal
 
Android Lollipop + Android Wear
Android Lollipop + Android WearAndroid Lollipop + Android Wear
Android Lollipop + Android Wear
Nelson Glauber Leal
 
Android Wear
Android WearAndroid Wear
Android Wear
Nelson Glauber Leal
 
Android Databinding Library
Android Databinding LibraryAndroid Databinding Library
Android Databinding Library
Takuji Nishibayashi
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
Fabio Collini
 

Viewers also liked (20)

Deep dive into Android Data Binding
Deep dive into Android Data BindingDeep dive into Android Data Binding
Deep dive into Android Data Binding
 
Android Wear DevFest Sudeste 2015
Android Wear DevFest Sudeste 2015Android Wear DevFest Sudeste 2015
Android Wear DevFest Sudeste 2015
 
Google Play Services Rocks!!!
Google Play Services Rocks!!!Google Play Services Rocks!!!
Google Play Services Rocks!!!
 
Android Libs - AndroidDevConf
Android Libs - AndroidDevConfAndroid Libs - AndroidDevConf
Android Libs - AndroidDevConf
 
Android FREETEC
Android FREETECAndroid FREETEC
Android FREETEC
 
Aumentando a produtividade com Android Libs
Aumentando a produtividade com Android LibsAumentando a produtividade com Android Libs
Aumentando a produtividade com Android Libs
 
Android Wear Androidos 2015
Android Wear Androidos 2015Android Wear Androidos 2015
Android Wear Androidos 2015
 
Android data binding
Android data bindingAndroid data binding
Android data binding
 
Conhecendo o Android Wear
Conhecendo o Android WearConhecendo o Android Wear
Conhecendo o Android Wear
 
MVVM & Data Binding Library
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
MVVM with DataBinding on android
MVVM with DataBinding on androidMVVM with DataBinding on android
MVVM with DataBinding on android
 
Android DevConference - Data Binding: Código limpo, manutenção garantida
Android DevConference - Data Binding: Código limpo, manutenção garantidaAndroid DevConference - Data Binding: Código limpo, manutenção garantida
Android DevConference - Data Binding: Código limpo, manutenção garantida
 
Data binding
Data bindingData binding
Data binding
 
Android L e Android Wear
Android L e Android WearAndroid L e Android Wear
Android L e Android Wear
 
Android e iOS: Por que eles são diferentes... ou não.
Android e iOS: Por que eles são diferentes... ou não.Android e iOS: Por que eles são diferentes... ou não.
Android e iOS: Por que eles são diferentes... ou não.
 
Android Lollipop + Android Wear
Android Lollipop + Android WearAndroid Lollipop + Android Wear
Android Lollipop + Android Wear
 
Android Wear
Android WearAndroid Wear
Android Wear
 
Android Databinding Library
Android Databinding LibraryAndroid Databinding Library
Android Databinding Library
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 

Similar to Dominando o Data Binding no Android

Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino KovacInfinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011
Johan Nilsson
 
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
Inhacking
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談
awonwon
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
Mario Jorge Pereira
 
Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017
Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017
Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017
Codemotion
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
InnovationM
 
Android programming basics
Android programming basicsAndroid programming basics
Android programming basics
Egerton University
 
CIRCUIT 2015 - Content API's For AEM Sites
CIRCUIT 2015 - Content API's For AEM SitesCIRCUIT 2015 - Content API's For AEM Sites
CIRCUIT 2015 - Content API's For AEM Sites
ICF CIRCUIT
 
JakartaData-JCon.pptx
JakartaData-JCon.pptxJakartaData-JCon.pptx
JakartaData-JCon.pptx
EmilyJiang23
 
List adapter with multiple objects
List adapter with multiple objectsList adapter with multiple objects
List adapter with multiple objects
baabtra.com - No. 1 supplier of quality freshers
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
Yurii Kotov
 
Data Binding Intro (Windows 8)
Data Binding Intro (Windows 8)Data Binding Intro (Windows 8)
Data Binding Intro (Windows 8)
Gilbok Lee
 
07_UIAndroid.pdf
07_UIAndroid.pdf07_UIAndroid.pdf
07_UIAndroid.pdf
ImranS18
 
[2019] 스몰 스텝: Android 렛츠기릿!
[2019] 스몰 스텝: Android 렛츠기릿![2019] 스몰 스텝: Android 렛츠기릿!
[2019] 스몰 스텝: Android 렛츠기릿!
NHN FORWARD
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android Apps
Gil Irizarry
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Java script -23jan2015
Java script -23jan2015Java script -23jan2015
Java script -23jan2015
Sasidhar Kothuru
 
Hibernate II
Hibernate IIHibernate II
Hibernate II
People Strategists
 

Similar to Dominando o Data Binding no Android (20)

Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino KovacInfinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011Custom UI Components at Android Only 2011
Custom UI Components at Android Only 2011
 
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...SE2016 Android Mikle Anokhin "Speed up application development with data bind...
SE2016 Android Mikle Anokhin "Speed up application development with data bind...
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
 
Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017
Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017
Nicola Corti - Building UI Consistent Android Apps - Codemotion Milan 2017
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
 
Android programming basics
Android programming basicsAndroid programming basics
Android programming basics
 
CIRCUIT 2015 - Content API's For AEM Sites
CIRCUIT 2015 - Content API's For AEM SitesCIRCUIT 2015 - Content API's For AEM Sites
CIRCUIT 2015 - Content API's For AEM Sites
 
JakartaData-JCon.pptx
JakartaData-JCon.pptxJakartaData-JCon.pptx
JakartaData-JCon.pptx
 
List adapter with multiple objects
List adapter with multiple objectsList adapter with multiple objects
List adapter with multiple objects
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
 
Data Binding Intro (Windows 8)
Data Binding Intro (Windows 8)Data Binding Intro (Windows 8)
Data Binding Intro (Windows 8)
 
07_UIAndroid.pdf
07_UIAndroid.pdf07_UIAndroid.pdf
07_UIAndroid.pdf
 
[2019] 스몰 스텝: Android 렛츠기릿!
[2019] 스몰 스텝: Android 렛츠기릿![2019] 스몰 스텝: Android 렛츠기릿!
[2019] 스몰 스텝: Android 렛츠기릿!
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android Apps
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
 
Java script -23jan2015
Java script -23jan2015Java script -23jan2015
Java script -23jan2015
 
Hibernate II
Hibernate IIHibernate II
Hibernate II
 

More from Nelson Glauber Leal

Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
Nelson Glauber Leal
 
Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
Nelson Glauber Leal
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
Nelson Glauber Leal
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
Nelson Glauber Leal
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
Nelson Glauber Leal
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
Nelson Glauber Leal
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
Nelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
Nelson Glauber Leal
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
Nelson Glauber Leal
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
Nelson Glauber Leal
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
Nelson Glauber Leal
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
Nelson Glauber Leal
 
Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
Nelson Glauber Leal
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
Nelson Glauber Leal
 

More from Nelson Glauber Leal (20)

Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
 
Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
 
Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
 

Recently uploaded

leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
alexjohnson7307
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
Brian Pichman
 
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
FIDO Alliance
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
Matthias Neugebauer
 
Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)
Debmalya Biswas
 
The Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - CoatueThe Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - Coatue
Razin Mustafiz
 
Sonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdfSonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdf
SubhamMandal40
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
SAI KAILASH R
 
Semantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software DevelopmentSemantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software Development
Baishakhi Ray
 
Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024
siddu769252
 
Finetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and DefendingFinetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and Defending
Priyanka Aash
 
The History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal EmbeddingsThe History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal Embeddings
Zilliz
 
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Nicolás Lopéz
 
Feature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptxFeature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptx
ssuser1915fe1
 
UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...
UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...
UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...
FIDO Alliance
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
Zilliz
 
Mastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for SuccessMastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for Success
David Wilson
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
bhumivarma35300
 
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Zilliz
 
Redefining Cybersecurity with AI Capabilities
Redefining Cybersecurity with AI CapabilitiesRedefining Cybersecurity with AI Capabilities
Redefining Cybersecurity with AI Capabilities
Priyanka Aash
 

Recently uploaded (20)

leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
 
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
UX Webinar Series: Essentials for Adopting Passkeys as the Foundation of your...
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
 
Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)Gen AI: Privacy Risks of Large Language Models (LLMs)
Gen AI: Privacy Risks of Large Language Models (LLMs)
 
The Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - CoatueThe Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - Coatue
 
Sonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdfSonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdf
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
 
Semantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software DevelopmentSemantic-Aware Code Model: Elevating the Future of Software Development
Semantic-Aware Code Model: Elevating the Future of Software Development
 
Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024Generative AI Reasoning Tech Talk - July 2024
Generative AI Reasoning Tech Talk - July 2024
 
Finetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and DefendingFinetuning GenAI For Hacking and Defending
Finetuning GenAI For Hacking and Defending
 
The History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal EmbeddingsThe History of Embeddings & Multimodal Embeddings
The History of Embeddings & Multimodal Embeddings
 
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024
 
Feature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptxFeature sql server terbaru performance.pptx
Feature sql server terbaru performance.pptx
 
UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...
UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...
UX Webinar Series: Drive Revenue and Decrease Costs with Passkeys for Consume...
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
 
Mastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for SuccessMastering OnlyFans Clone App Development: Key Strategies for Success
Mastering OnlyFans Clone App Development: Key Strategies for Success
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
 
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
 
Redefining Cybersecurity with AI Capabilities
Redefining Cybersecurity with AI CapabilitiesRedefining Cybersecurity with AI Capabilities
Redefining Cybersecurity with AI Capabilities
 

Dominando o Data Binding no Android

  • 1. Dominando o Data Binding
 no Android +Nelson Glauber @nglauber www.nglauber.com.br
  • 3. Por que Data Binding?
  • 6. public class Book { private String id; private String title; private String author; private String coverUrl; private int pages; private int year; private Publisher publisher; private boolean available; private MediaType mediaType; private float rating; // Getters and setters... }
  • 7. Book book = (Book)getIntent().getSerializableExtra(EXTRA_LIVRO); ImageView imgCover = (ImageView) findViewById(R.id.image_cover); TextView txtTitle = (TextView) findViewById(R.id.text_title); TextView txtAuthor = (TextView) findViewById(R.id.text_author); TextView txtPages = (TextView) findViewById(R.id.text_pages); TextView txtYear = (TextView) findViewById(R.id.text_year); TextView txtPublisher = (TextView) findViewById(R.id.text_publisher); TextView txtAvailable = (TextView) findViewById(R.id.text_available); TextView txtMediaType = (TextView) findViewById(R.id.text_media_type); RatingBar ratingBook = (RatingBar) findViewById(R.id.rating_book); Glide.with(this).load(book.getCoverUrl()).into(imgCover); txtTitle.setText(book.getTitle()); txtAuthor.setText(book.getAuthor()); txtPages.setText(getString(R.string.text_format_book_pages, book.getPages())); txtYear.setText(getString(R.string.text_format_book_year, book.getYear())); txtPublisher.setText(book.getPublisher().getName()); txtAvailable.setText(book.isAvailable() ? R.string.text_book_available : R.string.text_book_unavailable); txtMediaType.setText(book.getMediaType().toString()); ratingBook.setNumStars(book.getRating());
  • 9. Book book = (Book)getIntent().getSerializableExtra(EXTRA_BOOK); ActivityDetailViewBinding mBinding =
 DataBindingUtil.setContentView(this, R.layout.activity_detail_view); mBinding.setBook(book);
  • 11. Configuração Passo 1 Não tem passo 2 o/ android { ... dataBinding { enabled true } }
  • 13. public class MainActivity extends AppCompatActivity { ActivityMainBinding mBinding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); mBinding.textViewName.setText(“DataBinding is cool!!!”); } } MainActivity.java camelCase
  • 15. Se não gostar do nome da classe… MainActivity.java res/layout/activity_main.xml <layout ...> <data class="AwsomeBinding"> ... </data> public class MainActivity extends AppCompatActivity { AwsomeBinding binding; ...
  • 17. Book book = (Book)getIntent().getSerializableExtra(EXTRA_LIVRO); ImageView imgCover = (ImageView) findViewById(R.id.image_cover); TextView txtTitle = (TextView) findViewById(R.id.text_title); TextView txtAuthor = (TextView) findViewById(R.id.text_author); TextView txtPages = (TextView) findViewById(R.id.text_pages); TextView txtYear = (TextView) findViewById(R.id.text_year); TextView txtPublisher = (TextView) findViewById(R.id.text_publisher); TextView txtAvailable = (TextView) findViewById(R.id.text_available); TextView txtMediaType = (TextView) findViewById(R.id.text_media_type); RatingBar ratingBook = (RatingBar) findViewById(R.id.rating_book); Glide.with(this).load(book.getCoverUrl()).into(imgCover); txtTitle.setText(book.getTitle()); txtAuthor.setText(book.getAuthor()); txtPages.setText(getString(R.string.text_format_book_pages, book.getPages())); txtYear.setText(getString(R.string.text_format_book_year, book.getYear())); txtPublisher.setText(book.getPublisher().getName()); txtAvailable.setText(book.isAvailable() ? R.string.text_book_available : R.string.text_book_unavailable); txtMediaType.setText(book.getMediaType().toString()); ratingBook.setNumStars(book.getRating());
  • 18. Book book = (Book)getIntent().getSerializableExtra(EXTRA_BOOK); ActivityDetailViewBinding mBinding =
 DataBindingUtil.setContentView(this, R.layout.activity_detail_view); mBinding.setBook(book);
  • 19. <layout xmlns:android="http://schemas.android.com/apk/res/android" ...> <data> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <LinearLayout ... > <ImageView android:src="@{book.coverUrl}" ... /> <TextView android:text="@{book.title}" ... /> <TextView android:text="@{book.author}" ... /> <TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... /> <TextView android:text="@{@string/text_format_book_year(book.year)}" ... /> <TextView android:text="@{book.publisher.name}" ... /> <TextView android:text="@{book.available ? @string/text_book_available : @string/text_book_unavailable}" ... /> <TextView android:text="@{book.mediaTypeValue}" ... /> <RatingBar android:rating="@{book.rating}" ... /> </LinearLayout> </layout>
  • 20. <layout xmlns:android="http://schemas.android.com/apk/res/android" ...> <data> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <LinearLayout ... > <ImageView android:src="@{book.coverUrl}" ... /> <TextView android:text="@{book.title}" ... /> <TextView android:text="@{book.author}" ... /> <TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... /> <TextView android:text="@{@string/text_format_book_year(book.year)}" ... /> <TextView android:text="@{book.publisher.name}" ... /> <TextView android:text="@{book.available ? @string/text_book_available : @string/text_book_unavailable}" ... /> <TextView android:text="@{book.mediaTypeValue}" ... /> <RatingBar android:progress="@{book.rating}" ... /> </LinearLayout> </layout> <!-- strings.xml --> <string name="text_format_book_pages">Número de páginas: %1$d</string> <string name="text_format_book_year">Ano de publicação: %1$d</string>
  • 21. <layout xmlns:android="http://schemas.android.com/apk/res/android" ...> <data> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <LinearLayout ... > <ImageView android:src="@{book.coverUrl}" ... /> <TextView android:text="@{book.title}" ... /> <TextView android:text="@{book.author}" ... /> <TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... /> <TextView android:text="@{@string/text_format_book_year(book.year)}" ... /> <TextView android:text="@{book.publisher.name}" ... /> <TextView android:text="@{book.available ? @string/text_book_available : @string/text_book_unavailable}" ... /> <TextView android:text="@{book.mediaType}" ... /> <RatingBar android:progress="@{book.rating}" ... /> </LinearLayout> </layout>
  • 23. NÃO!
  • 24. <layout xmlns:android="http://schemas.android.com/apk/res/android" ...> <data> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <LinearLayout ... > <ImageView android:src="@{book.coverUrl}" ... /> <TextView android:text="@{book.title}" ... /> <TextView android:text="@{book.author}" ... /> <TextView android:text="@{@string/text_format_book_pages(book.pages)}" ... /> <TextView android:text="@{@string/text_format_book_year(book.year)}" ... /> <TextView android:text="@{book.publisher.name}" ... /> <TextView android:text="@{book.available ? @string/text_book_available : @string/text_book_unavailable}" ... /> <TextView android:text="@{book.mediaTypeValue}" ... /> <RatingBar android:progress="@{book.rating}" ... /> </LinearLayout> </layout>
  • 26. public class TextBinding { @BindingAdapter({"android:text"}) public static void setMediaTypeText(TextView textView, MediaType mediaType){ Context context = textView.getContext(); switch (mediaType) { case EBOOK: textView.setText(context.getString(R.string.text_book_media_ebook)); break; case PAPER: textView.setText(context.getString(R.string.text_book_media_paper)); break; default: textView.setText(null); } } } TextBinding.java
  • 28. public class ImageBinding { @BindingAdapter({"android:src"}) public static void setImageUrl(ImageView imageView, String url){ Glide.with(imageView.getContext()) .load(url) .into(imageView); } @BindingAdapter({"android:src", "placeHolder"}) public static void setImageUrl(ImageView imageView, String url, Drawable placeholder){ Glide.with(imageView.getContext()) .load(url) .placeholder(placeholder) .into(imageView); } } ImageBinding.java
  • 30. E se os dados mudarem?
  • 31. public class Book extends BaseObservable { // Atributos... @Bindable public String getTitle() { return title; } public void setTitle(String title) { this.title = title; notifyPropertyChanged(BR.title); } @Bindable public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; notifyPropertyChanged(BR.author); } // Demais getters/setters Book.java
  • 32. public class Book implements Observable { private PropertyChangeRegistry mCallbacks; // Copia as coisas do BaseObservable :) }
  • 33. public class BaseObservable implements Observable { private transient PropertyChangeRegistry mCallbacks; public BaseObservable() { } @Override public synchronized void addOnPropertyChangedCallback(OnPropertyChangedCallback callback) { if (mCallbacks == null) { mCallbacks = new PropertyChangeRegistry(); } mCallbacks.add(callback); } @Override public synchronized void removeOnPropertyChangedCallback(OnPropertyChangedCallback callback) { if (mCallbacks != null) { mCallbacks.remove(callback); } } public synchronized void notifyChange() { if (mCallbacks != null) { mCallbacks.notifyCallbacks(this, 0, null); } } public void notifyPropertyChanged(int fieldId) { if (mCallbacks != null) { mCallbacks.notifyCallbacks(this, fieldId, null); } } }
  • 34. import android.databinding.ObservableBoolean; import android.databinding.ObservableField; import android.databinding.ObservableInt; public class Book { //... private final ObservableField<String> title; private final ObservableInt year; private final ObservableBoolean available; public Book() { //... this.title = new ObservableField<>(); this.year = new ObservableInt(2016); this.available = new ObservableBoolean(false); } public ObservableField<String> getTitle() { return title; } public void setTitle(String title) { this.title.set(title); } public ObservableInt getYear() { return year; } public void setYear(double year) { this.year.set(year); } public ObservableBoolean isAvailable() { return available; } public void setAvailable(boolean available) { this.available.set(available); } }
  • 36. BookFragment.java private FragmentBookBinding mBinding; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_book, container, false); ... return mBinding.getRoot(); }
  • 37. res/layout/item_book.xml <layout ...> <data> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book"/> </data> <android.support.v7.widget.CardView ...> <RelativeLayout ...> <ImageView android:src="@{book.coverUrl}" ... /> <TextView android:text="@{book.title}" ... /> <TextView android:text="@{book.author}" ... /> </RelativeLayout> </android.support.v7.widget.CardView> </layout>
  • 38. BookViewHolder.java public static class BookViewHolder extends RecyclerView.ViewHolder { ItemBookBinding binding; public BookViewHolder(ItemBookBinding binding) { super(binding.getRoot()); this.binding = binding; } }
  • 39. @Override public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ItemBookBinding binding = DataBindingUtil.inflate( LayoutInflater.from(parent.getContext()), R.layout.item_book, parent, false); final BookViewHolder vh = new BookViewHolder(binding); vh.itemView.setOnClickListener(...); return vh; } @Override public void onBindViewHolder(BookViewHolder holder, int pos) { Book book = mBooksList.get(pos); holder.binding.setBook(book); holder.binding.executePendingBindings(); } BookAdapter.java
  • 42. <layout ...> <data> <variable name="texto" type="String"/> </data> <LinearLayout ... > <TextView ... android:id="@+id/textViewNome" android:text="@{texto}" /> <EditText ... android:id="@+id/editTextNome" android:text="@={texto}"/> </LinearLayout> </layout>
  • 44. <layout ...> <data> ... <import type="br.com.nglauber.livrosfirebase.model.MediaType" /> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <LinearLayout ...> <ImageView android:src="@{book.coverUrl}" ... /> <EditText android:text="@={book.title}" ... /> <EditText android:text="@={book.author}" ... /> <EditText android:text="@={book.pages}" ... /> <EditText android:text="@={book.year}" ... /> <Spinner ...> <!-- trataremos desse em breve. --> <CheckBox android:checked="@={book.available}" ... /> <RadioGroup ...> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" ... /> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.PAPER}" ... /> </RadioGroup> <RatingBar android:rating="@={book.rating}" ... /> ... </LinearLayout> </layout>
  • 45. <layout ...> <data> ... <import type="br.com.nglauber.livrosfirebase.model.MediaType" /> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <LinearLayout ...> <ImageView android:src="@{book.coverUrl}" ... /> <EditText android:text="@={book.title}" ... /> <EditText android:text="@={book.author}" ... /> <EditText android:text="@={book.pages}" ... /> <EditText android:text="@={book.year}" ... /> <Spinner ...> <!-- trataremos desse em breve. --> <CheckBox android:checked="@={book.available}" ... /> <RadioGroup ...> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" ... /> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.PAPER}" ... /> </RadioGroup> <RatingBar android:progress="@={book.rating}" ... /> ... </LinearLayout> </layout>
  • 47. Cuidado com loops! EditText
 android:text="@={book.title}" public class Book extends BaseObservable { // Atributos... @Bindable public String getTitle() { return title; } public void setTitle(String title) { this.title = title; notifyPropertyChanged(BR.title); } // Demais getters/setters
  • 48. public class EditTextBindingAdapters { @InverseBindingAdapter(attribute = "android:text") public static int getTextAsInt(EditText editText) { try { return Integer.parseInt(editText.getText().toString()); } catch (Exception e){ return 0; } } @BindingAdapter({"android:text"}) public static void setTextFromInt(EditText editText, int value){ if (getTextAsInt(editText) != value) { editText.setText(String.valueOf(value)); } } } EditTextBindingAdapters.java
  • 50. <layout ...> <data> ... <variable name="presenter" type=“br.com.nglauber.livrosfirebase.DetailEditActivity"/> </data> <LinearLayout ...> ... <TextView ... android:onLongClick="@{presenter::longClick}" /> <Button ... android:onClick=“@{presenter::clickSaveBook}”/> <EditText ... android:onFocusChange="@{presenter::focusChanged}"/> </LinearLayout> </layout> res/layout/activity_detail_edit.xml
  • 51. @Override protected void onCreate(Bundle savedInstanceState) { ... binding.setBook(book); binding.setPresenter(this); } public void clickSaveBook(View view) { Toast.makeText(this, book.toString(), Toast.LENGTH_SHORT).show(); } public boolean longClick(View view){ book.setRating(book.getRating() + 1); return true; } public void focusChanged(View v, boolean focus){ if (!focus) showProduct(v); } DetailEditActivity.java Respeite a assinatura do método
  • 52. <layout ...> <data> <import type="br.com.nglauber.livrosfirebase.model.MediaType" /> ... <variable name="presenter" type="br.com.nglauber.livrosfirebase.DetailEditActivity" /> </data> <LinearLayout ...> ... <RadioGroup ...> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" android:onCheckedChanged="@{presenter::onMediaTypeChanged}" /> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.PAPER}" android:onCheckedChanged="@{presenter::onMediaTypeChanged}" /> </RadioGroup> ... </LinearLayout> </layout>
  • 53. public void onMediaTypeChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { if (buttonView == mBinding.radioMediaEbook) { mBinding.getBook().setMediaTypeValue(MediaType.EBOOK); } else if (buttonView == mBinding.radioMediaPaper) { mBinding.getBook().setMediaTypeValue(MediaType.PAPER); } } }
  • 54. public class Publisher { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return name; } } public class Book extends BaseObservable { private Publisher publisher; ... @Bindable public Publisher getPublisher() { return publisher; } public void setPublisher(Publisher publisher) { this.publisher = publisher; notifyPropertyChanged(BR.publisher); } }
  • 55. <layout ...> <data> <import type="java.util.List"/> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> <variable name="presenter" type="br.com.nglauber.livrosfirebase.DetailEditActivity" /> <variable name="publishers" type="java.util.List&lt;br.com.nglauber.livrosfirebase.model.Publisher&gt;" /> </data>
 <LinearLayout ...> <Spinner ... android:entries="@{publishers}" android:selection="@{publishers.indexOf(book.publisher)}" android:onItemSelected="@{(p, v, pos, id)->book.setPublisher(publishers[pos])}" /> </LinearLayout> </layout>
  • 56. DetailEditActivity.java ObservableList<Publisher> publishers = loadListFromSomewhere(); mBinding.setPublishers(publishers);
  • 61. https://github.com/lisawray/fontbinding public class TextViewBinderAdapter { @BindingAdapter({"font"}) public static void setFont(TextView textView,String font){ AssetManager assets = textView.getContext().getAssets(); Typeface typeface = Typeface.createFromAsset(assets, font); textView.setTypeface(typeface); } } <TextView app:font="@{`FunnyKid.ttf`}" .../>
  • 62. Mas se tiver um “set” pode usar! <android.support.v4.widget.DrawerLayout ... app:scrimColor="@{@color/scrim}" app:drawerListener="@{fragment.drawerListener}"/>
  • 64. Expression Language <TextView ... android:text="@{user.displayName ?? user.lastName}"/> <TextView ... android:text="@{`User: ` + user.name}”/> <LinearLayout ... android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"/>
  • 65. res/values/colors.xml <color name="red">#F00</color> <color name="black">#000</color> <TextView ... android:id="@+id/text_title" android:textColor="@{book.available ? @color/black : @color/red}" android:text="@{book.title}" />
  • 66. res/values/strings.xml <string name="price_format">$ %1$.2f</string> <TextView ... android:id="@+id/text_price" android:text="@{@string/price_format(book.price)}" /> getString(R.string.price_format, product.price);
  • 67. Include <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="book" type=“...Book”/> <variable name=“presenter" type=“...DetailEditActivity" /> </data> <LinearLayout ...> <include android:id="@+id/content" layout="@layout/content_detail_edit" app:presenter="@{presenter}" app:book="@{book}" /> </LinearLayout> </layout>
  • 68. Include ActivityDetailEditBinding mBinding = DataBindingUtil.setContentView(this, R.layout.activity_detail_edit); mBinding.setBook(book); mBinding.setPresenter(this); mBinding.content.setPublishers(new ObservableArrayList<Publisher>());
  • 69. Expression Chain <layout ...> <data> <import type="android.view.View" /> ... </data> <LinearLayout ...> <ImageView ... android:id="@+id/image_cover" android:visibility="@{book.available ? View.VISIBLE : View.INVISIBLE}" /> <RadioGroup ... android:id="@+id/radio_group_media_type" android:visibility="@{imageCover.visibility}" /> <RatingBar android:visibility="@{radioGroupMediaType.visibility}" android:id=“@+id/rating_book"> <CheckBox ... android:id="@+id/check_available" android:checked="@={book.available}" />
  • 70. Ouvindo coisas… :) binding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() { @Override public void onPropertyChanged(Observable observable, int i) { if (i == br.com.nglauber.uidemo.BR.name){ Product p = (Product)observable; Log.d("NGVL", p.getName()); } } });
  • 71. Ouvindo coisas… :) Use para animações binding.addOnRebindCallback(new OnRebindCallback() { @Override public boolean onPreBind(ViewDataBinding binding) { return super.onPreBind(binding); } @Override public void onCanceled(ViewDataBinding binding) { super.onCanceled(binding); } @Override public void onBound(ViewDataBinding binding) { super.onBound(binding); } });
  • 72. Aplicando no seu projeto 1. Remova os findViewById’s :) 2. Faça o Binding dos seus objetos. 3. Use os callbacks (eventos) de UI. 4. Aproveite os objetos observáveis. 5. Two-way Data Binding é vida! ♥
  • 73. Boas práticas • Não coloque lógica de negócios na tela. Apenas lógica de tela. • Os eventos disparados executarão na UI Thread. • Simplifique a lógica de UI (não coloque expressões complicadas, crie métodos para isso. • Considere utilizar um ViewModel. • Leve os BinderAdapters com você :) Você só vai precisar escrevê- los uma vez. // TODO: Fazer uma lib para isso :p
  • 74. Referências • Data Binding -- Write Apps Faster (Android Dev Summit 2015)
 https://www.youtube.com/watch?v=NBbeQMOcnZ0 • Data Binding Documentation (pode melhorar né…?)
 http://developer.android.com/tools/data-binding/guide.html • Nelson Glauber Blog
 http://www.nglauber.com.br/2016/05/android-data-binding.html • Advanced Data Binding (Google I/O 2016)
 https://www.youtube.com/watch?v=DAmMN7m3wLU