Search code examples
javaandroidlistviewandroid-studiokumulos

Populating a ListView with Kumulos?


I am having a lot of difficulty using Kumulos to populate a ListView. Through my research Ive found numerous tutorials and postings about using SQLite or other databases but nothing with Kumulos =/.

What I need help with:

1) Implementation of Kumulos to fill a ListView

Source: https://docs.kumulos.com/integration/android/

Research conducted:

Encode and decode bitmap object in base64 string in Android

HashMap to ListView

How to retrieve data from DBHelper by HashMap in Multicolumn ListView

HashMap to ListView

MAIN ACTIVITY:

public class PersonSearchPop extends Activity {

private ListView personlist;
private CustomListViewAdapter customListViewAdapter;
public static final String YOUR_API_KEY = "HIDDEN";
public static final String YOUR_SECRET_KEY = "HIDDEN";

public static String encodeToBase64(Bitmap image, Bitmap.CompressFormat compressFormat, int quality)
{
    ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
    image.compress(compressFormat, quality, byteArrayOS);
    return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
}

public static Bitmap decodeBase64(String input)
{
    byte[] decodedBytes = Base64.decode(input, 0);
    return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listview_popup);

    Kumulos.initWithAPIKeyAndSecretKey(YOUR_API_KEY, YOUR_SECRET_KEY, this);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);

    int width = dm.widthPixels;
    int height = dm.heightPixels;

    getWindow().setLayout((int) (width * .4), (int) (height * .6));

   ?????????????????????????????????????????????????????????????????????????????????


    personlist.setOnItemClickListener(new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id){
            finish();
        }
    });
}

}

CUSTOM ADAPTER:

public class CustomListViewAdapter extends CursorAdapter {

public CustomListViewAdapter(Context context, Cursor c){
    super (context, c);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View retView = inflater.inflate(R.layout.personlist_row, parent, false);
    return retView;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    TextView dl = (TextView) view.findViewById(R.id.tvdl);
    dl.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(7))));

    TextView last = (TextView) view.findViewById(R.id.tvLastName);
    last.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1))));

    TextView first = (TextView) view.findViewById(R.id.tvFirstName);
    first.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(3))));

    TextView middle = (TextView) view.findViewById(R.id.tvMiddleName);
    middle.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2))));

    TextView ss = (TextView) view.findViewById(R.id.tvSS);
    ss.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(8))));

    //ImageView image = (ImageView) view.findViewById(R.id.idPic);
    //image.setImageDrawable(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(12))));
}

}

ENTER DATA:

public class EnterData extends Activity {

EditText lName;
EditText dl;
EditText ss;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.persons_popup);

    lName = (EditText) findViewById(R.id.etLastName);
    dl = (EditText) findViewById(R.id.etDL);
    ss = (EditText) findViewById(R.id.etSocial);
}

public void onClickSearch (View btnSearch) {

    String personName = lName.getText().toString();
    String personDL = dl.getText().toString();
    String personSS = ss.getText().toString();

    }
}

}

UPDATE: Ok, I changed my code to just two classes and it seems to be working. I am getting an error from Kumulos however =/.

Kumulos error: {"responseCode":32,"responseMessage":"Invalid request: ","payload":null,"sessionToken":"b29366e44a7cdbb905db18b51995e545daf4f816","requestedMethod":"searchPerson","requestedFormat":"json","timestamp":1462147387,"requestReceivedTime":1462147387,"maxAllowedRequestTime":40,"requestProcessingTime":0.012163877487183}

PersonSearchPop:

public class PersonSearchPop extends ListActivity {

public static final String YOUR_API_KEY = "HIDDEN";
public static final String YOUR_SECRET_KEY = "HIDDEN";

static class Person {

    public long personID;
    public String lastName;
    public String middleName;
    public String firstName;
    public String dateOfBirth;
    public String personAddress;
    public int phoneNumber;
    public int driversLicense;
    public int socialSecurity;
    public String personRace;
    public String personSex;
    public String personAge;

    public static Person createFromGenericMap(Map<String, Object> object) {

        Person p = new Person();

        p.personID = (long) object.get("personID");
        p.lastName = (String) object.get("lastName");
        p.middleName = (String) object.get("middleName");
        p.firstName = (String) object.get("firstName");
        p.dateOfBirth = (String) object.get("dob");
        p.personAddress = (String) object.get("address");
        p.phoneNumber = (int) object.get("phone");
        p.driversLicense = (int) object.get("dl");
        p.socialSecurity = (int) object.get("ss");
        p.personRace = (String) object.get("race");
        p.personSex = (String) object.get("sex");
        p.personAge = (String) object.get("age");

        return p;
    }

}

static class PersonAdapter extends BaseAdapter {

    private List<Person> people;

    public PersonAdapter(List<Person> people) {
        this.people = people;
        //inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    @Override
    public int getCount() {
        return people.size();
    }

    @Override
    public Object getItem(int position) {
        return people.get(position);
    }

    @Override
    public long getItemId(int position) {
        Person p = people.get(position);
        return p.personID;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;

        if (convertView == null) {


            TextView dl = (TextView) view.findViewById(R.id.tvdl);
            TextView last = (TextView) view.findViewById(R.id.tvLastName);
            TextView first = (TextView) view.findViewById(R.id.tvFirstName);
            TextView middle = (TextView) view.findViewById(R.id.tvMiddleName);
            TextView ss = (TextView) view.findViewById(R.id.tvSS);

            Person mperson = people.get(position);

            dl.setText(mperson.driversLicense);
            last.setText(mperson.lastName);
            first.setText(mperson.firstName);
            middle.setText(mperson.middleName);
            ss.setText(mperson.socialSecurity);
            //ImageView image = (ImageView) view.findViewById(R.id.idPic);
            //image.setImageDrawable(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(12))));
        }
        return view;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listview_popup);

    Kumulos.initWithAPIKeyAndSecretKey(YOUR_API_KEY, YOUR_SECRET_KEY, this);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);

    int width = dm.widthPixels;
    int height = dm.heightPixels;

    getWindow().setLayout((int) (width * .4), (int) (height * .6));

    // Call Kumulos
    Map<String, String> params = new HashMap<>();
    Intent intent = getIntent();
    String lastName = intent.getStringExtra("lastName");
    params.put("lastName",String.valueOf(lastName));
    Kumulos.call("searchPerson", params, new ResponseHandler() {

        // Handle result
        @Override
        public void didCompleteWithResult(Object result) {
            super.didCompleteWithResult(result);

            // Cast generic response down to list of maps
            ArrayList<LinkedHashMap<String, Object>> objects = (ArrayList<LinkedHashMap<String, Object>>) result;

            // Create a list for the models
            ArrayList<Person> people = new ArrayList<>();

            // Map models from generic objects and add to list
            for (Map<String, Object> personObject : objects) {
                Person p = Person.createFromGenericMap(personObject);
                people.add(p);
            }

            // Create adapter with model list
            final PersonAdapter adapter = new PersonAdapter(people);

            // Set adapter on main UI thread
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    setListAdapter(adapter);
                }
            });
        }
    });
}

}

PersonsPop

 @Override
public void onClick(View v){
    switch(v.getId()){
        case R.id.bCancelPerson:
            finish();
            break;
        case R.id.bSearchPerson:
            EditText lastName = (EditText) findViewById(R.id.etLastName);
            Intent intent = new Intent(PersonsPop.this, PersonSearchPop.class);
            intent.putExtra("lastName", lastName.getText().toString());
            startActivity(new Intent(PersonsPop.this, PersonSearchPop.class));

Solution

  • I'm Chris from Kumulos -- let me try to point you in the right direction.

    So in general, the process of displaying data in a list view from a web service looks like:

    1. Call out to the web service and retrieve the list of data

    2. Map those objects down to model classes and either hold in memory or persist to disk

    3. Create an adapter that is backed by the data on the phone

    4. Set the adapter of the list view to be your custom adapter instance

    Assuming that you would hold the objects in memory, creating a custom adapter backed by an ArrayList of your model type would be sufficient. This is one of the simplest ways to get started.

    So with Kumulos, you could do something like the following:

    package com.example.cgwyllie.simplelistview;
    
    import android.app.ListActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    
    import com.kumulos.android.jsonclient.Kumulos;
    import com.kumulos.android.jsonclient.ResponseHandler;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    
    public class MainActivity extends ListActivity {
    
        static class Person {
    
            public long personID;
            public String firstName;
            public String lastName;
    
            public static Person createFromGenericMap(Map<String, Object> object) {
                Person p = new Person();
    
                p.personID = (long) object.get("personID");
                p.firstName = (String) object.get("firstName");
                p.lastName = (String) object.get("lastName");
    
                return p;
            }
    
        }
    
        static class PersonAdapter extends BaseAdapter {
    
            private List<Person> people;
    
            public PersonAdapter(List<Person> people) {
                this.people = people;
            }
    
            @Override
            public int getCount() {
                return people.size();
            }
    
            @Override
            public Object getItem(int position) {
                return people.get(position);
            }
    
            @Override
            public long getItemId(int position) {
                Person p = people.get(position);
                return p.personID;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO implement your view
                return null;
            }
    
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Kumulos.initWithAPIKeyAndSecretKey("API_KEY", "SECRET_KEY", this);
    
            // Call Kumulos
            Map<String,String> params = new HashMap<>();
            Kumulos.call("getPeople", params, new ResponseHandler() {
    
                // Handle result
                @Override
                public void didCompleteWithResult(Object result) {
                    super.didCompleteWithResult(result);
    
                    // Cast generic response down to list of maps
                    ArrayList<LinkedHashMap<String, Object>> objects = (ArrayList<LinkedHashMap<String,Object>>) result;
    
                    // Create a list for the models
                    ArrayList<Person> people = new ArrayList<>();
    
                    // Map models from generic objects and add to list
                    for (Map<String,Object> personObject : objects) {
                        Person p = Person.createFromGenericMap(personObject);
                        people.add(p);
                    }
    
                    // Create adapter with model list
                    final PersonAdapter adapter = new PersonAdapter(people);
    
                    // Set adapter on main UI thread
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            setListAdapter(adapter);
                        }
                    });
                }
            });
        }
    }
    

    As mentioned, whilst this is one of the simplest approaches, it does have some limitations around the handling of orientation changes or navigation away from the activity whilst loading is taking place. Implementing the view with recycling is also not covered.

    For more comprehensive list view examples, it might be worth checking out http://developer.android.com/training/material/lists-cards.html and http://www.vogella.com/tutorials/AndroidListView/article.html.

    Hope this has been useful.