android版本4.4(kitkat)及以上版本的列表视图问题
我正在开发聊天应用程序。我在listview中面临异常行为问题我的代码在android OS 4.4下运行良好。但当在4.4 kitkat中运行我的应用程序时,我面临着一个问题 请查看下面的屏幕截图。 假设我的第一条消息长度较大,那么我的第二条消息高度相同 在第二个屏幕截图中,它将显示最后一条消息的正确视图。因为我已经关闭了我的键盘,同时适配器得到刷新,第一个可见视图的高度会自动增加android版本4.4(kitkat)及以上版本的列表视图问题,android,listview,baseadapter,Android,Listview,Baseadapter,我正在开发聊天应用程序。我在listview中面临异常行为问题我的代码在android OS 4.4下运行良好。但当在4.4 kitkat中运行我的应用程序时,我面临着一个问题 请查看下面的屏幕截图。 假设我的第一条消息长度较大,那么我的第二条消息高度相同 在第二个屏幕截图中,它将显示最后一条消息的正确视图。因为我已经关闭了我的键盘,同时适配器得到刷新,第一个可见视图的高度会自动增加 public class ChatAdapter extends BaseAdapter { Lay
public class ChatAdapter extends BaseAdapter {
LayoutInflater mInflater;
ChatActivity chatActivity;
private DatabaseHandler DatabaseHandler;
private DatabaseHandler dbHelper;
private List<HBMessage> mList = new ArrayList<HBMessage>();
private Context mContext;
public ChatAdapter(ChatActivity chatActivity) {
this.chatActivity = chatActivity;
mContext = chatActivity;
DatabaseHandler = new DatabaseHandler(mContext);
dbHelper = new DatabaseHandler(mContext);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public HBMessage getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private class Holder {
private RelativeLayout mSimpleRecieveLayout, mSimpleSenderLayout, rlImageSendLayout, rlImageReceiveLayout, mRecieveImageLayout;
private LinearLayout mSentImageLayout;
private TextView simpleFriendMessage, simpleFriendMessageTime, simpleMyMessage, simpleMyMessageTime, mtxtImageSentTime,
mtxtImageRecieveTime;
private ImageView mimgSent, mimgRecieve, mplayordownload, mplayorupload;
private TextView mMsgStatus, mtxtImageStatus;
private ProgressBar mSentProgress, mDownloadProgress;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder mHolder;
if (convertView == null) {
mHolder = new Holder();
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.single_chat_item, null);
mHolder.mSimpleRecieveLayout = (RelativeLayout) convertView.findViewById(R.id.recive_layout);
mHolder.mSimpleSenderLayout = (RelativeLayout) convertView.findViewById(R.id.sender_layout);
mHolder.mSentImageLayout = (LinearLayout) convertView.findViewById(R.id.sentImageLayout);
mHolder.mRecieveImageLayout = (RelativeLayout) convertView.findViewById(R.id.recieveImageLayout);
mHolder.simpleFriendMessage = (TextView) convertView.findViewById(R.id.txtMesssageSender);
mHolder.simpleFriendMessageTime = (TextView) convertView.findViewById(R.id.txtTimeSender);
mHolder.mtxtImageRecieveTime = (TextView) convertView.findViewById(R.id.txtImageRecieveTime);
mHolder.simpleMyMessage = (TextView) convertView.findViewById(R.id.txtMesssageRecieve);
mHolder.simpleMyMessageTime = (TextView) convertView.findViewById(R.id.txtTimeRecieve);
mHolder.mtxtImageSentTime = (TextView) convertView.findViewById(R.id.txtImageSentTime);
mHolder.mMsgStatus = (TextView) convertView.findViewById(R.id.txtStatusSender);
mHolder.mtxtImageStatus = (TextView) convertView.findViewById(R.id.txtImageSentStatus);
mHolder.mimgSent = (ImageView) convertView.findViewById(R.id.imgSent);
mHolder.mimgRecieve = (ImageView) convertView.findViewById(R.id.imgRecieve);
mHolder.mSentProgress = (ProgressBar) convertView.findViewById(R.id.sentProgress);
mHolder.mplayordownload = (ImageView) convertView.findViewById(R.id.playordownload);
mHolder.mplayorupload = (ImageView) convertView.findViewById(R.id.playorupload);
mHolder.mDownloadProgress = (ProgressBar) convertView.findViewById(R.id.downloadProgress);
mHolder.rlImageSendLayout = (RelativeLayout) convertView.findViewById(R.id.chat_rlSendImage);
mHolder.rlImageReceiveLayout = (RelativeLayout) convertView.findViewById(R.id.chat_rlReceiveImage);
int tempWidth = (int) (BaseApplication.SCREEN_WIDTH * 0.28);
int tempHeight = (int) (BaseApplication.SCREEN_WIDTH * 0.26);
int imageSize = (int) (tempHeight * 0.84);
LinearLayout.LayoutParams param1 = (LayoutParams) mHolder.rlImageSendLayout.getLayoutParams();
param1.width = tempWidth;
param1.height = tempHeight;
mHolder.rlImageSendLayout.setLayoutParams(param1);
RelativeLayout.LayoutParams param2 = (android.widget.RelativeLayout.LayoutParams) mHolder.rlImageReceiveLayout
.getLayoutParams();
param2.width = tempWidth;
param2.height = tempHeight;
mHolder.rlImageReceiveLayout.setLayoutParams(param2);
RelativeLayout.LayoutParams param3 = (android.widget.RelativeLayout.LayoutParams) mHolder.mimgSent.getLayoutParams();
param3.width = imageSize;
param3.height = imageSize;
mHolder.mimgSent.setLayoutParams(param3);
RelativeLayout.LayoutParams param4 = (android.widget.RelativeLayout.LayoutParams) mHolder.mimgRecieve.getLayoutParams();
param4.width = imageSize;
param4.height = imageSize;
mHolder.mimgRecieve.setLayoutParams(param4);
convertView.setTag(mHolder);
} else {
mHolder = (Holder) convertView.getTag();
}
if ((mList.get(position).getFromJID().equalsIgnoreCase(UserDetails.getInstance(mContext).getJabberId() + WSUtils.CHAT_DOMAIN))) {
setMyLayout(mList.get(position), mHolder, position, convertView);
} else {
setOtherLayout(mList.get(position), mHolder, position);
}
return convertView;
}
由于视图循环的行为,必须设置和取消设置与内容相关的所有内容,无论
convertView
是否为null
。您应该首先将与viewHolder绑定无关的代码移动到if-else之后的。另一个选择是开始使用类似于
ListView
的软件,它改进了回收机制(还有更多)。这里是一个例子。无论是新视图还是回收视图,都需要为所有视图执行一些代码。仅对新视图执行viewholder初始化部分
if (convertView == null) {
mHolder = new Holder();
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.single_chat_item, null);
mHolder.mSimpleRecieveLayout = (RelativeLayout) convertView.findViewById(R.id.recive_layout);
mHolder.mSimpleSenderLayout = (RelativeLayout) convertView.findViewById(R.id.sender_layout);
mHolder.mSentImageLayout = (LinearLayout) convertView.findViewById(R.id.sentImageLayout);
mHolder.mRecieveImageLayout = (RelativeLayout) convertView.findViewById(R.id.recieveImageLayout);
mHolder.simpleFriendMessage = (TextView) convertView.findViewById(R.id.txtMesssageSender);
mHolder.simpleFriendMessageTime = (TextView) convertView.findViewById(R.id.txtTimeSender);
mHolder.mtxtImageRecieveTime = (TextView) convertView.findViewById(R.id.txtImageRecieveTime);
mHolder.simpleMyMessage = (TextView) convertView.findViewById(R.id.txtMesssageRecieve);
mHolder.simpleMyMessageTime = (TextView) convertView.findViewById(R.id.txtTimeRecieve);
mHolder.mtxtImageSentTime = (TextView) convertView.findViewById(R.id.txtImageSentTime);
mHolder.mMsgStatus = (TextView) convertView.findViewById(R.id.txtStatusSender);
mHolder.mtxtImageStatus = (TextView) convertView.findViewById(R.id.txtImageSentStatus);
mHolder.mimgSent = (ImageView) convertView.findViewById(R.id.imgSent);
mHolder.mimgRecieve = (ImageView) convertView.findViewById(R.id.imgRecieve);
mHolder.mSentProgress = (ProgressBar) convertView.findViewById(R.id.sentProgress);
mHolder.mplayordownload = (ImageView) convertView.findViewById(R.id.playordownload);
mHolder.mplayorupload = (ImageView) convertView.findViewById(R.id.playorupload);
mHolder.mDownloadProgress = (ProgressBar) convertView.findViewById(R.id.downloadProgress);
mHolder.rlImageSendLayout = (RelativeLayout) convertView.findViewById(R.id.chat_rlSendImage);
mHolder.rlImageReceiveLayout = (RelativeLayout) convertView.findViewById(R.id.chat_rlReceiveImage);
convertView.setTag(mHolder);
} else {
mHolder = (Holder) convertView.getTag();
}
// This is now executed for all your views.
int tempWidth = (int) (BaseApplication.SCREEN_WIDTH * 0.28);
int tempHeight = (int) (BaseApplication.SCREEN_WIDTH * 0.26);
int imageSize = (int) (tempHeight * 0.84);
LinearLayout.LayoutParams param1 = (LayoutParams) mHolder.rlImageSendLayout.getLayoutParams();
param1.width = tempWidth;
param1.height = tempHeight;
mHolder.rlImageSendLayout.setLayoutParams(param1);
RelativeLayout.LayoutParams param2 = (android.widget.RelativeLayout.LayoutParams) mHolder.rlImageReceiveLayout
.getLayoutParams();
param2.width = tempWidth;
param2.height = tempHeight;
mHolder.rlImageReceiveLayout.setLayoutParams(param2);
RelativeLayout.LayoutParams param3 = (android.widget.RelativeLayout.LayoutParams) mHolder.mimgSent.getLayoutParams();
param3.width = imageSize;
param3.height = imageSize;
mHolder.mimgSent.setLayoutParams(param3);
RelativeLayout.LayoutParams param4 = (android.widget.RelativeLayout.LayoutParams) mHolder.mimgRecieve.getLayoutParams();
param4.width = imageSize;
param4.height = imageSize;
mHolder.mimgRecieve.setLayoutParams(param4);
此外,您还应该考虑在适配器(MyDead和您的其他布局)中更多地阅读不同的视图类型。起点是。
只有屏幕截图,没有人能够正确理解问题。因此,请用更多的细节来回答您的问题,因为我的代码在4.4版本以下运行得非常好,这就是为什么我没有将代码放在这里。您使用什么来显示聊天列表行?ListView还是动态布局?这可能与视图的动态调整有关。请发布您的XML,以及setMyLayout
和setOtherLayout
会发生什么。此外,您可能有一个非常复杂的XML,标记每个视图所表示的内容会有所帮助。这是一个过于复杂的布局。另外,您的getView(…)
必须处理几个可见性操作。我几乎可以保证,您可以通过简化xml和清理适配器来解决问题。您是否想过使用多行布局?发送、接收、图片消息的布局?这将删除很多可见性切换。另外,有几个视图组似乎是多余的:RelativeLayout
,idsender\u布局
。它的子项LinearLayout
可以独立运行。@id/recive\u布局也一样。
private synchronized void setOtherLayout(HBMessage hbMessage, final Holder mHolder, final int position) {
if (hbMessage.getMsgType().equalsIgnoreCase(HBMessage.IMAGE)) {
mHolder.mSimpleRecieveLayout.setVisibility(View.GONE);
mHolder.mSimpleSenderLayout.setVisibility(View.GONE);
mHolder.mSentImageLayout.setVisibility(View.GONE);
mHolder.mRecieveImageLayout.setVisibility(View.VISIBLE);
mHolder.mplayordownload.setTag(position);
mHolder.mimgRecieve.setTag(position);
String str = hbMessage.getMessage();
final String seperatedString[] = str.split("##@!@##");
if (hbMessage.getMediaStatus().equals(HBMessage.NOTDOWNLOADED)) {
mHolder.mplayordownload.setVisibility(View.VISIBLE);
mHolder.mDownloadProgress.setVisibility(View.GONE);
} else if (hbMessage.getMediaStatus().equals(HBMessage.DOWNLOADING)) {
mHolder.mplayordownload.setVisibility(View.GONE);
mHolder.mDownloadProgress.setVisibility(View.VISIBLE);
} else {
mHolder.mplayordownload.setVisibility(View.GONE);
mHolder.mDownloadProgress.setVisibility(View.GONE);
}
mHolder.mtxtImageRecieveTime.setText(StaticUtils.getChatHistoryDateTime(hbMessage.getMessageTime()));
chatActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mHolder.mimgRecieve.setImageBitmap(getImageFromBase64StringWithTimeStamp(seperatedString[0]));
}
});
mHolder.mplayordownload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View paramView) {
paramView.setVisibility(View.GONE);
int pos = (Integer) paramView.getTag();
HBMessage message = getItem(pos);
final String name[] = message.getMessage().split("##@!@##");
if (dbHelper.isImageAvaialble(name[1])) {
DatabaseHandler.updateImageStatus(mContext, message.getMessageId(), HBMessage.DOWNLOADED, HBMessage.CHAT_SINGLE);
message.setMediaStatus(HBMessage.DOWNLOADED);
setItem(message, pos);
} else {
((ViewGroup) paramView.getParent()).findViewById(R.id.downloadProgress).setVisibility(View.VISIBLE);
message.setMediaStatus(HBMessage.DOWNLOADING);
setItem(message, position);
chatActivity.callDownloadfileProcess(pos, ((ViewGroup) paramView.getParent()));
}
}
});
} else {
mHolder.mSimpleRecieveLayout.setVisibility(View.VISIBLE);
mHolder.mSimpleSenderLayout.setVisibility(View.GONE);
mHolder.mSentImageLayout.setVisibility(View.GONE);
mHolder.mRecieveImageLayout.setVisibility(View.GONE);
mHolder.simpleMyMessageTime.setText(StaticUtils.getChatHistoryDateTime(hbMessage.getMessageTime()));
mHolder.simpleMyMessage.setText(hbMessage.getMessage());
}
}
private synchronized void setMyLayout(HBMessage hbMessage, final Holder mHolder, int position, View view) {
if (hbMessage.getMsgType().equalsIgnoreCase(HBMessage.IMAGE)) {
mHolder.mSimpleRecieveLayout.setVisibility(View.GONE);
mHolder.mSimpleSenderLayout.setVisibility(View.GONE);
mHolder.mRecieveImageLayout.setVisibility(View.GONE);
mHolder.mSentImageLayout.setVisibility(View.VISIBLE);
String str = hbMessage.getMessage();
final String seperatedString[] = str.split("##@!@##");
mHolder.mimgSent.setTag(position);
mHolder.mplayorupload.setTag(position);
if (hbMessage.getMediaStatus().equals(HBMessage.NOTUPLOADED)) {
mHolder.mplayorupload.setVisibility(View.VISIBLE);
mHolder.mSentProgress.setVisibility(View.GONE);
} else if (hbMessage.getMediaStatus().equals(HBMessage.UPLOADING)) {
mHolder.mplayorupload.setVisibility(View.GONE);
mHolder.mSentProgress.setVisibility(View.VISIBLE);
} else {
mHolder.mplayorupload.setVisibility(View.GONE);
mHolder.mSentProgress.setVisibility(View.GONE);
}
mHolder.mSentProgress.setTag(view);
mHolder.mtxtImageSentTime.setText(StaticUtils.getChatHistoryDateTime(hbMessage.getMessageTime()));
chatActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mHolder.mimgSent.setImageBitmap(getImageFromBase64StringWithTimeStamp(seperatedString[0]));
}
});
mHolder.mtxtImageStatus.setText(hbMessage.getMessageStatus());
if (hbMessage.getMessageStatus().equals(HBMessage.STATUS_PENDDING)
|| hbMessage.getMessageStatus().equals(HBMessage.STATUS_FAILED)) {
mHolder.mtxtImageStatus.setTextColor(mContext.getResources().getColor(R.color.color_pending_red));
} else if (hbMessage.getMessageStatus().equals(HBMessage.STATUS_DELIVERED)) {
mHolder.mtxtImageStatus.setTextColor(mContext.getResources().getColor(R.color.color_black));
} else
mHolder.mtxtImageStatus.setTextColor(mContext.getResources().getColor(R.color.color_green));
if (hbMessage.isAutoUpload()) {
ImageHolder mImageHolder = dbHelper.getImageHolder(seperatedString[1]);
File mFile = StaticUtils.bitmapToFile(mImageHolder.getBitmap(), mImageHolder.getFileName(), false);
if (mFile != null) {
hbMessage.setAutoUpload(false);
mList.set(position, hbMessage);
chatActivity.uploadToserver(mFile, mImageHolder.getFileName(), hbMessage, position, view);
} else {
CommonUtils.showSingleBtnDialog("Image Not Available", mContext, null);
}
}
mHolder.mplayorupload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View paramView) {
int pos = (Integer) paramView.getTag();
HBMessage message = getItem(pos);
final String seperatedString[] = message.getMessage().split("##@!@##");
ImageHolder mImageHolder = dbHelper.getImageHolder(seperatedString[1]);
File mFile = StaticUtils.bitmapToFile(mImageHolder.getBitmap(), mImageHolder.getFileName(), false);
if (mFile != null) {
paramView.setVisibility(View.GONE);
ProgressBar pb = (ProgressBar) ((ViewGroup) paramView.getParent()).findViewById(R.id.sentProgress);
pb.setVisibility(View.VISIBLE);
View view = (View) pb.getTag();
((TextView) view.findViewById(R.id.txtImageSentStatus)).setText(HBMessage.STATUS_PENDDING);
message.setMediaStatus(HBMessage.UPLOADING);
message.setMessageStatus(HBMessage.STATUS_PENDDING);
setItem(message, pos);
chatActivity.uploadToserver(mFile, mFile.getName(), message, pos, view);
DatabaseHandler.updateImageStatus(mContext, message.getMessageId(), HBMessage.UPLOADING, HBMessage.CHAT_SINGLE);
} else {
CommonUtils.showSingleBtnDialog("Image Not Available", mContext, null);
}
}
});
} else {
mHolder.mSimpleRecieveLayout.setVisibility(View.GONE);
mHolder.mSimpleSenderLayout.setVisibility(View.VISIBLE);
mHolder.mSentImageLayout.setVisibility(View.GONE);
mHolder.mRecieveImageLayout.setVisibility(View.GONE);
mHolder.simpleFriendMessageTime.setText(StaticUtils.getChatHistoryDateTime(hbMessage.getMessageTime()));
mHolder.simpleFriendMessage.setText(hbMessage.getMessage());
mHolder.mMsgStatus.setText(hbMessage.getMessageStatus());
if (hbMessage.getMessageStatus().equals(HBMessage.STATUS_PENDDING)
|| hbMessage.getMessageStatus().equals(HBMessage.STATUS_FAILED)) {
mHolder.mMsgStatus.setTextColor(mContext.getResources().getColor(R.color.color_pending_red));
} else if (hbMessage.getMessageStatus().equals(HBMessage.STATUS_DELIVERED)) {
mHolder.mMsgStatus.setTextColor(mContext.getResources().getColor(R.color.color_black));
} else
mHolder.mMsgStatus.setTextColor(mContext.getResources().getColor(R.color.color_green));
}
}
if (convertView == null) {
mHolder = new Holder();
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.single_chat_item, null);
mHolder.mSimpleRecieveLayout = (RelativeLayout) convertView.findViewById(R.id.recive_layout);
mHolder.mSimpleSenderLayout = (RelativeLayout) convertView.findViewById(R.id.sender_layout);
mHolder.mSentImageLayout = (LinearLayout) convertView.findViewById(R.id.sentImageLayout);
mHolder.mRecieveImageLayout = (RelativeLayout) convertView.findViewById(R.id.recieveImageLayout);
mHolder.simpleFriendMessage = (TextView) convertView.findViewById(R.id.txtMesssageSender);
mHolder.simpleFriendMessageTime = (TextView) convertView.findViewById(R.id.txtTimeSender);
mHolder.mtxtImageRecieveTime = (TextView) convertView.findViewById(R.id.txtImageRecieveTime);
mHolder.simpleMyMessage = (TextView) convertView.findViewById(R.id.txtMesssageRecieve);
mHolder.simpleMyMessageTime = (TextView) convertView.findViewById(R.id.txtTimeRecieve);
mHolder.mtxtImageSentTime = (TextView) convertView.findViewById(R.id.txtImageSentTime);
mHolder.mMsgStatus = (TextView) convertView.findViewById(R.id.txtStatusSender);
mHolder.mtxtImageStatus = (TextView) convertView.findViewById(R.id.txtImageSentStatus);
mHolder.mimgSent = (ImageView) convertView.findViewById(R.id.imgSent);
mHolder.mimgRecieve = (ImageView) convertView.findViewById(R.id.imgRecieve);
mHolder.mSentProgress = (ProgressBar) convertView.findViewById(R.id.sentProgress);
mHolder.mplayordownload = (ImageView) convertView.findViewById(R.id.playordownload);
mHolder.mplayorupload = (ImageView) convertView.findViewById(R.id.playorupload);
mHolder.mDownloadProgress = (ProgressBar) convertView.findViewById(R.id.downloadProgress);
mHolder.rlImageSendLayout = (RelativeLayout) convertView.findViewById(R.id.chat_rlSendImage);
mHolder.rlImageReceiveLayout = (RelativeLayout) convertView.findViewById(R.id.chat_rlReceiveImage);
convertView.setTag(mHolder);
} else {
mHolder = (Holder) convertView.getTag();
}
// This is now executed for all your views.
int tempWidth = (int) (BaseApplication.SCREEN_WIDTH * 0.28);
int tempHeight = (int) (BaseApplication.SCREEN_WIDTH * 0.26);
int imageSize = (int) (tempHeight * 0.84);
LinearLayout.LayoutParams param1 = (LayoutParams) mHolder.rlImageSendLayout.getLayoutParams();
param1.width = tempWidth;
param1.height = tempHeight;
mHolder.rlImageSendLayout.setLayoutParams(param1);
RelativeLayout.LayoutParams param2 = (android.widget.RelativeLayout.LayoutParams) mHolder.rlImageReceiveLayout
.getLayoutParams();
param2.width = tempWidth;
param2.height = tempHeight;
mHolder.rlImageReceiveLayout.setLayoutParams(param2);
RelativeLayout.LayoutParams param3 = (android.widget.RelativeLayout.LayoutParams) mHolder.mimgSent.getLayoutParams();
param3.width = imageSize;
param3.height = imageSize;
mHolder.mimgSent.setLayoutParams(param3);
RelativeLayout.LayoutParams param4 = (android.widget.RelativeLayout.LayoutParams) mHolder.mimgRecieve.getLayoutParams();
param4.width = imageSize;
param4.height = imageSize;
mHolder.mimgRecieve.setLayoutParams(param4);
Finally I have solved this issue by applying stupid thing.Why i am facing issue,that i really don't know and Why its get solved after applying patch that i really don't know.
**My Solution:**
setMyLayout()
{
mHolder.mSentMessageLayout
.setBackgroundResource(R.drawable.chat_sender);
}
setOtherLayout()
{
mHolder.mRecieveMessageLayout
.setBackgroundResource(R.drawable.chat_receiver);
}