powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Android [игнор отключен] [закрыт для гостей] / ListView + ViewHolder
6 сообщений из 6, страница 1 из 1
ListView + ViewHolder
    #39644271
nikomp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробую реализовать вывод истории чата. Для этого в приложении использую ListView и ViewHolder. Пример нашел тут http://androiddocs.ru/pattern-viewholder-v-realizacii-spiska-listview/, да их на самом деле много и все похожи. Только вот у меня не получается корректно вывести историю сообщений. Путается источник и приемник сообщений. При в массиве с данными источник и приемник заданы верно.

Итак, вот мой код адаптера.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
public class MessageAdapter extends BaseAdapter {
    private Activity activity;
    private List<ChatBubble> messages;
    LayoutInflater lInflater;

    public MessageAdapter(Activity context, int resource, List<ChatBubble> objects) {
        //super(context, resource, objects);
        this.activity = context;
        this.messages = objects;

    }


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

    @Override
    public ChatBubble getItem(int position) {

      return messages.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d(LOGTAG,"getView " + position + " " + convertView);

        ViewHolder holder;


        int layoutResource = 0; // determined by view type
        ChatBubble chatBubble = getItem(position);

        if (convertView == null) {
          lInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
          if (chatBubble.myMessage()) {
            layoutResource = R.layout.right_chat_bubble;
          } else {
            layoutResource = R.layout.left_chat_bubble;
          }

          convertView = lInflater.inflate(layoutResource, parent, false);
          holder = new ViewHolder();
          holder.tvItem = (TextView) convertView.findViewById(R.id.txt_msg);
          convertView.setTag(holder);

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


        holder.tvItem.setText(chatBubble.getContent());

        return convertView;
    }

    static class ViewHolder {
        TextView tvItem;
    }
}



Видимо ViewHolder отрабатывает как-то неверно, или он вообще не подходит для этой задачи, прошу подскажите.
...
Рейтинг: 0 / 0
ListView + ViewHolder
    #39644282
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nikompПутается источник и приемник сообщений
потому что View в ListView переиспользуются. Создается какое-то количество и по мере скролла, одни и те же вьюхи заполняются актуальными данными. А теперь посмотри на свой код и подумай что происходит здесь

Код: sql
1.
2.
3.
4.
5.
6.
7.
if (convertView == null) {
          lInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
          if (chatBubble.myMessage()) {
            layoutResource = R.layout.right_chat_bubble;
          } else {
            layoutResource = R.layout.left_chat_bubble;
          }


в зависимости от того, какие сообщения идут первыми ты создаешь определенное количество вьюх 2х типов (left, right) и все - далее они переиспользуются и новые вьюхи не создаются. Правильное решение - это либо иметь 2 официальных типа вьюх как например описано тут http://android.amberfog.com/?p=296
либо иметь универсальную вьюху с сообщением слева и справа и в зависимости от chatBubble.myMessage() прятать одно и показывать другое. Ну и текст в правильный TextView записывать
...
Рейтинг: 0 / 0
ListView + ViewHolder
    #39644331
nikomp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpasha, спасибо за ответ!

Решил сделать одно универсальное вью. Изменил код адаптера

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
public class MessageAdapter extends BaseAdapter {
    private Activity activity;
    private List<ChatBubble> messages;
    LayoutInflater lInflater;

    public MessageAdapter(Activity context, List<ChatBubble> objects) {
        //super(context, resource, objects);
        this.activity = context;
        this.messages = objects;
        lInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    }


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

    @Override
    public ChatBubble getItem(int position) {

      return messages.get(position);
    }

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

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


        int layoutResource = 0;
        ChatBubble chatBubble = getItem(position);
        Log.d(LOGTAG,Integer.toString(position)+"_"+chatBubble.getContent() + " " + Boolean
            .toString
            (chatBubble.myMessage
            ()));

        if (convertView == null) {

          /*if (chatBubble.myMessage()) {
            layoutResource = R.layout.right_chat_bubble;
          } else {
            layoutResource = R.layout.left_right_chat_bubble;
          }*/

          convertView = lInflater.inflate(R.layout.left_right_chat_bubble, parent, false);

          holder = new ViewHolder();
          holder.htvR = (TextView) convertView.findViewById(R.id.tvR);
          holder.htvL = (TextView) convertView.findViewById(R.id.tvL);
          holder.llL = (LinearLayout) convertView.findViewById(R.id.llL);
          holder.llR = (LinearLayout) convertView.findViewById(R.id.llR);

          if (chatBubble.myMessage()) {
            holder.llL.setVisibility(View.INVISIBLE);
          } else {
            holder.llR.setVisibility(View.INVISIBLE);
          }

          convertView.setTag(holder);

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

        if (chatBubble.myMessage()) {
          holder.htvR.setText(chatBubble.getContent());
        } else {
          holder.htvL.setText(chatBubble.getContent());
        }

        return convertView;
    }

    static class ViewHolder {
        TextView htvR;
        TextView htvL;
        LinearLayout llR;
        LinearLayout llL;
    }


}



сейчас отправитель и получатель верно распределяются, а порядок сообщений нарушается
...
Рейтинг: 0 / 0
ListView + ViewHolder
    #39644365
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
видимость все равно не правильно делаешь. вот это вот

Код: sql
1.
2.
3.
4.
5.
if (chatBubble.myMessage()) {
            holder.llL.setVisibility(View.INVISIBLE);
          } else {
            holder.llR.setVisibility(View.INVISIBLE);
          }


должно быть в том же месте, где текст сообщения устанавливается. еще раз осмысли: создается каких-то 5-6 вьюх и они используются всегда и на все случаи жизни. т.е. для каждого сообщения ВСЕ изменяемые значения (в том числе видимость) должны устанавливаться каждый раз, когда это требуется
...
Рейтинг: 0 / 0
ListView + ViewHolder
    #39644368
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. когда вьюха переиспользуется, convertView != null, т.е. ты в блок if (convertView == null) просто не попадаешь
...
Рейтинг: 0 / 0
ListView + ViewHolder
    #39644386
nikomp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpasha,

все получилось! спасибо, за подробный и оперативный ответ!
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Android [игнор отключен] [закрыт для гостей] / ListView + ViewHolder
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]