Get Hashmap item from custom adapter - android

May i know how to get HashMap item from a custom adapter
Code:
ArrayList<HashMap<String, String>> feeds_List;
...
...
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put("username", usr_name);
map.put("datetime", feed_date);
map.put("pts", point_txt);
map.put("pic", pic);
// adding HashList to ArrayList
feeds_List.add(map);
ListAdapter adapter = new ExtendedSimpleAdapter(
getActivity(), feeds_List,
R.layout.feed_item, new String[]{"username", "datetime", "pts"},
new int[]{R.id.usr_name, R.id.feed_time, R.id.no_stamp});
setListAdapter(adapter);
My Custom Adapter:
public class ExtendedSimpleAdapter extends SimpleAdapter{
Context context2;
public ExtendedSimpleAdapter(Context context, List<? extends Map<String, String>> data, int resource, String[] from, int[] to){
super(context, data, resource, from, to);
context2=context;
}
public View getView(int position, View convertView, ViewGroup parent){
// here you let SimpleAdapter built the view normally.
View v = super.getView(position, convertView, parent);
// Then we get reference for Picasso
ImageView img = (ImageView) v.getTag();
if(img == null){
img = (ImageView) v.findViewById(R.id.usr_pic);
v.setTag(img); // <<< THIS LINE !!!!
}
// get the url from the data you passed to the `Map`
String TAG_IMAGE="pic";
String url = ((Map)getItem(position)).get("pic");
// do Picasso
// maybe you could do that by using many ways to start
Picasso.with(context2)
.load(url)
//.resize(100, 100)
.into(img);
// return the view
return v;
}
}
Here is the problem:
I cannot get the url string in the custom adapter.
always getting errors of
"Incompatible types"(needed String, but found is object)
for this line
String url = ((Map)getItem(position)).get("pic");

The object you are casting against, should have the exact type. Casting to the generic Map doesn't enforce the compile time check, that the generics are meant for.
String url = ((Map<String, String>)getItem(position)).get("pic");

Use
private ArrayList<Map<String, String>> data;
Map<String, String> category = new Map<String, String>();
category = data.get(position);
String url=category.get("pic");

Simply change this
String url = ((Map)getItem(position)).get("pic");
to
String url = list.get(position).get("pic");
Also here
Context context2;
List<HashMap<String, String>> list;
public ExtendedSimpleAdapter(Context context, List<HashMap<String, String>> data, int resource, String[] from, int[] to){
super(context, data, resource, from, to);
context2=context;
this.list = data;
}

Related

Android Picasso 2.5.2, showing images from adapter inside listivew. With async task

I would like to use Picasso library to download and show images that are in URL's inside JSON data from my server.
I've lost all hope, I saw something about custom adapter but to no avail.
I need help here.
Here's how I do stuff now to show data from json inside onPostExecute:
protected void onPostExecute(JSONObject objdanejson){
pDialog.dismiss();
try {
android = objdanejson.getJSONArray(TAG_ZAWARTOSC);
for(int i = 0; i < android.length(); i++){
JSONObject c = android.getJSONObject(i);
final String akt_tytul = c.getString(TAG_TYTUL);
final String akt_skrot = c.getString(TAG_SKROT);
final String akt_tresc = c.getString(TAG_TRESC);
final String akt_id = c.getString(TAG_ID);
final String akt_IMG = c.getString(TAG_IMG);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TYTUL, akt_tytul);
map.put(TAG_SKROT, akt_skrot);
map.put(TAG_ID, akt_id);
map.put(TAG_TRESC, akt_tresc);
map.put("http://www.apirest.poligon.webimpuls.pl/"+TAG_IMG, akt_IMG);
oslist.add(map);
lista_aktualnosci = (ListView)findViewById(R.id.lista_aktualnosci);
final ListAdapter adapter = new SimpleAdapter(aktualnosci.this, oslist,
R.layout.aktualnosc_item,
new String[]{TAG_TYTUL, TAG_SKROT, TAG_IMG}, new int[]{R.id.aktTytul, R.id.aktSkrot, R.id.aktIMG});
lista_aktualnosci.setAdapter(adapter);
lista_aktualnosci.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(aktualnosci.this, "Kliknąłeś na " + oslist.get(+position).get("akt_tytul"),Toast.LENGTH_SHORT).show();
Intent czytaj = new Intent(aktualnosci.this, aktualnosc_czytaj.class);
czytaj.putExtra("tytuł",oslist.get(+position).get("akt_tytul"));
czytaj.putExtra("tresc",oslist.get(+position).get("akt_tresc"));
czytaj.putExtra("id",oslist.get(+position).get("akt_id"));
startActivity(czytaj);
}
});
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
EDIT:
How my custom controler looks:
oslist.add(map);
lista_aktualnosci = (ListView)findViewById(R.id.lista_aktualnosci);
/* final ListAdapter adapter = new SimpleAdapter(aktualnosci.this, oslist,
R.layout.aktualnosc_item,
new String[]{TAG_TYTUL, TAG_SKROT}, new int[]{R.id.aktTytul, R.id.aktSkrot});
*/
class ListAdapter extends ArrayAdapter<ClipData.Item> {
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public ListAdapter(Context context, int resource, List<ClipData.Item> items) {
super(context, resource, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.aktualnosc_item, null);
}
ClipData.Item p = getItem(position);
if (p != null) {
aktTytul = (TextView)findViewById(R.id.aktTytul);
aktSkrot = (TextView)findViewById(R.id.aktSkrot);
aktIMG = (ImageView)findViewById(R.id.aktIMG);
}
return v;
}
}
lista_aktualnosci.setAdapter(adapter);
Create a class that extends Simple Adapter or Base Adapter. In getView() the adapter will ask you to create a list item when this is needed. As you create the item you can use Picasso to display the image in whatever image view you've selected for this purpose.
That being said you should ditch ListView and use RecyclerView instead - for which you can find all the information you need here
Other stuff that may improve your code are things like Retrofit and Gson.
Does that help?
you can get your image from listview. You can this code your activity after set adapter then you can set your imageview.
for(int i = 0; i < this.listView.getChildCount(); i ++) {
View view = this.listView.getChildAt(i);
ImageView img= (ImageView)view.findViewById(R.id.yourimage);
//do something your image
}

How to Show Dynamic Data in LazyList or Universal Image Loader?

I'm testing both LazyList (LL) and Universal Image Loader (UIL) that I found here. Also I have successfully made some modifications to retrieve the URL's to load from a JSON document. The JSON is from Flickr. I got the url (for obtain photos) and more data like title, description and author from JSON. Before using these image loading tools I passed data to the view with a SimpleAdapter like this:
// Hashmap for ListView
ArrayList<HashMap<String, String>> itemsList = new ArrayList<HashMap<String, String>>();
Then some code to put JSON DATA into itemsList, then
ListAdapter adapter = new SimpleAdapter(this, itemsList,
R.layout.item,
new String[] { TAG_TITLE, TAG_DESCRIPTION, TAG_AUTHOR }, new int[] {
R.id.title, R.id.description, R.id.author });
setListAdapter(adapter);
// selecting single ListView item
ListView list = getListView();
// Launching new screen on Selecting Single ListItem
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String title = ((TextView) view.findViewById(R.id.title)).getText().toString();
String description = ((TextView) view.findViewById(R.id.description)).getText().toString();
String author = ((TextView) view.findViewById(R.id.author)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(TAG_TITLE, title);
in.putExtra(TAG_DESCRIPTION, description);
in.putExtra(TAG_AUTHOR, author);
startActivity(in);
}
});
Following this guide. Now that I tried to merged my code with LL or UIL I can't make it work.
Those image loaders uses their own adapter with a GetWiew method. So finally here's the question:
How do I pass my own dynamic data to their adapters?
To make it more clear, I want to show info like title, description and author at the right side of the photo instead of "item X" from picture bellow:
Use custom adapter:
public class MySimpleAdapter extends SimpleAdapter {
private List<String> mImageUrls;
public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, List<String> imageUrls, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
mImageUrls = imageUrls;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
ImageView imageView = view.findViewById(R.id.my_image);
ImageLoader.getInstance().displayImage(mImageUrls.get(position), imageView);
return view;
}
}
And pass imageUrls to constructor.

Android custom SimpleAdapter

I'm trying this example for creating a simpleAdapter for a ListView. So, I got all created but when I change this line
List<Movie> movies = getData2();
ListAdapter adapter = new MovieListAdapter(this, movies, android.R.layout.simple_list_item_2, new String[]{Movie.KEY_NAME, Movie.KEY_YEAR}, new int[]{android.R.id.text1, android.R.id.text2});
I got this error:
The constructor is undefined
MovieListAdapter(ImdbApiActivity, List<Movie>, int, String[], int[])
It's the same example, I've just changed Cars for Movies. I know that this example is from 2009, my target is 2.1 on my project. Is there a incompatibility between versions or is there an error?
My simpleadapter class looks like this:
public class MovieListAdapter extends SimpleAdapter {
private List < Movie > movies;
private int[] colors = new int[] {
0x30ffffff, 0x30808080
};
#SuppressWarnings("unchecked")
public MovieListAdapter(Context context, List <? extends Map < String, String >> movies,
int resource,
String[] from,
int[] to) {
super(context, movies, resource, from, to);
this.movies = (List < Movie > ) movies;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
int colorPos = position % colors.length;
view.setBackgroundColor(colors[colorPos]);
return view;
}
}
Is there an error i'm missing? which is the "modern" way to achieve this?
Edit: Neither changing the context parameter or the List worked for this example. My Movie class extends from Hashmap. Any other idea? thanks!
import java.util.HashMap;
public class Movie extends HashMap {
public String year;
public String name;
public static String KEY_YEAR = "year";
public static String KEY_NAME = "name";
public Movie(String name, String year) {
this.year = year;
this.name = name;
}
#Override
public String get(Object k) {
String key = (String) k;
if (KEY_YEAR.equals(key))
return year;
else if (KEY_NAME.equals(key))
return name;
return null;
}
}
It seems to be problem in the parameter of your custom adapter class constructor.
You have defined it as List<? extends Map<String, String>> movies where you are passing List<Movies> object from the activity.That is why it is telling you,such constructor is not defined.
Try changing parameter of constuctor to List<Movies> movies,that would resolve your problem,i think!
Try changing
`ListAdapter adapter = new MovieListAdapter(this, movies, android.R.layout.simple_list_item_2, new String[]{Movie.KEY_NAME, Movie.KEY_YEAR}, new int[]{android.R.id.text1, android.R.id.text2});`
to
`ListAdapter adapter = new MovieListAdapter(YourClass.this, movies, android.R.layout.simple_list_item_2, new String[]{Movie.KEY_NAME, Movie.KEY_YEAR}, new int[]{android.R.id.text1, android.R.id.text2});`
because this may be referencing to the different instance.
YourClass.this is a reference to an instance of the YourClass.class. You can also send context returned by getApplicationContext()

Android passing image to a ListView containing an ImageView

I'm creating a ListView that contains two TextViews and an ImageView.
I'm passing data to my SimpleAdapter using a Hashmap, so I convert the ids of the images to a string and then later in the SimpleAdapter I convert them back to integers to set the image resource.
However that doesn't seem to work.
The relevant code is:
The oncreate of my activity
clubImages = new Integer[] {
R.drawable.pic1, R.drawable.pic2,
R.drawable.pic3, R.drawable.pic4,
R.drawable.pic5
};
ListView lv = (ListView)findViewById(android.R.id.list);
// create the grid item mapping
String[] from = new String[] {"image"};
int[] to = new int[] {R.id.club_image};
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < eventTitles.length; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("image", getString(clubImages[i]));
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new MySimpleAdapter(this, fillMaps, R.layout.eventview_row, from, to);
lv.setAdapter(adapter);
the simpleadapter class
public class MySimpleAdapter extends SimpleAdapter {
private List<HashMap<String, String>> results;
public MySimpleAdapter(Context context, List<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.results = data;
}
public View getView(int position, View view, ViewGroup parent){
Typeface type = Typeface.createFromAsset(getAssets(), "fonts/aircruiser.ttf");
View v = view;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.eventview_row, null);
}
mClubImageImageView = (ImageView) v.findViewById(R.id.club_image);
int ClubImageHelper = Integer.parseInt(results.get(position).get("image").toString());
mClubImageImageView.setImageResource(ClubImageHelper);
return v;
}
}
The error in my logcat
E/AndroidRuntime(19406): java.lang.NumberFormatException: unable to parse 'res/drawable-hdpi/pic1.png' as integer
You can't pass R.drawable.pic1 as a String and then parse it back as an Integer. This will not work, instead simply pass the initial Integer drawable ids directly in the HashMap:
List<HashMap<String, Integer>> fillMaps = new ArrayList<HashMap<String, Integer>>();
for(int i = 0; i < eventTitles.length; i++){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("image", clubImages[i]);
fillMaps.add(map);
}
I hope I understand what you want. You could make a class to hold the data that you want to pass in to the adapter, for example:
class DataObject {
int imageId;
String firstString;
String secondString; // add here any string that you want to put in your list
public DataObject(String firstString, String secondString, int imageId) {
this.imageId = imageId;
this.firstString = firstString;
this.secondString = secondString;
}
}
Then construct the list for the adapter:
List<HashMap<String, DataObject>> fillMaps = new ArrayList<HashMap<String, DataObject>>();
for(int i = 0; i < eventTitles.length; i++){
HashMap<String, DataObject> map = new HashMap<String, DataObject>();
map.put("image", new DataObject("First String", "second String", clubImages[i]));
fillMaps.add(map);
}
In the getView() method retrieve the DataObject and use its content data as you please.
here is an good example that may help you

Android: ListView with complex data model

I'd like to map an Array of "complex" data to a ListView. In a very simplified form my data model would look like something like this:
class ListPlacesValues {
String idObject;
String name;
String city;
String country;
ArrayList<String> classification;
double distance_quantity;
DistanceUnit distance_unit;
[...more stuff ...]
}
I know that I can convert my complex data into a HashList and then just use a SimpleAdapter:
SimpleAdapter mAdapter = new SimpleAdapter(
this,
hashList,
R.layout.places_listitem,
new String[] { "name", "city", "country"},
new int[] { R.id.name, R.id.city, R.id.country}
);
However, I would rather use my data model directly, but I've no idea where and how to start, so that in the end I can do something like this:
ArrayList<ListPlacesValues> values = getData();
MyAdapter mAdapter = new MyAdapter(
this,
values,
R.layout.places_listitem,
ListPlacesValues { values.name, values.city, values.country},
new int[] { R.id.name, R.id.city, R.id.country}
);
Solution: I found this Android API sample (List14), which was really helpful.
You can extend ArrayAdapter. Here's code example for you. In this example - SearchItem is some custom POJO. Basically you need to override getView() method to build your row by inflating row layout and then populating values based on List of items and current position
class SearchItemsAdapter extends ArrayAdapter<SearchItem> {
Activity context;
List<SearchItem> items;
SearchHeader header;
#SuppressWarnings("unchecked")
public SearchItemsAdapter(final Activity context,
final Map<SearchHeader, List<SearchItem>> result) {
super(context, R.layout.item, (List) ((Object[]) result.values()
.toArray())[0]);
this.context = context;
this.header = result.keySet().iterator().next();
this.items = result.get(this.header);
}
#Override
public View getView(final int position, final View convertView,
final ViewGroup parent) {
final View view = this.context.getLayoutInflater().inflate(
R.layout.item, null);
final SearchItem item = this.items.get(position);
((TextView) view.findViewById(R.id.jt)).setText(item.jt);
((TextView) view.findViewById(R.id.dp)).setText(item.dp);
((TextView) view.findViewById(R.id.cn)).setText(item.cn);
((TextView) view.findViewById(R.id.loc)).setText(item.loc.name);
final TextView body = ((TextView) view.findViewById(R.id.e));
body.setText(item.e);
body.setTag(item.src[0]);
((TextView) view.findViewById(R.id.src)).setText(item.src[1]);
return view;
}
}
There is one pitfall with the convertView in the sample you linked
if(convertView != null){ //reuse
convertView.setAnimation(null);
convertView.setAnyCustomFieldsIdontWantFilledWithData(null);
}
you want to set all animations or unused fields to null otherwise your items might have data in them or animations pending you dont want.

Categories

Resources