0

ちょっとしたチャットアプリを開発していて、ListViewメッセージを表示するためにを使用したいと思います。現在、ユーザーの入力を取得して「送信メッセージ」として表示しようとしています。私のrowレイアウトは次のとおりです:(TextViewタイムスタンプ)、TextView(メッセージ)、ImageView(メッセージ状態インジケーター)。私の問題:テキストとタイムスタンプが設定されておらず、「ダミー」のレイアウトが膨らんでいるだけです。どういうわけかアダプタ内にテキストを設定する必要があると思います。誰かが私が間違っていることを教えてもらえますか?コードは以下のとおりです。

私のアダプター:

public class ChatAdapter extends BaseAdapter {
private Context context;

private List<String> chat;

public ChatAdapter(Context context, List<String> listchat) {
    this.context = context;
    this.chat = listchat;
}

public int getCount() {
    return chat.size();
}

public Object getItem(int position) {
    return chat.get(position);
}

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

public View getView(int position, View convertView, ViewGroup viewGroup) {

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.row, null);
    }
    TextView tvTS = (TextView) convertView.findViewById(R.id.tvTS);
    // TODO set timestamp

    TextView tvMessage = (TextView) convertView
            .findViewById(R.id.tvMessage);
    // TODO set the text to the actual message text from etInput

    ImageView indicator = (ImageView) convertView.findViewById(R.id.imgInd);

    // TODO set the image Resource according to message state
    return convertView;
}

私の活動:

 public class ChatActivity extends ListActivity {

private EditText input;
private String tmpMessage;
ListView lv;
ChatAdapter adapter;
List<String> messages;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.lis);
    Button send = (Button) findViewById(R.id.btnSend);
    input = (EditText) findViewById(R.id.etInput);
    lv = getListView();

    messages = new ArrayList<String>();
    adapter = new ChatAdapter(this, messages);
    lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO
        }
    });

    lv.setAdapter(adapter);

    send.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            sendMessage();
        }
    });
}

public void sendMessage() {

    tmpMessage = input.getText().toString();
    input.setText("");
    messages.add(tmpMessage);
    adapter.notifyDataSetChanged();

}

@SuppressLint("SimpleDateFormat")
public String generateTimestamp() {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
    String ts = sdf.format(new Date());

    return ts;
}

アップデート

ホルダーを追加し、次のコードを使用してテキストを設定しました。

 String message = (String) getItem(position);
        holder.message.setText(message);

動作しますが、膨張したレイアウトがランダムに配置されるようになりました。下のスクリーンショットを参照してください。次のようになります

テスト

test1

test2

...。

ここに画像の説明を入力してください

理由は何ですか?

4

4 に答える 4

1

データをTextViews/ImageViewに設定していないようです。次のように、ChatAdapterのgetView()メソッドでこれを行う必要があります。

public View getView(int position, View convertView, ViewGroup viewGroup) {

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.row, null);
    }
    String chatMessage = getItem(position);
    TextView tvTS = (TextView) convertView.findViewById(R.id.tvTS);
    // TODO set timestamp

    TextView tvMessage = (TextView) convertView
            .findViewById(R.id.tvMessage);
    //Set the message to the TextView
    tvMessage.setText(chatMessage);

    ImageView indicator = (ImageView) convertView.findViewById(R.id.imgInd);

    // TODO set the image Resource according to message state
    return convertView;
}

(文字列のリストではなく)カスタムオブジェクトを使用して、表示するメッセージ、タイムスタンプ、およびメッセージ状態インジケーターのタイプを保持することを検討してください。その場合、あなたはこれを行うことができます

ChatMessage msgObj = getItem(position);
...
tvMessage.setText(msgObj.getMessage());
tvTS.setText(msgObj.getTimestamp());
if ( msgObj.getStatus() == ChatMessage.DELIVERED )
{
  indicator.setBackgroundResource(R.drawable.delivered);
}
else if (....)
于 2013-01-25T11:43:40.800 に答える
1

for text メソッドでsetTextメソッドを呼び出し、必要な各ビューのテキストを設定する必要があります。getViewまた、あなたのイメージを設定します。getViewリストの単一のビューを作成する責任があるため、毎回準備が整ったビューを返すように実装する必要があります。

あなたが今していることは、ID で要素を見つけて、何もしていないことです。デフォルトの膨張した行を返すだけです。

PSパフォーマンスの問題のViewHolderパターンについてもお読みください。

于 2013-01-25T11:35:42.170 に答える
1

getView で次の変更を試してください

public View getView(int position, View convertView, ViewGroup viewGroup) {

if (convertView == null) {
    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.row, null);

 TextView tvTS = (TextView) convertView.findViewById(R.id.tvTS);    

 TextView tvMessage = (TextView) convertView.findViewById(R.id.tvMessage);

 ImageView indicator = (ImageView) convertView.findViewById(R.id.imgInd);

}   
tvMessage.setText("......");

return convertView;

}

このリンクをご覧ください

于 2013-01-25T11:39:04.617 に答える
1

リストのパフォーマンスを向上させるために ViewHolder パターンを使用できます

ViewHolder クラス:

public class ViewHolder{
public TextView message;
public TextView timestamp;
public ImageView indicator
}

次に、アダプター getView メソッドで次のように使用します。

public View getView(int position, View convertView, ViewGroup viewGroup) {

    ViewHolder holder = null;

            if(convertView == null ){
                convertView = inflater.inflate(R.layout.<your_layout>, null);           

                holder = new ViewHolder();
                holder.message = (TextView) convertView.findViewById(R.id.message);
holder.timestamp = (TextView) convertView.findViewById(R.id.timestamp);
holder.indicator = (ImageView) convertView.findViewById(R.id.indicator);

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

            }

            holder.message.setText(chat.get(position).<whatever>);
            holder.timestamp.setText(chat.get(position).<whatever>);
holder.indicator.<method>
            return convertView;
}

それが役立つことを願っています。

BR、マイベックス

于 2013-01-25T11:39:32.490 に答える