Is there any way to replace a value in an ArrayAdapter
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
..
..
for (BluetoothDevice device : pairedDevices) {
String name = MPGDeviceDetailsControl.getDeviceDetails(this, device.getAddress(), device.getName()).getDisplayName();
mPairedDevicesArrayAdapter.add(name + "\n" + device.getAddress());
}
If I wish to replace one of the entries is there any way of doing it without deleting and reinstering.
Problem with that is that it puts it at the bottom.
Something like this should work to replace items
int i = 0;
for (BluetoothDevice device : pairedDevices) {
String name = MPGDeviceDetailsControl.getDeviceDetails(this, device.getAddress(), device.getName()).getDisplayName();
mPairedDevicesArrayAdapter.remove(name); // has to copy all items back 1 position
mPairedDevicesArrayAdapter.insert(name + "\n" + device.getAddress(), i); // copy them +1 again
i++;
}
but it would be more efficient, if you have access to the List that is backing this ArrayAdapter and replace / modify that.
ArrayList<Strign> mList = new ArrayList<String>();
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name, mList);
// setup
mList.add...
mPairedDevicesArrayAdapter.notifyDatasetChanged();
// change something
mList.set(i, newValue); // just a replace, no copy
mPairedDevicesArrayAdapter.notifyDatasetChanged();
It's possible to replace the display value without reinserting and using nested adapters. Simply change original collection and call adapter's notifyDatasetChanged()
//adapter initialization
MyClass[] someArray = ... ;
ArrayList<Strign> adapter = new ArrayList<String>(context, R.layout.item_layout, someArray);
//change something
someArray[i] = newValue;
adapter.notifyDatasetChanged();
It's pretty much the same as zapl's answer except it doesn't use nested adapters. It should work the same when the adapter is initialized with List but I haven't tested that.
No You can replace without deleting or reinserting.
Related
Please someone help me how to show all list array in listview, i have "eventname" which values are: "Party", "Study", "Exam".
and inside my for loop i have this codes and it only outputs "Exam"..
lv = (ListView) findViewById(R.id.textView);
List<String> your_array_list = new ArrayList<String>();
your_array_list.add(eventname);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(CalendarActivity.this,
android.R.layout.simple_list_item_1,
your_array_list );
lv.setAdapter(arrayAdapter);
You are not adding data in your arraylist correctly..you are adding only one data in arraylist.
String[] array ={"EXAM","Study"};
for(String str: array){
your_array_list.add(str);
}
You code works properly, you are adding just one item:
your_array_list.add(eventname);
If you want to add the items "Party", "Study", "Exam", you should add them one by one:
your_array_list.add("Party");
your_array_list.add("Study");
your_array_list.add("Exam");
Or much better, declare them in a constant array and add them in a loop:
String[] ITEMS = new String[]{"Party", "Study", "Exam"};
...
for(String item : ITEMS) {
your_array_list.add(item);
}
Also, consider using an enum instead of a constant array. But it depends on what you are specifically programming, of course.
I have a ListView with some items, but after I update a Database I'd like to "refresh" the ListView. Anyone can help me?
EDIT: populateListView add items to ListView
public void populateListView()
{
String URL = config.getUrl_For_Query() + ",&nameq=Select&tipo=select"; // my URL
String jsonString = reading.execute_query(URL); // jsonString is formatted well
try
{
JSONObject jsonResponse = new JSONObject(jsonString);
JSONArray array = jsonResponse.getJSONArray("elenco");
for (int i=0; i<array.length(); i++) // I scan all array
{
JSONObject nameObj = (JSONObject)array.get(i);
// I retrieve all information
allNames.add(nameObj.getString("name")); // Name
allLng.add(nameObj.getString("lng")); // Another information
}
}
catch (Exception e)
{ e.printStackTrace(); }
List<String> Array = new ArrayList<String>();
for(int i=0;i<allNames.size();i++) // I add all values
{
String value = allNames.get(i).toString() + ", \n\t" + allLng.get(i).toString();
Array.add(value); // here I populate my Array
}
final ListView listView = (ListView) getActivity().findViewById(R.id.List);
listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Array));
//
// Click
//
}
saveChanges
public void saveChanges()
{
// I update a Database
// And then I'd like to refresh ListView's items
populateListView(); // Update ListView
}
Use a Comparator. There you define what to compare and how, in the compare() method you define what should be returned from two of your instances. Here's an example for a String Comparator.
Comparator myComparator = new Comparator<String>() {
public int compare(final String user1, final String user2) {
// This would return the ASCII representation of the first character of each string
return (int) user2.charAt(0) - (int) user1.charAt(0);
};
};
adapter.sort(myComparator);
This way, when you add an item, you don't have to recreate the whole Adapter but it will be sorted instead. But don't forget to call .notifyDataSetChanged() on your adapter, this will make (amongs other things) to refresh your layout.
Try using ArrayAdapter.insert method to insert objects in specific index.
At first take a look at this tutorial about SQlite database in Android.
So, your problem is that new items are added at the end of the list. Huh? This is because you have not notified Adapter from the changes of the Array.
ArrayAdapter<String> Adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Array);
Your first solution is to clear Adapter before updating Database. Sth like:
Adapter.clear(); can do that. This way your Adapter is empty before updating database and new items are inserted. You can use Adapter.notifyDataSetChanched(); for awaring Adapter about the changes.
In above tutorial there is a custom Adapter. It uses this code:
List<String> Array = new ArrayList<String>();
Array = (ArrayList<String>) db.getAllContacts();
Adapter = new MyCustomAdapter(getActivity() [in fragment case or getApplicationContext() in Activity case], R.layout.simple_list_item_1, Array);
This way there is no need for clearing Adapter because it automatically does that. Wherever you use this method, updated adapter is used for showing the list.
I'm iterating through a cursor and populating a SparseArray with ArrayList's containing bundles of information from the cursor:
// An ArrayList to hold all of our components per section
ArrayList<ObjectKanjiLookupChar> al = new ArrayList<ObjectKanjiLookupChar>();
// We'll hold on to all of the above ArrayLists and process them at once
SparseArray<ArrayList<ObjectKanjiLookupChar>> compArray = new SparseArray<ArrayList<ObjectKanjiLookupChar>>();
do
{
// Read values from the cursor
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String component = cursor.getString(cursor.getColumnIndex("component"));
int compStrokes = cursor.getInt(cursor.getColumnIndex("strokes"));
// Create a new object for this component so we can display it in the GridView via an adapter
ObjectKanjiLookupChar oklc = new ObjectKanjiLookupChar();
oklc.setCharacterID(id);
oklc.setCharacter(component);
oklc.setStrokeCount(compStrokes);
al.add(oklc);
// Add headers whenever we change stroke groups
if(compStrokes != strokesSection)
{
compArray.put(strokesSection, al);
al.clear();
strokesSection = compStrokes;
}
}
while(cursor.moveToNext());
// Add the final group of components to the array
compArray.put(strokesSection, al);
Immediately afterwards, I iterate through the SparseArray:
for(int i = 0; i < compArray.size(); i++)
{
Integer strokes = compArray.keyAt(i);
ArrayList<ObjectKanjiLookupChar> alComp = compArray.get(strokes);
// DEBUG
Log.i("DialogKanjiLookup", "Components in Section " + strokes + ": " + alComp.size());
ll.addView(createNewSection(String.valueOf(strokes), alComp));
}
For some unknown reason, the Log() call above reports that alComp has zero entries. I verified that ArrayList.size() was returning numbers greater than 0 when I put() them into the SparseArray, so I must be doing something incorrect when iterating through the SparseArray. What is going on?
I suspect that the problem comes from this piece of code:
if(compStrokes != strokesSection)
{
compArray.put(strokesSection, al);
al.clear(); // Here
strokesSection = compStrokes;
}
You cleared the array list after you added to the SparseArray. You might think that after you have added the list to the SparseArray, SparseArray would keep a copy of the ArrayList. However, they actually share the same reference. Since you cleared the ArrayList, you cleared out the one inside SparseArray too.
The following code should fix the problem.
// We'll hold on to all of the above ArrayLists and process them at once
SparseArray<ArrayList<ObjectKanjiLookupChar>> compArray = new SparseArray<ArrayList<ObjectKanjiLookupChar>>();
do
{
// Read values from the cursor
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String component = cursor.getString(cursor.getColumnIndex("component"));
int compStrokes = cursor.getInt(cursor.getColumnIndex("strokes"));
// Create a new object for this component so we can display it in the GridView via an adapter
ObjectKanjiLookupChar oklc = new ObjectKanjiLookupChar();
oklc.setCharacterID(id);
oklc.setCharacter(component);
oklc.setStrokeCount(compStrokes);
ArrayList<ObjectKanjiLookupChar> al = compArray.get(comStrokes);
if(al == null) {
al = new ArrayList<ObjectKanjiLookupChar>();
compArray.put(comStrokes, al);
}
al.add(oklc);
}
while(cursor.moveToNext());
I am working on an application for Android. For this I am making an Activity in which you select your country and then a spot in that country. I have one spinner that contains a list of all available countries. Now, what I want it to do is get the country that has been selected, then filter a list of spots that I have for the items that start with the country that has been selected. Then it should put the spots for the selected country into a different spinner. Just for clarity, the list of countries is just a list of countries, and the list of spots looks like:
Country1 - Spot1
Country1 - Spot2
Country2 - Spot1
Country2 - Spot2
And so on.
This is what I thought the code should work like:
Get selected country from spinner 1.
Make a new ArrayList containing the spots.
Make a second empty ArrayList.
For each entry of the ArrayList containing the spots, check if it starts with the selected country.
If so, add it to the second ArrayList.
Once this is all done, make an ArrayAdapter with the second ArrayList.
Set this ArrayAdapter for spinner 2.
I tried to achieve this with the following code:
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
String selectedCountry = parent.getItemAtPosition(pos).toString();
ArrayList<CharSequence> arraylist = new ArrayList<CharSequence>();
arraylist.addAll(R.array.spots_array);
ArrayList<CharSequence> arraylist2 = new ArrayList<CharSequence>();
for (i=0; i<arraylist.size(); i++) {
String delimiter = " - ";
if ((arraylist(i).split(delimiter)).equals(selectedCountry)) {
arraylist2.add(arraylist(i).string.substring(string.lastIndexOf('-') + 1));
}
}
ArrayAdapter<CharSequence> arrayAdapter2 = ArrayAdapter.createFromResource(this, arraylist2<CharSequence>, android.R.layout.simple_spinner_item);
arrayAdapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setAdapter(arrayAdapter2);
spinner2.setOnItemSelectedListener(this);
}
But it gives several errors:
At addAll() it says: "The method addAll(int, Collection) in the type ArrayList is not applicable for the arguments (int)"
At arraylist it says: "The method arraylist(int) is undefined for the type Configuration"
At string (inside substring) it says: "string cannot be resolved"
I am still relatively new to Android, and am having a lot of trouble getting this working. Can anybody please help me out?
There is a lot of little mistakes in your code :
To access an element in an arraylist use the get(position) method
When you add your "spot_array", you actually add the id of the resource, not the array itself (see here)
Here is your code updated, it should works or may need some tweaks
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
String selectedCountry = parent.getItemAtPosition(pos).toString();
List<CharSequence> arraylist = new ArrayList<CharSequence>();
arraylist.addAll(Arrays.asList(getResources().getTextArray(R.array.spots_array)));
List<CharSequence> arraylist2 = new ArrayList<CharSequence>();
String delimiter = " - ";
for (int i=0; i<arraylist.size(); i++) {
String country = arraylist.get(i).toString();
if (country.contains(selectedCountry)) {
arraylist2.add(country.substring(country.lastIndexOf('-') + 2));
}
}
ArrayAdapter<CharSequence> arrayAdapter2 = ArrayAdapter.createFromResource(this, android.R.id.text1, android.R.layout.simple_spinner_item);
arrayAdapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setAdapter(arrayAdapter2);
spinner2.setOnItemSelectedListener(this);
}
You have several errors in your code.
Firstly, the method addAll of the ArrayList must take as an argument a Collection. You are passing an Android array id R.array.spots_array; bear in mind that the Android ids are integers.
The usually method to fetch a string array from Android resources is (inside an activity):
String[] myArray = getResources().getStringArray(R.array.spots_array);
Second error: you should access the ArrayList elements by calling the method get(position) , not directly (arraylist(position)). Something like arraylist.get(position).
Third error:
arraylist2.add(arraylist(i).string.substring(string.lastIndexOf('-') + 1));
should simply be arraylist2.add(arraylist.get(i)); for adding one list element to another.
More on ArrayLists can be found here.
In the following code I am able to retrieve the _id value of each record and display it along with the text in a ListView but when I select an item from the list the returned value is 0 to N dependent on how the results are laid out in the list.
How can I get the _id value, I guess as a named value pair so that when 0 or 1… is selected it outputs the _id field and not 0 or 1… for my OnItemClickListener
This is my method, it’s messy, once I get it working I’ll try to refine it!
private void GetCoordinates(double currentLatitude, double currentLongitude) {
List<String> ar = new ArrayList<String>();
dbBookHelper = new DatabaseHelper(this);
ourCursor = dbBookHelper.getCoordinates();
int counta = 0;
ourCursor.moveToFirst();
do {
id = ourCursor.getInt(ourCursor.getColumnIndex("_id"));
BeachName = ourCursor.getString(ourCursor.getColumnIndex("BeachName"));
beachLatitude = ourCursor.getDouble(ourCursor.getColumnIndex("latitude"));
beachLongitude = ourCursor.getDouble(ourCursor.getColumnIndex("longitude"));
distence = ConvertDistance(beachLatitude, beachLongitude);
if (distence <= 5) {
ar.add(id + " " + BeachName + " - " + distence + "Kms");
counta++;
}
} while (ourCursor.moveToNext());
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.row2, R.id.beachListText, ar);
setListAdapter(adapter);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(onListClick);
Toast.makeText(getBaseContext(), "There are " + String.valueOf(counta) + " beaches within a 5km radius!", Toast.LENGTH_LONG).show();
}
And this is my OnItemClickListener method
private AdapterView.OnItemClickListener onListClick = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Toast.makeText(getBaseContext(), String.valueOf(id) + " selected", Toast.LENGTH_LONG).show();
}
};
Any help would be greatly appreciated,
Cheers,
Mike.
Edit: Thanks guys, I was hoping for a slicker way too!
But I now have a second array holding just the id values with,
ar1.add(String.valueOf(id));
So the positions are the same, but how do I get them into the OnItemClickListener? I guess somewhere in here???
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.row2, R.id.beachListText, ar);
setListAdapter(adapter);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(onListClick);
The basic problem is the ArrayAdapter does not know anything about the Cursor or rowId. I think you have 2 choices. The first is to manage the mapping of array position to rowId yourself. For example, create a second array to map the ArrayList position to the rowId, and do a simple lookup in the listener.
If that is not appropriate for some reason then you could create a custom adapter with knowledge of the Cursor, by extending CursorAdapter. It involves over-riding 2 methods newView() and bindView() to allocate and populate the views (with your custom string) that will be displayed in each row. It also provides filtering hooks that would allow you to implement the < 5KM filter you need.
I haven't gone through this particular case myself, but did recently have to extend an ArrayAdapter to implement a SectionIndexer for a very long list. While it was a valuable exercise, I think in your case a custom adapter is possibly overkill. A second array look-up may be simpler and more appropriate.
1) Make your new array a class member so it is accessible in the listener
ArrayList<Long> mIdArr = null;
2) Create this in a similar way to your String array
mIdArr = new ArrayList<Long>();
3) Store the rowId at the same point you add to your String array
ar.add(id + " " + BeachName + " - " + distence + "Kms");
mIdArr.add(new Long(id));
4) Retrieve the Id in your listener like this
private AdapterView.OnItemClickListener onListClick = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Long rowId = mIdArr.get(position);
Toast.makeText(getBaseContext(), String.valueOf(rowId) + " selected", Toast.LENGTH_LONG).show();
}
};