[英]Listview strange behavior on scroll
我有一個listview(聊天)。 我得到一些奇怪的行為。 它發生在我向上滾動,然后一些項目開始搞亂,當我回到底部時,項目也搞砸了。 我唯一能想到的是每次滾動都會調用我的getView幾次。 有誰知道我怎么能解決這個問題?
我看到這篇文章: 自定義ListView適配器,奇怪的ImageView行為,但他沒有在創建后添加項目到列表。
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="@+id/right_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/right_profilePic"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
android:autoLink="all"
/>
<ImageView
android:id="@+id/left_profilePic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="@+id/left_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/left_profilePic"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
android:autoLink="all"
/>
<ImageView
android:id="@+id/right_profilePic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
/>
<TextView
android:id="@+id/left_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="70dp"
android:layout_toRightOf="@+id/left_profilePic"
android:textColor="@color/Gray"
/>
<TextView
android:id="@+id/right_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="70dp"
android:layout_toLeftOf="@+id/right_profilePic"
android:textColor="@color/Gray"
/>
<ImageView
android:id="@+id/left_image_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/left_profilePic"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
/>
<ImageView
android:id="@+id/right_image_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/right_profilePic"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
/>
更新
我必須在聊天中加載圖片和谷歌靜態地圖,我想這對於列表視圖來說很重要。
這是getView方法:
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Log.d("getView", "getview called");
ViewHolder holder;
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item, null);
holder.right_profilePic = (ImageView) convertView.findViewById(R.id.right_profilePic);
holder.right_message = (TextView) convertView.findViewById(R.id.right_message);
holder.left_profilePic = (ImageView) convertView.findViewById(R.id.left_profilePic);
holder.left_message = (TextView) convertView.findViewById(R.id.left_message);
holder.right_time = (TextView) convertView.findViewById(R.id.right_time);
holder.left_time = (TextView) convertView.findViewById(R.id.left_time);
holder.right_image_message = (ImageView) convertView.findViewById(R.id.right_image_message);
holder.left_image_message = (ImageView) convertView.findViewById(R.id.left_image_message);
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
ChatItemBean bean = (ChatItemBean) chatItemList.get(position);
Log.d("holder", bean.getId() + " | " + GlobalData.myId);
if (bean.getId().equals(GlobalData.myId)) {
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.right_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
//holder.right_image_message.setPadding(0, 0, 0, 20);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
} else {
holder.right_message.setText(bean.getMessage());
holder.right_message.setBackgroundResource(R.drawable.chat_background_right);
}
holder.right_time.setText(bean.getTime());
} else {
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.left_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
holder.left_image_message.setPadding(0, 10, 0, 30);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
} else {
holder.left_message.setText(bean.getMessage());
holder.left_message.setBackgroundResource(R.drawable.chat_background_left);
}
holder.left_time.setText(bean.getTime());
}
return convertView;
}public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Log.d("getView", "getview called");
ViewHolder holder;
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item, null);
holder.right_profilePic = (ImageView) convertView.findViewById(R.id.right_profilePic);
holder.right_message = (TextView) convertView.findViewById(R.id.right_message);
holder.left_profilePic = (ImageView) convertView.findViewById(R.id.left_profilePic);
holder.left_message = (TextView) convertView.findViewById(R.id.left_message);
holder.right_time = (TextView) convertView.findViewById(R.id.right_time);
holder.left_time = (TextView) convertView.findViewById(R.id.left_time);
holder.right_image_message = (ImageView) convertView.findViewById(R.id.right_image_message);
holder.left_image_message = (ImageView) convertView.findViewById(R.id.left_image_message);
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
ChatItemBean bean = (ChatItemBean) chatItemList.get(position);
Log.d("holder", bean.getId() + " | " + GlobalData.myId);
if (bean.getId().equals(GlobalData.myId)) {
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.right_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
//holder.right_image_message.setPadding(0, 0, 0, 20);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
} else {
holder.right_message.setText(bean.getMessage());
holder.right_message.setBackgroundResource(R.drawable.chat_background_right);
}
holder.right_time.setText(bean.getTime());
} else {
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.left_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
holder.left_image_message.setPadding(0, 10, 0, 30);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
} else {
holder.left_message.setText(bean.getMessage());
holder.left_message.setBackgroundResource(R.drawable.chat_background_left);
}
holder.left_time.setText(bean.getTime());
}
return convertView;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Log.d("getView", "getview called");
ViewHolder holder;
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item, null);
holder.right_profilePic = (ImageView) convertView.findViewById(R.id.right_profilePic);
holder.right_message = (TextView) convertView.findViewById(R.id.right_message);
holder.left_profilePic = (ImageView) convertView.findViewById(R.id.left_profilePic);
holder.left_message = (TextView) convertView.findViewById(R.id.left_message);
holder.right_time = (TextView) convertView.findViewById(R.id.right_time);
holder.left_time = (TextView) convertView.findViewById(R.id.left_time);
holder.right_image_message = (ImageView) convertView.findViewById(R.id.right_image_message);
holder.left_image_message = (ImageView) convertView.findViewById(R.id.left_image_message);
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
ChatItemBean bean = (ChatItemBean) chatItemList.get(position);
Log.d("holder", bean.getId() + " | " + GlobalData.myId);
if (bean.getId().equals(GlobalData.myId)) {
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.right_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
//holder.right_image_message.setPadding(0, 0, 0, 20);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
} else {
holder.right_message.setText(bean.getMessage());
holder.right_message.setBackgroundResource(R.drawable.chat_background_right);
}
holder.right_time.setText(bean.getTime());
} else {
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.left_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
holder.left_image_message.setPadding(0, 10, 0, 30);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
} else {
holder.left_message.setText(bean.getMessage());
holder.left_message.setBackgroundResource(R.drawable.chat_background_left);
}
holder.left_time.setText(bean.getTime());
}
return convertView;
}
更新
在這里,我嘗試使用兩種不同的布局:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Log.d("getView", "getview called");
ViewHolder holder;
ChatItemBean checkBean = (ChatItemBean) chatItemList.get(position);
if (checkBean.getId().equals(GlobalData.myId)) {
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item_right, null);
holder.right_profilePic = (ImageView) convertView.findViewById(R.id.right_profilePic);
holder.right_message = (TextView) convertView.findViewById(R.id.right_message);
holder.right_time = (TextView) convertView.findViewById(R.id.right_time);
holder.right_image_message = (ImageView) convertView.findViewById(R.id.right_image_message);
convertView.setTag(holder);
} else
holder=(ViewHolder)convertView.getTag();
ChatItemBean bean = (ChatItemBean) chatItemList.get(position);
Log.d("holder", bean.getId() + " | " + GlobalData.myId);
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.right_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
//holder.right_image_message.setPadding(0, 0, 0, 20);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.right_image_message);
holder.right_image_message.setBackgroundResource(R.drawable.chat_background_right);
} else {
holder.right_message.setText(bean.getMessage());
holder.right_message.setBackgroundResource(R.drawable.chat_background_right);
}
holder.right_time.setText(bean.getTime());
} else {
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item, null);
holder.left_profilePic = (ImageView) convertView.findViewById(R.id.left_profilePic);
holder.left_message = (TextView) convertView.findViewById(R.id.left_message);
holder.left_time = (TextView) convertView.findViewById(R.id.left_time);
holder.left_image_message = (ImageView) convertView.findViewById(R.id.left_image_message);
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
ChatItemBean bean = (ChatItemBean) chatItemList.get(position);
Log.d("holder", bean.getId() + " | " + GlobalData.myId);
Picasso.with(context).load(bean.getImage()).resize(130, 130).into(holder.left_profilePic);
if (bean.getType().equals("1")) {
Picasso.with(context).load(init_link + bean.getMessage()).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
holder.left_image_message.setPadding(0, 10, 0, 30);
} else if (bean.getType().equals("2")) {
StringTokenizer tokens = new StringTokenizer(bean.getMessage(), "&");
String first = tokens.nextToken();
String second = tokens.nextToken();
String url = "http://maps.google.com/maps/api/staticmap?center=" +
first + "," + second + "&zoom=15&size=200x200&sensor=false";
Picasso.with(context).load(url).into(holder.left_image_message);
holder.left_image_message.setBackgroundResource(R.drawable.chat_background_left);
} else {
holder.left_message.setText(bean.getMessage());
holder.left_message.setBackgroundResource(R.drawable.chat_background_left);
}
holder.left_time.setText(bean.getTime());
}
return convertView;
}
但是當我滾動一點時,我的應用程序崩潰,就像它試圖搞砸的那一刻,我得到的目標一定不能為空。 第124行使用畢加索加載配置文件。
12-01 21:14:40.442: E/AndroidRuntime(21764): java.lang.IllegalArgumentException: Target must not be null.
12-01 21:14:40.442: E/AndroidRuntime(21764): at com.squareup.picasso.RequestCreator.into(RequestCreator.java:333)
12-01 21:14:40.442: E/AndroidRuntime(21764): at com.squareup.picasso.RequestCreator.into(RequestCreator.java:319)
12-01 21:14:40.442: E/AndroidRuntime(21764): at com.petcial.petopen.custom.ChatCustomAdapter.getView(ChatCustomAdapter.java:124)
使用兩個布局文件最終會丟失一些convertView可重用性能的東西。 但是會幫助你擁有可以解決這個爛攤子的清潔用品。 確定哪個文件用於哪個項目。
2。 使用一個布局文件。
可以/(需要付出努力)干凈地定義一個文件的布局,以便為所有類型的列表項正確使用它們。 使用相對布局並將一個x1放在另一個x2之上。 並根據類型簡單地在getView中使x1或x2可見或不可見。 確保在getView中沒有繁重的操作。 其中x1和x2是您的一個項目類型的布局。
嘗試這個。 但您肯定可以發布您的代碼以獲得更多幫助。 但建議首先嘗試清理。
更新:轉到選項2.使用一個RelativeLayout並在其中添加兩個LinearLayout。 一個在另一個之上並在第一個LinearLayout中定義一個項類型,在第二個中定義另一個。 使這些容器(LL)在getView中可見或不可見
希望這個建議有所幫助
Lars Vogel的這個教程非常棒。 我強烈推薦使用它。 在沒有看到您的JAva代碼的情況下,我可以說您需要為列表條目提供兩種不同的布局XML。 一個用於左側圖像,另一個用於右側圖像。 然后,在適配器中,為會話的那一部分充氣。
這是正確的方法。 我認為發生在你身上的是你在回收的ViewGroup中添加了內容,這些內容傳遞給了getView而沒有刪除舊的內容,所以你的新東西被添加到舊的東西之上。 使用新流程,您需要確保循環視圖是正確的“方向”,然后刪除舊內容並添加新內容。
以下是我在上面鏈接的Vogella文章中的部分。
在
getView()
方法中,您將擴展基於XML的布局,然后根據此行的Java對象設置各個視圖的內容。 要LayoutInflator
XML布局文件,您可以使用系統服務LayoutInflator
。 可以通過活動或context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
方法調用訪問此服務。可以通過頂級視圖上的
findViewById()
方法調用找到布局中的各個元素。
順便說一句,getView()在滾動期間被多次調用,並且調用的順序是不可預測的。 因此,不要在getView方法中做任何過於密集的事情,否則減速將非常明顯。
我有確切的問題,我通過不使用convertView解決了它。
基本上,我做的是:
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = inflater.inflate(R.layout.your_layout, parent, false);
//Do what you intend to do, populate the TextView, or set the ImageViews, but do them with respect to rowView, not convertView.
ImageView imageView = (ImageView) rowView.findViewById(R.id.my_picture);
imageView.setImageResources(R.drawable.sample_picture);
return rowView;
}
無論您使用1個布局還是2個列表項,這都很有用,希望這會有所幫助:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.