我正在开发一个使用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
感谢您的任何建议。
答案 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;
}