I have simple imageview in my layout and I have a api which gives me a image url. I integrate Data binding in my layout. Now after parsing the api I'm setting the model through this line binding.setUserinfo(memberObj.getMemberdata());
Now I have also a binding adapter where imgurl code is written. Now the custom binding adapter calls twice when activity start and after parsing the api.
Now i want to notify the UI after api has been successfully parsed.
Here is my code of xml activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data class="MainBinding">
<variable
name="userinfo"
type="com.myapplication.retrofit.pojo.ImgTest"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.myapplication.retrofit.MainActivity">
<ImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:id="@+id/imageView"
app:image_url="@{userinfo.imgUrl}"
/>
</RelativeLayout>
</layout>
Here is my Pojo: ImgTest.java
public class ImgTest extends BaseObservable {
String imgUrl;
@Bindable
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
notifyPropertyChanged(BR.imgUrl);
}
}
Here is my CustomBinder.java
public class CustomBinders {
private static final String TAG = "CustomBinders";
@BindingAdapter({"image_url"})
public static void loadImageWithOUtProgressBar(ImageView view, String imageUrl){
Log.d(TAG, "before loadImageWithOUtProgressBar: "+imageUrl);
Log.d(TAG, "after loadImageWithOUtProgressBar: "+imageUrl);
Picasso.with(view.getContext())
.load(imageUrl)
.into(view);
}
}
Here is MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
RestManager mManager;
MainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
mManager = new RestManager();
Call<ResponseBody> getUserInfo = mManager.getService().getUserInfo("25","sell");
getUserInfo.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
int sc = response.code();
Log.d(TAG, "onResponse: "+sc);
if(response.isSuccessful())
{
ImgTest img = new ImgTest();
try {
String res = response.body().string();
JSONObject jobj = new JSONObject(res);
JSONObject obj = jobj.getJSONObject("memberdata");
String imgUrl = "";
imgUrl = obj.getString("prifile_picture");
img.setImgUrl(imgUrl);
binding.setUserinfo(img);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
}
Please let know how to solve this issue. Thanks in advance.
Binding adapters are responsible for making the appropriate framework calls to set values. One example is setting a property value like calling the setText() method. Another example is setting an event listener like calling the setOnClickListener() method.
Two-way Data Binding is a technique of binding your objects to your XML layouts so that the layout can send data to your binding object. This is compared to a “traditional” or “one-way” Data Binding setup, where data would only move from your binding object to the layout.
InverseBindingAdapter is associated with a method used to retrieve the value for a View when setting values gathered from the View.
As Ravi says in the comments, it is working as intended. After you create the initial binding, the values should be set to the values as they are. If you haven't set anything then they will be set to null.
You can change the behavior by explicitly telling the binding to not bind. Add an OnRebindCallback
to the binding:
private OnRebindCallback<ActivityMainBinding> delayRebindCallback =
new OnRebindCallback<ActivityMainBinding>() {
@Override
public boolean onPreBind(ActivityMainBinding binding) {
return false;
}
};
// ... and then after creating the binding ...
binding.addOnRebindCallback(delayRebindCallback);
In your onResponse (assuming it is on the UI thread):
binding.removeOnRebindCallback(delayRebindCallback);
binding.setUserinfo(img);
binding.executePendingBindings();
If it isn't on the UI thread, you will have to post an executable to run the binding.executePendingBindings()
on the UI thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With