【发布时间】:2010-08-22 21:17:05
【问题描述】:
我有一个由某些服务发送意图更新的 ListView。如果在我按下 ListView 中的某个项目时更新事件到达,我会得到一些奇怪的行为。被按下的项目中默认的橙色矩形消失,其他一些项目的文本变得更暗(就像它的项目被按下一样)。
ListView 变为“未按下”后如何推迟更新?或者更具体地说,我应该听哪些事件以确定不再按下 ListView? (我可以创建一些定期执行的线程以在适当的时候进行更新,但我认为这太过分了)。或者也许有更好的解决方案或解决方法。
这里是说明问题的示例代码。服务每 2 秒发送一次更新意图。如果我尝试长按列表中的某个项目,我会得到上面描述的奇怪行为。
活动:
package org.me.listviewupdate;
import android.app.ListActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ArrayAdapter;
public class MyActivity extends ListActivity {
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_DATA:
mAdapter.notifyDataSetChanged();
break;
default:
super.handleMessage(msg);
break;
}
}
}
private class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
mHandler.sendEmptyMessage(MSG_UPDATE_DATA);
}
}
private static final int MSG_UPDATE_DATA = 0;
private String[] mItems = new String[] { "Item1", "Item2", "Item3", "Item4" };
private ArrayAdapter<String> mAdapter;
private Handler mHandler;
private BroadcastReceiver mBroadcastReceiver;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mHandler = new MyHandler();
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
android.R.id.text1, mItems);
setListAdapter(mAdapter);
mBroadcastReceiver = new MyBroadcastReceiver();
registerReceiver(mBroadcastReceiver, new IntentFilter(MyService.UPDATE_EVENT));
startService(new Intent(this, MyService.class));
}
@Override
protected void onDestroy() {
unregisterReceiver(mBroadcastReceiver);
stopService(new Intent(this, MyService.class));
super.onDestroy();
}
}
服务:
package org.me.listviewupdate;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MyService extends Service {
private class MyUpdateTask implements Runnable {
public void run() {
sendBroadcast(new Intent(UPDATE_EVENT));
}
}
public static final String UPDATE_EVENT =
"org.me.listviewupdate.intent.event.UPDATED";
private static final int UPDATE_INTERVAL = 2;
private ScheduledExecutorService mUpdater;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mUpdater = Executors.newSingleThreadScheduledExecutor();
}
@Override
public void onDestroy() {
mUpdater.shutdownNow();
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
mUpdater.scheduleAtFixedRate(new MyUpdateTask(), UPDATE_INTERVAL,
UPDATE_INTERVAL, TimeUnit.SECONDS);
}
}
谢谢。
我的解决方案。好吧,以防万一它可以帮助这里的人是我的解决方案。添加到MyActivity.onCreate()的代码:
getListView().setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean isReleased = event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL;
if (mHasPendingUpdate && isReleased) {
mHandler.sendEmptyMessage(MSG_UPDATE_DATA);
}
return false;
}
});
getListView().setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|| keyCode == KeyEvent.KEYCODE_ENTER;
boolean isReleased = event.getAction() == KeyEvent.ACTION_UP;
if (mHasPendingUpdate && isKeyOfInterest && isReleased) {
mHandler.sendEmptyMessage(MSG_UPDATE_DATA);
}
return false;
}
});
另外我添加了一个变量mHasPendingUpdate并修改了MyHandler:
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_DATA:
if (getListView().isPressed()) {
mHasPendingUpdate = true;
} else {
mAdapter.notifyDataSetChanged();
mHasPendingUpdate = false;
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
【问题讨论】: