SlideShare a Scribd company logo
1 of 36
Download to read offline
Android Data Binding
Yeonhwa Woo
• 이름: 우연화
• 성별: 남. 남. 남. 남. 남. 남. 남.
• 개발을 하고 있습니다. 

다양한 것들에 관심이 많습니다.

뒹굴거립니다.

재밌는걸 좋아합니다.
• 블로그: http://novafactory.net (올라오는 글이 없습니다.)

이메일: yhwoo.croute@gmail.com

Previously…
• TextView textView = (TextView)findViewById(R.id.text_view);

textView.setText(“text”);
• public View getView(…) {

Holder h;

if (convertView == null) {

…

h = new Holder();

convertView = inflater…;

convertView.setTag(h);

h.textView = (TextView) convertView.findViewById(R.id…);

} else {

…

h = (Holder) convertView.getTag();

}

return convertView;

}
• RecyclerView

Data binding
• findViewById(…)

setText

setImage…
• onCreate In Activity

LayoutNameBinding binding = DataBindingUtil.setContentView(..);
• onViewCreated In Fragment

LayoutNameBinding binding = DataBindingUtil.bind(..);
Require
• Android 2.1 (API 7) +
• Android Gradle Plugin 1.3.0-beta1 or higher
• Data binding Code-completion and layout-preview support 

in Android Studio 1.3+
root/build.gradle
• buildscript {

repositories {

jcenter()

}

dependencies {

classpath "com.android.tools.build:gradle:1.3.0-beta2"

classpath "com.android.databinding:dataBinder:1.0-rc0"

}

}



allprojects {

repositories {

jcenter()

}

}

root/app/build.gradle
• apply plugin: 'com.android.databinding'
Basic DataBinding
Data class
• public class User {

private final Drawable profile;

private final String firstName;

private final String lastName;



public User(Drawable profile, String firstName, String lastName) {

this.profile = profile;

this.firstName = firstName;

this.lastName = lastName;

}



public Drawable getProfile() {

return profile;

}



public String getFirstName() {

return this.firstName;

}



public String getLastName() {

return this.lastName;

}

}
Layout
• <data>

<variable name="user" type=“mypackage.User” />

</data>



… 

<ImageView

android:id="@+id/user_iv_profile"

android:layout_width="200dp"

android:layout_height="200dp"

android:adjustViewBounds="true"

android:scaleType="centerCrop"

android:src="@{user.profile}"/>



<TextView

android:id="@+id/user_tv_first_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toRightOf="@id/user_iv_profile"

android:layout_toEndOf="@id/user_iv_profile"

android:text="@{user.firstName}" />



<TextView

android:id="@+id/user_tv_last_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toEndOf="@id/user_iv_profile"

android:layout_toRightOf="@id/user_iv_profile"

android:layout_below="@id/user_tv_first_name"

android:text="@{user.lastName}" />

</RelativeLayout>

…
Auto-generated LayoutNameBinding
• Layout file: user.xml
• Auto-generated binding class: UserBinding

(mypackage.databinding.UserBinding)
implementation data binding code in Activity or Fragment
• public class UserFragment extends Fragment {



private User user;



@Override

public void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

user = new User(ContextCompat.getDrawable(getActivity(), R.drawable.iu), "IU", "아이유");

}



@Nullable

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

return inflater.inflate(R.layout.user, container, false);

}



@Override

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

super.onViewCreated(view, savedInstanceState);

UserBinding binding = DataBindingUtil.bind(view);

binding.setUser(user);

}

}
Observable
•BaseObservable
Data class
• public class ObservableUser extends BaseObservable {

…



@Bindable

public Drawable getProfile() {

return profile;

}

public void setProfile(Drawable profile) {

this.profile = profile;

notifyPropertyChanged(net.novafactory.example.BR.profile);

}



@Bindable

public String getFirstName() {

return firstName;

}

public void setFirstName(String firstName) {

this.firstName = firstName;

notifyPropertyChanged(net.novafactory.example.BR.firstName);

}



@Bindable

public String getLastName() {

return lastName;

}

public void setLastName(String lastName) {

this.lastName = lastName;

notifyPropertyChanged(net.novafactory.example.BR.lastName);

}

}
Observable
•BaseObservable
•ObservableFields
Data class
• public class ObservableFieldsUser extends BaseObservable {



@Bindable

public final ObservableField<Drawable> profile = new ObservableField<>();



@Bindable

public final ObservableField<String> firstName = new ObservableField<>();



@Bindable

public final ObservableField<String> lastName = new ObservableField<>();
• 

}
Observable
•BaseObservable
•ObservableFields
•Observable Collection
Observable Collection Fragment
• public class ObservableCollectionFragment extends Fragment {



public final ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();



@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

user.put("profile", ContextCompat.getDrawable(getActivity(), R.drawable.iu));

user.put("firstName", "IU");

user.put("lastName", "아이유");

}



@Nullable

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

return inflater.inflate(R.layout.observable_collection, container, false);

}



@Override

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

super.onViewCreated(view, savedInstanceState);

ObservableCollectionBinding binding = DataBindingUtil.bind(view);



binding.setUser(user);

…

}

}
RecyclerView
Data class and Layout
• Data class: User 재사용
• Item layout: user.xml 재사용
ViewHolder
• public class ViewHolder extends RecyclerView.ViewHolder {



ImageView ivProfile;

TextView tvFirstName;

TextView tvLastName;



public ViewHolder(View itemView) {

super(itemView);



ivProfile = (ImageView) itemView.findViewById(R.id.user_iv_profile);

tvFirstName = (TextView) itemView.findViewById(R.id.user_tv_first_name);

tvLastName = (TextView) itemView.findViewById(R.id.user_tv_last_name);

}

}
in RecyclerView Adapter
• @Override

public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.user,
viewGroup, false);

return new ViewHolder(view);

}



@Override

public void onBindViewHolder(ViewHolder holder, int position) {

User user = list.get(position);

holder.ivProfile.setImageDrawable(user.getProfile());

holder.tvFirstName.setText(user.getFirstName());

holder.tvLastName.setText(user.getLastName());

}
RecyclerView DataBinding
Data class and Layout
• Data class: ObservableUser 재사용
• Item layout: observable_user.xml 재사용
ViewHolder
• public class BindingHolder extends RecyclerView.ViewHolder {



private ObservableUserBinding binding;



public BindingHolder(View itemView) {

super(itemView);

binding = DataBindingUtil.bind(itemView);

}



public ObservableUserBinding getBinding() {

return binding;

}

}
in RecyclerView Adapter
• @Override

public BindingHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

View view = LayoutInflater.from(viewGroup.getContext()).

inflate(R.layout.observable_user, viewGroup, false);

return new BindingHolder(view);

}



@Override

public void onBindViewHolder(BindingHolder holder, int position) {

ObservableUser user = list.get(position);

holder.getBinding().setUser(user);

}
in RecyclerView Adapter
• @Override

public BindingHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

View view = LayoutInflater.from(viewGroup.getContext()).

inflate(R.layout.observable_user, viewGroup, false);

return new BindingHolder(view);

}



@Override

public void onBindViewHolder(BindingHolder holder, int position) {

ObservableUser user = list.get(position);

holder.getBinding().setUser(user);

}
Image load
• <data>

<variable

name="image"

type="String" />

</data>



<ImageView

android:id="@+id/image_item_imageview"

android:layout_width="300dp"

android:layout_height="300dp"

android:adjustViewBounds="true"

android:scaleType="centerCrop"

app:imageUrl="@{image}"

app:error="@{@drawable/iu}">

</ImageView>
• @Override

public void onBindViewHolder(BindingHolder holder, int position) {

String image = list.get(position);

holder.getBinding().setImage(image);

}
• @BindingAdapter({"bind:imageUrl", "bind:error"})

public static void loadImage(ImageView view, String url, Drawable error) {

Picasso.with(view.getContext()).load(url).error(error).into(view);

}
Others
Expression language
• Mathematical: + - / * %

String concatenation: +

Logical: && ||

Binary: & | ^

Unary: + - ! ~

Shift: >> >>> <<

Comparison: == > < >= <=

instanceOf

Grouping: ()

Listerals: character, String, numeric, null

Cast

Method calls

Field access

Array access: []

Ternary operator: ?:
Expression example ..
• android:text="@{String.valueOf(index + 1)}"

android:visibility="@{age &lt; 13 ? View.GONE : View.VISIBLE}"

android:transitionName='@{"image_" + id}’
• Collections

<data>

<import type="android.util.SparseArray"/>

<import type="java.util.Map"/>

<import type="java.util.List"/>

<variable name="list" type="List<String>"/>

<variable name="sparse" type="SparseArray&lt;String>"/>

<variable name="map" type="Map&lt;String, String>"/>

<variable name="index" type="int"/>

<variable name="key" type="String"/>

</data>

…

android:text="@{list[index]}"

…

android:text="@{sparse[index]}"

…

android:text="@{map[key]}"
Expression example ..
• Class, method call

<data>

<import type="com.example.MyStringUtils"/>

<variable name="user" type="com.example.User"/>

</data>

…

<TextView

android:text="@{MyStringUtils.capitalize(user.lastName)}"

android:layout_width="wrap_content"

android:layout_height=“wrap_content"/>
• Casting

<TextView

android:text="@{((User)(user.connection)).lastName}"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>
available variable, interface or any class
• <data>

…

<variable name="fragment" type=“mypackage.Fragment” />



</data>



<Button

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:onClickListener=“@{fragment.onViewClickListener}”/>
Null Coalescing Operator
• android:text="@{user.lastName != null ? user.lastName : user.firstName}”
• android:text="@{user.lastName ?? user.firstName}"
Data binding
• 장점

- findViewById 등 귀찮은 작업들을 안해도 된다.

- 코드가 짧아진다.

- Data class와 View의 재사용이 쉽다.

- Annotation의 추가로 알아서 동작한다.

- 데이터 변경시 일일이 뷰 업데이트를 하지 않아도 된다.

- 예전 보다 좀 더 객체지향 프로그래밍을 하는것 같다.
• 단점

- layout xml 에 data 관련 variable 들을 추가해주어야 한다.

- ~Binding 으로 감싸여져 있고, 알아서 동작하므로 

뭘 하는 코드인지가 한 눈에 잘 보이지 않는다.

- Annotation을 추가해야한다.

- 예전 보다 좀 더 객체지향 프로그래밍을 하는것 같다.

- 아직 xml 에서 자동완성이 잘 되질 않는다.. (java 파일에서는 잘 되는듯)
?
• https://github.com/croute/DataBindingExample
• https://www.dropbox.com/s/e8h9eu12hvn72da/
Databinding.key?dl=0
• yhwoo.croute@gmail.com
• http://novafactory.net

More Related Content

What's hot

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
Yekmer Simsek
 
The Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptThe Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScript
Tim Perry
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
Wildan Maulana
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Jon Kruger
 

What's hot (20)

AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design Patterns
 
Mvp - типичные задачи и способ их решения в Moxy
Mvp - типичные задачи и способ их решения в MoxyMvp - типичные задачи и способ их решения в Moxy
Mvp - типичные задачи и способ их решения в Moxy
 
Test and profile your Windows Phone 8 App
Test and profile your Windows Phone 8 AppTest and profile your Windows Phone 8 App
Test and profile your Windows Phone 8 App
 
運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript
 
JavaScript Modules Done Right
JavaScript Modules Done RightJavaScript Modules Done Right
JavaScript Modules Done Right
 
Oojs 1.1
Oojs 1.1Oojs 1.1
Oojs 1.1
 
Advanced JavaScript Concepts
Advanced JavaScript ConceptsAdvanced JavaScript Concepts
Advanced JavaScript Concepts
 
Jquery
JqueryJquery
Jquery
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
 
Android development
Android developmentAndroid development
Android development
 
Reverse Engineering 안드로이드 학습
Reverse Engineering 안드로이드 학습Reverse Engineering 안드로이드 학습
Reverse Engineering 안드로이드 학습
 
The Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptThe Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScript
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Annotation processing tool
Annotation processing toolAnnotation processing tool
Annotation processing tool
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 

Viewers also liked

데이터 바인딩 ( Binding )
데이터 바인딩 ( Binding )데이터 바인딩 ( Binding )
데이터 바인딩 ( Binding )
대열 김
 
Java Micro Edition Platform & Android - Seminar on Small and Mobile Devices
Java Micro Edition Platform & Android - Seminar on Small and Mobile DevicesJava Micro Edition Platform & Android - Seminar on Small and Mobile Devices
Java Micro Edition Platform & Android - Seminar on Small and Mobile Devices
juricde
 

Viewers also liked (20)

FIrebase를 이용한 호우호우 미니게임 만들기
FIrebase를 이용한 호우호우 미니게임 만들기FIrebase를 이용한 호우호우 미니게임 만들기
FIrebase를 이용한 호우호우 미니게임 만들기
 
디자이너 없어도 괜찮아! (feat.Material Design Guide)
디자이너 없어도 괜찮아! (feat.Material Design Guide)디자이너 없어도 괜찮아! (feat.Material Design Guide)
디자이너 없어도 괜찮아! (feat.Material Design Guide)
 
데이터 바인딩 ( Binding )
데이터 바인딩 ( Binding )데이터 바인딩 ( Binding )
데이터 바인딩 ( Binding )
 
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel ArchitectureReactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
 
Reinfocement learning
Reinfocement learningReinfocement learning
Reinfocement learning
 
Introduce Android TV and new features from Google I/O 2016
Introduce Android TV and new features from Google I/O 2016Introduce Android TV and new features from Google I/O 2016
Introduce Android TV and new features from Google I/O 2016
 
같은 유저수, 다른 수익? 모바일 앱의 수익을 높이는 방법
같은 유저수, 다른 수익? 모바일 앱의 수익을 높이는 방법같은 유저수, 다른 수익? 모바일 앱의 수익을 높이는 방법
같은 유저수, 다른 수익? 모바일 앱의 수익을 높이는 방법
 
GKAC 2015 Apr. - 테스트 코드에서 코드 커버리지까지
GKAC 2015 Apr. - 테스트 코드에서 코드 커버리지까지GKAC 2015 Apr. - 테스트 코드에서 코드 커버리지까지
GKAC 2015 Apr. - 테스트 코드에서 코드 커버리지까지
 
Best Practices in Media Playback
Best Practices in Media PlaybackBest Practices in Media Playback
Best Practices in Media Playback
 
RetroFit by Square - GDG Dallas 06/09/16
RetroFit by Square - GDG Dallas 06/09/16RetroFit by Square - GDG Dallas 06/09/16
RetroFit by Square - GDG Dallas 06/09/16
 
GKAC 2015 Apr. - Xamarin forms, mvvm and testing
GKAC 2015 Apr. - Xamarin forms, mvvm and testingGKAC 2015 Apr. - Xamarin forms, mvvm and testing
GKAC 2015 Apr. - Xamarin forms, mvvm and testing
 
GKAC 2015 Apr. - Android Looper
GKAC 2015 Apr. - Android LooperGKAC 2015 Apr. - Android Looper
GKAC 2015 Apr. - Android Looper
 
Java Micro Edition Platform & Android - Seminar on Small and Mobile Devices
Java Micro Edition Platform & Android - Seminar on Small and Mobile DevicesJava Micro Edition Platform & Android - Seminar on Small and Mobile Devices
Java Micro Edition Platform & Android - Seminar on Small and Mobile Devices
 
Intro to Android : Making your first App!
Intro to Android : Making your first App!Intro to Android : Making your first App!
Intro to Android : Making your first App!
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
Tensorflow 101
Tensorflow 101Tensorflow 101
Tensorflow 101
 
GKAC 2014 Nov. - Android Wear 개발, 할까요 말까요?
GKAC 2014 Nov. - Android Wear 개발, 할까요 말까요?GKAC 2014 Nov. - Android Wear 개발, 할까요 말까요?
GKAC 2014 Nov. - Android Wear 개발, 할까요 말까요?
 
GKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroidGKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroid
 
GKAC 2014 Nov. - RxJava를 활용한 Functional Reactive Programming
GKAC 2014 Nov. - RxJava를 활용한 Functional Reactive ProgrammingGKAC 2014 Nov. - RxJava를 활용한 Functional Reactive Programming
GKAC 2014 Nov. - RxJava를 활용한 Functional Reactive Programming
 

Similar to 안드로이드 데이터 바인딩

Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
C.T.Co
 

Similar to 안드로이드 데이터 바인딩 (20)

ButterKnife
ButterKnifeButterKnife
ButterKnife
 
Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!
 
Recyclerview in action
Recyclerview in action Recyclerview in action
Recyclerview in action
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
 
Android crashcourse
Android crashcourseAndroid crashcourse
Android crashcourse
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design Patterns
 
Androidppt 1
Androidppt 1Androidppt 1
Androidppt 1
 
List adapter with multiple objects
List adapter with multiple objectsList adapter with multiple objects
List adapter with multiple objects
 
Entity framework practices
Entity framework practicesEntity framework practices
Entity framework practices
 
A resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangleA resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangle
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Saindo da zona de conforto… resolvi aprender android
Saindo da zona de conforto… resolvi aprender androidSaindo da zona de conforto… resolvi aprender android
Saindo da zona de conforto… resolvi aprender android
 
MVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) DetailsMVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) Details
 
The Principle of Hybrid App.
The Principle of Hybrid App.The Principle of Hybrid App.
The Principle of Hybrid App.
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr Tolstykh
 
Getting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUIGetting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUI
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
 
Android Support Libraries
Android Support LibrariesAndroid Support Libraries
Android Support Libraries
 
Vaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationVaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfiguration
 

More from GDG Korea (6)

접근성(Accessibility)과 안드로이드
접근성(Accessibility)과 안드로이드접근성(Accessibility)과 안드로이드
접근성(Accessibility)과 안드로이드
 
Building Extraordinary Apps with Firebase Analytics
Building Extraordinary Apps with Firebase AnalyticsBuilding Extraordinary Apps with Firebase Analytics
Building Extraordinary Apps with Firebase Analytics
 
GKAC 2014 Nov. - 안드로이드 스튜디오로 생산성 올리기
GKAC 2014 Nov. - 안드로이드 스튜디오로 생산성 올리기GKAC 2014 Nov. - 안드로이드 스튜디오로 생산성 올리기
GKAC 2014 Nov. - 안드로이드 스튜디오로 생산성 올리기
 
GKAC 2014 Nov. - 그루비로 안드로이드 앱 개발하기
GKAC 2014 Nov. - 그루비로 안드로이드 앱 개발하기GKAC 2014 Nov. - 그루비로 안드로이드 앱 개발하기
GKAC 2014 Nov. - 그루비로 안드로이드 앱 개발하기
 
GKAC 2014 Nov. - The Beautiful Design Collection 살펴보기
GKAC 2014 Nov. - The Beautiful Design Collection 살펴보기GKAC 2014 Nov. - The Beautiful Design Collection 살펴보기
GKAC 2014 Nov. - The Beautiful Design Collection 살펴보기
 
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
 

Recently uploaded

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 

안드로이드 데이터 바인딩

  • 2. • 이름: 우연화 • 성별: 남. 남. 남. 남. 남. 남. 남. • 개발을 하고 있습니다. 
 다양한 것들에 관심이 많습니다.
 뒹굴거립니다.
 재밌는걸 좋아합니다. • 블로그: http://novafactory.net (올라오는 글이 없습니다.)
 이메일: yhwoo.croute@gmail.com

  • 3. Previously… • TextView textView = (TextView)findViewById(R.id.text_view);
 textView.setText(“text”); • public View getView(…) {
 Holder h;
 if (convertView == null) {
 …
 h = new Holder();
 convertView = inflater…;
 convertView.setTag(h);
 h.textView = (TextView) convertView.findViewById(R.id…);
 } else {
 …
 h = (Holder) convertView.getTag();
 }
 return convertView;
 } • RecyclerView

  • 4. Data binding • findViewById(…)
 setText
 setImage… • onCreate In Activity
 LayoutNameBinding binding = DataBindingUtil.setContentView(..); • onViewCreated In Fragment
 LayoutNameBinding binding = DataBindingUtil.bind(..);
  • 5. Require • Android 2.1 (API 7) + • Android Gradle Plugin 1.3.0-beta1 or higher • Data binding Code-completion and layout-preview support 
 in Android Studio 1.3+
  • 6. root/build.gradle • buildscript {
 repositories {
 jcenter()
 }
 dependencies {
 classpath "com.android.tools.build:gradle:1.3.0-beta2"
 classpath "com.android.databinding:dataBinder:1.0-rc0"
 }
 }
 
 allprojects {
 repositories {
 jcenter()
 }
 }

  • 7. root/app/build.gradle • apply plugin: 'com.android.databinding'
  • 9. Data class • public class User {
 private final Drawable profile;
 private final String firstName;
 private final String lastName;
 
 public User(Drawable profile, String firstName, String lastName) {
 this.profile = profile;
 this.firstName = firstName;
 this.lastName = lastName;
 }
 
 public Drawable getProfile() {
 return profile;
 }
 
 public String getFirstName() {
 return this.firstName;
 }
 
 public String getLastName() {
 return this.lastName;
 }
 }
  • 10. Layout • <data>
 <variable name="user" type=“mypackage.User” />
 </data>
 
 … 
 <ImageView
 android:id="@+id/user_iv_profile"
 android:layout_width="200dp"
 android:layout_height="200dp"
 android:adjustViewBounds="true"
 android:scaleType="centerCrop"
 android:src="@{user.profile}"/>
 
 <TextView
 android:id="@+id/user_tv_first_name"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_toRightOf="@id/user_iv_profile"
 android:layout_toEndOf="@id/user_iv_profile"
 android:text="@{user.firstName}" />
 
 <TextView
 android:id="@+id/user_tv_last_name"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_toEndOf="@id/user_iv_profile"
 android:layout_toRightOf="@id/user_iv_profile"
 android:layout_below="@id/user_tv_first_name"
 android:text="@{user.lastName}" />
 </RelativeLayout>
 …
  • 11. Auto-generated LayoutNameBinding • Layout file: user.xml • Auto-generated binding class: UserBinding
 (mypackage.databinding.UserBinding)
  • 12. implementation data binding code in Activity or Fragment • public class UserFragment extends Fragment {
 
 private User user;
 
 @Override
 public void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 user = new User(ContextCompat.getDrawable(getActivity(), R.drawable.iu), "IU", "아이유");
 }
 
 @Nullable
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 return inflater.inflate(R.layout.user, container, false);
 }
 
 @Override
 public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
 super.onViewCreated(view, savedInstanceState);
 UserBinding binding = DataBindingUtil.bind(view);
 binding.setUser(user);
 }
 }
  • 14. Data class • public class ObservableUser extends BaseObservable {
 …
 
 @Bindable
 public Drawable getProfile() {
 return profile;
 }
 public void setProfile(Drawable profile) {
 this.profile = profile;
 notifyPropertyChanged(net.novafactory.example.BR.profile);
 }
 
 @Bindable
 public String getFirstName() {
 return firstName;
 }
 public void setFirstName(String firstName) {
 this.firstName = firstName;
 notifyPropertyChanged(net.novafactory.example.BR.firstName);
 }
 
 @Bindable
 public String getLastName() {
 return lastName;
 }
 public void setLastName(String lastName) {
 this.lastName = lastName;
 notifyPropertyChanged(net.novafactory.example.BR.lastName);
 }
 }
  • 16. Data class • public class ObservableFieldsUser extends BaseObservable {
 
 @Bindable
 public final ObservableField<Drawable> profile = new ObservableField<>();
 
 @Bindable
 public final ObservableField<String> firstName = new ObservableField<>();
 
 @Bindable
 public final ObservableField<String> lastName = new ObservableField<>(); • 
 }
  • 18. Observable Collection Fragment • public class ObservableCollectionFragment extends Fragment {
 
 public final ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 user.put("profile", ContextCompat.getDrawable(getActivity(), R.drawable.iu));
 user.put("firstName", "IU");
 user.put("lastName", "아이유");
 }
 
 @Nullable
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 return inflater.inflate(R.layout.observable_collection, container, false);
 }
 
 @Override
 public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
 super.onViewCreated(view, savedInstanceState);
 ObservableCollectionBinding binding = DataBindingUtil.bind(view);
 
 binding.setUser(user);
 …
 }
 }
  • 20. Data class and Layout • Data class: User 재사용 • Item layout: user.xml 재사용
  • 21. ViewHolder • public class ViewHolder extends RecyclerView.ViewHolder {
 
 ImageView ivProfile;
 TextView tvFirstName;
 TextView tvLastName;
 
 public ViewHolder(View itemView) {
 super(itemView);
 
 ivProfile = (ImageView) itemView.findViewById(R.id.user_iv_profile);
 tvFirstName = (TextView) itemView.findViewById(R.id.user_tv_first_name);
 tvLastName = (TextView) itemView.findViewById(R.id.user_tv_last_name);
 }
 }
  • 22. in RecyclerView Adapter • @Override
 public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
 View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.user, viewGroup, false);
 return new ViewHolder(view);
 }
 
 @Override
 public void onBindViewHolder(ViewHolder holder, int position) {
 User user = list.get(position);
 holder.ivProfile.setImageDrawable(user.getProfile());
 holder.tvFirstName.setText(user.getFirstName());
 holder.tvLastName.setText(user.getLastName());
 }
  • 24. Data class and Layout • Data class: ObservableUser 재사용 • Item layout: observable_user.xml 재사용
  • 25. ViewHolder • public class BindingHolder extends RecyclerView.ViewHolder {
 
 private ObservableUserBinding binding;
 
 public BindingHolder(View itemView) {
 super(itemView);
 binding = DataBindingUtil.bind(itemView);
 }
 
 public ObservableUserBinding getBinding() {
 return binding;
 }
 }
  • 26. in RecyclerView Adapter • @Override
 public BindingHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
 View view = LayoutInflater.from(viewGroup.getContext()).
 inflate(R.layout.observable_user, viewGroup, false);
 return new BindingHolder(view);
 }
 
 @Override
 public void onBindViewHolder(BindingHolder holder, int position) {
 ObservableUser user = list.get(position);
 holder.getBinding().setUser(user);
 }
  • 27. in RecyclerView Adapter • @Override
 public BindingHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
 View view = LayoutInflater.from(viewGroup.getContext()).
 inflate(R.layout.observable_user, viewGroup, false);
 return new BindingHolder(view);
 }
 
 @Override
 public void onBindViewHolder(BindingHolder holder, int position) {
 ObservableUser user = list.get(position);
 holder.getBinding().setUser(user);
 }
  • 28. Image load • <data>
 <variable
 name="image"
 type="String" />
 </data>
 
 <ImageView
 android:id="@+id/image_item_imageview"
 android:layout_width="300dp"
 android:layout_height="300dp"
 android:adjustViewBounds="true"
 android:scaleType="centerCrop"
 app:imageUrl="@{image}"
 app:error="@{@drawable/iu}">
 </ImageView> • @Override
 public void onBindViewHolder(BindingHolder holder, int position) {
 String image = list.get(position);
 holder.getBinding().setImage(image);
 } • @BindingAdapter({"bind:imageUrl", "bind:error"})
 public static void loadImage(ImageView view, String url, Drawable error) {
 Picasso.with(view.getContext()).load(url).error(error).into(view);
 }
  • 30. Expression language • Mathematical: + - / * %
 String concatenation: +
 Logical: && ||
 Binary: & | ^
 Unary: + - ! ~
 Shift: >> >>> <<
 Comparison: == > < >= <=
 instanceOf
 Grouping: ()
 Listerals: character, String, numeric, null
 Cast
 Method calls
 Field access
 Array access: []
 Ternary operator: ?:
  • 31. Expression example .. • android:text="@{String.valueOf(index + 1)}"
 android:visibility="@{age &lt; 13 ? View.GONE : View.VISIBLE}"
 android:transitionName='@{"image_" + id}’ • Collections
 <data>
 <import type="android.util.SparseArray"/>
 <import type="java.util.Map"/>
 <import type="java.util.List"/>
 <variable name="list" type="List<String>"/>
 <variable name="sparse" type="SparseArray&lt;String>"/>
 <variable name="map" type="Map&lt;String, String>"/>
 <variable name="index" type="int"/>
 <variable name="key" type="String"/>
 </data>
 …
 android:text="@{list[index]}"
 …
 android:text="@{sparse[index]}"
 …
 android:text="@{map[key]}"
  • 32. Expression example .. • Class, method call
 <data>
 <import type="com.example.MyStringUtils"/>
 <variable name="user" type="com.example.User"/>
 </data>
 …
 <TextView
 android:text="@{MyStringUtils.capitalize(user.lastName)}"
 android:layout_width="wrap_content"
 android:layout_height=“wrap_content"/> • Casting
 <TextView
 android:text="@{((User)(user.connection)).lastName}"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"/>
  • 33. available variable, interface or any class • <data>
 …
 <variable name="fragment" type=“mypackage.Fragment” />
 
 </data>
 
 <Button
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:onClickListener=“@{fragment.onViewClickListener}”/>
  • 34. Null Coalescing Operator • android:text="@{user.lastName != null ? user.lastName : user.firstName}” • android:text="@{user.lastName ?? user.firstName}"
  • 35. Data binding • 장점
 - findViewById 등 귀찮은 작업들을 안해도 된다.
 - 코드가 짧아진다.
 - Data class와 View의 재사용이 쉽다.
 - Annotation의 추가로 알아서 동작한다.
 - 데이터 변경시 일일이 뷰 업데이트를 하지 않아도 된다.
 - 예전 보다 좀 더 객체지향 프로그래밍을 하는것 같다. • 단점
 - layout xml 에 data 관련 variable 들을 추가해주어야 한다.
 - ~Binding 으로 감싸여져 있고, 알아서 동작하므로 
 뭘 하는 코드인지가 한 눈에 잘 보이지 않는다.
 - Annotation을 추가해야한다.
 - 예전 보다 좀 더 객체지향 프로그래밍을 하는것 같다.
 - 아직 xml 에서 자동완성이 잘 되질 않는다.. (java 파일에서는 잘 되는듯)