4
\$\begingroup\$

In my Android app, I need to disable a button in Layout if the api return status as 0. I get this status in the Adapter and based on it, I have disabled the button in ViewHolder which is inflating the corresponding Layout.

This is a part of the Adapter class.

            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            JSONObject reader= new JSONObject(sb.toString());
            status = reader.getInt("success");

I have read this status in the ViewHolder class and based on it disabled the button with id pass_vehicle.

  public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView vehicles;
        public TextView vehicle_type;
        public TextView vehicle_eta;
        public TextView timecard_no;
        public Button pass;public int test;public int gate_id; public int status;
        ContentAdapter ca;

        public ViewHolder(LayoutInflater inflater, ViewGroup parent) {
            super(inflater.inflate(R.layout.vehicle_status, parent, false));

            vehicles = (TextView) itemView.findViewById(R.id.vehicle_no);
            vehicle_type = (TextView) itemView.findViewById(R.id.vehicle_type);
            vehicle_eta = (TextView) itemView.findViewById(R.id.vehicle_eta);
            timecard_no = (TextView) itemView.findViewById(R.id.timecard_no);
            pass = (Button) itemView.findViewById(R.id.pass_vehicle);

            gate_id = ContentAdapter.this.gate_id;
            status = ContentAdapter.this.status;
            if(status==0)
                pass.setVisibility(View.GONE);
            pass.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    try {
                        URL url = new URL(passvehicle_url);
                        HttpURLConnection con = (HttpURLConnection) url.openConnection();
                        con.setRequestMethod("POST");
                        con.setDoInput(true);
                        con.setDoOutput(true);
                        Uri.Builder builder = new Uri.Builder()
                                .appendQueryParameter("timecard_no", timecard_no.getText().toString())
                                .appendQueryParameter("gate_id", Integer.toString(gate_id));

                        String query = builder.build().getEncodedQuery();
                        OutputStream os = con.getOutputStream();
                        BufferedWriter writer = new BufferedWriter(
                                new OutputStreamWriter(os,"UTF-8")
                        );
                        writer.write(query);
                        writer.flush();
                        writer.close();
                        os.close();
                        con.connect();

                        StringBuilder sb = new StringBuilder();
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
                        String json;
                        while ((json = bufferedReader.readLine()) != null) {
                            sb.append(json + "\n");
                        }
                        JSONObject reader= new JSONObject(sb.toString());
                        status = reader.getInt("success");

                        if(status == 1) {
                            Intent intentClear = new Intent(context, VehicleActivity.class);
                            //    intentClear.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                            intentClear.putExtra(VehicleActivity.EXTRA_POSITION, gate_id);
                            context.startActivity(intentClear);
                            ((VehicleActivity) context).finish();
                        }
                        else
                            Toast.makeText(context, Html.fromHtml("<big><b>Something Went Wrong !!!</b></big>"), Toast.LENGTH_LONG).show();


                    } catch (MalformedURLException e) {
                        System.out.println("The URL is not valid.");
                        System.out.println(e.getMessage());
                    }
                    catch(JSONException e){
                        e.printStackTrace();
                    }
                    catch (IOException e) {
                        System.out.println("The URL is not valid.");
                        System.out.println(e.getMessage());
                    }
                }
            });
        }
    }

I would like to know if my approach is right and the code can be improved.

Please find the complete code. Please suggest.

\$\endgroup\$
1
  • \$\begingroup\$ Do you define a ViewHolder as an inner class of the Adapter ? \$\endgroup\$
    – Tam Huynh
    May 25, 2018 at 8:41

1 Answer 1

1
\$\begingroup\$

I have following concern about this structure:

  • The ViewHolder keeps the layout logic, which shouldn't
  • You define the ViewHolder as the inner class of the Adapter. It's not a good idea

You don't provide the adapter code so problems I found only in the ViewHolder

The reason is:

The ViewHolder is just the holder of the inflated view. It should only contain the views, maybe some simple UI logic, but not the logic. The logic should be placed in the Adapter instead, it has all the necessary data, viewType, position and others method to construct the logic. An inner ViewHolder will create too many references since an inner class always has reference to its parent during its existence. It should be a stand-alone class, you can define your ViewHolder just like this:

public static class ViewHolder extends RecyclerView.ViewHolder {
    public TextView vehicles;
    public TextView vehicle_type;
    public TextView vehicle_eta;
    public TextView timecard_no;
    public Button pass;

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

        vehicles = (TextView) itemView.findViewById(R.id.vehicle_no);
        vehicle_type = (TextView) itemView.findViewById(R.id.vehicle_type);
        vehicle_eta = (TextView) itemView.findViewById(R.id.vehicle_eta);
        timecard_no = (TextView) itemView.findViewById(R.id.timecard_no);
        pass = (Button) itemView.findViewById(R.id.pass_vehicle);
    }
}

public class MyAdapter extends RecyclerView.Adapter<ViewHolder> {

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(getContext()).inflate(R.layout. vehicle_status, parent, false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // Put all the logic, access the holder view to update its data
        // Call holder.vehicles to access the ViewHolder vehicles view here
    }

    // Other implementations...
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.