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.
Related
I want to create a custom ListView.
Initially, the custom ListView has one array of data, but when user taps one of the list items, it's then removed from current array and added to another. If the user taps on the second array, the list item is then added back over into the first array.
Please suggest how to apply logic to do this.
Updates : I wants to use only one listview/recyclerview.
Following are screen shots..
Regarding the object switch - this is a simple transfer between lists, , just know beforehand if the insertion and removal is index based, e.g:
contacts.add(iLocation, ContactObject);
favorites.remove(iOtherLocation);
Regarding the ListView stuff, I would suggest converting to RecyclerView, let's build a general scenario:
You have a screen (Activity or Fragment) that holds one list (the implementation can be ListView or Recycler), and another screen that holds the other list.
In both of your lists you have adapters in which you implement the logic for the clicks on the objects in the lists.
The click transfers the object, either directly to the other list, OR to a temporary Object holder (because you might need it for other stuff), in which case you will need to pull that object from the other view, either way you remove it from the current one.
you switch to the other view, and refresh it.
An easy way to go -
Assuming the screens are the same, use only one Activity, holding a single RecyclerView, and handle 2 adapters, each for every list, the adapters allow you to handle the clicks easily, with an index for the object clicked, the click executes the info swap action,the Activity handles the visual swap Action.
a very general example would be:
//init everything obviously ;)
List<ContactObject> contacts;
List<ContactObject> favoritesContacts;
//the AdapteListener is an interface declared inside the adapter
mContactsRecyclerAdapter = new ContactsRecyclerAdapter(this, contacts,new ContactsRecyclerAdapter.AdapterListener()
{
#Override
public void cellClicked(int iIndex, ContactObject object)
{
favoritesContacts.add(iIndex, ContactObject);
contacts.remove(iIndex);
mContactsRecyclerAdapter.notifyDataSetChanged();
mFavoritesRecyclerAdapter.notifyDataSetChanged();
mRecyclerView.swapAdapter(mFavoritesRecyclerAdapter, false);
}
});
And vice-versa for the other adapter.
Hope this helps, comment if you have problems and I'll update.
Please implements with custom view extend with Linearlayout
Custom view has 2 child Linearlayout in which will add with this custom view
First time add all the element in first Linearlayout and based on user action please remove from first Linearlayout and add it in another layout
The problems is: I have a listview_products, for instance, and I have to select one of them per time and put it into another listview_sales, the listview_sales is going to hold all the products that I've been choosing for then make the proccess of sale completely. How could I achieve this behavior? Could you lend me a hand with this please!
You should have an ArrayList with object from where your first adapter gets data to draw.
Then you will need another arrayList with the objects of the first that will be drawn on the second ListView.
So, if you implement a OnItemClickListener in your first arraylist to get the selected items.
This is just a pseudocode example.
void OnItemClicked(int position) //This is not the real method definition
{
secondArray.put(firstArray.get(position));
}
Then when you want to show that second List just pass that data to its adapter
secondListView.setAdapter(new SecondAdapter(secondArray));
Hope this helps.
I have dug deep down into SO but, although I have found other people asking similar questions to mine, I have not yet find a question that addresses the same issues I have. I have not found a satisfying answer either.
I have a ListView. When I call from the adapter, .notifyDataSetChanged, the ListView is updated, but I can see the update only once onResume() is called. In other words, I do not see it instantly, only after I leave the activity and comeback.
What can I do to see the update instantly? I have tried the .notifyDataSetChanged method, I have tried resetting the adapter... nothing worked.
According to your comment, you dont update the array IN the adapter, but an array held by the activity you passed to the adapter once. Thats why the adapter isnt updating properly. You are changing the array outside of your adapter-class, which might not be the same array-object your adapter is using. At onResume(), your adapter is recreated with the new array and showing the new content.
A solution would be using the following custom Adapter class:
class MyAdapter extends BaseAdapter {
private Array[] myArray;
public MyAdapter(Array[] myArray) {
this.myArray = myArray;
}
public updateContent(Array[] myNewArray) {
this.myArray = myNewArray;
this.notifyDataSetChanged();
}
// your getItem, getView, and so on methods
}
Then from your activity, simple call myArray.updateContent() with your new Array and it will update immediatly.
Its never good to hold and manipulate an object used from one class (the adapter) within another one (the activity). Try to move all code for manipulating the array into the adapter and use methods to add/remove items. This will make it a lot easier finding this kind of errors!
Hi I have an activity which holds a layout, the layout is divided into two linear layouts. The first layout has 4 buttons. The second one has fragments. Basically with each button press, a new fragment is displayed. All the fragments hold a layout . This layout has an edit text field, a button and a list view. Now everything is working fine, no errors till now. But the problem I am having is , when I try to create a database object and pass the context of the fragment class as parameter in the contructor, it simply shows an error. Here's the code...Please have a look and guide me how can I solve the problem.
String text = null;
EditText enter_task;
// enter_task would be provided with its id, not a problem,
text = enter_task.getText().toString();
try{
// this is where te problem is
// normally I could pass the context of the activity within the constructr of database class as parameter. But since this class is a fragment, I am simply not able to do so.
myDatabase_today = new Database(MyFragment_today.this);
}
The solution which eclispe provides to the problem are:
1-> Change contructor Database(Context) to Database(MyFragment_today).
// here MyFragment_today is the fragment class's name
2-> Create contructor Database(MyFragment_today).
Could anyone please solve this problem. I mean we can pass the activity's context , but not the fragment class's context, then how to proceede further.
Use getActivity() instead of the Fragment class name
myDatabase_today = new Database(getActivity());
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]?