Search code examples
javaandroid-studioandroid-recyclerviewdata-bindingandroid-databinding

RecyclerView item's properites automatically changing while using DataBinding


I'm trying to build a simple task using DataBinding (in Java) without any design pattern. The scenario is that there is a RecyclerView in which items/ products are binding from a HardCoded List. Whenever a user clicks on any item, it should show that specific item on the Left (blank) side, with default values (properties). Now when the user clicks on that left-side item its properties (quantity, price, etc.) should be changed (only within that left-side box). Now everything is going fine. The problem is that after changing the left-side item's properties, whenever the user again clicks on the same item (that he clicked earlier) it is showing the item with changed values on the left side. But I want that on clicking again it should show the item with default values. I've attached all the classes and screenshots. Kindly identify me If I'm doing anything wrong.

Product.java

public class Product {
private String title;
private String price;
private String image;
private String quantity;
private String discount;

public Product(String title, String price, String image, String quantity, String discount) {
    this.title = title;
    this.price = price;
    this.image = image;
    this.quantity = quantity;
    this.discount = discount;
}

//Getters and Setters
}

MainTestActivity.java

public class MainTestActivity extends AppCompatActivity implements ProductsListAdapter.ProductItemClickListener{

ActivityMainTestingBinding binding;
private Product myCurrentProduct;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main_testing);

    getItems();
}



private void getItems(){

    List<Product> products = new ArrayList<>();

    products.add(new Product("Black Grapes", "480", "", "1", "0"));
    products.add(new Product("Oranges", "198", "", "1", "0"));
    products.add(new Product("Pears", "170", "", "1", "0"));
    products.add(new Product("Apple", "169", "", "1", "0"));
    products.add(new Product("Jonagold", "110", "", "1", "0"));
    products.add(new Product("Lemon", "198", "", "1", "0"));

    binding.rvProductList.setLayoutManager(new GridLayoutManager(this, 5));
    binding.rvProductList.setAdapter(new ProductsListAdapter(products, this));
}

@Override
public void onProductItemClicked(Product product) {

    myCurrentProduct = product;

    binding.setPopUpProduct(myCurrentProduct);
    binding.cvCurrentProduct.setVisibility(View.VISIBLE);

    binding.cvCurrentProduct.setOnClickListener(v -> {
        myCurrentProduct.setDiscount("100");
        myCurrentProduct.setPrice("50000");
        myCurrentProduct.setQuantity("5");
        myCurrentProduct.setTitle("Null");
        binding.setPopUpProduct(myCurrentProduct);
    });
}
}

ProductsListAdapter.java

public class ProductsListAdapter extends RecyclerView.Adapter<ProductsListAdapter.ViewHolder> {

private ProductItemClickListener mListener;
private List<Product> products;

public ProductsListAdapter(List<Product> products, ProductItemClickListener mListener) {
    this.products = products;
    this.mListener = mListener;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    ItemListProductsBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.item_list_products, viewGroup, false);
    return new ViewHolder(binding);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int i) {

    holder.bind(products.get(i), mListener);

}

@Override
public int getItemCount() {
    return products.size();
}

class ViewHolder extends RecyclerView.ViewHolder {

    ItemListProductsBinding binding;

    public ViewHolder(ItemListProductsBinding binding) {
        super(binding.getRoot());
        this.binding = binding;

    }

    void bind(Product currentProduct, ProductItemClickListener clickListener){
        //For each item, corresponding product object is passed to the binding
        binding.setProduct(currentProduct);
        binding.setProductItemClick(clickListener);
        //This is to force bindings to execute right away
        binding.executePendingBindings();
    }
}

public interface ProductItemClickListener {
    void onProductItemClicked(Product product);
}
}

activity_main_testing.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

    <variable
        name="popUpProduct"
        type="tech.oratier.parlour.models.Product" />


</data>


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:orientation="vertical">

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/cvCurrentProduct"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginBottom="8dp"
            app:cardCornerRadius="5dp"
            app:cardElevation="5dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:paddingTop="8dp"
                android:paddingBottom="8dp">

                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:gravity="center">

                    <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher_round" />

                </LinearLayout>

                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="2"
                    android:orientation="vertical">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:fontFamily="@font/garamond"
                        android:hint="Product Title"
                        android:text="@{popUpProduct.title}"
                        android:textSize="30sp"
                        android:textStyle="bold" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:text="Quantity:"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:gravity="end"
                            android:text="@{popUpProduct.quantity}"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:text="Discount:"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:gravity="end"
                            android:text="@{popUpProduct.discount}"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:text="Price:"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:gravity="end"
                            android:text="@{popUpProduct.price}"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                    </LinearLayout>

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="1dp"
                        android:background="@color/seperator" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:text="Total"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:fontFamily="@font/garamond"
                            android:gravity="end"
                            android:text="@{popUpProduct.price != null ? (popUpProduct.quantity != null ? (popUpProduct.discount != null ? String.valueOf((Double.parseDouble(popUpProduct.price) * Double.parseDouble(popUpProduct.quantity)) - Double.parseDouble(popUpProduct.discount)) : String.valueOf(Double.parseDouble(popUpProduct.price) * Double.parseDouble(popUpProduct.quantity))) : @string/nothing) : @string/nothing}"
                            android:textSize="20sp"
                            android:textStyle="bold" />

                    </LinearLayout>
                </LinearLayout>

            </LinearLayout>
        </com.google.android.material.card.MaterialCardView>
    </LinearLayout>

    <View
        android:layout_width="3dp"
        android:layout_height="match_parent"
        android:background="@color/seperator" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:orientation="vertical">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rvProductList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center" />
    </LinearLayout>
</LinearLayout>

item_list_products.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable
        name="product"
        type="tech.oratier.parlour.models.Product" />

    <variable
        name="productItemClick"
        type="tech.oratier.parlour.adapters.ProductsListAdapter.ProductItemClickListener" />
</data>

<com.google.android.material.card.MaterialCardView
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:onClick="@{()->productItemClick.onProductItemClicked(product)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:contentPaddingRight="5dp"
android:orientation="vertical">

<LinearLayout
    android:paddingStart="16dp"
    android:paddingRight="16dp"
    android:paddingEnd="16dp"
    android:paddingLeft="16dp"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<RelativeLayout
    android:layout_width="100dp"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_marginTop="8dp"
        android:src="@mipmap/ic_launcher_round"
        android:layout_width="100dp"
        android:layout_height="100dp"/>

    <TextView
        android:fontFamily="@font/garabd"
        android:paddingLeft="8dp"
        android:paddingStart="8dp"
        android:paddingEnd="8dp"
        android:paddingRight="8dp"
        android:background="@color/priceBackground"
        android:textColor="@color/defaultTextColor"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:text="@{product.price}"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

<com.google.android.material.textview.MaterialTextView
    android:singleLine="true"
    android:textSize="20sp"
    android:textColor="@android:color/black"
    android:fontFamily="@font/raleway_regular"
    android:layout_marginTop="8dp"
    android:layout_gravity="center_horizontal"
    android:text="@{product.title}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

<com.google.android.material.textview.MaterialTextView
    android:singleLine="true"
    android:textSize="20sp"
    android:textColor="@android:color/black"
    android:fontFamily="@font/raleway_regular"
    android:layout_marginTop="8dp"
    android:layout_gravity="center_horizontal"
    android:text="@{product.quantity}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

</LinearLayout>

Its working fine

Its working fine

Its working fine

Here I'm facing the problem


Solution

  • The problem is that I'm using

    myCurrentProduct = product;
    

    Here it binds myCurrentProduct with product / layout therefore its value automatically updating. So, to get rid of this I declared another object tempProduct as,

    tempProduct = product;
    

    then I get values from tempProduct

    myCurrentProduct = new Product();  //create a default constructor in Product model class
    myCurrentProduct.setTitle(tempProduct.getTitle());
    myCurrentProduct.setQuantity("5");
    myCurrentProduct.setPrice("50000");
    myCurrentProduct.setDiscount(tempProduct.getDiscount());
    binding.setPopUpProduct(myCurrentProduct);
    

    In this way I'm also able to get values from the clicked item, also set my own values.