我有一个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;
}
}
}
答案 0 :(得分:0)
捕获longpress并阻止更新数据集。覆盖listview的onlongpress方法。我会在一分钟内发布代码
更新: 其实。这可能不起作用,因为它可以在您按下时但在调用longpress方法之前更新。如果我上面提到的不起作用,我会在ListActivity上实现onClickListener,监听任何运动事件,设置阻止更新的全局变量,并在onMotionEvent()方法中返回false,以便列表项可以消耗点击