https://youtu.be/v4XO_y3RErI
40분 분량 java coding with mitch
product는 xml안에서 사용할 변수 이름이고 보통 obj, data class obj를 담게 된다. type은 obj의 class
.
.
.
.
.
.
일반 함수를 사용할수 있다. (정확히 어떤 함수가 일반 함수에 해당하는지는 확인요망)
.
.
외부의 class를 xml내로 가져와 사용하고자 하는 경우
.
.
이 강의에서는 StringUtil이라는 helper class를 xml에 가져와 사용하는 것을 가정한다.
.
.
xml안 변수로 사용하게될 class Product 의 내부함수를 xml에서 사용하는 것을 보여준다.
.
.
xml안 변수로 사용하게될 class Product 의 내부함수를 xml에서 사용하는 것을 보여준다.
.
.
xml내로 android view class를 import 해서 가져와 view의 속성을 변경하는 것을 보여준다.
.
.
클릭 이벤트 처리를 위한 interface
.
.
클릭이벤트를 이 강의에서는 activity가 처리한다고 가정한다.
.
.
클릭이벤트를 위한 interface를 implement한다.
.
.
클릭이벤트를 처리하는 class를 변수로 가져온다.
.
.
.
.
클릭이벤트 처리를 외부로 보낸다.
.
.
binding adapter를 통해 view를 외부로 보내 추가 처리를 하는 것을 보여준다. 이강의에서는 glide를 사용하는 것을 보여준다.
.
.
app:바인딩어댑터이름 즉 @BindingAdapter() 안에 들어간 이름
.
.
.
.
========================================================================================================================
https://medium.com/androiddevelopers/no-more-findviewbyid-457457644885
android { … dataBinding.enabled = true }
<layout xmlns:android=“http://schemas.android.com/apk/res/android” xmlns:tools=“http://schemas.android.com/tools”> <RelativeLayout android:layout_width=“match_parent” android:layout_height=“match_parent” android:paddingLeft=“@dimen/activity_horizontal_margin” android:paddingRight=“@dimen/activity_horizontal_margin” android:paddingTop=“@dimen/activity_vertical_margin” android:paddingBottom=“@dimen/activity_vertical_margin” tools:context=“.MainActivity”>
<TextView android:id=“@+id/hello” android:layout_width=“wrap_content” android:layout_height=“wrap_content”/>
</RelativeLayout> </layout>
HelloWorldBinding binding = DataBindingUtil.setContentView(this, R.layout.hello_world); binding.hello.setText(“Hello World”); // you should use resources!
.
.
https://medium.com/androiddevelopers/android-data-binding-that-include-thing-1c8791dd6038
hello_world.xml<layout xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/hello" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <include android:id="@+id/included" layout="@layout/included_layout"/> </LinearLayout> </layout>
included_layout.xml<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/world"/> </layout>
HelloWorldBinding binding = HelloWorldBinding.inflate(getLayoutInflater()); binding.hello.setText(“Hello”); binding.included.world.setText(“World”);
.
.
https://medium.com/google-developers/android-data-binding-adding-some-variability-1fe001b3abcc
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.myapp.model.User"/> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:src="@{user.image}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="@{user.firstName}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="@{user.lastName}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </layout>
You can see in the layout above that the Views no longer have IDs. (above)
private void setUser(User user, ViewGroup root) { UserInfoBinding binding = UserInfoBinding.inflate(getLayoutInflater(), root, true); binding.setUser(user); }
——————————————————————————————-
user_name.xml <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.myapp.model.User"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstName}"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.lastName}"/> </LinearLayout> </layout>
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="user" type="com.example.myapp.model.User"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@{user.image}"/> <include layout="@layout/user_name" app:user="@{user}"/> </LinearLayout> </layout>
.
.
https://medium.com/androiddevelopers/android-data-binding-express-yourself-c931d1f90dfe
The expression parser automatically tries to find the Java Bean accessor name (getXxx() or isXxx()) for your property. The same expression will work fine when your class has accessor methods. (기본적으로 xml에 @{a.bbb}가 있다고 한다면 parser가 알아서 a 클래스에서 getbbb()를 찾고 없다면 bbb()를 사용한다는 이야기 이다.)
If it can’t find a method named like getXxx(), it will also look for a method named xxx(), so you can use user.hasFriend to access method hasFriend().
Android Data Binding expression syntax also supports array access using brackets, just like Java:
android:text="@{user.friends[0].firstName}"
It also allows almost all java language expressions, including method calls, ternary operators, and math operations.
there is a null-coalescing operator ?? to shorten the simple ternary expressions:(즉 ?? 사용가능하다는 이야기)
android:text=”@{user.firstName ?? user.userName}”
which is essentially the same as:
android:text=”@{user.firstName != null ? user.firstName : user.userName}”
One really cool thing you can do with binding expressions is use resources:
android:padding=”@{@dim/textPadding + @dim/headerPadding}
You can also use string, quantity, and fraction formatting following the syntax from Resources methods getString , getQuantityString , and getFraction . You just pass the parameters as arguments to the resource:
android:text=”@{@string/nameFormat(user.firstName, user.lastName)}”
One very convenient thing is that data binding expressions always check for null values during evaluation. That means that if you have an expression like:
android:text=”@{user.firstName ?? user.userName}”
If user is null, user.firstName and user.userName will evaluate to null and the text will be set to null. No NullPointerException.
This doesn’t mean that it is impossible to get a NullPointerException. If, for example, you have an expression:
android:text=”@{com.example.StringUtils.capitalize(user.firstName)}”
And your StringUtils had:
public static String capitalize(String str) { return Character.toUpperCase(str.charAt(0)) + str.substring(1); }
You’ll definitely see a NullPointerException when a null is passed to capitalize.
Importing
In the example above, the expression to capitalize the name was very long. What we really want is to be able to import types so that they can be used as a shortened expression. You can do that by importing them in the data section:
<data> <variable name="user" type="com.example.myapp.model.User"/> <import type="com.example.StringUtils"/> </data>
Now our expression can be simplified to:
android:text=”@{StringUtils.capitalize(user.firstName)}”
(본래는 android:text=”@{com.example.StringUtils.capitalize(user.firstName)}” 이렇게 쓸것을 줄인결과)
Expressions are pretty much Java syntax with the few exceptions mentioned above. If you think it will work, it probably will, so just give it a go.
.
.
https://medium.com/androiddevelopers/android-data-binding-the-big-event-2697089dd0d7
data binding에서 listener를 view에 덧붙이는 방법은 아래와 같이3가지가 있다.
1. Listener Objects
<View android:onClickListener="@{callbacks.clickListener}" .../>
간단하게 줄여서 아래와 같이 할수도 있다.
<View android:onClick="@{listeners.clickListener}" .../>
public class Callbacks { public View.OnClickListener clickListener; }
2. Method References
<EditText android:afterTextChanged="@{callbacks::nameChanged}" .../>
public class Callbacks { public void nameChanged(Editable editable) { //... } }
아래와 같이 논리구조를 추가해서 상황에 따라 다른 리스너를 이용할수도 있다.
<EditText android:afterTextChanged= "@{user.hasName?callbacks::nameChanged:callbacks::idChanged}" .../>
3. Lambda Expressions
https://developer.android.com/reference/android/text/TextWatcher#afterTextChanged(android.text.Editable)
본래 afterTextChanged는 Editable 를 parameter로 받는다. 아래서 e는 Editable 이다.
<EditTextandroid:afterTextChanged="@{(e)->callbacks.textChanged(user, e)}" ... />
public class Callbacks { public void textChanged(User user, Editable editable) { if (user.hasName()) {//... } else {//... } } }
.
.
https://medium.com/androiddevelopers/android-data-binding-lets-flip-this-thing-dc17792d6c24
@={}
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@={user.firstName} "/>
아래에서는 xml에 있는 다른 view의 id를 이용 접근하는 것을 보여주고 있다.
<CheckBox android:id="@+id/showName " android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="@{user.firstName}" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="@{showName .checked ? View.VISIBLE : View.GONE}" />
<CheckBox android:id="@+id/showName" android:focusableInTouchMode="@{model.allowFocusInTouchMode}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="@{user.firstName}" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="@{showName.focusableInTouchMode}" />
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/firstName" android:text="@={user.firstName}" /> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:onCheckedChanged="@{()->handler.checked(firstName)}" />