Search code examples
androidlistviewandroid-listviewlistviewitem

Android ListView items that out of screen are not shown correctly


As the title says, i encounter a problem that using a adapter to setup a listview, so that the bottom items which are outside of the screen are duplicated with top items. For example, at the top of listview, appointment 14 is the first item, but when I scroll down to the bottom, the bottom item is supposed to be other item appointment 20, but it appear as appointment 14.

and here is my code:

public class AppointmentArrayAdapter extends BaseAdapter {

    ArrayList<Appointment> appointments;
    Context context;
    LayoutInflater inflater;

    public AppointmentArrayAdapter(ArrayList<Appointment> app, Context c){
        appointments=app;
        context=c;
        inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return appointments.size();
    }

    @Override
    public Object getItem(int position) {
        return appointments.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if(convertView==null){
            convertView = inflater.inflate(R.layout.appointment_list_item, parent, false);
            holder = new ViewHolder();
            TableLayout ll = (TableLayout) convertView.findViewById(R.id.tableLayout);
            TableRow[] row = new TableRow[6];
            TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,
                    TableRow.LayoutParams.WRAP_CONTENT);

            for(int i=0;i<6;i++){
                row[i]=new TableRow(context);
                row[i].setLayoutParams(lp);
            }

            TextView itemId = new TextView(context);
            TextView itemType = new TextView(context);

            itemId.setText(""+appointments.get(position).getId());
            itemType.setText(appointments.get(position).getAppointmentType().toString());

            row[0].setBackgroundColor(0xFF00FF00);
            row[0].addView(itemId);
            row[0].addView(itemType);

            TextView lable1 = new TextView(context);
            TextView patient = new TextView(context);
            lable1.setText("Patient: ");
            String patientName = DatabaseHandler.getInstance(null).getUserById(appointments.get(position).getPatient()).getName();
            patient.setText(patientName);
            row[1].addView(lable1);
            row[1].addView(patient);

            TextView lable2 = new TextView(context);
            lable2.setText("Consultant: ");
            TextView consultant = new TextView(context);
            String consultantName = DatabaseHandler.getInstance(null).getUserById(appointments.get(position).getConsultant()).getName();
            consultant.setText(consultantName);
            row[2].addView(lable2);
            row[2].addView(consultant);

            TextView lable3 = new TextView(context);
            lable3.setText("Clinic: ");
            TextView clinic = new TextView(context);
            String clinicName = DatabaseHandler.getInstance(null).getUserById(appointments.get(position).getClinic()).getName();
            clinic.setText(clinicName);
            row[3].addView(lable3);
            row[3].addView(clinic);

            TextView lable4 = new TextView(context);
            lable4.setText("Timeslot: ");
            TextView timelot = new TextView(context);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            String formattedDate = df.format(appointments.get(position).getTime());
            timelot.setText(formattedDate);
            row[4].addView(lable4);
            row[4].addView(timelot);

            for(int i=0;i<6;i++)
                ll.addView(row[i]);

            holder.tableLayout = ll;

            convertView.setTag(holder); 

        }else{
            holder = (ViewHolder)convertView.getTag();
        }


        return convertView;
    }
}
class ViewHolder{
    TableLayout tableLayout;
}

Solution

  • Android reuses the views you've created before. That's what you get when convertView is != null. So in those cases, you need to do the setText, setBackground, etc. I think the issue is that the if(convertView == null) { block should only be the first two lines that you have. Something like

    if (convertView == null) {
        inflate the view, create new ViewHolder
    } else {
        set the ViewHolder variable to the tag
    }
    set up the text views, background etc. in either case