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,但这是在我的AsyncTaskonLoad 中完成之前附加的,这意味着没有绑定。

所以我的问题是如何让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的主要内容,如果未能解决你的问题,请参考以下文章

Android AsyncTask 等待完成以检索数据并将其显示在 ListView

带有 ListView Asynctask 的多下载器

Android AsyncTask在完成工作后返回值

Android如何在数据进入后设置listview适配器

在 asynctask 类中设置为 listView

ListView 未在 AsyncTask 中使用适配器进行更新