这是我的活动:
public class Messaging extends Activity implements OnItemClickListener {
ListView lstv;
MessagingAdapter listAdapter;
List<Generic4lstv> rowItems = new ArrayList<Generic4lstv>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messaging);
// lstv
lstv = (ListView) findViewById(R.id.lstv_mess);
lstv.setOnItemClickListener(this);
listAdapter = new MessagingAdapter(this, rowItems);
lstv.setAdapter(listAdapter);
fillListview();
}
//***the trick
private final int interval = 200; // 1 Second
private Handler handler = new Handler();
private Runnable runnable = new Runnable(){
public void run() {
listAdapter.notifyDataSetChanged();
}
};
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if (!rowItems.get(arg2).getIsSelected()) {
Log.w("wwwwwww", "in");
rowItems.get(arg2).setIsSelected(true);
//call the ***trick
handler.postDelayed(runnable, interval);
}
}
我的适配器:
public class MessagingAdapter extends BaseAdapter {
private List<Generic4lstv> data;
private Context context;
public MessagingAdapter(Context context, List<Generic4lstv> items) {
this.context = context;
this.data = items;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup arg2) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(R.layout.activity_messaging_row, arg2, false);
holder = new ViewHolder();
holder.rowText = (TextView) row.findViewById(R.id.titleTextView);
holder.rowDate = (TextView) row.findViewById(R.id.dateTextView);
holder.rowImage = (ImageView) row.findViewById(R.id.mailIcon);
// store the holder with the view.
row.setTag(holder);
} else {
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
holder = (ViewHolder) row.getTag();
}
Generic4lstv item = (Generic4lstv) getItem(position);
if (item == null) {
Log.w("wwwwwww", "isnull!!!");
} else {
holder.rowText.setText(item.getRowText());
holder.rowDate.setText(item.getRowTextDate());
if (item.getIsSelected()) { // aka is red
Log.w("wwwwwww", "IsSelected" + item.getRowID());
holder.rowText.setTextColor(Color.GRAY);
holder.rowImage.setImageResource(R.drawable.mail);
} else {
Log.w("wwwwwww", "Is NOT Selected" + item.getRowID());
holder.rowText.setTextColor(Color.BLACK);
holder.rowImage.setImageResource(R.drawable.mail_new);
}
}
return row;
}
static class ViewHolder {
ImageView rowImage;
TextView rowText;
TextView rowDate;
}
}
正如您所看到的,在Activity onItemClick 事件中,我调用了一个执行适配器notifyDataSetChanged的runnable,一切正常,但是如果我执行 listAdapter.notifyDataSetChanged(); 在 rowItems.get(arg2).setIsSelected(true); 之后,UI没有更新!!
在我花了2小时之后创建了Runnable,最后我把它改为: https://stackoverflow.com/a/19074462/1320686
有人可以提供更好的方式,或者我在代码中做错了什么?
答案 0 :(得分:1)
我想您的代码中有一些内容会使列表变慢。我刚刚创建了一个新项目,我在setIsSelected(true)之后调用了notifyDataSetChanged();它工作正常。也许问题出在你的fillListView()方法上。您可以在不同的项目中尝试我的代码,看看它是如何工作的,以及两个项目之间的区别。
我的活动
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends Activity implements AdapterView.OnItemClickListener {
private ArrayList<Item> mItemArrayList;
private MyCustomAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mItemArrayList = new ArrayList<Item>();
//for simplicity we will add the same name for 20 times to populate the mItemArrayList view
for (int i = 0; i < 20; i++) {
Item item = new Item();
item.setName("Laura" + i);
mItemArrayList.add(item);
}
//relate the listView from java to the one created in xml
ListView myListView = (ListView) findViewById(R.id.list);
//show the ListView on the screen
// The adapter MyCustomAdapter is responsible for maintaining the data backing this mItemArrayList and for producing
// a view to represent an item in that data set.
adapter = new MyCustomAdapter(MainActivity.this, mItemArrayList);
myListView.setOnItemClickListener(this);
myListView.setAdapter(adapter);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (!mItemArrayList.get(position).isSelected()) {
mItemArrayList.get(position).setSelected(true);
adapter.notifyDataSetChanged();
}
}
}
我的自定义适配器
package ex.list.list;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class MyCustomAdapter extends BaseAdapter {
private ArrayList<Item> mListItems;
private LayoutInflater mLayoutInflater;
public MyCustomAdapter(Context context, ArrayList<Item> arrayList){
mListItems = arrayList;
//get the layout inflater
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
//getCount() represents how many items are in the mItemArrayList
return mListItems.size();
}
@Override
//get the data of an item from a specific position
//i represents the position of the item in the mItemArrayList
public Object getItem(int position) {
return mListItems.get(position);
}
@Override
//get the position id of the item from the mItemArrayList
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
// create a ViewHolder reference
ViewHolder holder;
//check to see if the reused view is null or not, if is not null then reuse it
if (view == null) {
holder = new ViewHolder();
view = mLayoutInflater.inflate(R.layout.list_item, null);
holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);
// the setTag is used to store the data within this view
view.setTag(holder);
} else {
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)view.getTag();
}
Item item = (Item) getItem(position);
if (item != null) {
if (holder.itemName != null) {
//set the item name on the TextView
holder.itemName.setText(item.getName());
}
if (item.isSelected()){
holder.itemName.setTextColor(Color.RED);
} else {
holder.itemName.setTextColor(Color.WHITE);
}
}
//this method must return the view corresponding to the data at the specified position.
return view;
}
/**
* Static class used to avoid the calling of "findViewById" every time the getView() method is called,
* because this can impact to your application performance when your mItemArrayList is too big. The class is static so it
* cache all the things inside once it's created.
*/
private static class ViewHolder {
protected TextView itemName;
}
}
项目对象
public class Item {
private boolean isSelected;
private String name;
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<强> activity_main.xml中强>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:transcriptMode="alwaysScroll"
android:cacheColorHint="#00000000"
android:listSelector="@android:color/transparent"/>
</LinearLayout>
<强> list_item.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/list_item"
android:gravity="center_vertical">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/list_item_text_view"
android:textSize="20sp"
android:padding="10dp"
android:layout_marginLeft="5dp"/>
</LinearLayout>