I am a beginner in Android studio and I am having hard time to debug this issue.
when any item in my ListView gets clicked the application crashes, here is the class for the OnItemClick. The objective is to change the ListView from the Categories to the items inside the categories. The Categories and items are stored in a HashMap <String, String[]>, so passing the value of cat.toString() should return the string containing the category. Lastly using myList (Stored outside of the function) should return an array of string containing the items. However, when I click any of the items the application instantly crashes. Thanks for your help!
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Choosen category
TextView cat = (TextView) view;
ArrayList<String> tempItems = new ArrayList<String>();
//Toast.makeText(this, cat.getText().toString(),Toast.LENGTH_SHORT).show();
listAdapter.clear();
for(String val : myList.get(cat.getText().toString())){
tempItems.add(val);
}
listAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,tempItems);
listAdapter.notifyDataSetChanged();
}
Variables
ListView myViewList;
Map<String, String[]> myList = new HashMap<String, String[]>();
ArrayAdapter<String> listAdapter;
Populating the ListView
//Creating a list of all categories
Set<String> myListKeys = myList.keySet();
ArrayList<String> categories = new ArrayList<String>();
for(String val : myListKeys){
categories.add(val);
}
//String[] categories = myListKeys.toArray(new String[myListKeys.size()]);
//Populating list
myViewList = (ListView) findViewById(R.id.groceryList);
listAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,categories);
myViewList.setAdapter(listAdapter);
myViewList.setOnItemClickListener(this);
You are getting exception because you are using listAdapter.clear(); which tries to clear the List inside the adapter. But apparently you have passed an array (String[] categories) which cannot be cleared. You should convert the array to ArrayList, (not just List) by iterating through it and pass it into the adapter.
You should create the adapter by passing ArrayList
What do you think you're doing by creating a new adapter inside the onItemClick of old adapter?
Inside the onItemClick, don't create a new adapter. Instead, after clearing the adapter and creating a temp ArrayList, add all the temp ArrayList to the adapter.
listAdapter.addAll(tempItems);
Also to get text from a TextView, use cat.getText().toString(); instead of cat.toString();
Related
I am trying to fill a ListView with Items. Everything seems to work perfectly but ListView doesn't show Items. I am wondering if I miss a step here.
Please take a look at my code below;
ListView listView = (ListView) myView.findViewById(R.id.listViewLocations);
List<WMS_Location> list = (List<WMS_Location>) response.body();
String listViewItems[] = new String[list.size()];
for (int i=0;i<list.size();i++)
{
listViewItems[i]= list.get(i).getCode().toString().toUpperCase();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, listViewItems);
listView.setAdapter(adapter);
NOTE: I am sure that listViewItems is not empty and it has 5 string object in it.
I'm trying to add a different icon to each of my list items but I'm having trouble. The idea was to have each of the list view items together to make editing easier but adding an image is proving to be more complicated than I thought.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<Map<String, String>> list = buildData();
String[] from = { "title", "description" };
int[] to = { android.R.id.text1, android.R.id.text2 };
SimpleAdapter adapter = new SimpleAdapter(this, list,
android.R.layout.simple_list_item_2, from, to);
setListAdapter(adapter);
}
private ArrayList<Map<String, String>> buildData() {
ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
list.add(putData("Title 1", "Description 1"));
list.add(putData("Title 2", "Description 2"));
list.add(putData("Title 3", "Description 3"));
return list;
}
private HashMap<String, String> putData(String name, String purpose) {
HashMap<String, String> item = new HashMap<String, String>();
item.put("name", name);
item.put("purpose", purpose);
return item;
}
This is if not impossible, then at least quite troublesome at your current setup.
As the name states a SimpleAdapter is a basic class which provides you with basic functionality. That is, usually - a list with text views.
When you create the adapter you specify an exact layout for every single item in it (that's your android.R.layout_simple_list_item_2). You cannot push any additional items there (unless you're really stubborn).
What you need:
A custom made adapter (preferably)
A custom made layout for the adapter
A data source in the adapter which will map specific icons to every element.
Here is a nice demo: http://hmkcode.com/android-custom-listview-titles-icons-counter/
you can use custom adaptor in listview . so can customize your row.
check this
Currently using simple_list_item_2.xml for ListView. this layout contains only two TextView's. so it's not possible to show image in ListView row's using simple_list_item_2.xml layout
How to I add an image to list view items in Android?
Should create a custom adapter :
1. Creating a custom layout with required views which want to show in each listview row like with TextView,ImageView,...
2. Create a custom adapter class by extending SimpleAdapter class to change behavior of getView method for showing images and textview from data-source
See following tutorial for reference :
ListView with Images and Text using Simple Adapter in Android
I want to populate a Spinner with items which have a main text and a sub text, just like Android Studio shows when building the view on the "Designer" tab.
So far I was able to fill it with the main text only.
I am doing it via code. Using a SimpleAdapter.
I tried the following but with no success, it just gives me same result (only main text):
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
List<Map<String, String>> itens = new ArrayList<>();
Map<String, String> item = new HashMap<>(2);
item.put("text", "MAIN TEXT");
item.put("subText", "SUB TEXT");
itens.add(item);
SimpleAdapter adapter = new SimpleAdapter(spinner.getContext(), itens,
android.R.layout.simple_spinner_dropdown_item,
new String[]{"text", "subText"},
new int[]{android.R.id.text1, android.R.id.text2}
);
// i am not sure what this does
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
I had the same problem and have used the OP's code as a base to create this solution:
final Spinner spinner = (Spinner)fragmentView.findViewById(R.id.spinner);
List<Map<String, String>> items = new ArrayList<Map<String, String>>();
Map<String, String> item0 = new HashMap<String, String>(2);
item0.put("text", "Browse aisles...");
item0.put("subText", "(Upgrade required)");
items.add(item0);
Map<String, String> item1 = new HashMap<String, String>(2);
item1.put("text", "Option 1");
item1.put("subText", "(sub text 1)");
items.add(item1);
Map<String, String> item2 = new HashMap<String, String>(2);
item2.put("text", "Option 2");
item2.put("subText", "(sub text 2)");
items.add(item2);
SimpleAdapter adapter = new SimpleAdapter(getActivity(), items,
android.R.layout.simple_spinner_item, // This is the layout that will be used for the standard/static part of the spinner. (You can use android.R.layout.simple_list_item_2 if you want the subText to also be shown here.)
new String[] {"text", "subText"},
new int[] {android.R.id.text1, android.R.id.text2}
);
// This sets the layout that will be used when the dropdown views are shown. I'm using android.R.layout.simple_list_item_2 so the subtext will also be shown.
adapter.setDropDownViewResource(android.R.layout.simple_list_item_2);
spinner.setAdapter(adapter);
You can also substitute android.R.layout.simple_spinner_item and/or android.R.layout.simple_list_item_2 with your own custom views (that would typically reside in your layout folder).
This is a much better solution than PhoneGap!! :D
You will have to create a custom ArrayAdapter that creates a custom view for your Spinner dropdown. This link gives a good example: How to customize the Spinner dropdown view
I have the following code in a tabbed Fragment:
private SetRowsCustomAdapter adapter;
private ArrayList<SetRows> rowsArray = new ArrayList<SetRows>();
for (Map.Entry<String, String> current_file:filesInFolder.entrySet()) {
rowsArray.add(new SetRows(R.drawable.ic_launcher, current_file.getKey().toString(), current_file.getValue().toString()));
}
adapter = new SetRowsCustomAdapter(getActivity(), R.layout.customlist, rowsArray);
dataList = (ListView) mFrame3.findViewById(R.id.lvFiles);
dataList.setAdapter(adapter);
}
getActivity().deleteFile(txt + ".trp");
adapter.remove(adapter.getItem(info.position));
adapter.notifyDataSetChanged();
startActivity(new Intent(getActivity(), MainActivity.class).putExtra("tab", 2));
which deletes a row within my ListView and starts a new activity to show the changes. Although I have the adapter.notifyDataSetChanged(), it doesn't display the changes once a row is deleted without the last line on the code above.
Can someone please help me fix that so it shows the changes without starting a new activity.
Use of custom adapter is better for it, these link will help you for it
Remove ListView items in Android
How to remove arraylist item and then update listview
I think you require to delete from arraylist then call adapter setNotifyDataChange(), b'cos when you call this function it reload the adapter from arraylist.
I am currently creating a basic news aggregator app for Android, I have so far managed to create multiple HorizontalListViews derived from this: http://www.dev-smart.com/archives/34
I am parsing all data from live JSON objects and arrays.
The process goes something like this:
1) Start app
2) Grab a JSON file which lists all feeds to display
3) Parse feed titles and article links, add each to an array
4) Get number of feeds from array and create individual HorizontalListView for each. i.e. "Irish Times".
5) Apply BaseAdapter "mAdapter" to each HorizontalListView during creation.
My baseadapter is responsible for populating my HorizontalListViews by getting each title and thumbnail.
My problem is however that all my feeds seem to contain the same articles and thumbnails. Now I am only new to Android so I'm not 100% sure whats going wrong here. See screenshot below.
Do I need to create a new BaseAdaptor for each HorizontalListview or can I use the same one to populate all my listviews with unique data.
Here's some code to help explain what I mean:
1) OnCreate method to get JSON data, parse it, get number of feeds and create each HorizontalListView
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listviewdemo);
//--------------------JSON PARSE DATA------------------
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
String json = jParser.getJSONFromUrl(sourcesUrl);
//Parse feed titles and article list
getFeeds(json);
//Create Listviews
for(int i = 0; i < feedTitle.size()-1; i++){
//getArticleImage(i);
addHorzListView(i);
articleArrayCount++;//Used to mark feed count for adaptor to know which array position to look at and retrieve data from.
//Each array position i.e. [1] represents a HorizontalListview and its related articles
}
}
2) addHorzListView method, used to create HorizontalListView and apply adaptor
//Method used to dynamically add HorizontalListViews
public void addHorzListView(int count){
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);
View view = getLayoutInflater().inflate(R.layout.listview, mainLayout,false);
//Set lists header name
TextView header = (TextView) view.findViewById(R.id.header);
header.setText(feedTitle.get(count));
//Create individual listview
HorizontalListView listview = (HorizontalListView) view.findViewById(R.id.listviewReuse);
listview.setAdapter(mAdapter);
//add listview to array list
listviewList.add(listview);
mainLayout.addView(view, count);
}
3) Baseadaptor itself:
private BaseAdapter mAdapter = new BaseAdapter() {
private OnClickListener mOnButtonClicked = new OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(HorizontalListViewDemo.this);
builder.setMessage("hello from " + v);
builder.setPositiveButton("Cool", null);
builder.show();
}
};
#Override
public int getCount() {
return noOfArticles.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
//Each listview is populated with data here
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);
TextView title = (TextView) retval.findViewById(R.id.title);
title.setText(getArticleTitle(position));
new DownloadImageTask((ImageView) retval.findViewById(R.id.ImageView01)) .execute(getArticleImage(position));
Button button = (Button) retval.findViewById(R.id.clickbutton);
button.setOnClickListener(mOnButtonClicked);
return retval;
}
};
The adapter mAdapter is currently displaying the articles from the last HorizontalListView that calls it.
Currently I am using the same BaseAdaptor for each ListView as I figured it populated the listview as soon as its called but i looks as though a BaseAdaptor can only be called once, I really dont know.
I want to dynamically populate feeds though without having to create a new Adaptor manually for each HorizontalListView.
Any help would be much appreciated.
So...you got the same info in 4 listview, right? In that case you only need oneAdapter populating 4 listview.
An adapter just provide the views which are visible in that moment to the listview (if it is implemented in the right way) so you can reuse the adapter if the info contained is the same.