Android:我的列表视图在向数据添加新行后,无法在触摸模式下选择行
我有一个活动和一个线程。线程处理数据(之后数据将从Internet活动中抓取,现在,它每10秒自动添加一行)。问题是,在添加新行后,我无法再触摸物品,重新获得焦点,我必须按下硬件键盘上的向上或向下箭头或菜单按钮。 当然,我首先想到重新设置.setFocusableOnTouchMode为true,但这似乎并没有解决我的问题。或者至少,我没有把它放在正确的地方。反正这是我的代码:Android:我的列表视图在向数据添加新行后,无法在触摸模式下选择行
的活动:
$
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();
}
}
}
}
好了,感谢上前进,任何解决方案将appretiated
你不能直接从一个线程不是UI线程修改UI元素。如果要从其他线程修改UI元素,则必须调用函数runOnUiThread。这意味着你将有一个refernce的活动传递给刷新类在它的构造函数,因此你可以做你的线程以下调用:
activity.runOnUiThread(new Runnable(){
public void run(){
EL.g.setFocusableInTouchMode(true);
}
});
这就是说,如果我是你,我会放弃这个而只需使用AsyncTaskLoader。它更容易,而且该类专门用于异步加载像listview之类的元素。你现在编写代码的方式不会很好,并且容易出现各种错误。在android中,一般的经验法则是不使用原始的Thread类,除非你必须这样做。使用AsyncTaskLoader,AsyncTask或IntentService。
最后注意,如果您开发的API级别低于10,您仍然可以通过android Support Package访问AsyncTaskLoader类。
在30分钟左右,我就可以测试这个解决方案。感谢您提前回答! – user982962
我现在正在尝试你所说的话。我只是说,我放的代码示例工作,它只是有我说的问题。但你可能是对的。我只学习了常规的Java,我试图将其应用于Android,但只是尝试了解那里的指南和示例。这就是为什么在很多情况下,我可能会有一些解决方案效率不高。 – user982962
很难相信这听起来可能。这并没有解决问题。事实上,我发现只调用.notifyDataSetChanged()而不进行任何更改是有问题的。 – user982962
两件事......我想你应该只在UI线程中运行'notifyDataSetChanged',但我可能是错的。其次,我相信'notifyDataSetChanged'只适用于使用适配器的'add','insert','remove'和'clear方法。看起来你正在重新分配底层数组,这可能是问题所在。看[这个问题](http://*.com/questions/3669325/notifydatasetchanged-example)。 – Craigy
Ahm ..我是否应该添加,删除或删除您正在讨论的功能?我的适配器不提供这些,我应该使用不同类型的适配器吗? – user982962
欢迎来到计算器!如果您发现特定回复有帮助,请投票。如果某个特定回复是正确的,请点击回复旁边的复选标记以接受该回复。 –