Share
Embed
Transcript
306 slides
-
Source: place source info here 2 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 1 2 3 4 5 6 7 8 -
private TextView mName protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); mName
= (TextView) findViewById(R.id.name); 4 ; public void updateUI(User user) { if (user == null) { mName.setText(null); } } } else { } mName.setText(user.getName()); -
private protected void setContentView(R.layout. mName 4 ; public
void } } } else { } -
private protected void setContentView(R.layout. mName 4 ,mLastName ;
public void } } } else { } -
private protected void setContentView(R.layout. mName 4 ,mLastName mLastName
= (TextView) findViewById(R.id.lastName); ; public void } } } else { } -
private protected void setContentView(R.layout. mName 4 ,mLastName mLastName
= (TextView) findViewById(R.id.lastName); mLastName.setText(null); ; public void } } } else { } -
private protected void setContentView(R.layout. mName 4 ,mLastName mLastName
= (TextView) findViewById(R.id.lastName); mLastName.setText(null); mLastName.setText(user.getLastName()); ; public void } } } else { } -
private TextView mName protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); mName
= (TextView) findViewById(R.id.name); 4 ,mLastName mLastName = (TextView) findViewById(R.id.lastName); mLastName.setText(null); mLastName.setText(user.getLastName()); ; public void updateUI(User user) { if (user == null) { mName.setText(null); } } } else { } mName.setText(user.getName()); -
Source: place source info here 5 } public void updateUI(User
user) { if (user == null) { mName.setText(null); mLastName.setText(null); } else { mName.setText(user.getName()); mLastName.setText(user.getLastName()); } } private private protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); R.id.name R.id.lastName TextView mName; TextView mLastName; mName = (TextView) findViewById( ); mLastName = (TextView) findViewById( ); -
Source: place source info here 5 } public void }
} } private private protected void setContentView(R.layout. R.id.name R.id.lastName TextView mName; TextView mLastName; mName = (TextView) findViewById( ); mLastName = (TextView) findViewById( ); -
Source: place source info here 5 } public void }
} } private private protected void setContentView(R.layout. R.id.name R.id.lastName TextView mName; TextView mLastName; @Bind( ) @Bind( ) mName = (TextView) findViewById( ); mLastName = (TextView) findViewById( ); -
Source: place source info here 5 } public void }
} } private private protected void setContentView(R.layout. R.id.name R.id.lastName TextView mName; TextView mLastName; @Bind( ) @Bind( ) ButterKnife.bind(this); -
Source: place source info here 5 } public void updateUI(User
user) { if (user == null) { mName.setText(null); mLastName.setText(null); } else { mName.setText(user.getName()); mLastName.setText(user.getLastName()); } } private private protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); R.id.name R.id.lastName TextView mName; TextView mLastName; @Bind( ) @Bind( ) ButterKnife.bind(this); -
protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); } public
void updateUI(User user) { if (user == null) { } else { } } Source: place source info here 6 private @Bind(R.id.name) TextView name; private @Bind(R.id.lastName) TextView lastName; ButterKnife.bind(this); name.setText(null); lastName.setText(null); name.setText(user.getName()); lastName.setText(user.getLastName()); -
protected void setContentView(R.layout. } public void if
} } } Source: place source info here 6 private @Bind(R.id.name) TextView name; private @Bind(R.id.lastName) TextView lastName; ButterKnife.bind(this); name.setText(null); lastName.setText(null); name.setText(user.getName()); lastName.setText(user.getLastName()); -
protected void setContentView(R.layout. } public void if
} } } Source: place source info here 6 ButterKnife.bind(this); private Holdr_ActivityMain holder; name.setText(null); lastName.setText(null); name.setText(user.getName()); lastName.setText(user.getLastName()); -
protected void setContentView(R.layout. } public void if
} } } holder = new Holdr_ActivityMain(findViewById(content)); Source: place source info here 6 private Holdr_ActivityMain holder; name.setText(null); lastName.setText(null); name.setText(user.getName()); lastName.setText(user.getLastName()); -
protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); } public
void updateUI(User user) { if (user == null) { } else { } } holder = new Holdr_ActivityMain(findViewById(content)); Source: place source info here 6 private Holdr_ActivityMain holder; name.setText(null); lastName.setText(null); name.setText(user.getName()); lastName.setText(user.getLastName()); holder. holder. holder. holder. -
Source: place source info here private Holdr_ActivityMain holder; protected void
onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); holder = new Holdr_ActivityMain(findViewById(content)); } public void updateUI(User user) { if (user == null) { holder.name.setText(null); holder.lastName.setText(null); } else { holder.name.setText(user.getName()); holder.lastName.setText(user.getLastName()); } } 7 -
Source: place source info here private Holdr_ActivityMain holder; protected void
onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); holder = new Holdr_ActivityMain(findViewById(content)); } public void updateUI(User user) { if (user == null) { holder.name.setText(null); holder.lastName.setText(null); } else { holder.name.setText(user.getName()); holder.lastName.setText(user.getLastName()); } } 7 -
Source: place source info here protected void onCreate(Bundle savedInstanceState)
{ } public void updateUI(User user) { 8 private Holdr_ActivityMain mHolder; setContentView(R.layout.activity_main); mHolder = new Holdr_ActivityMain(findViewById(content)); if (user == null) { mHolder.name.setText(null); mHolder.lastName.setText(null); } else { mHolder.name.setText(user.getName()); mHolder.lastName.setText(user.getLastName()); } } -
Source: place source info here protected void } public
void 8 private Holdr_ActivityMain mHolder; setContentView(R.layout.activity_main); mHolder = new Holdr_ActivityMain(findViewById(content)); if (user == null) { mHolder.name.setText(null); mHolder.lastName.setText(null); } else { mHolder.name.setText(user.getName()); mHolder.lastName.setText(user.getLastName()); } } -
Source: place source info here protected void } public
void 8 setContentView(R.layout.activity_main); mHolder = new Holdr_ActivityMain(findViewById(content)); if (user == null) { mHolder.name.setText(null); mHolder.lastName.setText(null); } else { mHolder.name.setText(user.getName()); mHolder.lastName.setText(user.getLastName()); } private ActivityMainBinding mBinding; } -
Source: place source info here protected void } public
void 8 if (user == null) { mHolder.name.setText(null); mHolder.lastName.setText(null); } else { mHolder.name.setText(user.getName()); mHolder.lastName.setText(user.getLastName()); } mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); private ActivityMainBinding mBinding; } -
Source: place source info here protected void } public
void 8 mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); private ActivityMainBinding mBinding; mBinding.setUser(user); } -
Source: place source info here protected void } public
void 8 mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); private ActivityMainBinding mBinding; mBinding.setUser(user); } -
Source: place source info here protected void onCreate(Bundle savedInstanceState)
{ } public void updateUI(User user) { 8 mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); private ActivityMainBinding mBinding; mBinding.setUser(user); } -
Source: place source info here 9 <TextView android: /> <TextView
android: /> <LinearLayout …> </LinearLayout> id="@+id/name" id="@+id/lastName" -
Source: place source info here 9 <TextView android: /> <TextView
android: /> <LinearLayout …> </LinearLayout> -
Source: place source info here 9 <TextView android: /> <TextView
android: /> <LinearLayout …> </LinearLayout> text="@{user.name}" text="@{user.lastName}" -
Source: place source info here 9 <TextView android: /> <TextView
android: /> <LinearLayout …> </LinearLayout> text="@{user.name}" text="@{user.lastName}" ? -
Source: place source info here 9 <TextView android: /> <TextView
android: /> <LinearLayout …> </LinearLayout> text="@{user.name}" text="@{user.lastName}" <layout> <data> <variable name=“user” type="com.android.example.User"/> </data> </layout> -
Source: place source info here 10 </LinearLayout> </layout> <TextView android:
/> <TextView android: /> <LinearLayout …> text="@{user.lastName}" <layout> <data> <variable name=“user” type="com.android.example.User"/> </data> text="@{user.name}" -
Source: place source info here 10 </LinearLayout> </layout> <TextView android:
/> <TextView android: /> <LinearLayout …> text="@{user.lastName}" <layout> <data> <variable name=“user” type="com.android.example.User"/> </data> text="@{user.name}" <TextView android:text=‘@{“” + user.age}’/> -
Source: place source info here 10 </LinearLayout> </layout> <TextView android:
/> <TextView android: /> <LinearLayout …> text="@{user.lastName}" <layout> <data> <variable name=“user” type="com.android.example.User"/> </data> text="@{user.name}" <TextView android:text=‘@{“” + user.age}’/> -
Source: place source info here 11 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 2 1 3 4 5 6 7 8 -
Source: place source info here What is happening ? 12
Process Layout Files -
Source: place source info here What is happening ? 12
Process Layout Files <TextView /> android:visibility=“@{user.isAdmin ? View.VISIBLE : View.GONE}” -
Source: place source info here What is happening ? 12
Process Layout Files <TextView /> -
user.isAdmin ? View.VISIBLE : View.GONE Source: place source info here
What is happening ? 12 Process Layout Files Parse Expressions -
user.isAdmin ? View.VISIBLE : View.GONE Source: place source info here
What is happening ? 12 Process Layout Files Parse Expressions -
user.isAdmin ? View.VISIBLE : View.GONE Source: place source info here
What is happening ? 12 Process Layout Files Parse Expressions ID ID ID -
user.isAdmin ? View.VISIBLE : View.GONE Source: place source info here
What is happening ? 12 Process Layout Files Parse Expressions ID field access field access ID ID field access -
user.isAdmin ? View.VISIBLE : View.GONE Source: place source info here
What is happening ? 12 Process Layout Files Parse Expressions ID field access field access Ternary ID ID field access -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies user.isAdmin -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies user.isAdmin variable -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies user.isAdmin variable boolean isAdmin() -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies user.isAdmin variable boolean isAdmin() boolean -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies Write Data Binders -
Source: place source info here What is happening ? 12
Process Layout Files Parse Expressions Resolve Dependencies Write Data Binders -
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Source: place source info here 13 <layout > <data> <variable name="user" type="com.android.example.User"/> </data> </layout> xmlns:android="http://schemas.android.com/apk/res/android" android:text="@{user.name}" android:text="@{user.lastname}" -
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Source: place source info here 13 xmlns:android="http://schemas.android.com/apk/res/ android:text="@{user.name}" android:text="@{user.lastname}" -
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Source: place source info here 13 xmlns:android="http://schemas.android.com/apk/res/ -
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Source: place source info here 13 xmlns:android="http://schemas.android.com/apk/res/ android:tag="binding_1" android:tag="binding_2" -
Source: place source info here 14 <TextView android:text=“@{ }"/> user.age
< 18 ? @string/redacted user.name : -
Source: place source info here 14 <TextView android:text=“@{ }"/> user.age
< 18 ? @string/redacted user.name : -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User int User String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int User String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int int boolean User String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int int boolean User getName() String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int int boolean User getName() String String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int int boolean User getName() String String String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int int boolean User getName() String String String -
Source: place source info here 14 <TextView android:text=“@{ }"/> user
. age < 18 ? @string/redacted user . name : User getAge() int int boolean User getName() String String String setText(CharSequence) -
Source: place source info here Resolving Setters 15 <TextView android:text="@{myVariable}"/>
textView.setText(myVariable); -
Source: place source info here Resolving Setters 15 <TextView textView.setText(myVariable);
<ImageView android:src="@{user.image}"/> -
Source: place source info here Resolving Setters 15 <TextView textView.setText(myVariable);
<ImageView android:src="@{user.image}"/> imageView.setSrc(user.image); -
Source: place source info here Resolving Setters 15 <TextView textView.setText(myVariable);
<ImageView android:src="@{user.image}"/> imageView.setSrc(user.image); -
imageView.setImageResource(user.image); Source: place source info here Resolving Setters 15 <TextView
textView.setText(myVariable); <ImageView android:src="@{user.image}"/> -
imageView.setImageResource(user.image); Source: place source info here Resolving Setters 15 <TextView
textView.setText(myVariable); <ImageView android:src="@{user.image}"/> @BindingMethod( type = android.widget.ImageView.class, attribute = "android:src", method = "setImageResource") -
Source: place source info here 16 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 3 1 2 4 5 6 7 8 -
obj. Expression language is mostly Java 18 obj. obj. obj.
obj. obj.friends[selectedIndex] -
obj. Expression language is mostly Java 18 obj. obj. View.VISIBLE
obj. obj. obj. obj.admin ? View.VISIBLE : View.GONE -
Short and readable 19 Fields access shortcut contact.name public
String name; public String getName() {…} public boolean isName() {…} public String name() {…} -
Short and readable 19 Automatic null check contact.friend.name Fields access
shortcut contact.name public String name; public String getName() {…} public boolean isName() {…} public String name() {…} -
Short and readable 19 Null coalescing operator contact.lastName ?? contact.name
contact.lastName != null ? contact.lastName : contact.name Automatic null check contact.friend.name Fields access shortcut contact.name public String name; public String getName() {…} public boolean isName() {…} public String name() {…} -
Short and readable 19 List & Map Access contacts[0]
contactInfo["firstName"] Null coalescing operator contact.lastName ?? contact.name contact.lastName != null ? contact.lastName : contact.name Automatic null check contact.friend.name Fields access shortcut contact.name public String name; public String getName() {…} public boolean isName() {…} public String name() {…} -
Resources In Expressions android:padding="@{isBig ? @dimen/bigPadding : @dimen/smallPadding}" Inline string
formatting android:text="@{@string/nameFormat(firstName, lastName)}" 20 -
Resources In Expressions android:padding="@{isBig ? @dimen/bigPadding : @dimen/smallPadding}" Inline
string formatting android:text="@{@string/nameFormat(firstName, lastName)}" Inline plurals android:text="@{@plurals/banana(bananaCount)}" 20 -
Automagic Attributes <android.support.v4.widget.DrawerLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" app:scrimColor="@{@color/scrim}"/> drawerLayout.setScrimColor( resources.getColor(R.color.scrim)) 21 -
Event Handlers 22 <Button android:onClick="clicked" …/> <Button android:onClick="@{handlers.clicked}"
…/> <Button android:onClick="@{isAdult ? handlers.adultClick : handlers.childClick}" …/> -
Event Handlers 22 <Button android:onClick="clicked" …/> <Button android:onClick="@{handlers.clicked}"
…/> <Button android:onClick="@{isAdult ? handlers.adultClick : handlers.childClick}" …/> <Button android:onTextChanged="@{handlers.textChanged}" …/> -
Source: place source info here 23 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 4 1 3 2 5 6 7 8 -
26 Image: pink_droid Price: $20.06 public class Item extends BaseObservable
{ private String price; @Bindable public String getPrice() { return this.name; } public void setPrice(String price) { this.price = price; notifyPropertyChanged(BR.price); } } -
26 Image: pink_droid Price: $20.06 public class Item extends BaseObservable
{ private String price; @Bindable public String getPrice() { return this.name; } public void setPrice(String price) { this.price = price; notifyPropertyChanged(BR.price); } } -
26 Image: pink_droid Price: $20.06 public class Item extends BaseObservable
{ private String price; @Bindable public String getPrice() { return this.name; } public void setPrice(String price) { this.price = price; notifyPropertyChanged(BR.price); } } -
26 Image: pink_droid Price: $20.06 public class Item extends BaseObservable
{ private String price; @Bindable public String getPrice() { return this.name; } public void setPrice(String price) { this.price = price; notifyPropertyChanged(BR.price); } } -
27 Image: pink_droid Price: $20.06 public class Item implements Observable
{ private PropertyChangeRegistry callbacks = new … … @Override public void addOnPropertyChangedCallback( OnPropertyChangedCallback callback) { callbacks.add(callback); } @Override public void removeOnPropertyChangedCallback( OnPropertyChangedCallback callback) { callbacks.remove(callback); } } -
28 Image: pink_droid Price: $20.06 public class Item {
public final ObservableField<Drawable> image = new ObservableField<>(); public final ObservableField<String> price = new ObservableField<>(); public final ObservableInt inventory = new ObservableInt(); } item.price.set("$33.41"); -
28 Image: pink_droid Price: $20.06 public class Item {
public final ObservableField<Drawable> image = new ObservableField<>(); public final ObservableField<String> price = new ObservableField<>(); public final ObservableInt inventory = new ObservableInt(); } item.price.set("$33.41"); -
29 Image: pink_droid Price: $20.06 ObservableMap<String, Object> item =
new ObservableArrayMap<>(); item.put("price", "$33.41"); <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text='@{item["price"]}'/> -
29 Image: pink_droid Price: $20.06 ObservableMap<String, Object> item =
new ObservableArrayMap<>(); item.put("price", "$33.41"); <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text='@{item["price"]}'/> -
Photo by Chet Haase Notify on any thread • UI
updates scheduled for next frame • Data read on UI thread • Only remove items from lists on the UI thread! 30 -
Photo by Chet Haase Notify on any thread • UI
updates scheduled for next frame • Data read on UI thread • Only remove items from lists on the UI thread! 30 -
Source: place source info here 31 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 5 1 3 2 4 6 7 8 -
Source: place source info here 34 <TextView android:text="@{user.address.street}"/> <TextView android:text="@{user.address.city}"/>
Address address = user.getAddress(); String street = address.getStreet(); String city = address.getCity(); -
Source: place source info here findViewById Traversal 35 view.findViewById(…) children[0].findViewById(…)
children[1].findViewById(…) -
Source: place source info here findViewById Traversal 35 view.findViewById(…) children[0].findViewById(…)
children[1].findViewById(…) -
Source: place source info here findViewById Traversal 35 view.findViewById(…) children[0].findViewById(…)
children[1].findViewById(…) -
Source: place source info here One Pass View Collection 36
findAllViews(root, View[]) -
Source: place source info here One Pass View Collection 36
findAllViews(root, View[]) findAllViews(child[0], View[]) -
Source: place source info here One Pass View Collection 36
findAllViews(root, View[]) findAllViews(child[0], View[]) findAllViews(child[0], View[]) -
Source: place source info here One Pass View Collection 36
findAllViews(root, View[]) findAllViews(child[0], View[]) findAllViews(child[0], View[]) -
Source: place source info here One Pass View Collection 36
findAllViews(root, View[]) findAllViews(child[0], View[]) findAllViews(child[0], View[]) NO SECOND PASS -
Source: place source info here 37 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 6 1 3 2 4 5 7 8 -
public class UserViewHolder extends RecyclerView.ViewHolder { } Source:
place source info here 38 -
public class UserViewHolder extends RecyclerView.ViewHolder { } static
UserViewHolder create(LayoutInflater inflater, ViewGroup parent) { UserItemBinding binding = UserItemBinding .inflate(inflater, parent, false); return new UserViewHolder(binding); } Source: place source info here 38 -
public class UserViewHolder extends RecyclerView.ViewHolder { } static
UserViewHolder create(LayoutInflater inflater, ViewGroup parent) { UserItemBinding binding = UserItemBinding .inflate(inflater, parent, false); return new UserViewHolder(binding); } Source: place source info here 38 private UserItemBinding mBinding; private UserViewHolder(UserItemBinding binding) { super(binding.getRoot()); mBinding = binding; } -
public class UserViewHolder extends RecyclerView.ViewHolder { } static
UserViewHolder create(LayoutInflater inflater, ViewGroup parent) { UserItemBinding binding = UserItemBinding .inflate(inflater, parent, false); return new UserViewHolder(binding); } Source: place source info here 38 private UserItemBinding mBinding; private UserViewHolder(UserItemBinding binding) { super(binding.getRoot()); mBinding = binding; } public void bindTo(User user) { mBinding.setUser(user); mBinding.executePendingBindings(); } -
public class UserViewHolder extends RecyclerView.ViewHolder { } static
UserViewHolder create(LayoutInflater inflater, ViewGroup parent) { UserItemBinding binding = UserItemBinding .inflate(inflater, parent, false); return new UserViewHolder(binding); } Source: place source info here 38 private UserItemBinding mBinding; private UserViewHolder(UserItemBinding binding) { super(binding.getRoot()); mBinding = binding; } public void bindTo(User user) { mBinding.setUser(user); mBinding.executePendingBindings(); } -
Source: place source info here 39 public UserViewHolder onCreateViewHolder(ViewGroup viewGroup,
int i) { return UserViewHolder.create(mLayoutInflater, viewGroup); } public void onBindViewHolder(UserViewHolder userViewHolder, int position) { userViewHolder.bindTo(mUserList.get(position)); } -
Source: place source info here What happens when user is
updated? 40 user.notifyPropertyChanged(BR.name); -
Source: place source info here What happens when user is
updated? 40 user.notifyPropertyChanged(BR.name); binding.requestRebind(); -
Source: place source info here What happens when user is
updated? 40 user.notifyPropertyChanged(BR.name); binding.requestRebind(); textView.setText(user.name); -
Source: place source info here What happens when user is
updated? 40 user.notifyPropertyChanged(BR.name); binding.requestRebind(); textView.setText(user.name); textView.requestLayout(); -
Source: place source info here What happens when user is
updated? 40 user.notifyPropertyChanged(BR.name); binding.requestRebind(); textView.setText(user.name); textView.requestLayout(); recyclerView.onLayout(…); -
Source: place source info here What happens when user is
updated? 40 user.notifyPropertyChanged(BR.name); binding.requestRebind(); textView.setText(user.name); textView.requestLayout(); recyclerView.onLayout(…); NO ANIMATIONS! -
Source: place source info here What we want it to
happen? 41 user.notifyPropertyChanged(BR.name); -
Source: place source info here What we want it to
happen? 41 user.notifyPropertyChanged(BR.name); adapter.notifyItemChanged(…); -
Source: place source info here What we want it to
happen? 41 user.notifyPropertyChanged(BR.name); adapter.notifyItemChanged(…); recyclerView.onLayout(…); -
Source: place source info here What we want it to
happen? 41 user.notifyPropertyChanged(BR.name); adapter.notifyItemChanged(…); adapter.onBind(…); recyclerView.onLayout(…); -
Source: place source info here What we want it to
happen? 41 user.notifyPropertyChanged(BR.name); textView.setText(user.name); adapter.notifyItemChanged(…); adapter.onBind(…); recyclerView.onLayout(…); -
Source: place source info here What we want it to
happen? 41 user.notifyPropertyChanged(BR.name); textView.setText(user.name); adapter.notifyItemChanged(…); adapter.onBind(…); recyclerView.onLayout(…); MUCHO ANIMATIONS! -
Source: place source info here 42 public UserViewHolder onCreateViewHolder(ViewGroup viewGroup,
int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } public boolean onPreBind(ViewDataBinding binding) { } -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } public boolean onPreBind(ViewDataBinding binding) { } public void onCanceled(ViewDataBinding binding) { } -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } public boolean onPreBind(ViewDataBinding binding) { } public void onCanceled(ViewDataBinding binding) { } return mRecyclerView != null && mRecyclerView.isComputingLayout(); -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } public boolean onPreBind(ViewDataBinding binding) { } public void onCanceled(ViewDataBinding binding) { } return mRecyclerView != null && mRecyclerView.isComputingLayout(); if (mRecyclerView == null || mRecyclerView.isComputingLayout()) { return; } int position = holder.getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { notifyItemChanged(position, DATA_INVALIDATION); } -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } public boolean onPreBind(ViewDataBinding binding) { } public void onCanceled(ViewDataBinding binding) { } return mRecyclerView != null && mRecyclerView.isComputingLayout(); if (mRecyclerView == null || mRecyclerView.isComputingLayout()) { return; } int position = holder.getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { notifyItemChanged(position, DATA_INVALIDATION); } -
holder.getBinding().addOnRebindCallback(new OnRebindCallback() { }); Source: place source info here 42
public UserViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final UserViewHolder holder = UserViewHolder.create(mLayoutInflater, viewGroup); return holder; } public boolean onPreBind(ViewDataBinding binding) { } public void onCanceled(ViewDataBinding binding) { } return mRecyclerView != null && mRecyclerView.isComputingLayout(); if (mRecyclerView == null || mRecyclerView.isComputingLayout()) { return; } int position = holder.getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { notifyItemChanged(position, DATA_INVALIDATION); } PAYLOAD -
Source: place source info here 43 public void onBindViewHolder(UserViewHolder userViewHolder,
int position) { userViewHolder.bindTo(mUserList.get(position)); } -
Source: place source info here 43 public void onBindViewHolder(UserViewHolder userViewHolder,
int position) { userViewHolder.bindTo(mUserList.get(position)); } public void onBindViewHolder(UserViewHolder holder, int position, List<Object> payloads) { } -
Source: place source info here 43 public void onBindViewHolder(UserViewHolder userViewHolder,
int position) { userViewHolder.bindTo(mUserList.get(position)); } public void onBindViewHolder(UserViewHolder holder, int position, List<Object> payloads) { } notifyItemChanged(position, DATA_INVALIDATION); -
Source: place source info here 43 public void onBindViewHolder(UserViewHolder userViewHolder,
int position) { userViewHolder.bindTo(mUserList.get(position)); } public void onBindViewHolder(UserViewHolder holder, int position, List<Object> payloads) { } -
Source: place source info here 43 public void onBindViewHolder(UserViewHolder userViewHolder,
int position) { userViewHolder.bindTo(mUserList.get(position)); } public void onBindViewHolder(UserViewHolder holder, int position, List<Object> payloads) { } if (isForDataBinding(payloads)) { holder.getBinding().executePendingBindings(); } else { onBindViewHolder(holder, position); } -
Source: place source info here 44 private boolean isForDataBinding(List<Object> payloads)
{ } if (payloads == null || payloads.size() == 0) { return false; } for (Object obj : payloads) { if (obj != DATA_INVALIDATION) { return false; } } return true; -
Source: place source info here 44 private boolean isForDataBinding(List<Object> payloads)
{ } static Object DATA_INVALIDATION = new Object(); if (payloads == null || payloads.size() == 0) { return false; } for (Object obj : payloads) { if (obj != DATA_INVALIDATION) { return false; } } return true; -
<layout> <data> <variable name="data" type=“com.example. "/> </data> Multiple View
Types 45 </layout> Photo <ImageView android:src=“@{data.url}" …/> -
<layout < < </ Multiple View Types 45 </
Photo <ImageView android:src=“@{data.url}" …/> -
<layout < < </ Multiple View Types 45 </
<ImageView android:src=“@{data.url}" …/> -
<layout < < </ Multiple View Types 45 </
Place <ImageView android:src=“@{data.url}" …/> -
<layout < < </ Multiple View Types 45 </
Place <TextView android:text=“@{data.name}" …/> <ImageView android:src="@{data.isFav ? @drawable/active : @drawable/passive}” -
<layout> <data> <variable name="data" type=“com.example. "/> </data> Multiple View
Types 45 </ Place <TextView android:text=“@{data.name}" …/> <ImageView android:src="@{data.isFav ? @drawable/active : @drawable/passive}” -
Source: place source info here public class }
46 private ViewDataBinding mBinding; -
Source: place source info here public class }
46 private public DataBoundViewHolder(ViewDataBinding binding) { super(binding.getRoot()); mBinding = binding; } -
Source: place source info here public class }
46 private public } public ViewDataBinding getBinding() { return mBinding; } -
Source: place source info here public class }
46 private public } public ViewDataBinding getBinding() { return mBinding; } public void bindTo( ) { mBinding mBinding.executePendingBindings(); } .setPlace(place); Place place -
Source: place source info here public class }
46 private public } public ViewDataBinding getBinding() { return mBinding; } public void bindTo( ) { mBinding mBinding.executePendingBindings(); } METHOD DOES NOT EXIST! .setPlace(place); Place place -
Source: place source info here public class }
46 private public } public ViewDataBinding getBinding() { return mBinding; } public void bindTo( ) { mBinding mBinding.executePendingBindings(); } -
.setVariable(BR.data, obj); Object obj Source: place source info here public
class } 46 private public } public ViewDataBinding getBinding() { return mBinding; } public void bindTo( ) { mBinding mBinding.executePendingBindings(); } -
.setVariable(BR.data, obj); Object obj Source: place source info here public
class DataBoundViewHolder extends RecyclerView.ViewHolder { } 46 private ViewDataBinding mBinding; public DataBoundViewHolder(ViewDataBinding binding) { super(binding.getRoot()); mBinding = binding; } public ViewDataBinding getBinding() { return mBinding; } public void bindTo( ) { mBinding mBinding.executePendingBindings(); } boolean setVariable(int id, Object obj) { if (id == BR.data) { setPhoto((Photo) obj); return true; } return false; } -
47 DataBoundViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) { return DataBoundViewHolder.create(mLayoutInflater, viewGroup,
type); } void onBindViewHolder(DataBoundViewHolder viewHolder, int position) { viewHolder.bindTo(mDataList.get(position)); } -
47 DataBoundViewHolder onCreateViewHolder(ViewGroup viewGroup, return } void viewHolder.bindTo( }
public int getItemViewType(int position) { Object item = mItems.get(position); } -
47 DataBoundViewHolder onCreateViewHolder(ViewGroup viewGroup, return } void viewHolder.bindTo( }
public int Object item = } if (item instanceof Place) { return R.layout.place_layout; } else if (item instanceof Photo) { return R.layout.photo_layout; } throw new RuntimeException("invalid obj"); -
47 DataBoundViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) { return DataBoundViewHolder.create(mLayoutInflater, viewGroup,
type); } void onBindViewHolder(DataBoundViewHolder viewHolder, int position) { viewHolder.bindTo(mDataList.get(position)); } public int getItemViewType(int position) { Object item = mItems.get(position); } if (item instanceof Place) { return R.layout.place_layout; } else if (item instanceof Photo) { return R.layout.photo_layout; } throw new RuntimeException("invalid obj"); -
Source: place source info here 48 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 7 2 3 4 5 6 1 8 -
Something a bit more complex than setText 50 <ImageView …
android:src="@{contact.largeImageUrl}" /> -
Something a bit more complex than setText 50 <ImageView …
android:src="@{contact.largeImageUrl}" /> @BindingAdapter("android:src") public static void setImageUrl(ImageView view, String url) { Picasso.with(view.getContext()).load(url).into(view); } -
Attributes working together 51 <ImageView … android:src="@{contact.largeImageUrl}"
app:placeHolder=“@{R.drawable.contact_placeholder}"/> -
Attributes working together 51 <ImageView … android:src="@{contact.largeImageUrl}"
app:placeHolder=“@{R.drawable.contact_placeholder}"/> @BindingAdapter(value = {"android:src", "placeHolder"}, requireAll = false) public static void setImageUrl(ImageView view, String url, int placeHolder) { RequestCreator requestCreator = Picasso.with(view.getContext()).load(url); if (placeHolder != 0) { requestCreator.placeholder(placeHolder); } requestCreator.into(view); } -
Using Previous Values 52 @BindingAdapter("android:onLayoutChange") public static void setOnLayoutChangeListener(View view,
View.OnLayoutChangeListener oldValue, View.OnLayoutChangeListener newValue) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { if (oldValue != null) { view.removeOnLayoutChangeListener(oldValue); } if (newValue != null) { view.addOnLayoutChangeListener(newValue); } } } -
Dependency Injection 53 public interface TestableAdapter {
@BindingAdapter("android:src") void setImageUrl(ImageView imageView, String url); } -
Dependency Injection 53 public interface TestableAdapter {
@BindingAdapter("android:src") void setImageUrl(ImageView imageView, String url); } public interface DataBindingComponent { TestableAdapter getTestableAdapter(); } -
Dependency Injection 53 public interface TestableAdapter {
@BindingAdapter("android:src") void setImageUrl(ImageView imageView, String url); } public interface DataBindingComponent { TestableAdapter getTestableAdapter(); } DataBindingUtil.setDefaultComponent(myComponent); -
Dependency Injection 53 public interface TestableAdapter {
@BindingAdapter("android:src") void setImageUrl(ImageView imageView, String url); } public interface DataBindingComponent { TestableAdapter getTestableAdapter(); } DataBindingUtil.setDefaultComponent(myComponent); -‐ or -‐ binding = MyLayoutBinding.inflate(layoutInflater, myComponent); -
Component For Context 54 @BindingAdapter("android:src") public static void setImageUrl(MyAppComponent
component, ImageView view, String imageUrl) { component.getImageCache().loadInto(view, imageUrl); } -
Event Handlers 55 <Button … android:onClick=“@{isAdmin ? handler.adminClick :
handler.userClick}” /> -
Event Handlers 55 <Button … android:onClick=“@{isAdmin ? handler.adminClick :
handler.userClick}” /> No “setOnClick” method for View. Need a way to find it. @BindingMethods({ @BindingMethod(type = View.class, attribute = “android:onClick", method = “setOnClickListener"}) -
Event Handlers 55 <Button … android:onClick=“@{isAdmin ? handler.adminClick :
handler.userClick}” /> No “setOnClick” method for View. Need a way to find it. @BindingMethods({ @BindingMethod(type = View.class, attribute = “android:onClick", method = “setOnClickListener"}) Look for setOnClickListener in View void setOnClickListener(View.OnClickListener l) -
Event Handlers 55 <Button … android:onClick=“@{isAdmin ? handler.adminClick :
handler.userClick}” /> No “setOnClick” method for View. Need a way to find it. @BindingMethods({ @BindingMethod(type = View.class, attribute = “android:onClick", method = “setOnClickListener"}) Look for setOnClickListener in View void setOnClickListener(View.OnClickListener l) Look for single abstract method in OnClickListener void onClick(View v); -
Event Handlers 56 static class OnClickListenerImpl1 implements OnClickListener {
public Handler mHandler; @Override public void onClick(android.view.View arg0) { mHandler.adminClick(arg0); } } static class OnClickListenerImpl2 implements OnClickListener { public Handler mHandler; @Override public void onClick(android.view.View arg0) { mHandler.userClick(arg0); } } -
Source: place source info here 57 Why Data Binding How
Data Binding Works Data Binding Goodies Observability in Detail Performance RecyclerView / ListView and Data Binding Binding Adapters and Callbacks Best Practices 8 2 3 4 5 6 1 7 -
Source: place source info here No Business Logic in Expressions
58 <ImageView android:click=“ "/> @{webservice.sendMoneyAsync} -
Source: place source info here No Business Logic in Expressions
58 <ImageView android:click=“ "/> -
Source: place source info here No Business Logic in Expressions
58 <ImageView android:click=“ "/> @{presenter.onSendClick} -
Source: place source info here Simple UI Logic is Welcome
59 <ImageView android:src="@{user.age > 18 ? @drawable/adult : @drawable/kid}" /> -
Source: place source info here <TextView android:text=‘@{user.age > 18 ?
Keep your expressions simple 60 user.name.substring(0,1).toUpperCase() + "." + user.lastName : @string/redacted}’/> -
Source: place source info here <TextView android:text=‘@{user.age > 18 ?
Keep your expressions simple 60 user.displayName : @string/redacted}’/> -
Source: place source info here <TextView android:text=‘@{user.age > 18 ?
Keep your expressions simple 60 @Bindable public String getDisplayName() { return mName.substring(0, 1).toUpperCase() + "." + mLastName; } user.displayName : @string/redacted}’/> -
Source: place source info here <TextView android:text=‘@{user.age > 18 ?
Keep your expressions simple 60 @Bindable public String getDisplayName() { return mName.substring(0, 1).toUpperCase() + "." + mLastName; } user.displayName : @string/redacted}’/> public void setLastName(String lastName) { … notifyPropertyChanged(BR.displayName); } -
Source: place source info here Consider using a ViewModel 61
public class ProfileViewModel { } -
Source: place source info here Consider using a ViewModel 61
public class ProfileViewModel { } public final ObservableInt friendCount; public final ObservableField<Date> subscriptionDate; -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel } extends BaseObservable { -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel private @Bindable String mDisplayName; } extends BaseObservable { -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; } extends BaseObservable { -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); } extends BaseObservable { -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); } extends BaseObservable { public String getDisplayName(){…} -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); } implements Observable { public String getDisplayName(){…} -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); PropertyChangeRegistry mRegistry = new PropertyChangeRegistry(); } implements Observable { public String getDisplayName(){…} -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); PropertyChangeRegistry mRegistry = new PropertyChangeRegistry(); } implements Observable { mRegistry. public String getDisplayName(){…} -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); PropertyChangeRegistry mRegistry = new PropertyChangeRegistry(); } implements Observable { mRegistry. public String getDisplayName(){…} -
Source: place source info here Consider using a ViewModel 62
public class ProfileViewModel public void setUser(User user) { mDisplayName.set(user.getName() + " " + user.getLastName()); } private @Bindable String mDisplayName; notifyPropertyChange(BR.displayName); PropertyChangeRegistry mRegistry = new PropertyChangeRegistry(); } implements Observable { public void addOnPropertyChangedCallback(OnPropertyChangedCallback cb) { mRegistry.add(cb); } public void removeOnPropertyChangedCallback(OnPropertyChangedCallback cb) { mRegistry.remove(cb); } mRegistry. public String getDisplayName(){…} -
Source: place source info here <TextView app:font="@{`Source-Sans-Pro-Regular.ttf`}"/> Take advantage of
BindingAdapters 63 public class AppAdapters { @BindingAdapter({“font"}) } -
Source: place source info here <TextView app:font="@{`Source-Sans-Pro-Regular.ttf`}"/> Take advantage of
BindingAdapters 63 public class } public static void setFont(TextView textView, String fontName){ AssetManager assetManager = textView.getContext().getAssets(); String path = "fonts/" + fontName; } -
Source: place source info here <TextView app:font="@{`Source-Sans-Pro-Regular.ttf`}"/> Take advantage of
BindingAdapters 63 public class } public static void AssetManager assetManager = textView.getContext().getAssets(); String path = } Typeface.createFromAsset(assetManager, path); textView.setTypeface(typeface); Typeface typeface = -
Source: place source info here <TextView app:font="@{`Source-Sans-Pro-Regular.ttf`}"/> Take advantage of
BindingAdapters 63 public class } public static void AssetManager assetManager = textView.getContext().getAssets(); String path = } Typeface.createFromAsset(assetManager, path); sCache.get(path); if (typeface == null) { typeface = sCache.put(path, typeface); } textView.setTypeface(typeface); Typeface typeface = -
Source: place source info here <TextView app:font="@{`Source-Sans-Pro-Regular.ttf`}"/> Take advantage of
BindingAdapters 63 public class AppAdapters { @BindingAdapter({“font"}) } public static void setFont(TextView textView, String fontName){ AssetManager assetManager = textView.getContext().getAssets(); String path = "fonts/" + fontName; } Typeface.createFromAsset(assetManager, path); sCache.get(path); if (typeface == null) { typeface = sCache.put(path, typeface); } textView.setTypeface(typeface); Typeface typeface = -
Source: place source info here public defaultImage) {
} } Use DataBindingComponent 64 static void setUrl(ImageView imageView, String url, Drawable public class ImageAdapter { @BindingAdapter(value={"photoUrl", "default"}, requireAll = false) Glide.with(imageView.getContext()) .load(url).into(imageView) .onLoadStarted(defaultImage); -
Source: place source info here public defaultImage) {
} } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class ImageAdapter { @BindingAdapter(value={"photoUrl", "default"}, requireAll = false) Glide.with(imageView.getContext()) .load(url).into(imageView) .onLoadStarted(defaultImage); -
public class AppComponent implements DataBindingComponent { } public ImageAdapter getImageAdapter()
{ return mImageAdapter; } Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class ImageAdapter { @BindingAdapter(value={"photoUrl", "default"}, requireAll = false) Glide.with(imageView.getContext()) .load(url).into(imageView) .onLoadStarted(defaultImage); ImageAdapter mImageAdapter = new ImageAdapter(); -
public class AppComponent implements DataBindingComponent { } public ImageAdapter getImageAdapter()
{ return mImageAdapter; } Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class MockImageAdapter extends ImageAdapter { @BindingAdapter(value={"photoUrl", "default"}, requireAll = false) Glide.with(imageView.getContext()) .load(url).into(imageView) .onLoadStarted(defaultImage); ImageAdapter mImageAdapter = new ImageAdapter(); -
public class AppComponent implements DataBindingComponent { } public ImageAdapter getImageAdapter()
{ return mImageAdapter; } Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class MockImageAdapter extends ImageAdapter { @Override Glide.with(imageView.getContext()) .load(url).into(imageView) .onLoadStarted(defaultImage); ImageAdapter mImageAdapter = new ImageAdapter(); -
public class AppComponent implements DataBindingComponent { } public ImageAdapter getImageAdapter()
{ return mImageAdapter; } Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class MockImageAdapter extends ImageAdapter { imageView.setImageDrawable(defaultImage); @Override ImageAdapter mImageAdapter = new ImageAdapter(); -
public class TestComponent extends AppComponent { } public ImageAdapter getImageAdapter()
{ return mImageAdapter; } Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class MockImageAdapter extends ImageAdapter { imageView.setImageDrawable(defaultImage); @Override ImageAdapter mImageAdapter = new ImageAdapter(); -
public class TestComponent extends AppComponent { } public ImageAdapter getImageAdapter()
{ return mImageAdapter; } MockImageAdapter mMockImageAdapter = new MockImageAdapter(); Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class MockImageAdapter extends ImageAdapter { imageView.setImageDrawable(defaultImage); @Override -
public class TestComponent extends AppComponent { } @Override public ImageAdapter
getImageAdapter() { return mMockImageAdapter; } MockImageAdapter mMockImageAdapter = new MockImageAdapter(); Source: place source info here public defaultImage) { } } Use DataBindingComponent 64 void setUrl(ImageView imageView, String url, Drawable public class MockImageAdapter extends ImageAdapter { imageView.setImageDrawable(defaultImage); @Override -
Source: place source info here DataBinding Dependency Injection 65 public
class AppComponent implements DataBindingComponent { } public ImageAdapter getImageAdapter() { return mImageAdapter; } ImageAdapter mImageAdapter = new ImageAdapter(); -
Source: place source info here DataBinding Dependency Injection 65 public
class AppComponent implements DataBindingComponent { } public ImageAdapter getImageAdapter() { return mImageAdapter; } @Inject ImageAdapter mImageAdapter; -
Dagger 2 Example 66 @Component(modules = ProductionModule.class) public interface
ProductionComponent extends DataBindingComponent {} @Module public class ProductionModule { @Provides TestableAdapter provideTestableAdapter() { return new ProductionAdapter(); } } DataBindingUtil.setDefaultComponent( ProductionComponent.builder().build()); -
Source: place source info here 67 Make better decisions by
accessing unique customer, industry and performance insights Win moments that matter by engaging billions of people, in the right context, with personalized experiences they love What we do: Google makes the web work for you We help you: Go bigger, faster by tapping into technology that works together, across your business needs -
Source: place source info here “Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Donec sollicitudin libero id elit. Sed euismod nonummy neque nam.” Name Title/company 69 -
Source: place source info here Agenda slide 70 First item
Second item Third item Fourth item Fifth item Sixth item Seventh item 1 2 3 4 5 6 7 -
Source: place source info here Agenda slide 71 First item
Second item Third item Fourth item Fifth item Sixth item Seventh item -
Source: place source info here One line title placeholder goes
here • Bullets are set in 22 point Open Sans font – Second-line bullets are Open Sans 20pt • Third level bullets are Open Sans 18pt • See source placeholder below* (Open Sans 8pt) • Limit the number of bullets on a slide • Text highlights are blue color • Try not to go below the recommended font sizes 72 -
Click to edit Master text styles Source: place source info
here Title placeholder goes here • Bullets are set in 22 point Open Sans font – Second-line bullets are Open Sans 18pt • Third level bullets are Open Sans 16pt • See source placeholder below* (Open Sans 8pt) • Limit the number of bullets on a slide • Text highlights are blue color • Try not to go below the recommended font sizes 73 -
Click to edit Master text styles Source: place source info
here Two line title placeholder goes here • Bullets are set in 22 point Open Sans font – Second-line bullets are Open Sans 18pt • Third level bullets are Open Sans 16pt • See source placeholder below* (Open Sans 8pt) • Limit the number of bullets on a slide • Text highlights are blue color • Try not to go below the recommended font sizes 74 -
• Click to edit Master text styles • Click to
edit Master text styles Click to edit master text styles Click to edit master text styles Click to edit Master text styles Source: place source info here Title placeholder goes here 75 -
Click to edit Master text styles Source: place source info
here Title placeholder goes here • This is a sample of a bullet slide with a photo • If you have too many items to fit on one page remember that you can always use another slide • This works better than reducing the font size • Better yet, try to convey your message with images 76 -
Click to edit Master text styles Source: place source info
here • This is a sample of a bullet slide with a bar chart • If you have too many items to fit on one page remember that you can always use another slide • This works better than reducing the font size • Better yet, try to convey your message with image Title placeholder goes here 77 0 1 2 3 4 5 6 Sales Profit Growth Revenue Q1 Q2 Q3 Q4 -
Source: place source info here 83 • Bullet one here
• Bullet two here • Bullet three here Place text here Place text here Place text here • Bullet one here • Bullet two here • Bullet three here • Bullet one here • Bullet two here • Bullet three here -
Source: place source info here Click to edit Master text
styles Two line title placeholder goes here 84 Place text here Place text here Place text here • Bullet one here • Bullet two here • Bullet three here • Bullet one here • Bullet two here • Bullet three here • Bullet one here • Bullet two here • Bullet three here -
Source: place source info here Performance summary 85 State of
the union Partnership update 1. Steady year in 2010 covario investment with google, lagging peers in growth $39m – 2010 covario investment with google (5.5% yoy growth) $27m – investment from top 2 clients (adobe, intel) $38m – 2010 covario investment in search and gdn text (98% of total) 4 – only 4 clients (intel, campmor, tek, solar) have invested in display in 2010 2. Limited presence in non-search opportunities. Ripe time to significantly advance leadership position 1. Certification! 2 people certified in 2010 2. Client business reviews with industry teams dec’10; jan, apr ‘11 3. Inflectionpoint feb’10, thinkagency march ‘10, agencycouncil dec’10 4. Inflectionpoint ‘11, sd strategy meetings, on-boarding new clients, @la, tv webinar -
Source: place source info here Column 1 Column 2 Column
3 Column 4 Row 1 Placeholder Placeholder Placeholder Placeholder Row 2 Placeholder Placeholder Placeholder Placeholder Row 3 Placeholder Placeholder Highlight Placeholder Row 4 Placeholder Placeholder Placeholder Placeholder Row 5 Placeholder Placeholder Placeholder Placeholder Row 6 Placeholder Placeholder Placeholder Placeholder Row 7 Placeholder Placeholder Placeholder Placeholder 86 -
Source: place source info here 0 8 17 25 33
42 50 2005 2006 2007 2008 2009 2010 2011 87 -
Source: place source info here 0 1 2 3 4
5 6 Sales Profit Growth Revenue Q1 Q2 Q3 Q4 88 -
Source: place source info here 0 8 17 25 33
42 50 Q1 Q2 Q3 Q4 Series 1 Series 2 Series 3 Series 4 Series 5 89 -
Source: place source info here 0 0.1 0 0.3 0.6
Q1 Q2 Q3 Q1 Q5 90 -
Source: place source info here Color palette 91 Gradient colors
Flat colors Neutral colors Color picker R:213 G:15 B:37 R:51 G:105 B:232 R:0 G:153 B:37 R:238 G:178 B:17 R:51 G:51 B:54 R:95 G:97 B:101 R:158 G:160 B:164 R:219 G:219 B:221 R:213 G:15 B:37 R:51 G:105 B:232 R:0 G:153 B:37 R:238 G:178 B:17 R:180 G:0 B:0 R:12 G:83 B:198 R:0 G:130 B:15 R:245 G:153 B:0