标签:android style io ar os sp java on 数据
今天同事做一个发送语音的功能,发现点击语音播放的时候,实际播放语音的喇叭不是点击的那个,而是跳到别的地方了,他的代码如下
public View getView(int position, View convertView, ViewGroup parent) {
ChatMsgEntity entity = coll.get(position);
boolean isComMsg = entity.getMsgType();
LayoutInflater mInflater = (LayoutInflater)context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewHolder viewHolder=null;
if (convertView == null) {
if (isComMsg) {
convertView = mInflater.inflate(
R.layout.chatting_item_msg_text_left, null);
} else {
convertView = mInflater.inflate(
R.layout.chatting_item_msg_text_right, null);
}
viewHolder = new ViewHolder();
viewHolder.tvSendTime = (TextView) convertView
.findViewById(R.id.tv_sendtime);
viewHolder.tvUserName = (TextView) convertView
.findViewById(R.id.tv_username);
viewHolder.tvContent = (TextView) convertView
.findViewById(R.id.tv_chatcontent);
viewHolder.icon = (ImageView) convertView
.findViewById(R.id.iv_userhead);
viewHolder.chatPic = (ImageView) convertView
.findViewById(R.id.chat_img);
viewHolder.isComMsg = isComMsg;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final String mass = entity.getMessage();
OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (mass.contains("/storage/")&&mass.endsWith(".jpg")) {
}else if (mass.contains("/storage/")&&mass.endsWith(".amr")) {
if (judgeAnmi) {
ad.start();
judgeAnmi = !judgeAnmi;
}else {
ad.stop();
judgeAnmi = !judgeAnmi;
}
}
}
};
viewHolder.tvSendTime.setText(entity.getDate());
viewHolder.tvUserName.setText(entity.getName());
if (mass.contains("/storage/")&&mass.endsWith(".jpg")) {
Bitmap bm = convertToBitmap(entity.getMessage(),200,200);
BitmapDrawable bd = new BitmapDrawable(bm);
viewHolder.chatPic.setBackgroundDrawable(bd);
viewHolder.tvContent.setText("");
}else if(mass.contains("/storage/")&&mass.endsWith(".amr")){
viewHolder.chatPic.setBackgroundResource(R.anim.voice_muti);
ad = (AnimationDrawable) viewHolder.chatPic.getBackground();
viewHolder.tvContent.setText(mass.substring(0, mass.indexOf("/"))+"″");
}else {
viewHolder.tvContent.setText(mass);
viewHolder.chatPic.setBackgroundDrawable(null);
}
viewHolder.chatPic.setOnClickListener(listener);
return convertView;
}先看看google官方demo的写法
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
static class ViewHolder {
TextView text;
ImageView icon;
}
}后来他将viewHolder的定义改为final ViewHolder就解决了问题。
大概想了一下,因为android对ListView做了缓存优化,实际上内存里只保留了一屏幕的View,也就是参数里面的convertView,而之前viewHolder是在convertView为空的时候new出来的,并被convertView setTag进去了,所以,后面取出来的ViewHold对象都是缓存的。但是对于每个holder里面的chatPic都要设定一个点击事件监听器。所以,其实只是对缓存的那些holder对象重复设置监听器。但是为什么将holder对象用final修饰就没问题了,由于final修饰的引用不会改变他所指向的对象。然后为什么这样就可以了我也想不清了,求看到的大神详解。
标签:android style io ar os sp java on 数据
原文地址:http://blog.csdn.net/runninghui/article/details/41843195