virtualpathum
virtualpathum

Reputation: 763

Load data to android list view with record id and pass the exact record id onListItemClick

Im getting my data from a web service and loads to a list view. Which is working fine. but When I click on a particular list item I need to pass the id of that record (Id should is coming from the database) to another activity. Here is the code where I populate the array

public String[] getNames(String response){
    String[] friends = null;
    try {
        JSONObject json = new JSONObject(response);
        String values = json.getString("friends");
        JSONArray jsonArray = new JSONArray(values);
        friends = new String[jsonArray.length()];
        //Bundle b = new Bundle();
        for (int i = 0; i < jsonArray.length(); i++) {

            friends[i] =  jsonArray.getJSONObject(i).getString("fname")+ " " + jsonArray.getJSONObject(i).getString("lname") ;
            friends[i+1] = jsonArray.getJSONObject(i).getString("id");
            //i++;  
            //friends[i]= jsonArray.getJSONObject(i).getString("id");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return friends;
}

This is the code Im trying to get the name and the ids

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    // Get the item that was clicked
    Object o = this.getListAdapter().getItem(position);
    String name = o.toString();
    Object x = this.getListAdapter().getItem(position+1);
    String userid= x.toString();
    Toast.makeText(this, "You selected: " + name +"The Id: "+userid, Toast.LENGTH_LONG)
            .show();
}

This is my xml file for the list view

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#ffffff"
>
<ImageView
android:id="@+id/icon"
android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/man"
/>
<TextView
android:id="@+id/txtName"
android:layout_width="210px"
android:layout_height="60px"
    android:padding="4dp"
    android:textSize="12sp" 
    android:textColor="#000000" 
    android:background="#ffffff"
/>

</LinearLayout>

This is how I populate the list view

public void setTheList(String response){
        String friends[] = getNames(response);
        ListView lv = getListView();
        lv.setTextFilterEnabled(true);
        if(adapter==null){
            LayoutInflater inflater = getLayoutInflater();
            ViewGroup header = (ViewGroup)inflater.inflate(R.layout.header, lv, false);
            lv.addHeaderView(header, null, false);
        }

        adapter = new MyArrayAdapter(this, friends);
        this.setListAdapter(adapter);

    }

}

This is my Adapter. I got it from here

package virtualpathum.web;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

public class MyArrayAdapter extends ArrayAdapter<String> {
    private final Activity context;
    private final String[] names;

    public MyArrayAdapter(Activity context, String[] names) {
        super(context, R.layout.friend, names);
        this.context = context;
        this.names = names;
    }

    // static to save the reference to the outer class and to avoid access to
    // any members of the containing class
    static class ViewHolder {
        public ImageView imageView;
        public TextView textView;
        public ImageButton ibConfirm;
        public ImageButton ibNotNow;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // ViewHolder will buffer the assess to the individual fields of the row
        // layout

        ViewHolder holder;
        // Recycle existing view if passed as parameter
        // This will save memory and time on Android
        // This only works if the base layout for all classes are the same
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            rowView = inflater.inflate(R.layout.friend, null, true);
            holder = new ViewHolder();
            holder.textView = (TextView) rowView.findViewById(R.id.txtName);
            holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
            //holder.ibConfirm = (ImageButton) rowView.findViewById(R.id.ibNotNow);
            //holder.ibNotNow= (ImageButton) rowView.findViewById(R.id.ibNotNow);
            rowView.setTag(holder);
        } else {
            holder = (ViewHolder) rowView.getTag();
        }

        holder.textView.setText(names[position]);
        // Change the icon for Windows and iPhone
        String s = names[position];
        holder.imageView.setImageResource(R.drawable.man);

        return rowView;
    }
}

Really appreciate if you have idea about this Thanks Pathum

Upvotes: 0

Views: 4229

Answers (5)

virtualpathum
virtualpathum

Reputation: 763

Thank you very much for all the given support. I used the approach which @Richard provided with @rafael-t's Tag concept. Thanks @yashwanth-kumar for the explanation. Following are the modifications did to my original codes

public ArrayList<Object> getNames(String response){
        ArrayList<Object>  arrList = null;
        try {
            JSONObject json = new JSONObject(response);
            String values = json.getString("friends");
            JSONArray jsonArray = new JSONArray(values);
            arrList = new ArrayList<Object>();
            for (int i = 0; i < jsonArray.length(); i++) {  
                arrList.add(new User(jsonArray.getJSONObject(i).getString("id"),jsonArray.getJSONObject(i).getString("fname"),jsonArray.getJSONObject(i).getString("lname"),jsonArray.getJSONObject(i).getString("email")));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return arrList;
    }

This is my getNames Method I added all the values to User Object. Thanks to @Richard .

Here is my Custom Adapter for this change

package virtualpathum.web;

import java.util.ArrayList;
import java.util.Iterator;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

public class MyArrayAdapter extends ArrayAdapter<ArrayList<Object>> {
    private final Activity context;
    private final ArrayList names;

    @SuppressWarnings("unchecked")
    public MyArrayAdapter(Activity context, ArrayList names) {
        super(context, R.layout.friend, names);
        this.context = context;
        this.names = names;
    }

    // static to save the reference to the outer class and to avoid access to
    // any members of the containing class
    static class ViewHolder {
        public ImageView imageView;
        public TextView textView;
        public ImageButton ibConfirm;
        public ImageButton ibNotNow;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // ViewHolder will buffer the assess to the individual fields of the row
        // layout

        ViewHolder holder;
        // Recycle existing view if passed as parameter
        // This will save memory and time on Android
        // This only works if the base layout for all classes are the same
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            rowView = inflater.inflate(R.layout.friend, null, true);
            holder = new ViewHolder();
            holder.textView = (TextView) rowView.findViewById(R.id.txtName);
            holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
            //holder.ibConfirm = (ImageButton) rowView.findViewById(R.id.ibNotNow);
            //holder.ibNotNow= (ImageButton) rowView.findViewById(R.id.ibNotNow);
            rowView.setTag(holder);
        } else {
            holder = (ViewHolder) rowView.getTag();
        }
        String [] frndNames = new String[names.size()];
        int count = 0;
        for (@SuppressWarnings("rawtypes")
        Iterator iterator = names.iterator(); iterator.hasNext();) {
            User user = (User) iterator.next();
            frndNames[count] = user.getFirstname()+" "+user.getLastname();
            count++;
        }
        String [] frndIds = new String[names.size()];
        int idCount = 0;
        for (@SuppressWarnings("rawtypes")
        Iterator iterator = names.iterator(); iterator.hasNext();) {
            User user = (User) iterator.next();
            frndIds[idCount] = user.getUserid();
            idCount++;
        }
        holder.textView.setText(frndNames[position]);
        holder.textView.setTag(frndIds[position]);
        holder.imageView.setImageResource(R.drawable.man);

        return rowView;
    }
} 

This is the on click Listener

@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        // Get the item that was clicked
        String userid = (String) v.findViewById(R.id.txtName).getTag();
        Toast.makeText(this, "Selected user ID = "+userid , Toast.LENGTH_LONG)
                .show();
    }

I still feel this can be further optimize for better performance but for now it's more than enough for me. Thank you guys again.

Upvotes: 1

Yashwanth Kumar
Yashwanth Kumar

Reputation: 29121

ok, here is what you do, add a new member to your holder class, lets assume your id data type is string. then add

public String mId;

to the holder. and populate it with the relating id of the view before returning from the getView.

holder.mId = Id_which_you_need;

in onItemClickListener, use this to get the Tag.

holder = (ViewHolder) v.getTag();

and to get the Id, as we assumed it's a string.

id = holder.mId;

id is what you need.This is all you need, there are other ways too, since you are using Tags, I thought this would be better.

Upvotes: 1

richardwiden
richardwiden

Reputation: 1602

Instead getnames returning String[]create a class representing a person together with an id and return ArrayList

class Person {
   String name;
   int id;
   public Person(int id, String name){
   //Implement
   }
   //Implement getters and setters      
}

//Consider renaming to getPersons
ArrayList<Person> person = getNames();

getNames(String inputString)
{
   ...
   ArrayList<Person> persons = new ArrayList...
   persons.add(new Person("Brother",2)
   persons.add(new Person("Jonas",1)
   return persons;
}

ArrayAdapter<Person> arrayadapter = new YourArrayAdapter<Person>();
arrayadapter.addAll(getNames(inputString);


In you arrayadapter you override the getItemId
@Overide
getItemId(int position)
{
   return getItem(position).getItemId();
}

(I assume you are using an ArrayAdapter or something similar)

And then in your arrayadaper implement getId and getItem accordingly

Upvotes: 1

Rafael T
Rafael T

Reputation: 15679

As far as I understand, you have no problem to get the id back. However, you could supply a Tag to any View (so you can pass the id as Tag inside the LinearLayout). Then if you have your id you could start your new Activity like this:

Intent intent = new Intent(getContext(), YOUR_ACTIVITY_YOU_WANNA_START.class);
intent.putExtra("ID", userid);
startActivity(0, intent);

in the recieving Activity (in this case YOUR_ACTIVITY_YOU_WANNA_START.class) you call maybe in onCreate()

Intent intent = getIntent();
String userId = intent.getExtra("ID" , "DEFAULT");

Upvotes: 0

Kirill Rakhman
Kirill Rakhman

Reputation: 43831

In the long click event you have a position parameter. Wherever you store your data, you can get it with this parameter. For further help, you should probably add some information about the type of adapter you use.

Upvotes: 0

Related Questions