Android - Custom listview changes while scrolling?

2019-09-14 18:29发布

问题:

My listview keeps changing while scrolling. I'm trying to display the messages in "messages" variable. Everything is fine when i scroll first time. But when i scroll again, the textviews overlap each other. I'm not sure what the problem is.

public class DisplayMessageAdapter extends ArrayAdapter<Message> {

    Context context;
    int resource;
    ArrayList<Message> messages = null;

    public DisplayMessageAdapter(Context context, int resource, ArrayList<Message> messages) {
        super(context, resource, messages);
        this.context = context;
        this.resource = resource;
        this.messages = messages; //list of messages to display
    }

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

        View row = convertView;
        final MessagesHolder holder;


        if(row == null)
        {
            //Log.i("row-null","row-null");
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(resource, parent, false);

            holder = new MessagesHolder();
            holder.sent  = (TextView) row.findViewById(R.id.sent_message);
            holder.received = (TextView) row.findViewById(R.id.received_message);
            row.setTag(holder);
        }

        else
        {
            //Log.i("holder-not-null","holder-not-null");
            holder = (MessagesHolder) row.getTag();
        }

        Message message = messages.get(position);


        if(message.sent != null)
        {
            holder.sent.setText(message.sent);
            holder.received.setBackground(null);
        }
        else
        {
            holder.received.setText(message.received);
            holder.sent.setBackground(null);
        }

        return row;
    }

    static class MessagesHolder
    {
        TextView sent;
        TextView received;

    }

}

Layout xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
      <TextView android:id="@+id/sent_message"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:textColor="#000000"
        android:background="@drawable/sent"
        android:layout_marginTop="4dp"
        android:layout_marginBottom="4dp"

        android:textSize="15sp"
         />

      <TextView
          android:id="@+id/received_message"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:background="@drawable/rcvd"
          android:layout_marginRight="20dp"
          android:textColor="#000000"
          android:layout_marginTop="4dp"
          android:layout_marginBottom="4dp"
          android:textSize="15sp"
           />

</RelativeLayout>

回答1:

Try to change your conditions as below to set the values in your TextView. In your below code the all if conditions are same. That does not make any difference.

  if(message.sent != null && message.received != null)
    {
        Log.i("adapter","both");
        holder.sent.setText(message.sent);
        holder.received.setText(message.received);
    }
    else if(message.sent != null)
    {
        holder.sent.setText(message.sent);
        //holder.received.setBackground(null);
    }
    else if(message.received != null)
    {
        holder.received.setText(message.received);
        //holder.sent.setBackground(null);
    }

Change it as below:

  if(message.sent != null && message.received != null)
    {
        holder.sent.setText(message.sent);
        holder.received.setText(message.received);
    }
    else
    {
        holder.sent.setText("NA");
         holder.received.setText("NA");
    }


回答2:

Temproary Solution :

The problem seems to be in the holder and it's use. It works now if i dont use the holder class for performance boost. Although i'm not sure how to use the holder properly.



回答3:

I had a similar issue. I had a progress bar in my rows. My problem is that I wasn't resetting the progress bar every time get view was called. You must reset ever asset.