I have a listview which i want it for displaying a text and corrs image. I have used an arrayadapter for it. I am able to get an arraylist of hashmaps containing the values of the text and the url for the image.
<Arraylist<Hashmap<String,string>> testdata : "name" and "image_url"
Now i am trying to bind it. But no image is shown and the logcat shows resolveuri failed on bad bitmap.
( my url is "/com.example.vocab.MainActivity/res/drawable-hdpi/right_icon.png" ). What am i doing wrong? Thanx in advance for any help.
// Binding resources Array to ListAdapter
this.setListAdapter(new SimpleAdapter(Grammar_tab_all.this, testdata ,
R.layout.list_item, new String[] { "name","img_url"},
new int[] { R.id.module_name_item, R.id.img_recom}));
final ListView lv = getListView();
To show the drawable images in listview, best method is to store only the int id of drawable image.
Try this.
listItems = new ArrayList<HashMap<String,Integer>>();
String fieldName = "image_id";
HashMap<String, Integer> listData1 = new HashMap<String, Integer>();
HashMap<String, Integer> listData2 = new HashMap<String, Integer>();
listData1.put(fieldName, R.drawable.camera_icon_focus_dim);
listData2.put(fieldName, R.drawable.camera_icon_scene_mode);
listItems.add(listData1);
listItems.add(listData2);
SimpleAdapter listItemAdapter = new SimpleAdapter(
this,
listItems,
R.layout.image_list_item,
new String[] { fieldName },
new int[] { R.id.listitem_img });
Instead of this <Arraylist<Hashmap<String,string>> testdata try with this <Arraylist<Hashmap<String,Object>> testdata if you need more refer this link http://developerboards.att.lithium.com/t5/AT-T-Developer-Program-Blogs/Developing-Apps-for-Android-Beyond-quot-Hello-World-quot-Part-I/ba-p/28983/page/2
You have to use a custom list view :
check out this website
http://blog.sptechnolab.com/2011/02/01/android/android-custom-listview-items-and-adapters/
If you use images from android resources folder then you can use the
// get Drawable from resources folder
Resources res = context.getResources();
Drawable drawable = res.getDrawable( R.drawable.myImage );
ImageView mImageView.setImageDrawable( mDrawable );
// or
ImageView mImageView.setImageBitmap( mBitmap );
The ImageView is the one from your ListItems layout. I wrote for every ListView a own ListAdapter in which i inflate the special layout and set the data to the layout.
You need a custom listadapter if you want to have different images and this one is the best tutorial I have ever found on internet about this topic :)
Related
I'm creating a game and here's the code I'm using to show a list of games with the user names, score, date etc. But how do I get the values of the TextViews tv_playerScore and tv_opponentScore so I can compare them and change the textColors of them? Because what I want is to parseInt and see which has the highest value and set its textcolor to green, and the others textcolor to red.
private void showGames(JSONArray games) throws JSONException {
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < games.length(); i++) {
map.put("challenger", games.getJSONObject(i).getString("challengerName"));
map.put("active", games.getJSONObject(i).getString("active"));
map.put("opponent", games.getJSONObject(i).getString("opponentName"));
map.put("date", games.getJSONObject(i).getString("date"));
map.put("gameID", games.getJSONObject(i).getString("gameID"));
map.put("amount", games.getJSONObject(i).getString("amount"));
map.put("playerScore", games.getJSONObject(i).getString("challengerScore"));
map.put("opponentScore", games.getJSONObject(i).getString("opponentScore"));
if (Integer.parseInt(games.getJSONObject(i).getString("active")) == 2) {
mylist.add(map);
}
map = new HashMap<String, String>();
}
SimpleAdapter sadapter = new SimpleAdapter(this, mylist, R.layout.list, new String[]
{"amount", "active", "gameID", "challenger", "opponent", "date", "playerScore", "opponentScore"},
new int[] {R.id.tv_amount, R.id.tv_activte, R.id.tv_gameID, R.id.tv_player, R.id.tv_opponent, R.id.tv_date, R.id.tv_playerScore, R.id.tv_opponentScore});
listView.setAdapter(sadapter);
}
If you want to get the values of a textview must use findViewById function from Activity.
TextView tv_playerScore = (TextView) findViewById (R.id.tv_playerScore);
If the showGames() method is not a class that inherits from Activity (or similiar), you should make a setter injection of the elements of sight to those who want to access.
To compare:
tv_playerScore.getText().toString().compareTo(tv_opponentScore.getText().toString());
Finally, to change the color:
tv_playerScore.setTextColor(Color.CYAN);
Regards.
I think you should have a closer look in how ListViews work ( http://developer.android.com/resources/tutorials/views/hello-listview.html )
In short I guess you'll have to write your own Adpater class (e.g. extend SimpleAdapater) and write over its getView method. Here you can set the color of the textviews depending on the according value. (I think it would make sense to have them sorted before instead of checking them every time a list element is drawn...
public ArrayList<HashMap<String,String>> c_tmp= new ArrayList<HashMap<String,String>>();
public HashMap<String,String>mapa=new HashMap<String, String>();
String[] name_Val = null;
//i fill the map and the array list in a while()
mapa.put(numberz,nnn);
c_tmp.add(mapa);
and an error occurs( force close)when trying to fill the next line name_Val=....
name_Val = (String[]) c_tmp.toArray(new String[c_tmp.size()]);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,name_Val);
txtPhoneName.setAdapter(adapter);
/// am I writing that line wrong ( because i've copied it from ArrayList<String>)
You should try to do it first with a map and when you initialize it then to hash map, and use a simple adapter
mAdapter = new SimpleAdapter(this, peopleList, R.layout.row ,new String[]
{ "Name", "Phone" }, new int[] { R.id.text1, R.id.text2 });
txtPhoneName.setAdapter(mAdapter);
But before all in another function populate the list of people...
What I would suggest is, you can simply use a HashMap<String,String> Data type as map has the property of adding values for a unique key
After you are done with storing the Data in the hashmap you can use the Iterator to iterate and get all keys from the HashMap and thus the Values from all those keys which shall be Stored in an ArrayList , and then converting it to your String Array would not be a problem for you.
Is it possible to pass both strings and drawables as objects in the same HashMap, and then use this hashmap to populate a ListView via SimpleAdapter ?
I want this because I first get JSON data which also contains the URL to a thumbnail. Then I download this thumbnail. Relevant code (I think):
for (...) {
...
InputStream is = (InputStream)content;
Drawable image = Drawable.createFromStream(is, "src");
// Hashmap
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("title", new String(jsonObject.getString("Title")));
map.put("thumb", image);
mylist.add(map);
}
ListAdapter adapter = new SimpleAdapter(getActivity(), mylist, R.layout.listitem,
new String[] { "title", "thumb"},
new int[] { R.id.title, R.id.thumb });
setListAdapter(adapter);
R.id.title = TextView, and R.id.thumb = ImageView
This works for the title string, but not for the drawable. Is this approach just stupid?
Thanks in advance.
you should create a XML layout file for your row representation in the list and a custom adapter that inflate your row
As far as I can tell from the SimpleAdapter documentation, ImageViews are supported only for binding with a resource identifier or a String, which (the String, I mean) must represent an image resource or an image URI. It won't work if you pass it directly a Drawable object.
in my app i am using a list view. The data which i want to list out are from a database of my app and an xml server database.
For example i am getting some two set of data from server and store it in a array as follows
firstname = {arun, Arun, Rajesh}
lastname = {kumar, sundar, kannan}
Now again i am getting some data from my app database and store it in array as follows
first = {arul}
last = {raj}
Now i have combined the array list together as follows
firstname.addAll(first);
lastname.addAll(last);
Now i have the output as
{arun, Arun, Rajesh, arul}
{kumar, sundar, kannan, raj}
Now i want to list out these items as in the following image
how to do this, please help me......
If you finally get all your firstname and lastname in two separate array then it is very simple to display on ListView as you want
first create a layout which has a listview element lets us name main.xml
then create a another layout having two TextView in Horizontal layout orientation let us name mainitem.xml
so now you create a new activity then call setContentView(R.layout.main)
then retrive list view
and now create a adapter by following code
this code is in onCreate(Bundle b) method
ListView lv= (ListView)findViewById(R.id.listview1);
// create the grid item mapping
String[] from = new String[] {"col_1","col_2"};
int[] to = new int[] { R.id.firstname, R.id.secondname};
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i <firstname.length && lastname.length; i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("col_1",firstname[i]);
map.put("col_2",lastname[i]);
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.mainitem, from, to);
lv.setAdapter(adapter);
create mainitem.xml file having two TextView which id are 1)R.id.firstname, 2) R.id.lastname in layout horizontal orientation
Create a bean to store data
Example
public class NameDetails {
String firstName = null;
String middleName = null;
NameDetails(String firstName, String middleName){
this.firstName = firstName;
this.middleName=middleName;
}
String getFirstName(){
return firstName;
}
String getMiddleName(){
return middleName;
}
}
Add data to that bean using
NameDetails name1 = new NameDetails("arun","kumar");
..
...
Create array of Bean Objects. use this array for listview
{name1 , name2, name3, name4}
As per the snap you have attached in the question, you need to define the custom listview adapter for the same.
For defining a custom row with 2 columnar output, you need to define an xml layout file containing 2 textviews side by side. Don't be confused, just go through this example. In this example you need to modify the row layout file. Make a row file as such two textviews will be displayed side by side.
Are you looking for notifyDataSetChanged()?
I'm trying to put different images (.jpg , .png) dynamically into a ListView from res/drawable .
The names from the images I get from a database.
The images themselves are in the res/drawable folder.
This is what I already have, With an error of :D
String imgName; --> There are the img names I need from the database
Drawable drawable;
drawable = Class.appContext.getResources().getDrawable(Class.appContext.getResources().getIdentifier("com.example.test:drawable/"+imgName,null,null));
Then I get this into a ArrayList for every image in the database(+- 200 images):
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map = new HashMap<String, Object>();
map = new HashMap<String, Object>();
map.put("img",drawable);
map.put("text", "some text");
list.add(map);
Now I RETURN list;
In the Class where I call :
listReceive = Class.getImages(appContext);
listSetup = new SimpleAdapter(this, listReceive, R.layout.row,
new String[] {"img", "text"}, new int[] {R.id.IMG_CELL, R.id.TEXT_CELL});
lvList.setAdapter(listSetup);
XML row is an ImageView and a TextView.
System.out :resolveUri failed on bad
bitmap uri:
android.drawable.bitmapDrawable#405739
resolveUri failed on bad bitmap uri:
android.drawable.bitmapDrawable#405639
resolveUri failed on bad bitmap uri:
android.drawable.bitmapDrawable#405959
resolveUri failed on bad bitmap uri:
android.drawable.bitmapDrawable#405677...
... ...
I got it working when I saved images into local or SDcard memory, and then put the path inside the arraylist like:
map.put("img","/data/data/com.example.test/images/" + imgName);
I can't use this because then i will need to copy the pictures from res/drawable onto local or SD.This takes up 2 times the memory. can't have that of.
There must be a way to get images dynamically from the drawable.
Any one knows what I'm missing here?
Thanks.
The SimpleAdapter expects an integer or string that specifies a resource or image URI:
public void setViewImage (ImageView v, String value)
Since: API Level 1
Called by bindView() to set the image for an ImageView but only if there is no existing ViewBinder or if the existing ViewBinder cannot handle binding to an ImageView. By default, the value will be treated as an image resource. If the value cannot be used as an image resource, the value is used as an image Uri. This method is called instead of setViewImage(ImageView, int) if the supplied data is not an int or Integer.
I believe should use setViewBinder to provide a ViewBinder for the SimpleAdapter to handle binding the Drawable data to the ImageView. Basically, the setViewValue() method should return false unless it is called for your image view. When it is called for your image view, the method should set the data in the view and return true. The return value indicates whether the ViewBinder was able to set the view or whether the adapter should try to bind the data itself via its default behavior.
Maybe something like:
private final SimpleAdapter.ViewBinder mViewBinder =
new SimpleAdapter.ViewBinder() {
#Override
public boolean setViewValue(
final View view,
final Object data,
final String textRepresentation) {
if (view instanceof ImageView) {
((ImageView) view).setImageDrawable((Drawable) data);
return true;
}
return false;
}
};
...
listSetup .setViewBinder(mViewBinder);
I've done a similar thing with a SimpleCursorAdapter and its ViewBinder.
The simple adapter expects String in the map. But your map contains a drawable for the key "img".
Instead try extending the BaseAdapter class. Override the getView method and then manually set the drawable to the imageview and text to textview.
Another thought, it might not be a good idea to keep every drawable in memory. Rather get the drawable dynamically while rendering that particular row of the list
This following method or way also works - if anyone is still interested
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
Integer flags[] = new Integer[listdetail.size()];
Resources resources = getResources();
for (int i = 0; i < listdetail.size(); i += 2) {
listName = listdetail.get(i).getName();
int dynamicId = resources.getIdentifier(listdetail.get(i).getName().replaceAll(" ", "").toLowerCase(), "drawable", getActivity().getPackageName());
if(dynamicId == 0) {
dynamicId = R.drawable.test_image;
flags[i] = dynamicId;
}else {
flags[i] = dynamicId;
}
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("value1", listdetail.get(i).getName());
hm.put("valueImage1", Integer.toString(flags[i]));
list.add(hm);
}
String[] from = { "value1", "valueImage1"};
int[] to = { R.id.textview, R.id.imageView };
SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(), list, R.layout.listlayout, from, to);
ListView listView = (ListView) getActivity().findViewById(R.id.listview);
listView.setAdapter(adapter);