llenar listview android con json
Llenar Listview de JSON (5)
¿Alguien sabe de algún ejemplo para cargar dinámicamente datos Json en un ListView, la mayoría de los ejemplos que he visto solo usan una matriz estática de algún tipo. Necesito cargar, digamos, 10 filas de datos de Json, luego, en la parte inferior, tengo una carga más ... para obtener los próximos 10 etc. etc. Ejemplos usando Json, por favor ...
Android no tiene un adaptador listo para llenar un ListView
con una matriz JSON, como lo hace para llenar un ListView
con registros de la base de datos.
Recomiendo que te sientas cómodo rellenando una estructura de datos Java de tu elección con los datos JSON, y que te sientas cómodo trabajando con ListViews
, ListViews
de diferentes colecciones, con diferentes filas personalizadas.
Aquí hay un ejemplo simple de llenar una List
de una matriz JSON, y luego usar la List
para poblar una ListView
List
.
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Main extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try
{
String jsonInput = "[/"one/",/"two/",/"three/",/"four/",/"five/",/"six/",/"seven/",/"eight/",/"nine/",/"ten/"]";
JSONArray jsonArray = new JSONArray(jsonInput);
int length = jsonArray.length();
List<String> listContents = new ArrayList<String>(length);
for (int i = 0; i < length; i++)
{
listContents.add(jsonArray.getString(i));
}
ListView myListView = (ListView) findViewById(R.id.my_list);
myListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listContents));
}
catch (Exception e)
{
// this is just an example
}
}
}
El programador Bruce tiene razón, no hay una forma predeterminada de hacerlo. Sin embargo, hay una manera muy limpia y simple de lograr esto. Aquí está el adaptador que uso para manejar JSONArrays.
class JSONAdapter extends BaseAdapter implements ListAdapter {
private final Activity activity;
private final JSONArray jsonArray;
private JSONAdapter(Activity activity, JSONArray jsonArray) {
assert activity != null;
assert jsonArray != null;
this.jsonArray = jsonArray;
this.activity = activity;
}
@Override public int getCount() {
return jsonArray.length();
}
@Override public JSONObject getItem(int position) {
return jsonArray.optJSONObject(position);
}
@Override public long getItemId(int position) {
JSONObject jsonObject = getItem(position);
return jsonObject.optLong("id");
}
@Override public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = activity.getLayoutInflater().inflate(R.layout.row, null);
JSONObject jsonObject = getItem(position);
return convertView;
}
}
Hice un JSONAdapter simple como este:
public abstract class JSONAdapter extends BaseAdapter {
private JSONArray array;
@Override
public int getCount() {
return array == null ? 0 : array.length();
}
@Override
public Object getItem(final int position) {
if (array == null | array.length() < position) {
return null;
}
try {
return array.get(position);
} catch (final JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
public long getItemId(final int position) {
return position;
}
public JSONObject getObject(final int position) {
return (JSONObject) getItem(position);
}
public void setData(final JSONArray data) {
array = data;
notifyDataSetChanged();
}
}
y cuando necesito una instancia específica de la misma, tengo que anular el método getView en el adaptador con mi necesidad concreta:
@Override
public View getView(final int position, final View convertView,
final ViewGroup parent) {
final View view;
final ViewHolder holder;
if (convertView != null) {
view = convertView;
holder = (ViewHolder) view.getTag();
} else {
view = context.getLayoutInflater().inflate(
R.layout.<mylayout>, parent, false);
holder = new ViewHolder();
holder.name = (TextView) view.findViewById(R.id.name);
[...]
view.setTag(holder);
}
final JSONObject jsonObj = getObject(position);
holder.name.setText(jsonObj.optString("name"));
[...]
return view;
}
y establecer datos como este:
final JSONObject json = new JSONObject(jsonString);
adapter.setData(json.getJSONArray("projects"));
Pruebe lo siguiente:
Clase JSON Parser:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if (method == "POST") {
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} else if (method == "GET") {
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "/n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Clase de fragmento que muestra Listview:
public static class EventFragment extends ListFragment {
ArrayList<HashMap<String, String>> eventsList;
private String url_all_events = //url goes here;
private ProgressDialog pDialog;
JSONParser jParser = new JSONParser();
// JSON Node names
private static final String CONNECTION_STATUS = "success";
private static final String TABLE_EVENT = "Event";
private static final String pid = "pid";
private static final String COL_GROUP = "Group";
private static final String COL_NAME = "Event_Name";
private static final String COL_DESC = "Event_Desc";
private static final String COL_DATE = "Event_Date";
private static final String COL_TIME = "Event_Time";
JSONArray Events = null;
public static final String ARG_SECTION_NUMBER = "section_number";
public EventFragment() {
}
public void onStart() {
super.onStart();
eventsList = new ArrayList<HashMap<String, String>>();
new LoadAllEvents().execute();
// selecting single ListView item
ListView lv = getListView();
// Lauching the Event details screen on selecting a single event
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String ID = ((TextView) view.findViewById(R.id.pid))
.getText().toString();
Intent intent = new Intent(view.getContext(),
EventDetails.class);
intent.putExtra(pid, ID);
view.getContext().startActivity(intent);
}
});
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_events,
container, false);
return rootView;
}
class LoadAllEvents extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_events,
"GET", params);
try {
// Checking for SUCCESS TAG
int success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// products found
// Getting Array of Products
Events = json.getJSONArray(TABLE_EVENT);
// looping through All Contacts
for (int i = 0; i < Events.length(); i++) {
JSONObject evt = Events.getJSONObject(i);
// Storing each json item in variable
id = evt.getString(pid);
group = evt.getString(COL_GROUP);
name = evt.getString(COL_NAME);
desc = evt.getString(COL_DESC);
date = evt.getString(COL_DATE);
time = evt.getString(COL_TIME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(pid, id);
map.put(COL_GROUP, group);
map.put(COL_NAME, name);
map.put(COL_DESC, desc);
map.put(COL_DATE, date);
map.put(COL_TIME, time);
// adding HashList to ArrayList
eventsList.add(map);
}
} else {
// Options are not available or server is down.
// Dismiss the loading dialog and display an alert
// onPostExecute
pDialog.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
getActivity().runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(getActivity(),
eventsList, R.layout.list_item, new String[] {
pid, COL_GROUP, COL_NAME, COL_DATE, COL_TIME },
new int[] { R.id.pid, R.id.group, R.id.name, R.id.header,
R.id.title2 });
setListAdapter(adapter);
}
});
}
}
}
Clase de detalles de la actividad:
public class EventDetails extends Activity {
String pid;
TextView EvtName, EvtDesc, EvtDate, EvtTime, Header;
ImageView logo;
private String url_event_details = "http://centrubook.eu.pn/eventDetails.php";
private ProgressDialog pDialog;
JSONParser jParser = new JSONParser();
// JSON Node names
private static final String CONNECTION_STATUS = "success";
private static final String TABLE_EVENT = "Event";
private static final String COL_PID = "pid";
private static final String COL_NAME = "Event_Name";
private static final String COL_DESC = "Event_Desc";
private static final String COL_DATE = "Event_Date";
private static final String COL_TIME = "Event_Time";
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar''s Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.eventdetails);
// ActionBar actionBar = getActionBar();
// actionBar.setDisplayHomeAsUpEnabled(true);
EvtName = (TextView) findViewById(R.id.BombaName);
EvtDesc = (TextView) findViewById(R.id.BombaDesc);
EvtDate = (TextView) findViewById(R.id.BombaDate);
EvtTime = (TextView) findViewById(R.id.BombaTime);
logo = (ImageView) findViewById(R.id.BombaLogo);
Intent i = getIntent();
pid = i.getStringExtra(COL_PID);
new getEventDetails().execute();
}
class getEventDetails extends AsyncTask<String, String, String> {
String name, desc, date, time;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EventDetails.this);
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... args) {
// Check for success tag
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jParser.makeHttpRequest(url_event_details,
"GET", params);
// json success tag
success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// successfully received product details
JSONArray eventsObj = json.getJSONArray(TABLE_EVENT);
// get first product object from JSON Array
JSONObject details = eventsObj.getJSONObject(0);
name = details.getString(COL_NAME);
desc = details.getString(COL_DESC);
date = details.getString(COL_DATE);
time = details.getString(COL_TIME);
} else {
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(final String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
EvtName.setText(name);
EvtDesc.setText(desc);
EvtDate.setText(date);
EvtTime.setText(time);
logo.setImageResource(R.drawable.events);
}
});
}
}
}
Espero que esto ayude ;)
dbaugh tiene una buena respuesta, pero this publicación explica cómo usarla para el resto de nosotros que no sabemos a dónde ir desde allí.