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!
Related
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
I have made a ListView which is populated with elements of an ArrayList. I do not have an XML file with this ListView, it is only in Java. Given this, how would I change the background color of the ListView as well as change the color of the text of the ListView?
This is the code for the ListView:
setListAdapter(new ArrayAdapter<String>(CollegeList.this, android.R.layout.simple_list_item_1, nameList));
In case you want to customize each line of the listview you have to use a custom adapter with custom listview item. Then you can use the "getView" Method to catch each item and position to change colors.
Here is a sample:
public class ListViewAdapter extends ArrayAdapter<Item> {
private Context context;
private int itemResourceId;
private ArrayList<Item> items;
public ListViewAdapter(Context context, int layoutId, ArrayList<Item> items) {
super(context, layoutId, items);
this.context = context;
this.itemResourceId = layoutId;
this.items = items;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder = null;
if (view == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(itemResourceId, null);
holder.listItem = (TextView) view.findViewById(R.id.item);
view.setTag(holder);
}
else
holder = (ViewHolder) view.getTag();
if (position % 2 == 0)
view.setBackgroundColor(context.getResources().getColor(R.color.listItemEven));
else
view.setBackgroundColor(context.getResources().getColor(R.color.listItemOdd));
Item item = items.get(position);
holder.listItem.setText((position+1) + ". " + item.sTitle);
return view;
}
static class ViewHolder {
TextView listItem;
}
}
android.R.layout.simple_list_item_1
You have to add an extra parameter to your ArrayAdapter, this will be a CUSTOM XML OF YOUR OWN and the next one will be a textview that is inside that custom layout, that way the array adapter will know which layout to fill and which textview needs to show the data you want to show.
from that xml you can modify background and color. will look something like this:
setListAdapter(new ArrayAdapter<String>(CollegeList.this, R.layout.your_custom_layout, R.id.the-text-view-in-that-layout, nameList));
You can get the xml for simple_list_item_1 here. You can copy it to your project and modify it, just change the code for your listview to setListAdapter(new ArrayAdapter<String>(CollegeList.this, R.layout.simple_list_item_1, nameList)); You can also create one yourself, since simple_list_item_1 is nothing but a textview. Just make sure that the id is android:id="#android:id/text1" otherwise it won't work with the default adapter.
I got a problem. I got some code which I'm not going to put all here because it's to big. But I got a listview. And i do it like this:
lv = (ListView) findViewById(R.id.list);
(Here is normally some asynctask code and stuff)
// list adapter
ListAdapter adapter = new SimpleAdapter(MainActivity.this, placesListItems,
R.layout.list_item, new String[] { KEY_REFERENCE, KEY_NAME, KEY_VICINITY, KEY_DISTANCE,
KEY_LOCATION}, new int[] { R.id.reference, R.id.name, R.id.vicinity, R.id.radius, R.id.location});
// Adding data into listview
lv.setAdapter(adapter);
Now the thing is I got an url and the only thing on the site is an image. It's from Google Place Photos. Now I want an image in my listview. So in every item there is another image.
I can do it with an imageview or with a webview.
So let's sey the url is stored in this:
KEY_URL;
And the imageview or webview is this:
R.id.image;
How can I do this?
Thanks in advance!!
At first,
WebView takes more memory than ImageView.
So I recommend you to use ImageView.
At Second,
Check out following URLs.
Lazy load of images in ListView
In this article,
The first library, which I have used, is small and customizable library.
It uses thread pool and seems to control transfers.
The second library, which I haven't used, is larger.
But more methods in this library seem to make it easy to control various configurations.
Finally,
I think you should create your own Adapter, extending SimpleAdapter(or CursorAdapter, or…).
like following pseudo code.
public class MySimpleAdapter extends SimpleAdapter {
private ImageLoader mImageLoader;
private int mResource;
private LayoutInflater inflater;
public static class ViewHolder {
public ImageView img;
public TextView txt;
}
public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
mResource = resource;
mImageLoader = new ImageLoader(context);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.cell_text, null);
holder = new ViewHolder();
holder.txt = (TextView) convertView.findViewById(R.id.txt);
holder.img = (ImageView) convertView.findViewById(R.id.img);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.txt.setText("something text");
mImageLoader.displayImage("url", holder.img);
return convertView;
}
}
You Can use [androidQuery]https://code.google.com/p/android-query/
It has a thread pool. It load images in different ways. Has the option to down sample images to save memory. Made by google :)
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.
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>();