1

ListViewユーザーが送信したメッセージが白で表示され、友人が受信したメッセージが青で表示される、多数の行からチャットビューが形成されるチャットアプリケーションを作成しました。

この動作は正常に機能しますが、非常に大きくなった後(たとえば、30行)にリストをスクロールすると、色が乱れます。行ごとに異なるレイアウト、白い行のレイアウトと青い行のレイアウトを使用します。

リストを上下に複数回スクロールすると、色がランダムに切り替わり続けます(つまり、メッセージの一部が青で、他のメッセージが白で、もう一方の端(チャットしている友人)が白になり、他のメッセージが青になります。ランダムな方法。

使用したコードのプレビューを簡単に説明します。

これはgetView私のカスタムアダプタのメソッドであり、以下を拡張しますBaseAdapter

public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        final int pos = position;                           
        String from = messages.get(pos).getFrom();
        if (convertView == null) {
            holder = new ViewHolder();    
                     // If message is sent by me (the user)
            if(from.toString().toLowerCase().equals("me")){
               convertView = mInflater.inflate(R.layout.chat_msg_row2, null);
            }
                    // if message is sent by his friend (the other end user)
            else{
                convertView = mInflater.inflate(R.layout.chat_msg_row, null);           
            }

            holder.userName = (TextView) convertView.findViewById(R.id.msgusername);
            holder.userImage = (ImageView) convertView.findViewById(R.id.ppic);
                holder.date = (TextView) convertView.findViewById(R.id.msgdate);
            holder.text = (TextView) convertView.findViewById(R.id.msg);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }           
        holder.userName.setText( messages.get(pos).getFrom() );
        holder.text.setText( messages.get(pos).getText() );
        holder.date.setText( messages.get(pos).getDate() );         
        String img = messages.get(pos).getImage();          
        if(img.substring(0,4).equalsIgnoreCase("http") ){

            try{
                  ImageLoader imloader = new ImageLoader( ChatActivity.this );      
                          holder.userImage.setTag(img);
              imloader.DisplayImage( img, ChatActivity.this , holder.userImage );
                }
            catch(Exception e){
              e.printStackTrace();                      
            }
        }

        return convertView;
    }

    public long getItemId(int position){
         return 1;
    }

    public class ViewHolder{
        TextView userName;
        ImageView userImage;
        TextView text;
        TextView date;
    }

2つのレイアウトchat_msg_row2chat_msg_rowは、1つが白い画像を使用し、もう1つが青い画像を使用するDrawableを使用していることを除いて、同じです。

4

2 に答える 2

2

最近、同様の問題に直面しました。私がしたことは、

if (convertView == null) 

ビュー自体を返します。上記のコードが行うことは次のとおりです。現在のリストに以前のキャッシュが存在するかどうかを確認します。存在する場合は、以前に存在したリストを再利用します。それが役に立てば幸い

于 2013-06-17T11:32:25.900 に答える
1

アダプターのgetItemViewTypeおよびメソッドを使用しなかったため、は 1 つのタイプの行しかないと想定し (実際には 2 つのタイプを使用します)、リストに表示される行をリサイクルします。したがって、そうでない場合は、その位置に応じて、これらの 2 つのタイプのいずれかになる可能性のあるリサイクルされた行を取得します。getViewTypeCountListViewconvertViewnull

ただし、上記のメソッドは、行が実際に異なる場合 (追加のウィジェット、配置ルールなど) にのみ実装する必要があります。2 つの行が背景画像だけが異なる場合、必要なのは 1 行だけで、アプリのロジックに基づいて背景を次のように設定します。

//...
if (convertView == null) {
    holder = new ViewHolder();    
    // just inflate one of the rows if they are identical
    convertView = mInflater.inflate(R.layout.chat_msg_row, parent, false);           
    holder.userName = (TextView) convertView.findViewById(R.id.msgusername);
    holder.userImage = (ImageView) convertView.findViewById(R.id.ppic);
    holder.date = (TextView) convertView.findViewById(R.id.msgdate);
    holder.text = (TextView) convertView.findViewById(R.id.msg);
    convertView.setTag(holder);
} else {
    holder = (ViewHolder) convertView.getTag();
}           
// set the background image as desired   
if(from.toString().toLowerCase().equals("me")){
    // I assumed you set the background on the root of the View row, convertView
    // otherwise search for the desired view in convertView and set the background
    convertView.setBackgroundResource(R.drawable.the_me_background_drawable);
} else {
    convertView.setBackgroundResource(R.drawable.the_other_user_background_drawable);
}
// ...
于 2012-11-01T08:10:16.607 に答える