Custom SimpleAdapter only shows Sample Text Android - java

Before making my own SimpleAdapter object because I wanted to change the color of the rows, I was just using new SimpleAdapter(...). Now that I am using my own custom SimpleAdapter, the row color is changing, but my text is not getting updated. I have called adapter.notifyDataSetChanged(), but it is still showing only the sample text- "TextView". As I said, everything was working fine when I didn't create my own adapter. I suspect it might have something to do with the order I am initializing things:
public class AddScreen extends Activity implements OnClickListener,
OnItemClickListener, OnItemLongClickListener {
SimpleAdapter adapter;
List<HashMap<String, String>> painItems = new ArrayList<HashMap<String, String>>();
ListView listthings;
int[] to;
String[] from;
public void onCreate(Bundle savedInstanceState) {
...
listthings = (ListView) findViewById(R.id.listthings);
from = new String[] { "row_1", "row_2" };
to = new int[] { R.id.row1, R.id.row2 };
adapter = new Adapter(this, painItems, R.layout.mylistlayout,
from, to);
listthings.setAdapter(adapter);
...
}
public class Adapter extends SimpleAdapter{
HashMap<String, String> map = new HashMap<String, String>();
public Adapter(Context context, List<? extends Map<String, String>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View row = convertView;
if (row == null) {
LayoutInflater mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = mInflater.inflate(R.layout.mylistlayout, parent, false);
}
row.setBackgroundColor(0xFF0000FF);
TextView rw1 = (TextView)findViewById(R.id.row1);
// TextView rw2 = (TextView)findViewById(R.id.row2);
rw1.setText(map.get(position));
return row;
}
}
// to add the item, put it in the map, and add the map into the list
private void addItem() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("row_1", row1);
map.put("row_2", row2);
map.put("row_3", painLevelString);
map.put("row_4", painLocation);
map.put("row_5", timeOfPainString);
map.put("row_6",textTreatmentString);
painItems.add(map);
adapter.notifyDataSetChanged();
}
EDIT:Added Code
This is how I am getting the data from the intent(onActivityResult()), placed before the addItem Code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == 1) {
row1 = data.getStringExtra("com.painLogger.row1");
row2 = data.getStringExtra("com.painLogger.row2");
painLevelString = data.getStringExtra("com.painLogger.painLevel");
painLocation = data.getStringExtra("painLocation");
timeOfPainString = data.getStringExtra("com.painLogger.painTime");
textTreatmentString = data
.getStringExtra("com.painLogger.treatment");
addItem();
}
}
*Also, just in case this is relevant the order of placement is this: onCreate() -> custom Adapter class -> onActivityResult() -> addItem()* **
Here is a screenshot of what it looks like. The two TextView fields in each item should be filled with info(which they were, until I did this).

If it worked previously with just using new SimpleAdapter(...) then in your getView(...) implementation change the first line to this:
View row = super.getView(position, convertView, parent);
And see if that is what you're expecting. Take out the LayoutInflater stuff too.

In getView(), about where you are setting the row background, you should also set the text for the TextView.
Calling notifyDataSetChanged(), doesn't automagically set your texts right, it just causes the ListView to redraw the visible rows with the new data...practically calling getView() for each row that needs a refresh.
I also suggest setting the background color from the mylistlayout.xml file, and if the getView() function starts taking on a few findViewByID's, you should also consider using a "view holder" approach like in this sample: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

You need to set the text in getView(). Like this:
public View getView(int position, View convertView, ViewGroup parent){
TextView text;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.mylistlayout, parent, false);
text = (TextView) convertView.findViewById(R.id.more_list_text);
}
convertView.setBackgroundColor(0xFF0000FF);
text.setText(map.get(position));
return convertView;
}
Also, and this is VERY important - store you map as a member variable of the SimpleAdapter
ie, put this line at the top of your object definition:
HashMap<String, String> map = new HashMap<String, String>();

Related

Listview not populated after onPostExecute

I am running into some difficulty with populating values to a listview, which currently displays no rows.
Firstly I am retrieving values from my database table and storing them in Arrays within onPostExecute.
LikedListAdapter listAdapter = new LikedListAdapter(context, R.layout.liked_list_main, restID, restName, restAddr1, restAddr2, restImgPath);
lvPlaces.setAdapter(listAdapter);
These values are then successfully passed into my ListAdapter.
public LikedListAdapter(Context context, int resource, String[] restID, String[] restName, String[] restAddr1, String[] restAddr2, String[] restImgPath) {
super(context, resource);
this.context = context;
this.resource = resource;
this.restID = restID;
this.restName = restName;
this.restAddr1 = restAddr1;
this.restAddr2 = restAddr2;
this.restImgPath = restImgPath;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout likedItemsView;
if(convertView==null) {
likedItemsView = new LinearLayout(getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater vi;
vi = (LayoutInflater)getContext().getSystemService(inflater);
vi.inflate(resource, likedItemsView, true);
}
else {
likedItemsView = (LinearLayout) convertView;
}
ImageView restaurantImg = (ImageView)likedItemsView.findViewById(R.id.listItemThumbImg);
TextView restaurantName =(TextView)likedItemsView.findViewById(R.id.listItemTitle);
TextView restaurantDesc = (TextView)likedItemsView.findViewById(R.id.listItemSubText);
restaurantName.setText(restName[position]);
restaurantDesc.setText(restAddr1[position] + ", " + restAddr2[position]);
Picasso
.with(getContext())
.load(restImgPath[position])
.into(restaurantImg);
return likedItemsView;
}
However, when i run the app the Listview is empty. When debugging i notice that the values are successfully passed to my listAdapter (on debugging it displays the values retrieved being displayed in the constructor) however it never hits the method getView, where values are set to each listview widget.
Is there something i am misunderstanding, or do i need to call the getView method at some point? Thanks in advance.
Did you override
getCount()
method? If not then return the size of your rows. Ex-
#Override
public int getCount() {
return restName.length;
}
Hope your problem will be solved. If already populated list then use
adapter.notifyDataSetChanged()
method.
LikedListAdapter listAdapter = new LikedListAdapter(context, R.layout.liked_list_main, restID, restName, restAddr1, restAddr2, restImgPath);
lvPlaces.setAdapter(listAdapter);
listAdapater.notifyDataSetChanged(); // <-- add this

ListView with images only

I was just asking myself if there was a way of making a ListView without any texts. I've only found ListViews with images + texts, and that exactly what i dont want. I just want to add a lot of images like in a list and don't want to make it with ImageView because that makes my app crash. Also, i dont want my app to lag. Thanks!
this is what i got in my activity_main.xml
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
and i found this from another post that actually helped me, but it doesnt display all images
public class MainActivity extends Activity {
// Array of integers points to images stored in /res/drawable-hdpi/
int[] vehs = new int[]{
R.drawable.veh1,
R.drawable.veh2,
R.drawable.veh3,
R.drawable.veh4,
R.drawable.veh5,
R.drawable.veh6,
R.drawable.veh7,
R.drawable.veh8,
R.drawable.veh9,
R.drawable.veh10,
R.drawable.veh11,
R.drawable.veh12,
R.drawable.veh13,
R.drawable.veh14,
R.drawable.veh15,
R.drawable.veh16,
R.drawable.veh17,
R.drawable.veh18,
R.drawable.veh19,
R.drawable.veh20,
R.drawable.veh21,
R.drawable.veh22,
R.drawable.veh23,
R.drawable.veh24,
R.drawable.veh25,
R.drawable.veh26,
R.drawable.veh27,
R.drawable.veh28,
R.drawable.veh29,
R.drawable.veh30,
R.drawable.veh31,
R.drawable.veh32,
R.drawable.veh33,
R.drawable.veh34,
R.drawable.veh35,
R.drawable.veh36,
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Each row in the list stores country name, currency and flag
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(int i=0;i<10;i++){
HashMap<String, String> hm = new HashMap<String,String>();
hm.put("vehs", Integer.toString(vehs[i]) );
aList.add(hm);
}
// Keys used in Hashmap
String[] from = { "vehs","txt","cur" };
// Ids of views in listview_layout
int[] to = { R.id.vehs,R.id.txt,R.id.cur};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to);
// Getting a reference to listview of main.xml layout file
ListView listView = ( ListView ) findViewById(R.id.listview);
// Setting the adapter to the listView
listView.setAdapter(adapter);
}
}
Didn't edit all the code, so you might find some things confusing xD
The way ListView displays data is by using an adapter. The adapter takes your data, inserts it into a custom view, and then adds it to the list.
To build a fast images ListView, the first thing you'd want to do is to add Picasso to your project. This library will automatically download and cache your images, handle ImageView recycling, and more.
The next thing you'd want to do is to write your item view. If you want an images-only list, the view could be as simple as:
<!-- res/layout/list_item.xml -->
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight" />
Next, you want to create your adapter. It accepts a List<String> of image URLs as an input, builds the items and inserts them to the ListView.
public class ImageListAdapter extends ArrayAdapter<String> {
List<String> items;
public ImageListAdapter(Context context, int resource, List<String> items) {
super(context, resource, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_item, null);
}
Picasso.with(getContext())
.load(items.get(position))
.into((ImageView) convertView);
return convertView;
}
}
Read the Picasso library documentation if you want to add more options such as image placeholders, transformations, and more.
Finally, to use the adapter on your ListView, add this to your activity's onCreate method:
List<String> images = new ArrayList<String>();
images.add("http://hometowncolumbia.files.wordpress.com/2007/12/lol-cats-dont-look-behind-cat.jpg");
images.add("http://i232.photobucket.com/albums/ee245/topswing/cat-lol.jpg");
listView = (ListView)findViewById(R.id.myListView);
listView.setAdapter(new ImageListAdapter(this, R.layout.list_item, images))
In a real application though, you'd probably want to load the image list from your server. You'd need to use an AsyncTask for that.
Don't make things difficult, the solution is simple in the classic 3 steps
Step 1:
Make a RelativeLayout in XML. Move the image to desired position (always to center, but you can choose if left or right) and change layout_height to wrap_content
Step 2:
Create a custom adapter for ListView, if you do this, you'll be able to all any layout as an item
public class ImagesAdapter extends ArrayAdapter<String> {
private Activity mContext;
private ArrayList<Bitmap> mImages;
public ImagesAdapter(Activity context, ArrayList<String> listOfValues, ArrayList<Bitmap> images) {
//The listOfValues is used when you make item click to get value
//Each image must to have a text value
super(context, R.layout.yourlayout, listOfValues);
mContext = context;
mImages = images;
}
#Override
public void getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = mContext.getLayoutInflater();
View returnView = inflater.inflate(R.layout.yourlayout, null);
ImageView imageView = (ImageView) returnView.findViewById(R.id.yourimageid);
imageView.setImageBitmap(mImages.get(position));
return returnView;
}
}
Step 3:
Implement in your code
ImagesAdapter adapter = new ImagesAdapter(this, myList, myImages);
mylistView.setAdapter(adapter);
myListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//volov = Values Of ListOfValues
String volov = (String) myListView.getItemPosition(position);
Log.i(TAG, "listOfValues is useful " + volov);
}
});

Set list view height without TextView with adapter

I have a ListView which is supposed to become a menu with two drawables and two text views per row.
Activity Code:
ArrayList<MenuItem> itemArray = new ArrayList<MenuItem>();
itemArray.add(new MenuItem("Headertexxt", "subbtexdt"));
itemArray.add(new MenuItem("asf", "asf"));
ListView listView = (ListView) findViewById(R.id.listViewCM);
String[] array = getResources().getStringArray(R.array.buttonsCM);
int[] images = new int[] { R.drawable.btn_car, R.drawable.btn_star, R.drawable.btn_bag};
listView.setAdapter(new HomeScreenButtonsAdapterSubtext(this, R.layout.row,
itemArray, images, R.drawable.list_arrow));
Utils.setListViewHeightBasedOnChildren(listView);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
findViewById(R.id.buttonCreditCompilation).performClick();
break;
case 1:
findViewById(R.id.buttonYourCredits).performClick();
break;
}
}
});
Adapter code:
public class HomeScreenButtonsAdapterSubtext extends ArrayAdapter<MenuItem> {
private Drawable[] drawables;
private Drawable arrowDrawable;
private ArrayList<MenuItem> items;
public HomeScreenButtonsAdapterSubtext(Context context, int resourceId,
ArrayList<MenuItem> items, int[] images, int arrowImage) {
super(context, resourceId, items);
this.items = items;
Resources resources = context.getResources();
if (images != null) {
drawables = new Drawable[images.length];
int i = 0;
for (int id : images) {
Drawable drawable = resources.getDrawable(id);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
drawables[i++] = drawable;
}
}
arrowDrawable = resources.getDrawable(arrowImage);
arrowDrawable.setBounds(0, 0, arrowDrawable.getIntrinsicWidth(),
arrowDrawable.getIntrinsicHeight());
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (v instanceof TextView) {
Drawable dr = drawables != null ? drawables[position %
drawables.length] : null;
((TextView) v).setCompoundDrawables(dr, null, arrowDrawable, null);
Utils.setFont((TextView) v);
}
// View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
MenuItem station = items.get(position);
if (station != null) {
TextView tt = (TextView) v.findViewById(R.id.headerText);
TextView bt = (TextView) v.findViewById(R.id.subText);
if (tt != null) {
tt.setText(station.getHeaderText());
}
if (bt != null) {
bt.setText(station.getSubText());
}
}
return v;
}
The problem I have right now is that I can't set the listview height based on the children. I'm trying to do that here: Utils.setListViewHeightBasedOnChildren(listView); but getting the error: arrayadapter requires the resource id to be a textview at this row. Does anyone know a solution for this?
Can I use some other method for setting the ListView height?
Thanks
but getting the error: arrayadapter requires the resource id to be a
textview at this row.
R.layout.row is a layout file which it doesn't have just a TextView. If you call the super constructor you have used and you also call the super.getView(in the getView method) method in the adapter, then ArrayAdapter will complain as it expects a single widget in the layout file passed to it(a single TextView).
I don't understand why you have that piece of code in the getView method(with the super call) when you know precisely that the row can't be an instance of Textview .
I'm not sure about setting the height of the ListView either, if you're trying to show all the rows of the ListView, don't do it(as you make the ListView basically useless). If you still want to do this, then it's better to lose the ListView and build the row layouts manually.
In fact it does not really make sense to set the height of ListView depending on its content.
Because the whole point of a ListView is to make its content scrollable (however big it is)...so it is supposed to have a fixed height.

Bitmap in listview doesn't work [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I do a lazy load of images in ListView
i have listview with bitmap and text. When i download picture and i want to view it, it not appears in my app. When i used image from R.drawable.imagename then it works...
My code:
List<HashMap<String, Object> > aList = new ArrayList<HashMap<String, Object> >();
for(int i=0;i<ilosctalentow.size();i++){
if (ilosctalentow.get(i).indexOf("0/")==-1)
{
HashMap<String, Object> hm = new HashMap<String,Object>();
hm.put("txt", "xxx");
hm.put("cur","Currency : " + ilosctalentow.get(i));
Bitmap bmp = DownloadImage("http://www.xxx.pl/xxx/xxx/xhxuxj.png");
hm.put("flag",bmp);
aList.add(hm);
Log.i(TAG,Integer.toString(R.drawable.afghanistan) );
}
}
// Keys used in Hashmap
String[] from = { "flag","txt","cur" };
// Ids of views in listview_layout
int[] to = { R.id.flag,R.id.txt,R.id.cur};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to);
// Getting a reference to listview of main.xml layout file
ListView listView = ( ListView ) findViewById(R.id.listview);
// Setting the adapter to the listView Zaraz mnie huj strzeli
listView.setAdapter(adapter);
Please help!
I think I can post a link to another question as an answer and explain how to apply it to your current solution.
Lazy load of images in ListView
When your application starts, display a simple list without images. Then start a background thread which downloads and creates bitmaps. When the thread completes its job - update the list so that it displays loaded images.
To make this work, you should create a custom adapter. Take the DrawableManager class from this answer (because the class from the accepted answer contains some bugs) and write the adapter like this:
// You should create your own class instead of TestItem
public class TestAdapter extends ArrayAdapter<TestItem> {
private final LayoutInflater mInflater;
private final DrawableBackgroundDownloader mDrawableBackgroundDownloader = new DrawableBackgroundDownloader();
public TestAdapter(Context context, List<TestItem> objects) {
super(context, -1, objects);
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final TestItem item = this.getItem(position);
View view = convertView == null
? mInflater.inflate(R.layout.listview_layout, null)
: convertView;
TextView txtView = (TextView) view.findViewById(R.id.txt);
TextView curView = (TextView) view.findViewById(R.id.cur);
ImageView flagView = (ImageView) view.findViewById(R.id.flag);
txtView.setText(item.getText());
curView.setText(item.getCurrency());
mDrawableBackgroundDownloader.loadDrawable(item.getFlagUrl(), flagView, null);
return view;
}
}
This adapter can be improved by storing found elements in a view bag or using different class for downloading and caching of images. But I will leave it as it is for the sake of simplicity.

Custom ArrayAdapter not displaying results

This one has me quite stumped. I'm sure it is just something simple I am missing, but I cant seem to find out what...
When I run the program, it opens up the dialog box and displays the AutoCompleteTextView I have initialized. When I try to type something into it, nothing drops down or is displayed other than the text I type in. I have created a similar system in another part of my program with the same mechanics, but using a regular ArrayAdapter and it works fine so the interface is not the problem.
Here is where I initialize my custom ArrayList. I have been trying to use just strings to make it simpler.
final Dialog weaponDialog = new Dialog(BattleScreen.this);
weaponDialog.setContentView(R.layout.weapon_selection_dialog);
weaponDialog.setTitle("Add a Weapon");
weaponDialog.setCancelable(true);
String[] weaponStringArrayList = ConstantEquipmentHelper.getCondensedWeaponString();
WeaponArrayAdapter weaponAdapter = new WeaponArrayAdapter(this, R.layout.weapon_list_item, weaponStringArrayList);
weaponDialogAcTextView = (AutoCompleteTextView) weaponDialog.findViewById(R.id.weaponSelectionAutoCompleteTxt);
weaponDialogAddButton = (Button) weaponDialog.findViewById(R.id.weaponSelectionAddButton);
weaponDialogWeaponInfo = (TextView) weaponDialog.findViewById(R.id.weaponSelectionInformationTxt);
...
...
...
Here is my custom ArrayAdapter Class
public class WeaponArrayAdapter extends ArrayAdapter<String> {
private Context context;
String[] objects;
public WeaponArrayAdapter(Context context, int textViewResourceId, String[] objects) {
super(context, textViewResourceId);
this.objects = objects;
this.context = context;
}
private class WeaponItemHolder {
TextView weaponName;
TextView weaponCat;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//return super.getView(position, convertView, parent);
final WeaponItemHolder holder;
if (convertView == null) {
//Sets up a new holder to temporaraly hold the listeners that will be assigned to the binded variables
holder = new WeaponItemHolder();
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.weapon_list_item, null);
//Find the IDs! Find them!!!!
holder.weaponName = (TextView) convertView.findViewById(R.id.weaponListItemName);
holder.weaponCat = (TextView) convertView.findViewById(R.id.weaponListItemCategory);
//"Sets the tag associated with this view. A tag can be used
//to mark a view in its hierarchy and does not have to be unique within the hierarchy."
convertView.setTag(holder);
} else {
holder = (WeaponItemHolder) convertView.getTag();
}
String spellName = objects[position];
String[] weaponInfo = spellName.split("\\:");
weaponInfo[1] = weaponInfo[1].trim();
holder.weaponName.setText(weaponInfo[0]);
holder.weaponCat.setText(weaponInfo[1]);
return convertView;
}
}
Additional Info: I have tried debugging it and it never reaches getView. This makes sense of course, as its not displaying anything.
Thanks,
-Andrew
EDIT: I have found out how to implement the above problem:
I used a SimpleAdapter with a custom layout.
However, now I can not select any of the items... onItemClick is not even called when I try to click it. It probably has to do with using the SimpleAdapter??
LINK: http://lemonbloggywog.wordpress.com/2011/02/15/customer-autocomplete-contacts-android/
ArrayList<Map<String, String>> weaponStringArrayList = ConstantEquipmentHelper.getCondensedWeaponString();
//The adapter that recieves the layout type from android and the array creatd by the above function.
SimpleAdapter simpleAdapter = new SimpleAdapter(this, weaponStringArrayList, R.layout.weapon_list_item ,new String[] {"name", "category"}, new int[] { R.id.weaponListItemName, R.id.weaponListItemCategory});
//Find the view blah blah blah...
weaponDialogAcTextView = (AutoCompleteTextView) weaponDialog.findViewById(R.id.weaponSelectionAutoCompleteTxt);
weaponDialogAddButton = (Button) weaponDialog.findViewById(R.id.weaponSelectionAddButton);
weaponDialogWeaponInfo = (TextView) weaponDialog.findViewById(R.id.weaponSelectionInformationTxt);
//Set that adapter!
weaponDialogAcTextView.setAdapter(simpleAdapter);
You have to implement getCount() and set the count of your data, i.e. objects.length.
You also have to set the adapter to the view using the method setAdapter().
Hope this helps!

Categories