在listview中设置textview的宽度不起作用(自定义ArrayAdapter)

时间:2015-05-13 13:38:51

标签: android listview android-arrayadapter

我正在开发一个使用android的Messenger应用程序(我的#34;拥有" WhatsApp),我现在正试图动态扩充消息历史记录。我正在使用自定义ArrayAdapter。消息应始终只占我屏幕宽度的5/6,因此消息旁边始终是一个空闲的位置。我的问题是,它忽略了我设置的maxWidth,并且我无法使用textView.setWidth()设置宽度,也没有使用LayoutParams。

当我只创建一条消息时,TextView尊重maxWidth,但getWidth()返回更高的值(这怎么可能?)。当我创建另一条消息时,TextView将扩展为之前返回的宽度getWidth(),并重置布局设置。

以下是我的文件:

message_from.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/message_from"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/message_from"
        android:gravity="start" >

            <TextView
                android:id="@+id/messageText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:maxWidth="400dp"
                android:paddingStart="6dp"
                android:paddingLeft="6dp"
                android:paddingEnd="4dp"
                android:paddingRight="4dp"
                android:paddingTop="4dp"
                android:paddingBottom="2dp"
                android:textSize="16sp" />

             <TextView
                 android:id="@+id/timeView"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:paddingBottom="4dp"
                 android:paddingStart="2dp"
                 android:paddingLeft="2dp"
                 android:paddingEnd="4dp"
                 android:paddingRight="4dp"
                 android:textColor="#707070"
                 android:textSize="12sp" />



    </RelativeLayout>

activity_chat.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent" >

            <ListView
                android:id="@+id/messagesListView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@null"
                android:dividerHeight="0dp" />
    <RelativeLayout/>

MessageListItem.java

public class MessageListItem {
public String text;
public long time;
public String timeFormatted;
public boolean from;
public int state;
public Drawable stateImage;
private int stateResourceId;

final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());

    public MessageListItem() {
        super();
    }

    public MessageListItem(String text, long time, boolean from, int state, Context c) {
        super();
        this.text = text;
        this.time = time;
        this.from = from;
        this.state = state;
        timeFormatted = timeFormat.format(time);
}
}

MessageAdapter.java (只有重要部分,点击here查看完整档案)

    public class MessageAdapter extends ArrayAdapter<MessageListItem> {

        int resourceIdFrom = R.layout.message_from;
        Context context;
        MessageListItem[] data;
        static View row;
        static ListHolder holder;

        public MessageAdapter(Context context, int resourceId, MessageListItem[] data) {
            super(context, resourceId, data);
            this.context = context;
            this.data = data;
        }

        @Override
        public View getView(final int position, View convertView, final ViewGroup parent) {
            row = convertView;
            if (row == null) {
                LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                holder = new ListHolder();
                if (data[position].from) {
                    row = (RelativeLayout) inflater.inflate(resourceIdFrom, parent, false);
                    holder.messageText = (TextView) row.findViewById(R.id.messageText);
                    holder.timeView = (TextView) row.findViewById(R.id.timeView);
                    MessageListItem message = data[position];
                    holder.messageText.setText(message.text);
                    holder.timeView.setText(message.timeFormatted);

                    ViewTreeObserver observer = row.getViewTreeObserver();
                    observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                        @SuppressLint("NewApi")
                        @SuppressWarnings("deprecation")
                        @Override
                        public void onGlobalLayout() {
                            positionViews();
                            if (android.os.Build.VERSION.SDK_INT >= 16) {
                            row.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                            } else {
                                row.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                            }
                        }
                    });
                row.setTag(holder);
            }
             holder = (ListHolder) row.getTag();
            }
            return row;
        }

    static class ListHolder {
        ImageView messageState;
        TextView messageText;
        TextView timeView;
    }

    public void positionViews() {
        Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        holder.messageText.setMaxWidth(size.x / 6 * 5); //doesn't work? 
        if (holder.messageText.getWidth() > holder.messageText.getMaxWidth()) holder.messageText.setWidth(holder.messageText.getMaxWidth()); // doesn't work either
        holder.messageText.invalidate();
        System.out.println(holder.messageText.getWidth()); // always returns 464, no matter how big the TextView is
    }
}

使用它:

MessageListItem[] testData = new MessageListItem[2];
for (int i = 0; i<=1; i++) testData[i] = new MessageListItem("I can dynamically create message bubbles!", System.currentTimeMillis(), true, 0, this);
final MessageAdapter adapter = new MessageAdapter(this, R.layout.listview_item_row, testData);
messageList.setAdapter(adapter);

屏幕截图here

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

试试这个:

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        row = convertView;
        if (row == null) {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            holder = new ListHolder();
            row = (RelativeLayout) inflater.inflate(resourceIdFrom, parent, false);
            holder.messageText = (TextView) row.findViewById(R.id.messageText);
            holder.timeView = (TextView) row.findViewById(R.id.timeView);
            row.setTag(holder);
        }
         holder = (ListHolder) row.getTag();
        }
            if (data[position].from) {
                MessageListItem message = data[position];
                holder.messageText.setText(message.text);
                holder.timeView.setText(message.timeFormatted);

                ViewTreeObserver observer = row.getViewTreeObserver();
                observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                    @SuppressLint("NewApi")
                    @SuppressWarnings("deprecation")
                    @Override
                    public void onGlobalLayout() {
                        positionViews();
                        if (android.os.Build.VERSION.SDK_INT >= 16) {
                        row.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        } else {
                            row.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        }
                    }
                });
        return row;
    }