How can I add an image from drawables to a RecyclerView. I tried to add by using the method below:
names.add(R.drawables.image, "Image1");
but it gives me error.
Is there any alternative for adding image into the arraylist without creating another class.
Solution: Please follow.
Step1: Declare a Global Object.
public ArrayList<Integer> imgArrayList;
Step2: Initialize
imgArrayList = new ArrayList<>();
Step3: Add your Drawables in two ways.
First Way: Directly add images one by one.
imgArrayList.add(R.drawable.image1);
imgArrayList.add(R.drawable.image2);
imgArrayList.add(R.drawable.image3);
..... etc etc
Second Way: Make an array of int as shown below:
int imgList[] = {R.drawable.image1, R.drawable.image2, R.drawable.image3}
then,
imgArrayList.addAll(imgList);
That's it, Now you choose which you want to use. All the best.
To bring an image from drawables you have to have the context in the adapter so that you can use the method:
context.getDrawable(R.drawable.image)
But this will force you to send the context to the adapter or you have to use the very same method(getDrawable(R.drawable.image)) directly from inside the activity launching the adapter like that:
getDrawable(R.drawable.image)
I know that this does not sound helpful because you need the images in the adapter so
all what you have to do is preparing the images list in the activity, then send that in the constructor of the Adapter
names.add(R.drawables.image, "Image1");
Assuming names is a String ArrayList, you're trying to add "Image1" to index R.drawables.image (which is a big number, in your case 2131165305)
To fix your issue, you can create a List of Integer values and only add the drawable identifier, so
ArrayList<Integer> drawableIds = new ArrayList<>();
drawableIds.add(R.drawable.image1);
drawableIds.add(R.drawable.image2);
then set your image like
// add a for loop here or whatever
imageView.setImageResource(drawableIds.get(i));
Related
I have one fragment in which I'm generating an ArrayList. After the ArrayList is generated, I'm sending it to the Activity using interface
Inside my fragment-
public interface sendTheArraylist{
void ArrayList(ArrayList<Song> songArrayList);
}
And in the MainActivity-
#Override
public void accessArrayList(ArrayList<Song> songArrayList) {
this.queueArrayList=songArrayList;
queueAdapter =new SongAdapter(this,queueArrayList);
....
}
However, I see that whenever any changes are made in the queueArrayList in MainActivity, the songArrayList in the fragment is also getting affected. How can I stop the ArrayList in the Fragment from getting changed?
Try with the following.
this.queueArrayList.clear();
this.queueArrayList.addAll(songArrayList);
The reason is that you are referencing the arraylist to queueArrayList directly which also reflects changes back in songArrayList
Using an interface you pass the reference of that list so whenever you change that list will also affect on fragment list too. so the solution is rather than pass a reference to that list create one new list and make copy of it.
You can try and give a look at the Collections.copy method:
public static void copy(List dest, List src)
Copies all of the elements from one list into another. After the operation, the index of each copied element in the destination list will be identical to its index in the source list. The destination list must be at least as long as the source list. If it is longer, the remaining elements in the destination list are unaffected. This method runs in linear time.
Parameters: dest - The destination list. src - The source list.
hope it will help you.
Here is the complete solution:
before calling sendTheArraylist Inside your fragment-
ArrayList<Song> songArrayListToPass= new ArrayList<Song>(songArrayList.size());
Collections.copy(songArrayListToPass, songArrayList);
YourActivityRef.sendTheArraylist(songArrayListToPass);
This way your any update on your songArrayListToPass inside Activity will not reflect in Fragment.
I'm using a list view to displace names. The user needs to be able to add a name to the bottom of the list view and to be able to delete names within. The names are saved using SharedPreferences and loaded into an original string array which I then load to an ArrayAdapter. The problem with this method is that, unless I fill up the entire string array, I get a NPE for the ArrayAdapter. So my solution was to set the string array to only be as big as the number of names. This means, however, that I cannot add a name to the list, as the list is only so long.
What's the best way to be able to add and remove strings from a list view and still be able to tell what they are?
After changing values of listview data please put code
notifyDataSetChanged();
Use the List<T> overload rather than the static array for the ArrayAdapter constructor. Then you can add or remove items to your List<T> and call notifyDataSetChanged() once you are done. Using a dynamic data structure like a List<T> will avoid any NPE.
I have a ListFragment backed by an ArrayAdapter that gets populated by a Loader. When the user clicks on one of the items, I want to pass a reference to the selected item, as well as the rest of the list items to another fragment. My question is how should I get all of the items from the adapter? Here are the possibilities that I see:
1. Keep a reference to the backing List
Create the adapter like so:
List<DomainObject> items = new ArrayList<DomainObject>();
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine, items);
and then simply pass items or a copy of it to the next activity.
The downside I see of this is that I'm relying on the undocumented fact that the same list that I pass to the constructor contains the items later on.
2. Iterate through the adapter
When an item is clicked, iterate through the adapter and build up the list. This seems like an unnecessary amount of work. The items are contained in a List in the adapter and I'm manually copying each item to a new list.
3. Keep a separate list of items when adding to adapter
Before adding an item to the adapter, add it to a separate list that I maintain in the fragment. This is also wasteful as the list of items is copied in the ArrayAdapter and the fragment.
I'm a little late to the game, but I've run up against a similar issue.
One way to deal with #1 would be to maintain the reference to the list within a subclass of ArrayAdapter, so that your reuse is controlled by the adapter object.
Something like:
public class DomainAdapter extends ArrayAdapter<DomainObject> {
private final List<DomainObject> items;
public DomainAdapter(Context context, List<DomainObject> items) {
super(context, R.layout.mine, items);
this.items = items;
}
public List<DomainObject> getItems() {
return items;
}
}
The solution that I've gone with in the meantime is just to not use ArrayAdapter. In cases where you're fighting against this API, it seems like it's better just to use the less fully-featured (and complex) BaseAdapter. You can read more about the decision to go with BaseAdapter instead of ArrayAdapter in this article: Android Adapter Good Practices.
A quick test says that method 1 works. It seems the quickest and cleanest, but since it is undocumented you may want to test it across the intended platforms and whenever they update in case the underlying structure of ArrayAdapter changes.
I am using compile SDK version 22 and min SDK Version 10.
The best method is to "keep a reference to the List" BUT not passing "items" variable/parameter to the Constructor:
List<DomainObject> items = new ArrayList<DomainObject>();
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine);
In this way you only instantiate the ArrayList as an empty array and you will have to manage YOUR list by yourself.
I think first method is best way to do this.
I dont think, Data would be original for the Another Activity. because, You would pass items through bundle, so the object is written on bundle first and then in next Activity we read from bundle.
However, if you are using some other way to pass the list, use list.clone() to create new Object, instead of passing original one.
I have a class called people that has its own name, id etc...
I have a full list of people in an array list public ArrayList<people> pList;
When I click on some names I want to add the people in pList to public ArrayList<people> followList; Doing followList.add(pList.get(position)) doesn't work. What is the proper way to do this.
Also, on another click I would like to remove the particular object from the followList so I tried doing followList.remove(pList.get(position)) but obviously it doesn't work as well.
Im basically trying to have a list of people from the original list.
The followList seems to be not initialized. You should call initialize it with new ArrayList<people>() before adding to or removing from it.
Are you sure that you have instantiated the ArrayList followList, and that there is in fact a element at pList[position]?
Hello folkes I have this little problem for which I cannot find a suitable answer looking around the web and on these forums. Please don't direct me to articles in which people have requested list view text color changes at run time, as I read lots of them and not found one to help me out.
I have a simple ListView that displays an array of String objects via the use of a ListAdapter.
I need to update some of ListView Strings at run time, based on their contents. Using a global reference to the list adapter used in the lists views creation I can get the contents of each list view String using following code below.
However, in addition to retrieval I'd like to be able to modify each string in turn, then put it back in the same index position and have the list view reflect the changes. How?
for (int x = 0; x <= listAdapter.getCount();x++)
{
Object o = this.listAdapter.getItem(x);
if (o.getClass().getSimpleName().equals("String"))
{
String s = (String) o;
s = modifyString(s);
//s is the string I want to modify then put back in the same place.
}//end if
}//end for
As far as I know you cannot change the items in an Adapter - unless you are using a custom Adapter (by extending a BaseAdapter etc...)
So, I think you will have to:
make sure you Adapter's constructor takes in the data structure that holds your strings
make sure your data structure is global
make the changes in that data structure whenever you need to
call myAdapter.notifyDataSetChanged();
This will tell adapter that there were changes done in the list and listview should be recreated.
And after your listview is renewed you can even take the user back to the index by:
list.setSelection(positionWhereTheUserClicked);
I hope this helps, let me know if you need more code references.
Here is some code
private ArrayList<String> results = new ArrayList<String>(); //global
private BaseAdapter searchAdapter = new BaseAdapter (results, this); //global
private void updateResults(final ArrayList<String> updatedList){
results = updatedList;
final ListView list = (ListView)findViewById(R.id.search_results);
list.setAdapter(searchAdapter);
list.setOnItemClickListener(new ListView.OnItemClickListener(){
// implementation of what happens when you click on an item //
});
searchAdapter.notifyDataSetChanged();
}
This code works just fine on my end, I hope it helps.
Just stumbled on this problem and found a solution.
I'm using a
m_ListAdapter = new SimpleAdapter(this, m_List, R.layout.option_list_row, columns, renderTo);
Each item in my listView is a manu option causing a dialog to show, once data is received through the dialog, all I have to do is just create a new SimpleAdapter with an updated ArrayList that includes the new data, then just setAdapter to the new adapter.
The ListView will update instantly.