Search code examples
androiddatabaseandroid-recyclerviewretrofitadapter

RecyclerView showing database entries as null strings


I'm working on an Android app which uses PHP API and retrofit. My SQL database has an "orders" table which is the result of join between "users" and "foods" tables. My code works successfully in showing "users" and "foods" in recyclerviews in different fragments, but the same method fails to show the "orders" and I get an empty recyclerview (with the right numbers of rows and items of the orders table) but the strings are null and the integers are 0. The code runs with no error. I also tested PHP request in POSTMAN and the response is correct, so the PHP code is working well. Could you please tell me what is wrong with this code? Could the problem be related to using columns of other tables in the join query or something else? Please help me friends.

I found this in Logcat: 2019-08-08 00:43:52.967 21951-21951/com.nikappzaar.app.foodtakeout E/RecyclerView: No adapter attached; skipping layout

public function getAllOrders(){
            $stmt = $this->con->prepare(
                                "SELECT o.oid, o.uid, o.fid, o.quantity, o.otime
                                   , f.fname, f.unitprice
                                   , u.phone, u.uname, u.uaddress
                                 FROM orders o
                                 INNER JOIN foods f
                                   on o.fid = f.fid
                                 INNER JOIN users u
                                   on o.uid = u.uid ;");
            $stmt->execute(); 
            $stmt->bind_result($oid, $uid, $fid, $quantity, $otime, $fname, $unitprice, $phone, $uname, $uaddress);
            $orders = array(); 
            while($stmt->fetch()){ 
                $order = array(); 
                $order['o.oid'] = $oid; 
                $order['o.uid'] = $uid; 
                $order['o.fid'] = $fid; 
                $order['o.quantity']=$quantity; 
                $order['o.otime'] = $otime;
                $order['f.fname'] = $fname; 
                $order['f.unitprice'] = $unitprice; 
                $order['u.phone']=$phone; 
                $order['u.uname'] = $uname; 
                $order['u.uaddress'] = $uaddress;
                array_push($orders, $order);
            }             
            return $orders; 
        }

OperatorHomeFargment.java

public class OperatorHomeFragment extends Fragment {

    private RecyclerView recyclerView;
    private OrdersAdapter adapter;
    private List<Order> orderList;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_orders, container, false);
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        recyclerView = view.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));


        Call<OrdersResponse> call = RetrofitClient.getInstance().getApi().getOrders();

        call.enqueue(new Callback<OrdersResponse>() {
            @Override
            public void onResponse(Call<OrdersResponse> call, Response<OrdersResponse> response) {

                orderList = response.body().getOrders();
                adapter = new OrdersAdapter(getActivity(), orderList);
                recyclerView.setAdapter(adapter);
            }

            @Override
            public void onFailure(Call<OrdersResponse> call, Throwable t) {

            }
        });

    }
}

OrdersAdapter.java

public class OrdersAdapter extends RecyclerView.Adapter<OrdersAdapter.OrdersViewHolder> {

    private Context mCtx;
    private List<Order> orderList;

    public OrdersAdapter(Context mCtx, List<Order> orderList) {
        this.mCtx = mCtx;
        this.orderList = orderList;
    }

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

    @Override
    public void onBindViewHolder(@NonNull OrdersViewHolder holder, int position) {
        Order order = orderList.get(position);

        holder.textViewOId.setText(String.format("%d", order.getOId()));
        holder.textViewOTime.setText(order.getOTime());
        holder.textViewFName.setText(order.getFName());
        holder.textViewQuantity.setText(String.format("%d", order.getQuantity()));
        holder.textViewUnitPrice.setText(String.format("%d", order.getUnitPrice()));
        holder.textViewPhone.setText(order.getPhone());
        holder.textViewUName.setText(order.getUName());
        holder.textViewUAddress.setText(order.getUAddress());
    }

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

    class OrdersViewHolder extends RecyclerView.ViewHolder {

        TextView textViewOId, textViewOTime, textViewFName, textViewQuantity, textViewUnitPrice,
                 textViewPhone, textViewUName, textViewUAddress;

        public OrdersViewHolder(View itemView) {
            super(itemView);

            textViewOId = itemView.findViewById(R.id.textViewOId);
            textViewOTime = itemView.findViewById(R.id.textViewOTime);
            textViewFName = itemView.findViewById(R.id.textViewFName);
            textViewQuantity = itemView.findViewById(R.id.textViewQuantity);
            textViewUnitPrice = itemView.findViewById(R.id.textViewUnitPrice);
            textViewPhone = itemView.findViewById(R.id.textViewPhone);
            textViewUName = itemView.findViewById(R.id.textViewFName);
            textViewUAddress = itemView.findViewById(R.id.textViewUAddress);

        }
    }
}

Order.java

public class Order {

    private int oid, uid, fid, quantity, unitprice;
    private String otime, fname, phone, uname, uaddress;

    public Order(int oid, int uid, int fid, int quantity, String otime,
                 String fname, int unitprice, String phone, String uname, String uaddress) {
        this.oid = oid;
        this.uid = uid;
        this.fid = fid;
        this.quantity = quantity;
        this.otime = otime;
        this.fname = fname;
        this.unitprice = unitprice;
        this.phone = phone;
        this.uname = uname;
        this.uaddress = uaddress;
    }

    public int getOId() {
        return oid;
    }

    public int getUId() {
        return uid;
    }

    public int getFId() {
        return fid;
    }

    public int getQuantity() {
        return quantity;
    }

    public String getOTime() {
        return otime;
    }

    public String getFName() {
        return fname;
    }

    public int getUnitPrice() {
        return unitprice;
    }

    public String getPhone() {
        return phone;
    }

    public String getUName() {
        return uname;
    }

    public String getUAddress() {
        return uaddress;
    }

}

recyclerview_orders.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="3dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="4dp">

            <TextView
                android:id="@+id/textViewOId"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />

            <TextView
                android:id="@+id/textViewOTime"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />

            <TextView
                android:id="@+id/textViewFName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />

            <TextView
                android:id="@+id/textViewQuantity"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />

            <TextView
                android:id="@+id/textViewUnitPrice"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />

            <TextView
                android:id="@+id/textViewPhone"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />

            <TextView
                android:id="@+id/textViewUName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />

            <TextView
                android:id="@+id/textViewUAddress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />



        </LinearLayout>

    </android.support.v7.widget.CardView>

</RelativeLayout>

fragment_orders.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


</LinearLayout>

Solution

  • As I understand from comments that you have a problem with parsing response json to model class. Can you try to put a default constructor in Order class and @SerializedName("json_key_name") annotation to top of the attributes which has different name from json keys.