Гость
Форумы / Android [игнор отключен] [закрыт для гостей] / ListView + ViewHolder / 6 сообщений из 6, страница 1 из 1
14.05.2018, 11:15
    #39644271
nikomp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView + ViewHolder
Пробую реализовать вывод истории чата. Для этого в приложении использую 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
14.05.2018, 11:26
    #39644282
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView + ViewHolder
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
14.05.2018, 12:31
    #39644331
nikomp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView + ViewHolder
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
14.05.2018, 13:18
    #39644365
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView + ViewHolder
видимость все равно не правильно делаешь. вот это вот

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


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

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


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