Элемент списка не правильно выровнен

1

Я создал на экране чата, и я хочу отображать отправленное сообщение с левой стороны и полученные сообщения с правой стороны.
Для этого я создал два xml один для правого и один для слева, и я связал этот два xml с адаптером.
Проблема в том, что когда я отправляю текст, он находится на левой стороне, и когда я получаю текст, отправляемый текст также выравнивается с правой стороны. И когда я отправляю снова, весь текст (чат) выравнивается слева.

Вот мой ArrayAdapter:

private void setListAdapterL() {
    ArrayAdapter<String> adapterL = new ArrayAdapter<String>(this,
            R.layout.row_left, messages);
    mList.setAdapter(adapterL);
}

private void setListAdapterR() {
    // TODO Auto-generated method stub
    ArrayAdapter<String> adapterR = new ArrayAdapter<String>(this,
            R.layout.row_right, messages);
    mList.setAdapter(adapterR);
}

Мой xml- файл для row_right.xml.in другого row_left.xml изменяется только гравитация:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:paddingLeft="5dip" />

Любые идеи и предложения будут оценены.
благодаря

  • 0
    Покажите нам свой экран для просмотра списка
Теги:
android-layout

3 ответа

2
Лучший ответ

Для этого вам нужно создать пользовательский адаптер для представления списка вместо создания двух отдельных адаптеров для левого элемента (т.е. Отправленного элемента) и правого элемента (т.е. Полученного элемента).

Это означает, что вы управляете отправленными/полученными сообщениями в одном настраиваемом адаптере.

например,

// Sample messages inside MessageActivity
void initMessages() {
  HashMap<String, String> messageSent = new HashMap<String, String>();
  messageSent.put("message", "Hi");
  messageSent.put("type", "sent");
  messageSent.put("date", "");

  HashMap<String, String> messageReceived = new HashMap<String, String>();
  messageSent.put("message", "Hello");
  messageSent.put("type", "received");
  messageSent.put("date", "");

  ArrayList<HashMap<String, String>> messages = new ArrayList<HashMap<String, String>>();
  messages.add(messageSent);
  messages.add(messageReceived);

  MessageAdapter adapter = new MessageAdapter(mContext, messages);
  setListAdapter(apater);
}

// adapter class
class MessageAdapter extends ArrayAdapter<HashMap<String, String>> {

    LayoutInflater inflater;

    public MessageAdapter(Context context, ArrayList<HashMap<String, String>> data) {
        super(context, R.layout.raw_message, data);
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

        if(convertView == null) {
            convertView = inflater.inflate(R.layout.raw_message, null);
            holder = new ViewHolder();
            holder.txtSent = convertView.findViewByTag("sent");
            holder.txtReceived = convertView.findViewByTag("received");
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        HashMap<String,String> message = getItem(position);
        boolean sent = message.get("type").equals("sent");

        if(sent) {
            holder.txtSent.setVisibility(View.VISIBLE);
            holder.txtSent.setText(message.get("message"));
            holder.txtReceived.setVisibility(View.GONE);
        } else {
            holder.txtSent.setVisibility(View.GONE);
            holder.txtReceived.setText(message.get("message"));
            holder.txtReceived.setVisibility(View.VISIBLE);     
        }
    }

    class ViewHolder {
        TextView txtSent;
        TextView txtReceived;
    }
}

// raw_message.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"    
    android:padding="5dp">

    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:tag="sent"/>

    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:tag="received"/>

</RelativeLayout>
1

Проблема в том, что когда я отправляю текст, он находится на левой стороне, и когда я получаю текст, отправляемый текст также выравнивается с правой стороны. И когда я отправляю снова, весь текст (чат) выравнивается слева.

Вероятно, это происходит потому, что каждый раз, когда вы получаете новое сообщение, вы устанавливаете новый адаптер для ListView с новой силой тяжести (слева или справа). Поскольку новый адаптер содержит все сообщения в чате, все они выравниваются влево или вправо.

Мой совет - использовать класс объектов данных, который будет содержать фактическое сообщение + его статус (это принятое или отправленное сообщение):

class Message {
    String actualMessage;
    int status = 0; //(for example 0 for sent messages and 1 for received messages)

    public String toString() {
       return actualMessage;
    }
}

Затем реализуйте свой собственный адаптер и в методе getView посмотрите, какой тип сообщения у вас есть, и установите ориентацию для этой конкретной строки влево или вправо. Это также позволит вам просто обновлять список сообщений, а не создавать каждый раз новый объект ArrayAdapter. Пример адаптера:

public class CustomAdapter extends ArrayAdapter<Message> {

     public CustomAdapter(Context context, int resId, List<message> data) {
          super(context, resId, data);
     }

     public View getView(int position, View convertView, ViewGroup parent) {
         TextView tv = (TextView) super.getView(position, convertView, parent);
         Message msg = getItem(position);
         if (msg.status == 0) {
               tv.setGravity(Gravity.LEFT);
         } else {
               tv.setGravity(Gravity.RIGHT);
         } 
     }

}
  • 0
    в вышеприведенном классе, как определить статус сообщения, потому что откуда этот статус не указан?
  • 0
    @juned Я не знаю ваш код, чтобы сказать вам точно, но все, что вам нужно сделать, это вместо того, чтобы вызывать метод setListAdapterL или setListAdapterR создания объекта Message с obj.status = 0; (если вы обычно вызываете setListAdapterL ) или с obj.status = 1; (если вы обычно вызываете setListAdapterR ) и добавляете его в адаптер (возможно, также вызывайте notifydataSetChanged ).
0

вы столкнулись с проблемой, что все элементы всегда меняются на новый макет. Поэтому каждый раз, когда вы устанавливаете левый макет, все перемещается влево, наоборот.

Вам нужен пользовательский адаптер, который позволяет вам иметь 2 текстовых поля - один для правой и один для левой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню