I'm trying to add items to an arraylist using this class template:
public class Template {
public String username;
public String email;
}
Here's the whole code:
public void JsonToArrayList(JSONArray myJsonArray) throws JSONException
{
ArrayList<Template> listItems = new ArrayList<Template>();
JSONObject jo = new JSONObject();
Template tem = new Template();
ListView lv = (ListView) findViewById(R.id.listView1);
for(int i = 0; i<myJsonArray.length(); i++)
{
jo = myJsonArray.getJSONObject(i);
tem.username = jo.getString("username");
tem.email = jo.getString("user_email");
listItems.add(tem);
Log.e("Ninja Archives", tem.username);
}
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<Template> arrayAdapter = new ArrayAdapter<Template>(this,android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(arrayAdapter);
}
The problem is, instead of filling my listview with nice username and email strings, it's filling up with items like this:
com.android.ninjaarchives.
Template#40585690
I think somewhere along the line I have become lost, but I've been trying all sorts for ages now and getting nowhere. Can anyone point me in the right direction?
Thanks for any help.
Note: not really sure what's going on with the code; it doesn't appear to be pasting correctly.
Use below code, it can be a solution for you
public void JsonToArrayList(JSONArray myJsonArray) throws JSONException
{
ArrayList<Template> listItems = new ArrayList<Template>();
JSONObject jo = new JSONObject();
Template tem = new Template();
ListView lv = (ListView) findViewById(R.id.listView1);
String listItemString[] = new String[myJsonArray.length];
for(int i = 0; i<myJsonArray.length(); i++)
{
jo = myJsonArray.getJSONObject(i);
tem.username = jo.getString("username");
tem.email = jo.getString("user_email");
listItemString[i] = tem.username +" - " + tem.email; // u can change it according to ur need.
listItems.add(tem);
Log.e("Ninja Archives", tem.username);
}
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listItemString);
lv.setAdapter(arrayAdapter);
}
But better to write Custom adapter by extending BaseAdapter, and do listItem handling in getView method here is one simple tutorial
Take a class extending Base
private class CustomAdapter extends BaseAdapter
{
LayoutInflater inflater;
public CustomAdapter(Context context)
{
inflater = LayoutInflater.from(context);
}
public int getCount()
{
return listItems.size();
}
public Object getItem(int position)
{
return listItems.get(position);
}
public long getItemId(int position)
{
return position;
}
public View getView(final int position, View convertView,ViewGroup parent)
{
//if(convertView==null)
//convertView = inflater.inflate(R.layout.listlayout, parent, false);
Template data = (Template) getItem(position);
TextView v=new TextView(context);
v.setText(data.name);
return v;
}
}
and set adapter to your listview
lv.setAdapter(new CustomAdapter(this));
In this case you have to use a custom adapter (that extends from ArrayAdapter) and override the getView method to display in a custom layout the username and the email.
Related
Bonjour
I have spent days and night looking for an answer suitable to my case
can you help please
Here is the code I am using
anytime I add the ligne with Picasso, the program crashes
It works fine with static images from drawable
I just want to display the text with the image that corresponds
public void Afficher_les_vues(String url_in) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url_in)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
myResponse = response.body().string();
Annonces.this.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
JSONObject reader = new JSONObject(myResponse);
JSONArray eglises = reader.getJSONArray("Annonces_adv");
arrayList.clear();
for (int i = 0; i < eglises.length(); i++) {
JSONObject eglise = eglises.getJSONObject(i);
String titre = eglise.getString(titret);
String description = eglise.getString(descriptionet);
int ref = Integer.parseInt(eglise.getString(reft));
String image = eglise.getString(imaget);
String url_image = eglise.getString(imaget);
HashMap<String, String> data = new HashMap<>();
data.put(titret, titre);
data.put(descriptionet, description);
data.put(reft, String.valueOf(ref));
data.put(imaget, image);
data.put(url_imaget, url_image);
arrayList.add(data);
ImageView imageViewlogo = findViewById(R.id.imageViewLogoNews);
//Picasso.get().load(url_image).into(imageViewlogo);
//new GetImageFromUrl(imageViewlogo).execute(url_image);
ListAdapter adapter = new SimpleAdapter(Annonces.this, arrayList, R.layout.listview_layout
, new String[]{titret, descriptionet, reft, url_imaget}, new int[]{R.id.titre_de, R.id.description_de,
R.id.reference, R.id.url_image});
lv.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
When I use Picasso to display and image in a simple ImageView not in a listView, it works fine
Thank you in advance
I work with android studio
Blessings
The main things you need to fix are not creating the adapter every loop instance and not accessing row views (the ImageView) from outside the adapter.
1. Do not make the adapter inside the loop
You should build the array of data to display first, then after the loop that builds the array create the adapter and set it on the ListView. When you have a custom adapter, it is helpful to use a small data class to hold the data you need to show in each row (see RowData later in the answer)
arrayList.clear(); // ArrayList<RowData>()
for (int i = 0; i < eglises.length(); i++) {
JSONObject eglise = eglises.getJSONObject(i);
String titre = eglise.getString(titret);
String description = eglise.getString(descriptionet);
int ref = Integer.parseInt(eglise.getString(reft));
String url_image = eglise.getString(imaget);
RowData data = new RowData(titre, description, String.valueOf(ref), url_image);
arrayList.add(data);
}
// You CANNOT access row view here - in this context findViewById searches the main
// view heirarchy, and will not find views in your ListView rows
// Make the adapter *AFTER* the loop where you fill the array
// you will need to make your own custom adapter to load the image
ListAdapter adapter = new CustomAdapter(Annonces.this, R.layout.listview_layout, arrayList);
lv.setAdapter(adapter);
2. Do not attempt to access row views outside the adapter
Your row views should only be accessed inside getView in your adapter itself. This is where you should load the image. If you were using a standard adapter before, you will need to implement your own custom adapter to do this. There are instructions for how to do that here. The adapter below takes an ArrayList of RowData items and uses that to populate each row.
public class CustomAdapter extends ArrayAdapter<RowData> {
private Context mContext;
private int mResource;
public MainAdapter(#NonNull Context context, int resource, #NonNull ArrayList<RowData> objects) {
super(context, resource, objects);
mContext=context;
mResource=resource;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if( convertView == null ) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
}
// Get the views for this row (these must be in the
// layout xml you passed in to the adapter constructor)
TextView title = convertView.findViewById(R.id.titre_de);
TextView description = convertView.findViewById(R.id.description_de);
TextView reference = convertView.findViewById(R.id.reference);
ImageView imageViewlogo = convertView.findViewById(R.id.imageViewLogoNews);
// Get the RowData class for this row
RowData data = getItem(position);
// Set the text fields
title.setText(data.title);
description.setText(data.description);
reference.setText(data.reference);
// Start Picasso loading into the ImageView for this row
Picasso.get().load(data.url).into(imageViewlogo);
return convertView;
}
}
Make a small data class
When you have a custom adapter it is useful to make a custom data class that holds the data you want to show in each row. This avoids the possible errors in missing keys etc... you can get with a plain old map or passing in multiple lists.
public class RowData {
final String title;
final String description;
final String reference;
final String url;
RowData(String title, String desc, String ref, String url) {
this.title = title;
this.description = desc;
this.reference = ref;
this.url = url;
}
}
How can I create a listview that looks for more than one information in an array?
An example, suppose I have a listview of names from an array, but I still have another array that contains data like age and profession that match each name of the first array.
How could I get more than one information from an array?
Thank you so much.
What is happening when you load an ArrayList into an ArrayAdapter, and then an ArrayAdapter into a ListView, is the ArrayAdapter uses a layout file which contains a TextView. The ArrayAdapter takes the string in each ArrayList element, inflates (creates) a new View with a layout per ArrayList element, and then places the element string in each new layout's TextView.
If you want to customize each row's visual appearance (including what data appears) in your list on the screen, you can make your own custom Adapter by making a new class that extends BaseAdapter and you can make your own layout file that you will inflate in the BaseAdapter. Then find the elements in your layout and assign the data to the elements on a per row basis. Below is example code I wrote for you. I would highly suggest reading the Android documentation on ListViews and Adapters: https://developer.android.com/guide/topics/ui/layout/listview.html
https://developer.android.com/guide/topics/ui/declaring-layout.html#AdapterViews
In my activity OnCreate method (You will need to have a ListView in your layout called list_view or change the name of the ListView in my code):
ArrayList<MyDataModel> myDataModels = new ArrayList<>();
for(int i = 0; i < 50; i++) {
MyDataModel newModel = new MyDataModel("Person" + i, new Random().nextInt() % 100, "Some Profession" + i);
myDataModels.add(newModel);
}
MyListAdapter myListAdapter = new MyListAdapter(myDataModels);
ListView listView = (ListView)findViewById(R.id.list_view);
listView.setAdapter(myListAdapter);
MyDataModel.java:
public class MyDataModel {
public String mName, mProfession;
public int mAge;
public MyDataModel(String name, int age, String profession) {
mName = name;
mAge = age;
mProfession = profession;
}
}
MyListAdapter.java:
public class MyListAdapter extends BaseAdapter {
private ArrayList<MyDataModel> mMyDataModels;
public MyListAdapter(ArrayList<MyDataModel> dataModels) {
mMyDataModels = dataModels;
}
#Override
public int getCount() {
return mMyDataModels.size();
}
#Override
public MyDataModel getItem(int position) {
return mMyDataModels.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view == null) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_data_model_item, parent, false);
}
MyDataModel model = mMyDataModels.get(position);
((TextView)view.findViewById(R.id.person_name)).setText(model.mName);
((TextView)view.findViewById(R.id.person_age)).setText(String.valueOf(model.mAge));
((TextView)view.findViewById(R.id.person_profession)).setText(model.mProfession);
return view;
}
}
I have written a code to display json items into listview , when i debug the code i can see the data properly , when i am setting the list to the listview i am only seeing the last item
Code i tried :
try {
foodintervallist.clear();
final String result = response.body().string();
JSONObject jsonObject = new JSONObject(result);
String data = jsonObject.getString("data");
JSONArray foodintervalarray = new JSONArray(data);
HashMap<String, String> menuMap =
new HashMap<String, String>();
for (int j = 0; j < foodintervalarray.length(); j++) {
String key1 = "";
JSONObject jsonObject1 =
foodintervalarray.getJSONObject(j);
final String food_interval =
jsonObject1.getString(FOOD_INTERVAL);
if (jsonObject1.isNull(ITEM_NAME)) {
item_name = "";
} else {
item_name = jsonObject1.getString(ITEM_NAME);
}
if (!menuMap.containsKey(food_interval)) {
menuMap.put(food_interval, item_name);
} else {
String key = menuMap.get(food_interval);
key1=key+","+item_name;
menuMap.put(food_interval, key1);
}
runOnUiThread(new Runnable() {
#Override
public void run() {
foodintervallist.add(menuMap);
listViewAdapter = new ListViewAdapter(Diet_Order_Activity_New.this, foodintervallist);
listView.setAdapter(listViewAdapter);
listViewAdapter.notifyDataSetChanged();
}
});
}
My BaseAdapter class
#Override
public View getView(int position, View convertView, ViewGroup parent) {
inflater = (LayoutInflater)
activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.table_row, parent,
false);
resultp = fooditervallist.get(position);
txtFoodInterval = (TextView)
itemView.findViewById(R.id.foodInterval);
txtFoodItem = (TextView) itemView.findViewById(R.id.foodItems);
for (Map.Entry<String, String> entry : resultp.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
txtFoodInterval.setText(key);
Toast.makeText(activity, "" + key, Toast.LENGTH_LONG).show();
txtFoodItem.setText(value);
// do what you have to do here
// In your case, an other loop.
}
return itemView;
}
I am declaring the foodintervallist globally in my main activity class and also the listviewadapter i am initializing inside oncreate method
I am getting the data inside my arraylist , but i am able to display only the last item , what to do ?
Thanx
I would recommend to check your implementation of Adapter's getCount(). As it is not provided how it looks, I would looked there...
it should be like:
public int getCount (){ return fooditervallist.get(0).size() }
As you provide a list with only one item. Also I see there some issues in getView() :
fooditervallist.get(position); --> don't use position there, your list has always only one item therefore use 0 instead otherwise you'll get null pointer
your for loop is setting the txtFoodInterval and txtFoodItem with the all values in the Map.Set which might result in all list items having the same value ... instead of for loop you should use a "position" parameter here which is not possible with HashMap as order is not predicable. Use LinkedHashMap instead to have correct order and logic needs to be adjusted
Nevertheless I would implement it differently:
JSON parsing - I would create a new object model for holding the data
class FoodItem { int interval; String name; // getters and setters
here }
I would put these items in the list you put your map
In adapter you can then use this object quite easily like without any for loop like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
inflater = (LayoutInflater)
activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.table_row, parent, false);
FoodItem item = fooditervallist.get(position);
txtFoodInterval = (TextView) itemView.findViewById(R.id.foodInterval);
txtFoodItem = (TextView) itemView.findViewById(R.id.foodItems);
txtFoodInterval.setText(item.interval) ;
txtFoodItem.setText(item.name);
return itemView;
}
Also I would recommend to have a look on Retrofit library. It will make your life easier...
put your Hashmap inside the for loop. Because when you use globally the data will be overrided and you get only last item.
Put the below code outside the loop // set adapter outside the loop
listViewAdapter = new ListViewAdapter(Diet_Order_Activity_New.this,foodintervallist);
listView.setAdapter(listViewAdapter);
listViewAdapter.notifyDataSetChanged();
After a tremendous amount of time searching in here, and everywhere else I am hopeless to find a solution.
So here is my problem.
I have created a list-view and on top of that I added a search-bar.
When I use the search-bar, to filter the results... when I click on item 7, instead of opening the specific clicked activity i.e. 7, it always starts from the first one.
I am looking forward to your help guys; because I need it!
public class Group extends ListActivity {
// ArrayList thats going to hold the search results
ArrayList<HashMap<String, Object>> searchResults;
// ArrayList that will hold the original Data
ArrayList<HashMap<String, Object>> originalValues;
LayoutInflater inflater;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grouplist);
final EditText searchBox = (EditText) findViewById(R.id.searchBox);
ListView playersListView = (ListView) findViewById(android.R.id.list);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final EditText searchBox = (EditText) findViewById(R.id.searchBox);
ListView playersListView = (ListView) findViewById(android.R.id.list);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// these arrays are just the data that
// I'll be using to populate the ArrayList
String names[] = {/*list of names*/ };
String teams[] = {/*list of teams*/};
Integer[] photos = {R.drawable.... /*list of drawables*/};
Integer[] id ={/*Position*/};
originalValues = new ArrayList<HashMap<String, Object>>();
// temporary HashMap for populating the Items in the ListView
HashMap<String, Object> temp;
// total number of rows in the ListView
int noOfPlayers = names.length;
// now populate the ArrayList players
for (int i = 0; i < noOfPlayers; i++) {
temp = new HashMap<String, Object>();
temp.put("name", names[i]);
temp.put("team", teams[i]);
temp.put("photo", photos[i]);
temp.put("id", id[i]);
// add the row to the ArrayList
originalValues.add(temp);
}
// searchResults=OriginalValues initially
searchResults = new ArrayList<HashMap<String, Object>>(originalValues);
final CustomAdapter adapter = new CustomAdapter(this, R.layout.players, searchResults);
// finally,set the adapter to the default ListView
playersListView.setAdapter(adapter);
searchBox.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
// get the text in the EditText
String searchString = searchBox.getText().toString();
int textLength = searchString.length();
// clear the initial data set
searchResults.clear();
for (int i = 0; i < originalValues.size(); i++) {
String playerName = originalValues.get(i).get("name").toString();
if (textLength <= playerName.length()) {
// compare the String in EditText with Names in the
// ArrayList
if (searchString.equalsIgnoreCase(playerName.substring(0, textLength)))
searchResults.add(originalValues.get(i));
}
}
adapter.notifyDataSetChanged();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
}
});
// listening to single list item on click
playersListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int pos=Integer.ParseInt(searchResults.get(position).get("id").toString());
switch (pos) {
case 0:
Intent newActivity = new Intent(TeamsList.this, Barca.class);
startActivity(newActivity);
break;
case 1:
etc...
}
}
}
});
}
Custom adapter Class:
private class CustomAdapter extends ArrayAdapter<HashMap<String, Object>> {
public CustomAdapter(Context context, int textViewResourceId, ArrayList<HashMap<String, Object>> Strings) {
// let android do the initializing :)
super(context, textViewResourceId, Strings);
}
// class for caching the views in a row
private class ViewHolder {
ImageView photo;
TextView name, team;
}
ViewHolder viewHolder;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.players, null);
viewHolder = new ViewHolder();
// cache the views
viewHolder.photo = (ImageView) convertView.findViewById(R.id.photo);
viewHolder.name = (TextView) convertView.findViewById(R.id.name);
viewHolder.team = (TextView) convertView.findViewById(R.id.team);
//Take one textview in listview design named id
viewHolder.id = (TextView) convertView.findViewById(R.id.id);
// link the cached views to the convert view
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) convertView.getTag();
int photoId = (Integer) searchResults.get(position).get("photo");
// set the data to be displayed
viewHolder.photo.setImageDrawable(getResources().getDrawable(photoId));
viewHolder.name.setText(searchResults.get(position).get("name").toString());
viewHolder.team.setText(searchResults.get(position).get("team").toString());
viewHolder.id.setText(searchResults.get(position).get("id").toString());
// return the view to be displayed
return convertView;
}
}
}
I think you cant find correct position on listview item click. so u can use one textview with visibility="Gone" and insert the position in that textview in every row. now u can easily access position while clicking on item with the value of textview which shows perfect position. Hope it works. Thanx
The problem is that Adapter is populated once but with search results it gets overViewed by the searched items so on clicking it refers to the original items of list instead of the filtered list once , so we have to use the filtered lists' positions instead of the original one, i also faced this problem, try this:
In your listView.setOnItemClickListener
playersListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
//Object objFilteredItem = parent.getItemAtPosition(position);
//String a = searchResults.get(position);
switch (Integer.parseInt((String) adapter.getItem(position))) {
case 0:..
Intent newActivity = new Intent(TeamsList.this,Barca.class);
startActivity(newActivity);
break;
case 1:
etc...
break;
}
}
});
As from my previously answered question here, you have to override the getItem(position) method in your CustomAdapter. You are setting the onItemClick somewhat correctly but the list adapter doesn't know what exactly it's getting from getItem(position).
EDIT (details): You need to add something like this in your custom adapter -
#Override
public Object getItem(int position) {
return list.get(position);
}
You should already have the list in your custom adapter. If not, you can add a list reference to your CustomAdapter:
private ArrayList<HashMap<String, Object>> list;
Then setting it using a setter in your Group activity:
customAdapter.setList(searchResults);
I'm new to android, i've spent the last 2 days trying previous examples and online solutions but I just can't seem to get my head around it :(
I'm able to display a list view, parse some json from online and store a book title, book description and book ID and display this data in the listview. I want to be able to put a 'download' button in each row for the ListView, each button will correspond to its book ID on Click() and the action listener will download the book by appending that ID to a url.
e.g www.books.com/download_book1 or /download_book2....
Here is my code. Catalogue.java class
public class Catalogue extends ListActivity {
private JSONObject json;
private ListView lv;
private ArrayList<Integer> alKey = new ArrayList<Integer>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //icicle
setContentView(R.layout.shelflist);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
....
try{
JSONArray entries = json.getJSONArray("entries");
for(int i=0;i<entries.length();i++){
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = entries.getJSONObject(i);
alKey.add(e.getInt("key"));
map.put("id", String.valueOf(i));
map.put("title", "Title:" + e.getString("title"));
map.put("description", "Description: " + e.getString("description"));
mylist.add(map);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.shelfrow,
new String[] { "title", "description" },
new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
lv = getListView();
lv.setTextFilterEnabled(true);
.....
This is as far as I get. I don't know how to add 1 button per row in the List and assign an action listener to each button.
I also have a shelfrow.xml file (textView, textView for item_title and item_subtitle) and a shelflist.xml file (ListView).
I have a shelf.xml file with
Basically you need to learn the concept of ListAdapter.
Here's the short story: picture an object that holds the data to be displayed inside a list, along with the way to display each line individually. That's your ListAdapter. Now take each individual line: it's a book with a title and an OnClickListener. It's rendered inside a View with a TextView (for the title) and a Button (for the OnClickListener). All you need to do is give one View to the adapter that will be used for each line, and a List of the books you want to be inside the list.
Here's some sample code. I hope it clears things up a bit
private class MyItemModel{ //that's our book
String title; // the book's title
String description;
long id;
OnClickListener listener = new OnClickListener(){ // the book's action
#Override
public void onClick(View v) {
// the default action for all lines
doSomethingWithTheBookTitleOrUniqueId(this);
}
};
}
private class MyListAdapter extends BaseAdapter{
View renderer;
List<MyItemModel> items;
// call this one and pass it layoutInflater.inflate(R.layout.my_list_item)
public MyListAdapter(View renderer) {
this.renderer = renderer;
}
// whenever you need to set the list of items just use this method.
// call it when you have the data ready and want to display it
public void setModel(List<MyItemModel> items){
this.items = items;
notifyDataSetChanged();
}
#Override
public int getCount() {
return items!=null?items.size():0;
}
#Override
public Object getItem(int position) {
return items!=null?items.get(position):null;
}
#Override
public long getItemId(int position) {
return items!=null?items.get(position).id:-1;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView = renderer;
}
MyItemModel item = items.get(position);
// replace those R.ids by the ones inside your custom list_item layout.
TextView label = (TextView)convertView.findViewById(R.id.item_title);
label.setText(item.label);
Button button = (Button)convertView.findViewById(R.id.item_button);
button.setOnClickListener(item.listener);
return convertView;
}
}
In order to pass the List, instead of putting the data inside your list of hashmaps you can do this for instance (be careful, I also updated the MyItemModel and MyListAdapter to your need, added the id and description properties):
List<MyItemModel> myListModel = new ArrayList<MyItemModel>();
try{
JSONArray entries = json.getJSONArray("entries");
for(int i=0;i<entries.length();i++){
MyItemModel item = new MyItemModel();
JSONObject e = entries.getJSONObject(i);
alKey.add(e.getInt("key"));
item.id = i;
item.title = e.getString("title");
item.description = e.getString("description");
// you can change the button action at this point:
// item.onClickListener = new OnClickListener(){...};
myListModel.add(item);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new MyListAdapter(getLayoutInflater().inflate(R.layout.shelfrow, this));
adapter.setModel(myListModel);
setListAdapter(adapter);
lv = getListView();
lv.setTextFilterEnabled(true);
You can create your own class extending ArrayAdapter that will hold your list and set onClickListener to the Button in each row.
But in getView method of your ArrayAdapter you have to create a new view every time.
for example - row layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="110dp"
android:background="#FFF"
android:layout_width="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="2dp"
android:layout_height="110dp">
<TextView android:id="#+id/list_item_title"
android:background="#FFF"
android:layout_width="fill_parent"
android:layout_height="40dp"/>
<Button android:id="#+id/download_button"
android:gravity="center"
android:text="Download"
android:layout_height="35dp"/>
</LinearLayout>
</RelativeLayout>
and getView method in ArrayAdapter
private List<Map<String, String>> jsonMapList;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.list_item, null);
// here you set textview values (title and description)
// TextView title = (TextView) v.findViewById(R.id.list_item_title);
// title.setText('bla');
// and set OnClickListener
Button button = (Button) v.findViewById(R.id.download_button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
downloadFile(getUrl(position));
}
});
return v;
}
// method that downloads file
private void downloadFile(String url) {}
// get url from your list by index
private String getUrl(int index) {
return jsonMapList.get(index).get("url");
}
Usage of Map is unnecessary, you could use any object you prefer.
In activity class
CustomAdapter listAdapter = new CustomAdapter(this, android.R.layout.simple_list_item_single_choice, jsonMapList);
setListAdapter(listAdapter);