hipkiss
hipkiss

Reputation: 197

Android ListView multiple arrays with custom adapter

I've pulled a couple json arrays from a DB, these are the arrays (Name = a list of names, address = a list of integers) and hosted in DialerFragment:

String[] contactNameArray= LoginHandler.getMyName();
String[] contactAddressArray= LoginHandler.getMyContactsAddress();
ListAdapter contactadapter = new ContactsAdapter(getActivity(), contactNameArray);
ListView contactsListView = (ListView) view.findViewById(R.id.contact_list);    
contactsListView.setAdapter(contactadapter);

Here is my ContactsAdapter:

public class ContactsAdapter extends ArrayAdapter<String>{
private static final String TAG = "ContactsListAdapter";


public ContactsAdapter(Context context, String[] values){
    super(context, R.layout.contact_row_layout,  values);
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    Log.d(TAG, "getView");
    // The LayoutInflator puts a layout into the right View
    LayoutInflater inflater = LayoutInflater.from(getContext());
    // inflate takes the resource to load, the parent that the resource may be
    // loaded into and true or false if we are loading into a parent view.
    View view = inflater.inflate(R.layout.contact_row_layout, parent, false);
    // We retrieve the text from the array
    String contact = getItem(position);
    // Get the TextView we want to edit
    TextView mContactName = (TextView)view.findViewById(R.id.contact_name);
    view.findViewById(R.id.contacts_avatar);

    // Put the next TV Show into the TextView
    mContactName.setText(contact);

    return view;
}}

Additionally, within my DialerFragment I have this code:

private final View.OnClickListener mOnMakeCallClick = new OnClickListener(){
    public void onClick(final View view){
        String numberToCall = "2";
        if (!TextUtils.isEmpty(numberToCall)){
            mCallWithVideo = view.getId() == R.id.contact_videocall;
            Log.d(TAG, "make call clicked: " + numberToCall + ", video=" + (mCallWithVideo ? "true" : "false"));
            mCallInitiated = ((Main)getActivity()).makeCall(numberToCall, mCallWithVideo);
            mTelNumberView.setText("");
        }
    }
};

I have ListView (fragment_dialer.xml) and the row template (contact_row_layout.xml).

The code currently works with no errors, populating the ListView with the contacts I have in my DB.

The issue: I need to dynamically call the contacts depending on which ImageButton was clicked. i.e. How do I match up 1 array of Names with 1 array of addresses and then pass that address into the OnCallClick to initiate the call? It would be nice if I could assign the ImageButton a value (as you would do something similar in PHP) and then call that "value" within the contactsadapter.

I'm really quite stuck on this, any help would be greatly appreciated. Also I'm quite new to Android.

Solution: DialerFragment:

ListView contactsListView = (ListView) view.findViewById(R.id.contact_list);
contactsListView.setAdapter(new ContactsBaseAdapter(getActivity()));

Then my "single row" class:

class SingleRow{
String name;
String address;

SingleRow(String name, String address){
    this.name=name;
    this.address=address;
}}

Then my "contacts base adapter":

public class ContactsBaseAdapter extends BaseAdapter{
private static final String TAG = "CONTACTS_BASE_ADAPTER";
ArrayList<SingleRow> list;
Context context;
ContactsBaseAdapter(Context c){
    list = new ArrayList<SingleRow>();
    context = c;
    String[] contactNameArray= LoginHandler.getMyName();
    String[] contactAddressArray= LoginHandler.getMyContactsAddress();

    for(int i= 0; i< contactNameArray.length; i++){
        list.add(new SingleRow(contactNameArray[i], contactAddressArray[i]));
    }
}
@Override
public int getCount() {
    return list.size();
}
@Override
public Object getItem(int i) {
    return list.get(i);
}
@Override
public long getItemId(int i) {
    return i;
}
@Override
public View getView(int i, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) 
    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View row = inflater.inflate(R.layout.contact_row_layout,parent, false);

    ImageView mContactPresence = (ImageView)row.findViewById(R.id.contacts_avatar);
    TextView mContactName = (TextView)row.findViewById(R.id.contact_name);
    TextView mContactAddress = (TextView)row.findViewById(R.id.contact_number);

    SingleRow contactrow = list.get(i);

    mContactName.setText(contactrow.name);
    mContactAddress.setText(contactrow.address);
    Drawable drawable = null;
    mContactPresence.setImageDrawable(drawable);

    return row;
}}

Notes: You were right thank you. My issue was I was completely new to this sort of programming. I'd done OOP before but only in PHP and didn't know how to manipulate data like that within android. Thumbs up to all who pointed me in the right direction, I learned a lot! Also, found this youtube video playlist that helped me understand a lot of the fundamentals of listviews and adapters etc.

Next: I'll be looking at ViewHolders and RecyclerViews to optimize the code :). and to pass the data into a call handler along with presence!!

Upvotes: 3

Views: 4739

Answers (2)

aikmanr
aikmanr

Reputation: 725

I would recommend making a new array of a new object (Contact) which you would populate from your existing contactNameArray & contactAddressArray arrays.

    Contact {
        public String name;
        public String address;
    }

You would pass this array in to ContactsAdapter.

In your implementation of AdapterView.onItemClick, you'd simply call

    contactadapter.getItem(position);

In order to get your Contact object associated with the clicked row.

As an additional note, I'd strongly recommend implementing the static ViewHolder pattern in your getView (https://www.codeofaninja.com/2013/09/android-viewholder-pattern-example.html).

Upvotes: 2

Vulovic Vukasin
Vulovic Vukasin

Reputation: 1748

So, create object called Contact, add him atributes, after that in your adapter layout, add the TextViews you want and just call them when setting number, name, etc. Look below.

public class ContactsAdapter extends ArrayAdapter{ private static final String TAG = "ContactsListAdapter";

public ContactsAdapter(Context context, String[] values){
    super(context, R.layout.contact_row_layout,  values);
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    Log.d(TAG, "getView");
    // The LayoutInflator puts a layout into the right View
    LayoutInflater inflater = LayoutInflater.from(getContext());
    // inflate takes the resource to load, the parent that the resource may be
    // loaded into and true or false if we are loading into a parent view.
    View view = inflater.inflate(R.layout.contact_row_layout, parent, false);
    // We retrieve the text from the array

    // Get the TextView we want to edit
//Create more textviews for showing desired atributes
    TextView mContactName = (TextView)view.findViewById(R.id.contact_name);
    TextView mContactNumber = (TextView) view.findViewById(R.id.contact_number);
    view.findViewById(R.id.contacts_avatar);
    //Create object contact that will have name, number, etc atributes...
    Contact contact = getItem(position);
    // Put the next TV Show into the TextView
    mContactName.setText(contact.getName());
    mContactNumber.setText(contact.getNumber());
    return view;

Upvotes: 3

Related Questions