DemoAPI (JSONs) to recyclerView using retrofit

22 Views Asked by At

Trying to take the JSONs from the API using jsonlint and apply to the recyclerview without success, the application crashes without any warning in the debugger.

Layouts:

dt_product:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:orientation="vertical">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/records_BTN_back"
            style="@style/Widget.Material3.Button.TextButton.Icon"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:iconSize="45dp"
            app:icon="@drawable/back"
            app:iconTint="@null"
            />

        <androidx.appcompat.widget.LinearLayoutCompat
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="#000000"
            android:orientation="vertical"
            android:padding="32dp">



            <ImageView
                android:id="@+id/ivImage2"

                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="centerCrop"
                android:src="@drawable/paris"
                android:contentDescription="@string/todo" />



        </androidx.appcompat.widget.LinearLayoutCompat>

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/descriptionTextView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="#000000"
            android:gravity="center"
            android:text="@string/details"
            android:textColor="@color/white"
            android:textSize="12sp"
            android:textStyle="bold" />

    </androidx.appcompat.widget.LinearLayoutCompat>

</RelativeLayout>

activity_rv_prodcts:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rvProducts"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

rv_product_item:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="216dp"
    android:layout_margin="2dp"
    android:id="@+id/item"
    app:cardCornerRadius="12dp"
    >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <ImageView
            android:id="@+id/ivImage"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="centerCrop"
            android:src="@drawable/paris"
            android:contentDescription="@string/todo" />

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentBottom="true"
            android:background="#595959"
            android:gravity="center"
            android:text="paris"
            android:textColor="@color/white"
            android:textSize="10sp"
            android:textStyle="bold"/>
    </RelativeLayout>
</androidx.cardview.widget.CardView>

myapplication-adaptors,networking: ActivityRvProducts:

package com.example.myapplication;

import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.adaptors.RVRetrofitAdaptor;
import com.example.myapplication.networking.ProductResult;
import com.example.myapplication.networking.RetrofitClient;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class ActivityRvProducts extends AppCompatActivity implements RVRetrofitAdaptor.OnItemClickListener {
    RecyclerView rvProducts;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rv_prodcts);
        rvProducts = findViewById(R.id.rvProducts);

        getProducts();
    }

    private void getProducts() {
        Call<List<ProductResult>> apiCall = RetrofitClient.getInstance().getApis().getProducts();
        apiCall.enqueue(new Callback<List<ProductResult>>() {
            @Override
            public void onResponse(Call<List<ProductResult>> call, Response<List<ProductResult>> response) {
                List<ProductResult> productResult = response.body();
                Toast.makeText(ActivityRvProducts.this, "Got Products", Toast.LENGTH_SHORT).show();
                setAdapter(productResult);
            }

            @Override
            public void onFailure(Call<List<ProductResult>> call, Throwable t) {
                Toast.makeText(ActivityRvProducts.this, "Error", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void setAdapter(List<ProductResult> productResults) {
        rvProducts.setLayoutManager(new LinearLayoutManager(this));
        RVRetrofitAdaptor rvRetrofitAdaptor = new RVRetrofitAdaptor(this, productResults);
        rvRetrofitAdaptor.setOnItemClickListener(this); // Set the click listener
        rvProducts.setAdapter(rvRetrofitAdaptor);
    }

    // Implementing onItemClick method of the OnItemClickListener interface
    @Override
    public void onItemClick(String productId) {
        // Handle item click here, start DetailActivity with necessary data
        Intent intent = new Intent(this, DetailActivity.class);
        intent.putExtra("productId", productId);
        startActivity(intent);
    }
}

DetailActivity:

package com.example.myapplication;

import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.example.myapplication.networking.RetrofitClient;

public class DetailActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dt_product);

        // Retrieve data passed from previous activity
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            String productId = extras.getString("productId");

            // Display the data as needed in your detail layout
            ImageView imageView = findViewById(R.id.ivImage2);
            TextView descriptionTextView = findViewById(R.id.descriptionTextView);

            // Use RetrofitClient to fetch product details
            RetrofitClient.getInstance().fetchProductDetails(productId, new RetrofitClient.OnProductDetailsFetchedListener() {
                @Override
                public void onProductDetailsFetched(String[] productDetails) {
                    // If product details are fetched successfully
                    String description = productDetails[0];
                    String imageUrl = productDetails[1];

                    // Load image using Glide
                    Glide.with(DetailActivity.this).load(imageUrl).placeholder(R.drawable.paris).into(imageView);

                    descriptionTextView.setText(description);
                }

                @Override
                public void onProductDetailsFetchFailed() {
                    // Handle case when fetching fails
                    Toast.makeText(DetailActivity.this, "Failed to load product details", Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            // Handle case when no data is passed
            Toast.makeText(this, "No data available", Toast.LENGTH_SHORT).show();
        }

        // Find and set click listener for the back button
        findViewById(R.id.records_BTN_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Finish the current activity to go back to the previous one
                finish();
            }
        });
    }
}

MainActivity:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Find the start button
        ImageButton startBtn = findViewById(R.id.startBtn);

        // Set OnClickListener for the start button
        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Start ActivityRvProducts when the button is clicked
                Intent intent = new Intent(MainActivity.this, ActivityRvProducts.class);
                startActivity(intent);
            }
        });
    }
}

adaptors-RVRetrofitAdaptor:

package com.example.myapplication.adaptors;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.myapplication.R;
import com.example.myapplication.networking.ProductResult;
import java.util.List;

public class RVRetrofitAdaptor extends RecyclerView.Adapter<RVRetrofitAdaptor.RVHolderRetrofit> {
    private Context mContext;
    private List<ProductResult> mProductResults;
    private OnItemClickListener mListener;

    public RVRetrofitAdaptor(Context context, List<ProductResult> productResults) {
        this.mContext = context;
        this.mProductResults = productResults;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mListener = listener;
    }

    @NonNull
    @Override
    public RVHolderRetrofit onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.rv_product_item, parent, false);
        return new RVHolderRetrofit(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RVHolderRetrofit holder, int position) {
        ProductResult product = mProductResults.get(position);
        holder.tvTitle.setText(product.getTitle());
        Glide.with(mContext)
                .load(product.getProductImage())
                .placeholder(R.drawable.paris)
                .error(R.drawable.paris)
                .into(holder.ivImage);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onItemClick(product.getId());
                }
            }
        });
    }

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

    public static class RVHolderRetrofit extends RecyclerView.ViewHolder {
        TextView tvTitle;
        ImageView ivImage;

        public RVHolderRetrofit(@NonNull View itemView) {
            super(itemView);
            ivImage = itemView.findViewById(R.id.ivImage);
            tvTitle = itemView.findViewById(R.id.tvTitle);
        }
    }

    // Interface for item click
    public interface OnItemClickListener {
        void onItemClick(String productId);
    }
}

networking: APIs:

package com.example.myapplication.networking;
import java.util.List;
import retrofit2.http.GET;
import retrofit2.Call;

public interface APIs {
    String BASE_URL = "https://fakestoreapi.com/";
    @GET("products")
    Call<List<ProductResult>> getProducts();
}

ProductResult:

package com.example.myapplication.networking;
import com.google.gson.annotations.SerializedName;
public class ProductResult {
  @SerializedName("id")
  String id;

  @SerializedName("title")
  String title;

  @SerializedName("description")
  String description;

  @SerializedName("image")
  String productImage;

  public String getId() {
    return id;
  }

  public String getTitle() {
    return title;
  }

  public String getProductImage() {
    return productImage;
  }

  public String getDescription() {
    return description;
  }
}

RetrofitClient:

package com.example.myapplication.networking;

import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    private static RetrofitClient instance = null;
    private final APIs apis;

    private RetrofitClient(){
        Retrofit retrofit = new Retrofit.Builder().baseUrl(APIs.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
        apis = retrofit.create(APIs.class);
    }
    public static synchronized RetrofitClient getInstance(){
        if(instance == null)
            instance = new RetrofitClient();
        return instance;
    }
    public APIs getApis(){
        return apis;
    }
    public void fetchProductDetails(String productId, final OnProductDetailsFetchedListener listener) {
        Call<List<ProductResult>> call = apis.getProducts();
        call.enqueue(new Callback<List<ProductResult>>() {
            @Override
            public void onResponse(Call<List<ProductResult>> call, Response<List<ProductResult>> response) {
                if (response.isSuccessful()) {
                    List<ProductResult> productList = response.body();
                    if (productList != null && !productList.isEmpty()) {
                        for (ProductResult product : productList) {
                            if (product.getId().equals(productId)) {
                                String description = product.getDescription();
                                String imageUrl = product.getProductImage();
                                String[] productDetails = new String[]{description, imageUrl};
                                listener.onProductDetailsFetched(productDetails);
                                return;
                            }
                        }
                    }
                }
                // If product details are not found or response is not successful
                listener.onProductDetailsFetchFailed();
            }

            @Override
            public void onFailure(Call<List<ProductResult>> call, Throwable t) {
                // Handle failure case
                listener.onProductDetailsFetchFailed();
            }
        });
    }
    public interface OnProductDetailsFetchedListener {
        void onProductDetailsFetched(String[] productDetails);

        void onProductDetailsFetchFailed();
    }
}
0

There are 0 best solutions below