Android RecyclerView with ViewBinding - notifyItemChanged only works the first time - android

So I have my RecyclerView setup with ViewDataBinding and I'm showing a ProgressBar on click of a button inside the item. The ProgressBar shows and pops a dialog, on cancelling dialog I can notifyItemChanged to hide the ProgressBar, it only works the first time.
Here is my layout of the item:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<import type="android.view.View"/>
<variable
name="inProgress"
type="boolean" />
<variable
name="userModel"
type="com.smartsco.recaru.room.dataModels.UserModel" />
<variable
name="messageModel"
type="com.smartsco.recaru.room.dataModels.MessageModel" />
<variable
name="clickHandler"
type="com.smartsco.recaru.interfaces.OnClickHandler" />
</data>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<androidx.cardview.widget.CardView
android:id="#+id/ll_invoice"
android:layout_width="#dimen/ml_invoice_width"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="8dp"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
app:cardBackgroundColor="#color/bg_ml_invoice"
app:cardCornerRadius="2dp"
app:cardElevation="3dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/bg_ml_invoice"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/ll_invoice_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="horizontal"
android:padding="8dp"
android:visibility="#{!inProgress && messageModel.InvoiceData.status.equalsIgnoreCase(`pending`) ? View.VISIBLE : View.INVISIBLE}"
android:weightSum="2">
<Button
style="#style/Button_Invoice_Positive"
android:id="#+id/btn_agree"
android:layout_width="match_parent"
android:layout_height="#dimen/btn_invoice_height"
android:layout_weight="1"
android:text="#string/agree"
android:onClick="#{(v)-> clickHandler.onClick(v)}"/>
<Space
android:layout_width="6dp"
android:layout_height="0dp"/>
<Button
android:id="#+id/btn_disagree"
style="#style/Button_Invoice_Negative"
android:layout_width="match_parent"
android:layout_height="#dimen/btn_invoice_height"
android:layout_weight="1"
android:text="#string/disagree"
android:onClick="#{(v)-> clickHandler.onClick(v)}" />
</LinearLayout>
<ProgressBar
android:id="#+id/pb_invoice"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:padding="8dp"
android:visibility="#{inProgress ? View.VISIBLE : View.INVISIBLE}" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
</layout>
Here is how the ViewHolder looks like:
private class InvoiceMessageHolder extends RecyclerView.ViewHolder implements OnClickHandler {
private RowRecyclerViewChatInvoiceMessageBinding binding;
InvoiceMessageHolder(RowRecyclerViewChatInvoiceMessageBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void bind(MessageModel message, UserModel userModel) {
binding.setMessageModel(message);
binding.setUserModel(userModel);
binding.setClickHandler(this);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_agree:
case R.id.btn_disagree:
binding.setInProgress(true);
invoiceClickHandler.onClick(v, getAdapterPosition(), binding.getMessageModel());
break;
}
}
}
as you can see I have created a variable inside the layout itself to toggle inProgress boolean which works perfectly except won't reset itself on 2nd call of notifyItemChanged.
Another weird behaviour I have witnessed is that sometimes I click on button inside one item and it shows progress bar in all the viewholders for that itemViewType.
P.S.On calling notifyItemChanged, the view animates as if it was notified of a change but is only effective the first time.
Thanks

Related

PagedList.Config loads list in the middle with recycleview

My RecyclerView loads in the middle of the list instead of the most top item first. The list should load the topmost item. In this case, it's the "latest" post. Which I have set to the reverse layout to true and that works.
My RecyclerView
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:viewBindingIgnore="true">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/postsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="5dp"
tools:listitem="#layout/post_item" />
</FrameLayout>
My Post list fragment
// Set up FirebaseRecyclerAdapter with the Query
val postsQuery = database.child(Globals().POSTS_ROOT_PATH)
// This configuration comes from the Paging Support Library
// https://developer.android.com/reference/androidx/paging/PagedList.Config
val config = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(10)
.build()
// The options for the adapter combine the paging configuration with query information
// and application-specific options for lifecycle, etc.
val options = DatabasePagingOptions.Builder<Post>()
.setLifecycleOwner(this)
.setQuery(postsQuery, config, Post::class.java)
.build()
adapter = object : FirebaseRecyclerPagingAdapter<Post, PostViewHolder>(options) {
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): PostViewHolder {
val inflater = LayoutInflater.from(viewGroup.context)
return PostViewHolder(inflater.inflate(R.layout.post_item, viewGroup, false))
}
override fun onBindViewHolder(viewHolder: PostViewHolder, position: Int, model: Post) {
val postRef = getRef(position)
// Set click listener for the whole post view
val postKey = postRef.key
// Log.d("PostListFragment", "post key id is: " + postKey)
viewHolder.itemView.setOnClickListener {
// Launch PostDetailActivity
val intent = Intent(activity, PostDetailActivity::class.java)
intent.putExtra(PostDetailActivity.EXTRA_POST_KEY, postKey)
startActivity(intent)
}
}
override fun onLoadingStateChanged(state: LoadingState) {
when (state) {
LoadingState.LOADING_INITIAL -> {
Log.d(TAG, "Initial data loading")
}
LoadingState.LOADING_MORE -> {
}
LoadingState.LOADED -> {
}
LoadingState.FINISHED -> {
Log.d(TAG, "All data loaded.")
}
LoadingState.ERROR -> {
Log.d(TAG, "Error occured while loading data")
}
}
}
override fun onError(databaseError: DatabaseError) {
super.onError(databaseError)
databaseError.toException().printStackTrace()
}
}
// Set up Layout Manager, reverse layout
manager = LinearLayoutManager(activity)
manager.reverseLayout = true
manager.stackFromEnd = true
recyclerList.layoutManager = manager
recyclerList.adapter = adapter
}
When I set the setPageSize() to a very large number then it loads the most top item. What do I need to do so this always loads the most top list item first?
Thanks
Edit:
post_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
tools:viewBindingIgnore="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/postTextLayout"
layout="#layout/post_text_include"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp"
android:layout_marginStart="2dp" />
<include
android:id="#+id/postThumbnailImg"
layout="#layout/post_video_thumbnail_include"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/postTextLayout"
android:layout_alignParentStart="true" />
<include
android:id="#+id/postAuthorLayout"
layout="#layout/post_author_thumbnail_include"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/postThumbnailImg"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
Sub layouts
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/postTitle"
style="#style/TextAppearance.AppCompat.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textStyle="bold"
android:textColor="#color/colorPrimaryDark"
tools:text="My First Post"
android:paddingStart="5dp"
android:paddingEnd="5dp" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:viewBindingIgnore="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/videoThumbnailImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/main_background" />
/>
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="#+id/playButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="centerCrop"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_baseline_play_arrow_24" />
</RelativeLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="40dp"
android:layout_height="40dp"
app:cardCornerRadius="20dp">
<ImageView
android:id="#+id/postAuthorPhoto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/ic_person_outline_40" />
</androidx.cardview.widget.CardView>
<TextView
android:id="#+id/postAuthor"
style="#style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:textColor="#color/colorPrimaryDark"
tools:text="someauthor#email.com" />
</LinearLayout>
You need to set height wrap_content rather than match_parent for sublayouts.

recyclerView child won't be clickable after putting recyclerView in SwipeRefreshLayout

I have a recyclerView which I implemented a listener for its child in ViewHolder class just like this:
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun binding(model: NewsAdapterModel) {
itemView.setOnClickListener {
onClick.onClick(model.id)
}
}
and use this code for my onBindViewHolder:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding(items[position])
}
also here is my xml code which contains recyclerView and a SwipeRefreshLayout:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".main.news.NewsFragment">
<ProgressBar
android:id="#+id/loading"
style="#style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
app:layout_constraintTop_toTopOf="parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/loading">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/loading" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
</layout>
my problem is as soon as I put my recyclerView inside Swipe Refreshing layout, item of recycler view are not clickable anymore. when I remove swipe refresh layout it become clickable again,
how can I solve this issue?
You should use SwipeRefreshLayout as parent of your LinearLayout and notify recycle view on setOnRefreshListener, code as follows-
Main Layout File
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data></data>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/loading">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".main.news.NewsFragment">
<ProgressBar
android:id="#+id/loading"
style="#style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/loading" />
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
Doing so you can choose to show progress base until your recycle view will be updated with new information.
SwipeRefreshListener
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.i(LOG_TAG, "onRefresh called from SwipeRefreshLayout");
// This method performs the actual data-refresh operation.
// The method calls setRefreshing(false) when it's finished.
myUpdateOperation();
}
}
);

How do you add multiple child layout views to a MaterialCardView dynamically from within a fragment?

On one of my fragment, I have a CardView, where I want to add multiple child views, based on a layout file. The number of child views being added will depend on how many items are in a List object (so I use a for loop to iterate over the list). When I add a view to the cardview, the app crashes with an error saying I have to remove child views before adding another view.
<?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>
<import type="com.mahaprasad.mahaprasad.models.DeliveryMethod" />
<import type="android.view.View" />
<variable
name="viewModel"
type="com.mahaprasad.mahaprasad.screens.checkoutflow.CheckoutSharedViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="#+id/nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.card.MaterialCardView
android:id="#+id/basket_products_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<!-- Layout Child Views Should go here -->
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.button.MaterialButton
android:id="#+id/checkout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:insetBottom="0dp"
android:text="Place Order"
android:textAlignment="viewStart"
app:backgroundTint="#color/green_button_colour"
app:cornerRadius="0dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
Layout template
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="product"
type="com.mahaprasad.mahaprasad.models.Product" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/product_image"
android:layout_width="90dp"
android:layout_height="90dp"
android:maxWidth="100dp"
android:maxHeight="100dp"
android:src="#drawable/chedvo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteX="50dp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/product_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:maxWidth="300dp"
android:textSize="18sp"
android:textColor="#color/colourBlack"
android:autoSizeMaxTextSize="18sp"
android:autoSizeMinTextSize="14sp"
android:autoSizeStepGranularity="1sp"
android:autoSizeTextType="uniform"
android:maxLines="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/product_image"
app:layout_constraintBottom_toTopOf="#id/product_size_text"
app:productName="#{product}"
app:autoSizeMaxTextSize="18sp"
app:autoSizeMinTextSize="14sp"
app:autoSizeStepGranularity="2sp"
tools:text="Chedvo (Farari Chedvoooooo)"
tools:targetApi="o" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/product_size_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textSize="15sp"
app:layout_constraintTop_toBottomOf="#id/product_name_text"
app:layout_constraintStart_toEndOf="#id/product_image"
app:productSize="#{product}"
tools:text="6 per pack" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/product_price_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textColor="#color/colourBlack"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="#id/product_image"
app:layout_constraintTop_toBottomOf="#id/product_size_text"
app:layout_constraintBottom_toBottomOf="parent"
app:productBasketQuantity="#{product}"
tools:text="1 x £5.00" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class ReviewOrderFragment : Fragment() {
private lateinit var viewModel: CheckoutSharedViewModel
private val args: ReviewOrderFragmentArgs by navArgs()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: FragmentReviewOrderBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_review_order, container, false)
viewModel = activity?.run {
ViewModelProviders.of(this).get(CheckoutSharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
populateBasketProductsCard(inflater, binding.basketProductsCard)
binding.viewModel = viewModel
binding.lifecycleOwner = this
return binding.root
}
private fun populateBasketProductsCard(inflater: LayoutInflater, basketProductsCard: MaterialCardView) {
val productInfoView: View = inflater.inflate(R.layout.layout_review_order_product_card, null)
val basket = args.order.basket.basket
basket.forEachIndexed { index, product ->
val productsCardBinding: LayoutReviewOrderProductCardBinding = DataBindingUtil.inflate(
inflater, R.layout.layout_review_order_product_card, null, false)
productsCardBinding.product = product
basketProductsCard.addView(
productInfoView,
index,
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
)
}
}
}
Just add a LinearLayout inside the MaterialCardView and insert your child views to the layout directly. MaterialCardView extends CardView and CardView is designed to hold a single child view within itself.
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<LinearLayout
android:id="#+id/basket_products_card"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Layout Child Views Should go here -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Why don't you set a Layout as the child view of the CardView and add your list elements programmatically to this Layout instead of adding them all to CardView?

'void android.databinding.ViewDataBinding.executePendingBindings()' on a null object reference - Algolia

The Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.databinding.ViewDataBinding.executePendingBindings()' on a null object reference
I double checked the names to the references used. Seems fine to me. I don't know why I keep getting this error. The view crashes as soon as I open it.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_findfriend);
searcher = Searcher.create(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY, ALGOLIA_INDEX_NAME);
helper = new InstantSearch(this, searcher);
helper.search();
// Get a reference to your Hits widget
final Hits hits = (Hits) findViewById(R.id.hits);
// Add an OnItemClickListener
hits.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClick(RecyclerView recyclerView, int position, View v) {
JSONObject hit = hits.get(position);
// Do something with the hit
}
});
}
#Override
protected void onDestroy() {
searcher.destroy();
super.onDestroy();
}
}
Here's my Activity:
activity_findfriend.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:algolia="http://schemas.android.com/apk/res-auto"
android:paddingTop="0dp"
android:background="#color/white">
<LinearLayout
android:id="#+id/search_emoji"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:background="#drawable/search_drawable"
android:gravity="top"
android:paddingTop="8dp"
android:orientation="horizontal">
<com.algolia.instantsearch.ui.views.SearchBox
android:id="#+id/searchBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/message_rectangle"
android:layout_marginRight="12dp"
android:layout_marginLeft="12dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/search_emoji">
<com.algolia.instantsearch.ui.views.Hits
android:id="#+id/hits"
android:layout_width="match_parent"
android:layout_height="wrap_content"
algolia:itemLayout="#layout/hits_item"
android:layout_below="#+id/search_emoji"/>
</LinearLayout>
To use data binding in your layout, wrap it in a <layout> root tag.
New hits_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:algolia="http://schemas.android.com/apk/res-auto">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:id="#+id/hits_items">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/user_image"
android:layout_width="100dp"
android:layout_height="100dp"
app:civ_border_width="4dp"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
android:src="#drawable/profile_thumbnail"
app:civ_border_color="#c42f92"
algolia:attribute='#{"image"}'/>
<TextView
android:id="#+id/user_name"
android:paddingTop="53dp"
android:paddingLeft="20dp"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
algolia:attribute='#{"username"}'
algolia:highlighted='#{true}'/>
</LinearLayout>
</layout>

Android GridView DataBinding - ItemClickListener does not fire

I've tried the following implementation for GridView ItemClickListener, the project are compiling fine, but when i clicks on GridView item, the Toast dont show my message, what's wrong ?
Java Click handler
public class MultiChoiceActions {
public void onItemClick(View view, int position, List<FieldOption> objectList) {
boolean currentValue = objectList.get(position).isChecked();
objectList.get(position).setChecked(!currentValue);
Toast.makeText(view.getContext(), "!currentValue " + (!currentValue) , Toast.LENGTH_SHORT).show();
}
}
XML Layout EDITED
<?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="vm"
type="br.com.viewluck.viewmodel.MultiChoiceViewModel"/>
<variable
name="adapter"
type="br.com.viewluck.viewmodel.MultiChoiceAdapter"/>
<variable
name="actions"
type="br.com.viewluck.viewmodel.MultiChoiceActions"/>
</data>
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:orientation="vertical">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/txt_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#{vm.fieldLabel}"
android:textSize="14sp"
android:textStyle="bold" />
<GridView
android:id="#+id/gd_multiple_choice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="multipleChoice"
app:options="#{vm.objectList}"
app:OnItemClickListener="#{(parent, view, position,id)->actions.onItemClick(view, position, vm.answer)}"
android:numColumns="auto_fit" />
</android.support.v7.widget.LinearLayoutCompat>
</layout>
Any suggestion is appreciated!
I guess you might have forgot to bind it from activity/fragment
binding.setActions(listener)

Categories

Resources