开发者

Android onItemClicklistener in listview not working

Can anyone help me out with my problem. I have a TabActivity each tab is on touch opens a new activity which extends ListActivity at this time i get the list of desired items which i want to make clickable by using OnItemClickListener.

i'm attaching my main.xml please go through it and let me know if there are any changes required

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="5dp">
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="5dp"/>
            <TextView  
                android:id="@+id/item_title"
                android:layout_width="fill_parent" 
                android:layout_height="wrap_content" 
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:padding="2dp"
                android:textSize="20dp" />
            <TextView  
                android:id="@+id/item_subtitle"
                android:layout_width="fill_parent" 
                android:layout_height="wrap_content" 
                android:padding="2dp"
                android:textSize="13dp" />
        </LinearLayout>
    </TabHost>
</LinearLayout>

Activity

public class TopNewsActivity extends ListActivity
{

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listplaceholder);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

        String xml = XMLfunctions.getTopNewsXML();
        Document doc = XMLfunctions.XMLfromString(xml);

        int numResults = XMLfunctions.numResults(doc);

        if ((numResults <= 0))
        {
            Toast.makeText(TopNewsActivity.this, "No Result Found", Toast.LENGTH_LONG).show();
            finish();
        }

        NodeList nodes = doc.getElementsByTagName("result");

    for (int i = 0; i < nodes.getLength(); i++) {                           
        HashMap<String, String> map = new HashMap<String, String>();    

        Element e = (Element)nodes.item(i);
        map.put("id", XMLfunctions.getValue(e, "id"));
        map.put("name", "Naam:" + XMLfunctions.getValue(e, "name"));
        map.put("Score", "Score: " + XMLfunctions.getValue(e, "score"));
        mylist.add(map);            
    }       

    ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main, 
                    new String[] { "name", "Score" }, 
                    new int[] { R.id.item_title, R.id.item_subtitle });

    setListAdapter(adapter);

        final ListView lv = getListView();
        /*lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                @SuppressWarnings("unchecked")
                HashMap<String, String> o = (HashMap<String, String>) lv.getOnItemClickListener();

                Intent i = new Intent(view.getContext(), NewsDetails.class);
                i.putExtra("content_id", o.get("id"));
                i.putExtra("title", o.get("title"));
                startActivity(i);
                lv.setOnItemClickListener(this);

            }
        });*/

        final OnItemClickListener myClickListener = new OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> a, View view, int position, long id)
            {
                @SuppressWarnings("unchecked")
                HashMap<String, String> o = (HashMap<String, String>) lv.getOnItemClickListener();

                Intent i = new Intent(view.getContext(), NewsDetails.class);
                i.putExtra("content_id", o.get("id"));
                i.putExtra("title", o.get("naam"));
                startActivity(i);
            }
        };
        lv.setOnItemClickListener(myClickListener);
    }
}

TabActivity

 public class InfralineTabWidget extends TabActivity{

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Resources res = getResources(); // Resource object to get Drawables
    TabHost tabHost = (TabHost)getTabHost();  // The activity TabHost
    TabHost.TabSpec spec;  // Resusable TabSpec for each tab
    Intent intent;  // Reusable Intent for each tab

    // Create an Intent to launch an Activity for the tab (to be reused)
    intent = new Intent().setClass(this, TopNewsActivity.class);

    // Initialize a TabSpec for each tab and add it to the TabHost
    spec = tabHost.newTabSpec("topNews").setIndicator("Top News", res.getDrawable(R.drawable.tab_news)).setContent(intent);
    tabHost.addTab(spec);

    // Do the same for the other tabs
    intent = new Intent().setClass(this, PowerActivity.class);
    spec = tabHost.newTabSpec("power").setIndicator("Power", res.getDrawable(R.drawable.tab_power)).setContent(intent);
    tabHost.addTab(spec);

    tabHost.setCurrentTab(0);

}

 }

ListPlaceHolder.xml

 <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">    

<ListView
    android:id="@id/android:list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:drawSelectorOnTop="false" />

  <TextView
    android:id="@id/android:empty"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="No data"/>
 </LinearLayout>

XMLFunction.java

 package com.infra.android.views;

 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.text.CharacterIterator;
 import java.text.StringCharacterIterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
  import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XMLfunctions {

public final static Document XMLfromString(String xml){

    Document doc = null;

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {

        DocumentBuilder db = dbf.newDocumentBuilder();

        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(xml));
        doc = db.parse(is); 

    } catch (ParserConfigurationException e) {
        System.out.println("XML parse error: " + e.getMessage());
        return null;
    } catch (SAXException e) {
        System.out.println("Wrong XML file structure: 开发者_如何学运维" + e.getMessage());
        return null;
    } catch (IOException e) {
        System.out.println("I/O exeption: " + e.getMessage());
        return null;
    }

    return doc;

}


/** Returns element value
  * @param elem element (it is XML tag)
  * @return Element value otherwise empty String
  */
 public final static String getElementValue( Node elem ) {
     Node kid;
     if( elem != null){
         if (elem.hasChildNodes()){
             for( kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling() ){
                 if( kid.getNodeType() == Node.TEXT_NODE  ){
                     return kid.getNodeValue();
                 }
             }
         }
     }
     return "";
 }

 /*Start Parsing Top News XML*/
 public static String getTopNewsXML(){   
        String line = null;

        try {

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost("http://p-xr.com/xml");

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            line = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
        } catch (MalformedURLException e) {
            line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
        } catch (IOException e) {
            line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
        }

        return line;

}


public static int numResults(Document doc){     
    Node results = doc.getDocumentElement();
    int res = -1;

    try{
        res = Integer.valueOf(results.getAttributes().getNamedItem("count").getNodeValue());
    }catch(Exception e ){
        res = -1;
    }

    return res;
}

public static String getValue(Element item, String str) {       
    NodeList n = item.getElementsByTagName(str);        
    return XMLfunctions.getElementValue(n.item(0));
}   

   }


You must get ClassCastException and if not that, at least NullPointerException because of the following line in your listener's code:

HashMap<String, String> o = (HashMap<String, String>) lv.getOnItemClickListener();

You should change it to

HashMap<String, String> o = (HashMap<String, String>) adapter.getItem(position);

in case that you are trying to access the underlying object of the list item renderer.

Edit

I've just tried out this application, and it works on my end (with dummy data, classes, etc.)
What i've changed though, is

final ListAdapter adapter = new SimpleAdapter(this, mylist, R.layout.main, 
        new String[] { "title" }, new int[] { R.id.item_title });
setListAdapter(adapter);

getListView().setOnItemClickListener(new OnItemClickListener()
{
    @Override
    public void onItemClick(AdapterView<?> a, View view, int position, long id)
    {
        HashMap<String, String> o = (HashMap<String, String>) adapter.getItem(position);

        Intent i = new Intent(TopNewsActivity.this, NewsDetails.class);
        i.putExtra("content_id", o.get("id"));
        i.putExtra("title", o.get("title"));
        startActivity(i);
    }
});

Edit 2

Rookie mistake focusing on the symptoms as we're sure the problem is there... Not that there wasn't, the notes above are standing.

But only when adopting the classes and layouts shared above, i realized, that you are actually using your TabView's layout as an itemrenderer for the list inside your TabView...

That main.xml shouldn't contain those two TextViews, they should be in a separate xml file (say: list_item.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TextView android:id="@+id/item_title" android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium"
        android:padding="2dp" android:textSize="20dp" />
    <TextView android:id="@+id/item_subtitle"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:padding="2dp" android:textSize="13dp" />
</LinearLayout>

and your main.xml should look like

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="5dp">
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="5dp"/>
        </LinearLayout>
    </TabHost>
</LinearLayout>

finally, when you initialize your list adapter, you should change it to use this list_item.xml:

final ListAdapter adapter =
    new SimpleAdapter(this, mylist, R.layout.list_item, new String[] 
        { "name", "Score" }, new int[] { R.id.item_title, R.id.item_subtitle });

and that's it.

Now it works, and doesn't have a whole new TabView (without any tabs) in each of your list items, neither has extra, useless and invisible TextViews in your main layout.


I had a similar issue when using RatingBar.

In my case I had to remove focus from the RatingBar using android:isIndicator="true".

I see a lot of similar questions about ListView in Android. In general people are using some widget in their layout which overrides the default ListView click handling.

My answer is to check all widgets are not intercepting click events.


Try this Edited File :

 public class TopNewsActivity extends ListActivity {

 /** Called when the activity is first created. */
 @Override
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.listplaceholder);

ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();


String xml = XMLfunctions.getTopNewsXML();
Document doc = XMLfunctions.XMLfromString(xml);

int numResults = XMLfunctions.numResults(doc);

if((numResults <= 0)){
    Toast.makeText(TopNewsActivity.this, "No Result Found", Toast.LENGTH_LONG).show();  
    finish();
}

NodeList nodes = doc.getElementsByTagName("result");

for (int i = 0; i < nodes.getLength(); i++) {                           
    HashMap<String, String> map = new HashMap<String, String>();    

    Element e = (Element)nodes.item(i);
    map.put("id", XMLfunctions.getValue(e, "id"));
    map.put("title", XMLfunctions.getValue(e, "title"));
    mylist.add(map);            
}       

ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main, new String[] { "title"}, new int[] { R.id.item_title});



final ListView lv = getListView();
setListAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        @SuppressWarnings("unchecked")
        //HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);

        Toast.makeText(getApplicationContext(),"Inside onItemClick",Toast_LONG).show();
        /*  
        Intent i = new Intent(view.getContext(), NewsDetails.class);
        i.putExtra("content_id", o.get("id"));
        i.putExtra("title", o.get("title"));
        startActivity(i);*/
    }
});



}

}


here's a reason that bit me recently: if you add a clicklistener to the view returned by your adapter, it masks the longclick behavior....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜