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
How to retrieve data from DBHelper by HashMap in Multicolumn 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));
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:
Call out to the web service and retrieve the list of data
Map those objects down to model classes and either hold in memory or persist to disk
Create an adapter that is backed by the data on the phone
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.