AsyncTask 完成后 ListView 上的 setOnItemClickListener
Posted
技术标签:
【中文标题】AsyncTask 完成后 ListView 上的 setOnItemClickListener【英文标题】:setOnItemClickListener on ListView after AsyncTask finished 【发布时间】:2015-02-11 06:02:36 【问题描述】:我已经设置了一个ListView
和一个SimpleAdapter
,它们通过一个在AsyncTask
中运行的函数获取数据,但问题是我现在想在这个ListView
上设置一个setOnItemClickListener
。
问题是我正在尝试附加setOnItemClickListener
,但这是在我的AsyncTask
在onLoad
中完成之前附加的,这意味着没有绑定。
所以我的问题是如何让Async
执行并完成以填充我的ListView
并绑定setOnItemClickListener
在 我的Async
任务完成后?
注意:我已经用类和视图的完整代码更新了我的答案,因为这是由用户提出的,并且会给其他人更多的见解。如需完整代码,请向下滚动到更新部分!
代码:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_overview);
//Context inladen
context = ContactOverview.this;
listViewContacts = (ListView)findViewById(R.id.listViewContacts);
//new GetAllContactsAsync().execute();
asny.execute();
Log.i("finished?","finished?");
Log.i("listLength", "" + listViewContacts.getCount());
listViewContacts.setOnItemClickListener(new OnItemClickListener()
public void onItemClick(AdapterView parent, View view, int position, long id)
Toast.makeText(ContactOverview.this, "ee", Toast.LENGTH_SHORT).show();
Log.i("test","test");
);
listViewContacts.setOnItemClickListener
应该在 Async
任务完成后附加。那么我该怎么做呢?如果在我的Async
任务完成之前触发了我的listViewContacts.setOnItemClickListener
,则不会进行绑定..
更新:完整代码
列表视图 (contact_overview.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"
tools:context=".MainActivity"
android:background="#1e78bc">
<ListView
android:id="@+id/listViewContacts"
android:background="@android:color/white"
android:shadowColor="#f9f9f9"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:layout_
android:layout_ >
</ListView>
</RelativeLayout>
列表视图的行 (row.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:layout_
android:layout_
android:id="@+id/customerName"
android:paddingLeft="3dp"
android:textSize="18sp"
android:drawableLeft="@drawable/user"
android:gravity="center_vertical"
android:textStyle="bold"/>
<TextView android:layout_
android:layout_
android:id="@+id/customerPhone"
android:paddingTop="3dp"
android:paddingRight="3dp"
android:gravity="center_vertical"
android:layout_below="@id/customerName"
android:drawableLeft="@drawable/telefoon"
android:autoLink="phone"/>
<TextView android:layout_
android:layout_
android:id="@+id/customerGsm"
android:paddingTop="3dp"
android:paddingRight="3dp"
android:layout_below="@id/customerName"
android:gravity="center_vertical|right"
android:layout_toRightOf="@id/customerPhone"
android:drawableLeft="@drawable/telefoon"
android:autoLink="phone"/>
<TextView android:layout_
android:layout_
android:id="@+id/customerEmail"
android:drawableLeft="@drawable/email"
android:layout_below="@id/customerPhone"
android:gravity="center_vertical"
android:autoLink="email"/>
<TextView
android:layout_
android:layout_
android:id="@+id/customerZip"
android:paddingLeft="3dp"
android:drawableLeft="@drawable/user"
android:layout_below="@id/customerEmail"/>
<TextView
android:layout_
android:layout_
android:id="@+id/customerCity"
android:paddingLeft="3dp"
android:layout_toRightOf="@id/customerZip"
android:layout_below="@+id/customerEmail"/>
<TextView android:layout_
android:layout_
android:id="@+id/customerStreet"
android:paddingRight="3dp"
android:layout_toRightOf="@id/customerCity"
android:layout_below="@+id/customerEmail"/>
</RelativeLayout>
ListView 填充类 (ContactOverview.java)
public class ContactOverview extends ActionBarActivity
public int uid = 0;
final String url = "dev.myurl.com";
final int port = 8072;
final String dbName = "dbname";
final String username = "dbPass";
private ProgressDialog progressDialog;
Context context;
ArrayList<Object> customerArray = new ArrayList<Object>();
ArrayList<Object> companyArray = new ArrayList<Object>();
List companyList = null;
List customerList = null;
ListView listViewContacts;
int finished = 0;
GetAllContactsAsync asny = new GetAllContactsAsync();
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_overview);
//Context inladen
context = ContactOverview.this;
//new GetAllContactsAsync().execute();
listViewContacts = (ListView) findViewById(R.id.listViewContacts);
asny.execute();
listViewContacts.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView parent, View view, int position, long id)
Toast.makeText(ContactOverview.this, "Clicked", Toast.LENGTH_SHORT).show();
);
private class GetAllContactsAsync extends AsyncTask<Void, Integer, Void>
//Before running code in separate thread
@Override
protected void onPreExecute()
//Create a new progress dialog
progressDialog = new ProgressDialog(ContactOverview.this);
//Set the progress dialog to display a horizontal progress bar
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//Set the dialog title to 'Loading...'
progressDialog.setTitle(R.string.loading);
//Set the dialog message to 'Loading application View, please wait...'
progressDialog.setMessage(ContactOverview.this.getString(R.string.loadingMessage));
//This dialog can't be canceled by pressing the back key
progressDialog.setCancelable(false);
//This dialog isn't indeterminate
progressDialog.setIndeterminate(false);
//The maximum number of items is 100
progressDialog.setMax(100);
//Set the current progress to zero
progressDialog.setProgress(0);
//Display the progress dialog
progressDialog.show();
protected Void doInBackground(Void... params)
try
//Get the current thread's token
synchronized (this)
//counter progress dialog
int counter = 0;
//Wait 100 milliseconds
this.wait(200);
try
//get uid
uid = Connect(url, port, dbName, username, "myPass");
catch (MalformedURLException e1)
//Toast.makeText(MainActivity.this, context.getString(R.string.authenticateError), Toast.LENGTH_LONG).show();
e1.printStackTrace();
//Models en connectie maken voor xml-rpc
XmlRpcClient models = null;
try
models = new XmlRpcClient()
/*was:
setConfig(new XmlRpcClientConfigImpl()
setServerURL(new URL(String.format("http://%s:%s/xmlrpc/2/object", "dev.myurl.com", port)));
);
;
*/
setConfig(new XmlRpcClientConfigImpl()
private static final long serialVersionUID = 1L;
setServerURL(new URL(String.format("http://%s:%s/xmlrpc/2/object", "dev.myurl.com", port)));
);
;
catch (MalformedURLException e1)
e1.printStackTrace();
//Loading to 20%
counter += 20;
publishProgress(counter);
try
/*final Array list = (Array)models.execute("execute_kw", Arrays.asList(
dbName, uid, "myPass",
"res.partner", "search",
Arrays.asList(new HashMap()
Arrays.asList("is_company", "=", "true");
Arrays.asList("customer", "=", "true");
)
));
Log.i("Array", "" + list);*/
customerList = (List)Arrays.asList((Object[])models.execute("execute_kw", Arrays.asList(
dbName, uid, "myPass",
"res.partner", "search_read",
Arrays.asList(Arrays.asList(
Arrays.asList("customer", "=", true))),
new HashMap()
private static final long serialVersionUID = 1L;
put("fields", Arrays.asList("name", "phone", "mobile","email","website", "street", "city", "zip"));
put("limit", 0);
)));
Log.i("customerList",""+customerList);
//30% further in progressdialog
counter += 30;
publishProgress(counter);
companyList = (List)Arrays.asList((Object[])models.execute("execute_kw", Arrays.asList(
dbName, uid, "myPass",
"res.partner", "search_read",
Arrays.asList(Arrays.asList(
Arrays.asList("is_company", "=", true))),
new HashMap()
private static final long serialVersionUID = 1L;
put("fields", Arrays.asList("name", "phone", "mobile","email","website", "street", "city", "zip"));
put("limit", 0);
)));
//Another 30% further (= 80%)
counter += 30;
publishProgress(counter);
//customerArray = new ArrayList<Object>(Arrays.asList(customerObject));
//companyArray = new ArrayList<Object>(Arrays.asList(companyObject));
//Log.i("Customers", "object: " + customerObject);
//parsing, now at @90%.
counter += 20;
publishProgress(counter);
//100% after data is parsed in parseDataInLijsten()
counter += 10;
publishProgress(counter);
catch (XmlRpcException e)
e.printStackTrace();
publishProgress(counter);
catch (InterruptedException e)
e.printStackTrace();
return null;
//Update the progress
@Override
protected void onProgressUpdate(Integer... values)
//set the current progress of the progress dialog
progressDialog.setProgress(values[0]);
//Parse data from here on and then show it. (parseDataInLijsten does this)
@Override
protected void onPostExecute(Void result)
//close the progress dialog
progressDialog.dismiss();
//initialize the View
//show ListView on screen.
parseDataInLijsten();
Log.i("listViewContacts987", "" + listViewContacts.getCount());
//Finally parse the data and show it in the ListView.
private void parseDataInLijsten()
//Vars
HashMap testMap = null;
String phone = null;
String gsm = null;
String id = null;
String email = null;
String name = null;
String street = null;
String city = null;
String website = null;
String zip = null;
List<String> listItems=new ArrayList<String>();
//ArrayList<String> listItems=new ArrayList<String>();
listViewContacts = (ListView)findViewById(R.id.listViewContacts);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
ArrayList<HashMap<String, String>> mylist2 = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
//Loopen over every record in the list. This is per company.
for(int teller = 0; teller < companyList.size(); teller++)
//HashMap contains one set
testMap = (HashMap) companyList.get(teller);
int teller2 = 0;
//every value is an item in the list of a record
for (Object value : testMap.values())
teller2++;
if(teller2 == 1)
street = value.toString();
map = new HashMap<String, String>();
map.put("street", street);
if(teller2 == 2)
id = value.toString();
map.put("id",id);
if(teller2 == 3)
gsm = value.toString();
if(gsm == "false")
gsm = "-";
map.put("gsm", gsm);
if(teller2 == 4)
website = value.toString();
if(website == "false")
website = "-";
map.put("website", website);
if(teller2 == 5)
city = value.toString();
if(city == "false")
city = "";
map.put("city", city + " - ");
if(teller2 == 6)
email = value.toString();
if(email == "false")
email = "";
map.put("email", email);
if(teller2 == 7)
phone = value.toString();
if(phone == "false")
phone = "-";
map.put("phone", phone);
if(teller2 == 8)
name = value.toString();
map.put("name", name);
if(teller2 == 9)
zip = value.toString();
map.put("zip", zip + " ");
if(zip == "false")
zip = "";
mylist2.add(map);
SimpleAdapter mSchedule = new SimpleAdapter(this, mylist2, R.layout.row,
new String[] "name","phone", "gsm", "email", "zip", "city", "street", new int[] R.id.customerName, R.id.customerPhone, R.id.customerGsm,
R.id.customerEmail,
R.id.customerZip, R.id.customerCity, R.id.customerStreet);
listViewContacts.setAdapter(mSchedule);
谢谢 延特
【问题讨论】:
把你的那个setOnItemClickListener放到AsyncTask的onPostExecute方法中 只要在 asynctask 中使用 adapter.notifyDataSetChanged 来刷新 listview,应该可以正常工作。为什么要在 asynctask 完成后附加监听器?有什么原因吗? SarthakMittal 也不起作用,如果我点击列表视图中的项目,则不会触发任何内容。 @MagicalPhoenixϡ我想在异步任务之后附加监听器,因为我从我的异步任务中填充了列表视图(因为它包含大量数据并显示自定义加载屏幕)。我会稍微更新代码以添加 onPostExecute。 如果 onPostExecute 没有被调用,这意味着你的 async 仍在运行:你在 doInBackground 中的代码仍在运行 @HugoG onPostExecute 也被调用并完成。我可以将 Log.i 放入其中并打印,如果我创建第二个函数等待 xxx 秒以完成异步任务,我将看到我的 ListView 中有 28 个项目,这也是正确的。很遗憾,我认为这不是问题.. 【参考方案1】:把这个属性放到每个TextView中
android:focusable="false"
android:focusableInTouchMode="false"
【讨论】:
以上是关于AsyncTask 完成后 ListView 上的 setOnItemClickListener的主要内容,如果未能解决你的问题,请参考以下文章