0

ユーザーがテキストメッセージと画像を送信できるチャットアプリを開発していますテキストメッセージのみがデータセットにある場合、リストビューは適切な方法で適切なデータを表示し、ユーザーが画像を送信すると画像はリストに適切に追加されます私は通知データセットを呼び出します変更されたデータセットの位置が変更される例:画像が0に追加され、3番目または4番目の位置に表示されます

package com.exception.chatapp;

import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class ChatAdapter extends BaseAdapter {

Context context;
ArrayList<HashMap<String, String>> data;
LayoutInflater inflator;
String imageurl = "http://www.example.com/webservices/";

public ChatAdapter(Context context, ArrayList<HashMap<String, String>> data) {
    this.context = context;
    this.data = data;
    inflator = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    // return data.size();
    return data.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public View getView(int position, View convertview, ViewGroup parentview) {
    // TODO Auto-generated method stub

    ViewHolder holder;
    if (convertview == null) {
        convertview = inflator.inflate(R.layout.chat_item, parentview,false);
        holder = new ViewHolder();
        holder.message = (TextView) convertview
                .findViewById(R.id.txtusermessage);
        holder.userimage = (ImageView) convertview
                .findViewById(R.id.userimage);
        convertview.setTag(holder);
    } else {
        holder = (ViewHolder) convertview.getTag();
    }
    holder.userimage.setVisibility(View.GONE);
    HashMap<String, String> map = data.get(position);
    if (!map.get("user_name").equals("me")) {
        if (map.get("type").equals("text")) {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            holder.message.setLayoutParams(params);
            holder.message.requestLayout();
            holder.message.setText(map.get("message"));
            holder.message.setBackgroundResource(R.drawable.farhan_blue);
        } else if (map.get("type").equals("image")) {
            holder.userimage.setVisibility(View.VISIBLE);
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    200,
                    200);
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            holder.userimage.setLayoutParams(params);
            holder.userimage.requestLayout();
            holder.userimage.setBackgroundResource(R.drawable.farhan_blue);
            holder.message.setVisibility(View.GONE);
            ImageLoader loader = new ImageLoader(context);
            Log.d("image_url", imageurl + map.get("image_url"));
            loader.DisplayImage(imageurl + map.get("image_url"),
                    holder.userimage);
        } else if (map.get("type").equals("gps")) {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            holder.message.setLayoutParams(params);
            holder.message.requestLayout();
            holder.message.setText(map.get("lat") + "," + map.get("lng"));
            holder.message.setBackgroundResource(R.drawable.farhan_blue);
        }

        else if (map.get("type").equals("contact")) {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            holder.message.setLayoutParams(params);
            holder.message.requestLayout();
            holder.message.setText(map.get("name") + "\n"
                    + map.get("number"));
            holder.message.setBackgroundResource(R.drawable.farhan_blue);
        }
    } else {
        if (map.get("type").equals("text")) {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            holder.message.setLayoutParams(params);
            holder.message.requestLayout();
            holder.message.setText(map.get("message"));
            holder.message.setBackgroundResource(R.drawable.farhan_white);
        } else if (map.get("type").equals("image")) {
            holder.message.setVisibility(View.GONE);
            holder.userimage.setVisibility(View.VISIBLE);
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    200,
                    200);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            holder.userimage.setLayoutParams(params);
            holder.userimage.requestLayout();
            holder.userimage.setBackgroundResource(R.drawable.farhan_white);


            if (map.get("from") != null) {
                Log.d("image_url",map.get("image_url"));
                holder.userimage
                        .setImageURI(Uri.parse(map.get("image_url")));
            } else {
                ImageLoader loader = new ImageLoader(context);
                Log.d("image_url", imageurl + map.get("image_url"));
                loader.DisplayImage(imageurl + map.get("image_url"),
                        holder.userimage);
            }

        }

        else if (map.get("type").equals("gps")) {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            holder.message.setLayoutParams(params);
            holder.message.requestLayout();
            holder.message.setText(map.get("lat") + "," + map.get("lng"));
            holder.message.setBackgroundResource(R.drawable.farhan_white);
        } else if (map.get("type").equals("contact")) {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            holder.message.setLayoutParams(params);
            holder.message.requestLayout();
            holder.message.setText(map.get("name") + "\n"
                    + map.get("number"));
            holder.message.setBackgroundResource(R.drawable.farhan_white);
        }

    }

    return convertview;
}

static class ViewHolder {
    TextView message;
    ImageView userimage;
}

}

これが私のリストビューです。レイアウトxmlの2つのレイアウトの上と下で、幅と高さをmatch_parentに設定します

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/chatlayout"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/linearLayout1"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:stackFromBottom="true" >
</ListView>

アクティビティの結果で、リストビューに画像を追加します

if (resultCode == RESULT_OK && requestCode == 1 && data1!=null) {   
        try {

            Uri selectedImage = data1.getData();
            filepath = getRealPathFromURI(selectedImage);
            Log.d("path", filepath);
            ChatItem item = new ChatItem();
            item.setUsername("me");
            item.setMessage("");
            item.setType("image");
            item.setImage_uri(filepath);
            item.setFrom("local");
            data.add(item);
            adapter.notifyDataSetChanged();
            list.smoothScrollToPosition(data.size() - 1);
            message.setText("");
            new UploadFile().execute(filepath, id, rid, "image");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
4

2 に答える 2

1

あなたの説明と提供されたコードに基づいて、この問題は、条件を使用してビュー レイアウトを切り替える方法と、ListView.

ListView、以前に膨張したビューをリサイクルするように最適化されています。これは、アイテムごとに新しいレイアウトをインフレートする必要がないように設計されています。このリサイクルは、アイテムの種類を選択するために使用しているロジック (アイテムごとに異なる子要素を表示および非表示にする) と組み合わされて、picutre を追加したときに新しいビューが作成されない可能性があるため、この問題の原因となる可能性があります。古いものを更新しているだけです。

アイテムのビューを切り替える方法を、ビューのタイプごとに異なるモデル オブジェクト (メッセージ オブジェクト、画像オブジェクトなど) が存在するように変更します。次に、次の方法でアダプターをセットアップします。

View v = convertView;
Object o = data.get(position);
LayoutInflaer inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

if(o != null){
    if(o instanceof ImageMessage){
        if(v == null){
            v = inflater.inflate(R.layout.image_message);
        }
        createImageMessagView(v, (ImageMessage) o);
    } else if (o instanceOf textMessage){
        // handle different object type
    }

createImageMes​​sageView は、関連するレイアウトの子ビューを id で見つけて、そのコンテンツを設定する場所です。

このアプローチにより、アイテム クラスごとに異なるレイアウトを使用できます。この方法では、1 つのビューを作成してビュー ホルダーに保存し、後でその内容を変更しようとすることはありません。むしろ、その項目タイプのコンテンツを表示するように設計されたカスタム レイアウトが存在しない場合は、それを膨らませています。

于 2013-07-15T12:59:09.650 に答える
0

問題はここにあります

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}

私はこれを

@Override
public ChatItem getItem(int arg0) {
    // TODO Auto-generated method stub
    return data.get(arg0);
}

私の問題は解決しましたが、別の問題があります

Plz dntは静的ビューホルダーを使用すると、メモリリークエラーが発生します

于 2013-07-16T11:51:40.017 に答える