title: Get values of views inside listview item on click
body: <p>I have a listview containing different xml layouts, each with different views. I was wondering how I can get the data from the views inside the item that the user has clicked on, inside the <code>onItemClick</code> method.</p>
  
  <p>My listview is made up of multiple layouts so I cannot know for sure which layout is being pressed when the onItemClick method is called. For example, one of the items in the layouts in the listview is:</p>
  
  <pre><code>// list_item.xml
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" &gt;
  
      &lt;TextView
          android:id="@+id/lblSub"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentRight="true"
          android:layout_alignParentTop="true"
          android:padding="6dp"
          android:layout_marginRight="4dp"
          android:text=""
          android:textColor="#FFFFFF"
          android:textSize="18sp" /&gt;
  
      &lt;TextView
          android:id="@+id/lblMain"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentLeft="true"
          android:layout_alignParentTop="true"
          android:padding="6dp"
          android:layout_marginLeft="4dp"
          android:text=""
          android:textColor="#FFFFFF"
          android:textSize="18sp" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>Where as another layout in the listview could be:</p>
  
  <pre><code>// list_item_name.xml 
  &lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent" &gt;
  
      &lt;TextView
          android:id="@+id/lblName"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentLeft="true"
          android:layout_alignParentTop="true"
          android:layout_marginLeft="4dp"
          android:padding="4dp"
          android:text="TextView"
          android:textColor="#FFFFFF"
          android:textSize="28sp" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>So I am at a loss as to how to get the data for all these views for any layout within the listview.</p>
  
  <p>My previous attempt was this:</p>
  
  <pre><code>public void onItemClick(AdapterView&lt;?&gt; listView, View view, int position, long id) {            
      Object obj = adapter.getItem(position);
      String value = obj.toString();
  }
  </code></pre>
  
  <p>However <code>value</code> in this instance, returns a string containing all the values of all the views inside this item, for example: <code>{caption=MobileNumber, value=07000123456}</code> &lt;&lt;&lt; I cannot do anything with this string unless I try and pick it apart using <code>substring</code>, which is unreliable at best considering the values may have been created by the user.</p>
  
  <p>This is my adapter in use (credit to <a href="http://jsharkey.org/blog/2008/08/18/separating-lists-with-headers-in-android-09/" rel="nofollow">Jeff Sharkey</a>, I did not create this adapter):</p>
  
  <pre><code>public class SeparatedListAdapter extends BaseAdapter {  
  
      public final Map&lt;String,Adapter&gt; sections = new LinkedHashMap&lt;String,Adapter&gt;();  
      public final ArrayAdapter&lt;String&gt; headers;  
      public final static int TYPE_SECTION_HEADER = 0;  
  
      public SeparatedListAdapter(Context context) {  
          headers = new ArrayAdapter&lt;String&gt;(context, R.layout.list_header);  
      }  
  
      public void addSection(String section, Adapter adapter) {  
          this.headers.add(section);  
          this.sections.put(section, adapter);  
      }
      public void addSectionNoHeader(String section, Adapter adapter) {
          this.sections.put(section, adapter);
      }
  
      public Object getItem(int position) {  
          for(Object section : this.sections.keySet()) {  
              Adapter adapter = sections.get(section);  
              int size = adapter.getCount() + 1;  
  
              // check if position inside this section   
              if(position == 0) return section;  
              if(position &lt; size) return adapter.getItem(position - 1);  
  
              // otherwise jump into next section  
              position -= size;  
          }  
          return null;  
      }  
  
      public int getCount() {  
          // total together all sections, plus one for each section header  
          int total = 0;  
          for(Adapter adapter : this.sections.values())  
              total += adapter.getCount() + 1;  
          return total;  
      }  
  
      public int getViewTypeCount() {  
          // assume that headers count as one, then total all sections  
          int total = 1;  
          for(Adapter adapter : this.sections.values())  
              total += adapter.getViewTypeCount();  
          return total;  
      }  
  
      public int getItemViewType(int position) {  
          int type = 1;  
          for(Object section : this.sections.keySet()) {  
              Adapter adapter = sections.get(section);  
              int size = adapter.getCount() + 1;  
  
              // check if position inside this section   
              if(position == 0) return TYPE_SECTION_HEADER;  
              if(position &lt; size) return type + adapter.getItemViewType(position - 1);  
  
              // otherwise jump into next section  
              position -= size;  
              type += adapter.getViewTypeCount();  
          }  
          return -1;  
      }  
  
      public boolean areAllItemsSelectable() {  
          return false;  
      }  
  
      public boolean isEnabled(int position) {  
          return (getItemViewType(position) != TYPE_SECTION_HEADER);  
      }  
  
      @Override  
      public View getView(int position, View convertView, ViewGroup parent) {  
          int sectionnum = 0;  
          for(Object section : this.sections.keySet()) {  
              Adapter adapter = sections.get(section);  
              int size = adapter.getCount() + 1;  
  
              // check if position inside this section   
              if(position == 0) return headers.getView(sectionnum, convertView, parent);  
              if(position &lt; size) return adapter.getView(position - 1, convertView, parent);  
  
              // otherwise jump into next section  
              position -= size;  
              sectionnum++;  
          }  
          return null;  
      }  
  
      @Override  
      public long getItemId(int position) {  
          return position;  
      }  
  
  }  
  </code></pre>
  
  <p>I'm looking for a way of extracting the values of <em>all</em> the views inside the item. But the fact that the item that has been clicked could be one of any layouts is confusing me. Any ideas?</p>
  
  <p>EDIT:</p>
  
  <p>Here is an example of how I am using this adapter in code:</p>
  
  <pre><code>SeparatedListAdapter adapter;
  Customer cust;
  ListView lvDetails;
  
  public Map&lt;String,?&gt; createDoubleItem(String title, String caption) {  
          Map&lt;String,String&gt; item = new HashMap&lt;String,String&gt;();  
          item.put(ITEM_VALUE, title);  
          item.put(ITEM_CAPTION, caption);  
          return item;  
      }
  
      public Map&lt;String,?&gt; createSingleItem(String name) {  
          Map&lt;String,String&gt; item = new HashMap&lt;String,String&gt;();  
          item.put(ITEM_VALUE, name);
          return item;
      } 
  
  @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_view_customer);
  
          Intent intent = getIntent();
          cust = Db.Functions.getCustomer(intent.getStringExtra("uuid"));
          lvDetails = (ListView) findViewById(R.id.custdetails);
          adapter = new SeparatedListAdapter(this);
          lvDetails.setOnItemClickListener(new OnItemClickListener() {
              @Override
              public void onItemClick(AdapterView&lt;?&gt; listView, View view, int position, long id) {
                  Gen.popup("Item clicked");
              }
          });
  
          // Name
          List&lt;Map&lt;String,?&gt;&gt; name = new LinkedList&lt;Map&lt;String,?&gt;&gt;();
          if (cust.firstName == null &amp;&amp; cust.lastName == null)
              name.add(createSingleItem("Unnamed Customer"));
          else
              name.add(createSingleItem(
                      ((cust.title != null) ? cust.title + " " : "") +
                      ((cust.firstName != null) ? cust.firstName + " " : "") +
                      ((cust.lastName != null) ? cust.lastName : "")));
          adapter.addSection("Name", new SimpleAdapter(this, name, R.layout.list_item_name,   
                  new String[] { ITEM_VALUE },
                  new int[] { R.id.lblName }));
          // Phones
          if ((cust.mobileNumber != null || cust.homeNumber != null || cust.workNumber != null) &amp;&amp; SHOW_PHONES)
          {
              List&lt;Map&lt;String,?&gt;&gt; phone = new LinkedList&lt;Map&lt;String,?&gt;&gt;();
              if (cust.mobileNumber != null)
                  phone.add(createDoubleItem(cust.mobileNumber, "Mobile"));
              if (cust.homeNumber != null)
                  phone.add(createDoubleItem(cust.homeNumber, "Home"));
              if (cust.workNumber != null)
                  phone.add(createDoubleItem(cust.workNumber, "Work"));
              adapter.addSection("Phone", new SimpleAdapter(this, phone, R.layout.list_item,   
                      new String[] { ITEM_VALUE, ITEM_CAPTION },
                      new int[] { R.id.lblSub, R.id.lblMain }));
          }  
          lvDetails.setAdapter(adapter);
          adapter.notifyDataSetChanged();
      }
  }
  </code></pre>