Android:向数据添加新行后,无法在触摸模式下选择我的 ListView 行
我有一个活动和一个线程。该线程处理数据(稍后数据将从 Internet 活动中获取,目前,它只是每 10 秒自动添加一个新行)。问题是,添加新行后,我无法再触摸这些项目,要重新获得焦点,我必须按硬件键盘上的向上或向下箭头或菜单按钮。 当然,我首先想到将 .setFocusableOnTouchMode 重新设置为 true,但这似乎并没有解决我的问题。或者至少,我没有将其设置在正确的位置。无论如何,这是我的代码:
活动:
$
package com.ejemplolisbox;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class EL extends Activity {
/**
* @see android.app.Activity#onCreate(Bundle)
*/
public Refresh actualizar;
// The thread
public static ListView g;
public static EfficientAdapter instance ;
// The adapter (is a custom made adapter, I didn't do it myself, just grabbed it from the Internet)
public static String[] abbreviations = { "Item0",
"Item1", "Item2"};
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
g = (ListView) findViewById(R.id.lv_country);
g.setFocusable(true);
g.setFocusableInTouchMode(true);
instance = new EfficientAdapter(this);
// The adapter is now set to this instance
g.setAdapter(instance);
actualizar = new Refresh();
actualizar.start();
//I start the thread
g.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View arg0, boolean arg1) {
// TODO Auto-generated method stub
// Code should be here (??)
}
});
g.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView a, View v, int position,
long id) {
//use position to get clicked position
//your code goes here
}
});
}
public static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return abbreviations.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.rowlayout, null);
holder = new ViewHolder();
holder.text1 = (TextView) convertView
.findViewById(R.id.TextView01);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text1.setText(abbreviations[position]);
return convertView;
}
static class ViewHolder {
TextView text1;
}
}
}
现在线程好了。
package com.ejemplolisbox;
public class Refresh extends Thread{
public void run(){
while(true){
String[] ex=EL.abbreviations;
String[] ne=new String[ex.length+1];
for(int i=0;i<ex.length;i++){
ne[i]=ex[i];
}
ne[ex.length]="newItem"+ex.length;
EL.abbreviations=ne;
try{
EL.instance.notifyDataSetChanged();
EL.g.setFocusableInTouchMode(true);
}
catch(Exception e){
int i = 0;
EL.g.setFocusableInTouchMode(true);
}
EL.g.setFocusableInTouchMode(true);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
好的,提前致谢,任何解决方案将不胜感激
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您无法从非 UI 线程的线程中直接修改 UI 元素。如果你想从不同的线程修改UI元素,你必须调用函数runOnUiThread。这意味着您必须将对活动的引用传递给其构造函数中的 Refresh 类,以便您可以在线程上执行以下调用:
也就是说,如果我是您,我会废弃它并只使用 AsyncTaskLoader 代替。它更容易,并且该类是专门为异步加载列表视图等元素而创建的。现在编写代码的方式不会很好地工作,并且很容易出现各种错误。在 android 中,一般的经验法则是不要使用原始 Thread 类,除非绝对必要。使用 AsyncTaskLoader、AsyncTask 或 IntentService。
最后注意,如果您正在开发低于 10 的 API 级别,您仍然可以通过 android 支持包。
You can't directly modify UI elements from a thread that isn't the UI thread. If you want to modify a UI element from a different thread, you have to call the function runOnUiThread. That means you'll have to pass a refernce to the activity to the Refresh class in it's constructor so you can do the following call on your thread:
That said, if I were you I'd scrap this and just use an AsyncTaskLoader instead. It's much easier and the class was specifically created for asynchronously loading up elements in things like a listview. The way you have the code written right now is not going to work very well and is prone to all kinds of error. In android, a general rule of thumb is to not use the raw Thread class unless you abosultely have to. Use either the AsyncTaskLoader, AsyncTask, or IntentService.
Final note, if you're developing for API levels less than 10, you can still access the AsyncTaskLoader class via the android Support Package.