-5

NULL POINTER EXCEPTION HAPPENDS HEREI have 2 recyclerviews and 2 adapters. One is for the shop names, and one for the deliverables per shop. I need to display the deliverables per shop. When I populate my layout component, deliverable imageview returns null.

Here is my code for populating the recyclerview of the deliverables.

public class DeliverableView extends ConstraintLayout {

    @BindView(R.id.iv_deliverable_image)
    ImageView iv_deliverable_image;
    @BindView(R.id.tv_deliverable_name)
    TextView tv_deliverable_name;
    @BindView(R.id.tv_deliverable_size)
    TextView tv_deliverable_size;
    @BindView(R.id.tv_deliverable_quantity)
    TextView tv_deliverable_quantity;
    @BindView(R.id.tv_deliverable_amount)
    TextView tv_deliverable_amount;

    public DeliverableView(Context context) {
        super(context);
    }

    public DeliverableView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DeliverableView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void populate(Entity deliverable) {
        Glide.with(getContext()).load(StringUtil.trimUrlByHeight(deliverable.attributes.image_url, 60)).into(iv_deliverable_image);
        tv_deliverable_quantity.setText(String.valueOf(deliverable.attributes.count));
        tv_deliverable_name.setText(deliverable.attributes.name);
        tv_deliverable_size.setText(deliverable.attributes.size);
        tv_deliverable_amount.setText(StringUtil.getDisplayedBill(deliverable.attributes.amount_in_cents * deliverable.attributes.count));
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        View.inflate(getContext(), R.layout.layout_componet_deliverable, this);
        ButterKnife.bind(this);
    }
}

Below is the code for the adapter of shops. This is where I setup the deliverableadapter and updating it.

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

    private Context context;
    private LayoutInflater inflater;
    private List<Entity> jobOrders = new ArrayList<>();
    private DeliverableAdapter deliverableAdapter;
    private List<OrderItem> orderItems = new ArrayList<>();v


    public ViewReceiptShopNameAdapter(Context context) {
        this.context = context;
        this.inflater = LayoutInflater.from(context);
    }

    public void updateViewShopAdapter(List<Entity> jobOrders) {
        this.jobOrders = jobOrders;
        notifyDataSetChanged();
    }


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        return new ViewHolderShopName(inflater.inflate(R.layout.layout_view_receipt_shopname, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        final Entity jobOrder = jobOrders.get(position);
//        final OrderItem orderItemList = orderItems.get(position);
        ViewHolderShopName viewHolder = (ViewHolderShopName) holder;
        viewHolder.bindModel(jobOrder);
    }

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

    class ViewHolderShopName extends RecyclerView.ViewHolder {

        @BindView(R.id.store_name)
        TextView tv_shop_name;
        @BindView(R.id.count_items_delivered)
        TextView tv_items_count;
        @BindView(R.id.rv_receipt_items)
        RecyclerView rv_receipt_items;

        ViewHolderShopName(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        void bindModel(Entity jobOrder) {
//            tv_shop_name.setText(orderItem.shop.attributes.name);
            tv_items_count.setText(String.format("%d items delivered", jobOrder.attributes.deliverables_purchased_count));

            //deliverable adapter
            LinearLayoutManager layoutManager = new LinearLayoutManager(context);
            layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
            rv_receipt_items.setLayoutManager(layoutManager);
            deliverableAdapter = new DeliverableAdapter(context);
            rv_receipt_items.setAdapter(deliverableAdapter);

            deliverableAdapter.updateDeliverableAdapter(Arrays.asList(jobOrder.relationships.deliverables.data));

        }
    }
}

This is the DeliverableAdapter.class where I am calling the updateDeliverableAdapter() method.

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

    private Context context;
    private LayoutInflater inflater;
    private List<Entity> deliverables = new ArrayList<>();

    public DeliverableAdapter(Context context) {
        this.context = context;
        this.inflater = LayoutInflater.from(context);
    }

    public void updateDeliverableAdapter(List<Entity> deliverables) {
        this.deliverables = deliverables;
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
        return new ViewHolderDeliverable(inflater.inflate(R.layout.layout_item_deliverable, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        final Entity deliverable = deliverables.get(position);
        ViewHolderDeliverable viewHolder = (ViewHolderDeliverable) holder;
        viewHolder.bindModel(deliverable);
    }

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

    class ViewHolderDeliverable extends RecyclerView.ViewHolder {

        @BindView(R.id.deliverableView)
        DeliverableView deliverableView;

        ViewHolderDeliverable(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        void bindModel(Entity deliverable) {
            deliverableView.populate(deliverable);
        }
    }
}

This is my Entity.class . I checked AttributesBase includes the need data.

public class Entity implements BaseModel{

    public String id;
    public String type;
    public AttributesBase attributes;
    public RelationshipsBase relationships;

    public boolean isCancelled(){
        return attributes.status.equalsIgnoreCase("cancelled");
    }

    @Override
    public String toString() {
        return new Gson().toJson(this);
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }
}

These are the ATTRIBUTES I am accessing on the AttributesBase.class.

@SerializedName("image-url") public String image_url; @SerializedName("name") public String name; public String size; public int count;

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
rereh
  • 1
  • 3
  • 1
    what line is it that gives that problem? how/where is it called? Can you be more specific? – Stultuske Dec 19 '19 at 07:55
  • in your image deliverable object is not null – Makarand Dec 19 '19 at 07:57
  • @Stultuske I attached the image where I get the null pointer exception. It's on the populate() method. It happens upon calling the deliverableAdapter.updateDeliverableAdapter() – rereh Dec 19 '19 at 07:58
  • @Makarand how come? my app crashes due to null pointer exception. I updated the image so you could see it. – rereh Dec 19 '19 at 08:01
  • I see from the log that Is not he ImageView that is null, but the field attribute of deliverable – christian mini Dec 19 '19 at 08:06
  • @rereh yes, but we can't copy-paste from an image. We 'll have to open an outside link. Please provide all information within the question, and all (textual) information as formatted text – Stultuske Dec 19 '19 at 08:07
  • where is the updateDeliverableAdapter() methode?? – Makarand Dec 19 '19 at 08:07

1 Answers1

0

You are trying to bind values which are not present in your class Entity.

As per screen shot attached Entity deliverable contains only two members i.e id and type. and you are trying to access value of image_url which is not present in deliverable object. You will get this error for all the lines where you are trying to set values which are not present in deliverable.

deliverable object does not contains attributes like image_url, count, name, size. All this places you will get NullPointException.

jarvis
  • 61
  • 5
  • I see what you are trying to say. Can you explain me why it is only getting the ID and not the attributes? @jarvis – rereh Dec 19 '19 at 08:35
  • @rereh Please share your Entity class. – jarvis Dec 19 '19 at 08:38
  • I updated my question and posted the Entity class as well as the Attributes – rereh Dec 19 '19 at 08:49
  • @rereh As you can see debugger displays Entity deliverable object with 2 members which are id and type are type of String but as per your Entity class Attribute is missing in debugger output.You are missing something while binding Entity class with GSON library. There may be two chances you are initialising Attribute class separately and Entity class separately. And trying to access Attribute class variable through Entity class.If you are doing separately then you need to combine both then only you are able to access Attribute class members from Entity class. – jarvis Dec 19 '19 at 09:08
  • Thank you @jarvis for this. I managed to find the problem and solved it. – rereh Dec 19 '19 at 09:20