I am creating a submenu in a NavigationView that is populated with the last three projects the user has worked with.
RealmResults<Project> lastestProjectsReaml = mDB.where(Project.class).findAll().sort("pLastModification", Sort.DESCENDING);
ArrayList<String> recentProjects = new ArrayList<>();
for (int i = 0; i < 3; i++){
recentProjects.add(lastestProjectsReaml.get(i).getpName());
}
for (String value : lastestProjects){
recentProjectSubMenu.add(value)
}
My problem is that the list will not be updated if a new project is created or if one of the latest projects is deleted. Update the list with new projects is not a problem since I can do it manually every time the user creates one. However, when a project is deleted, I don't know how to deal with it since this operation is handled internally by the adapter and not in the activity.
Any idea how could overcome this?
Thanks in advance for your time.
After a couple of days breaking my mind to solve this, as soon as I posted the question, the solution came to my mind.
I simply added a changelistener to my RealmResults that will be triggered when adding/deleting projects.
RealmResults<Project> userProject = mDB.where(Project.class).findAll().sort("pLastModification", Sort.DESCENDING);
userProject.addChangeListener(new RealmChangeListener<RealmResults<Project>>() {
#Override
public void onChange(RealmResults<Project> element) {
setRecentProjectSubMenu(navigationView);
}
});
A small remark: within setRecentProjectSubMenu, the submenu has to be cleared. recentProjectSubMenu.clear();
Related
everyone.
I'm currently writing a vocabulary app ("Vocabulator) by using a room database and a RecyclerView to display the information.
My problem is that the way I implemented the feature to delete data from the RecyclerView (and the database) does not work on a dataset>10 items.
gif of how the delete function works
On the gif you can see that whenever an item is longClicked, a radio button for each item appears.
Upon clicking the button, the respective item is removed from the RecyclerView (and the db).
As you can see, this works on this very small dataset, but once I add more items the app starts to crash when performing the longClick.
Under the hood, it is implemented using a for loop to reiterate over each item like this:
#Override
public void onLongItemClick(int adapterPosition) {
//wordList.get(position);
// Show radio buttons
for (int i = 0; i < adapter.getItemCount(); i++)
{
vh = recyclerView.findViewHolderForAdapterPosition(i);
v = ((RecyclerAdapter.MyViewHolder) vh).getView();
rb = v.findViewById(R.id.delete_selector);
if (rb.getVisibility() == View.INVISIBLE)
{
rb.setVisibility(View.VISIBLE);
}
else
{
rb.setVisibility(View.INVISIBLE);
}
}
longClicked = true;
}
I can imagine this isn't among the most performant lines of code ever written.
However, that's the solution a beginner like me came up with.
I'd love to implement my delete feature in terms of its functionality exactly as demonstrated in the gif.
However, I can't find a way to make this work.
Can you give me any advice on the issue? :)
Thank you for reading.
I'm trying to fill a list view with data i'm receiving from and odata service in json format. The data is already fetched and can be accessed with getIODataEntry().
I'm appending the respective values to a string to see an output in LogCat and split the string afterwards to fill my listView with the single values.
ListView listView_CarrierCollection = null;
...
private void showData() {
Log.d("debug", "log 1");
String carrierCollection = "";
for(int i=0; i<getIODataEntry().size(); i++) {
carrierCollection += getIODataEntry().get(i).getPropertyValue("Carrname");
carrierCollection += ";";
}
Log.d("debug", carrierCollection);
ArrayList<String> list = new ArrayList<String>(Arrays.asList(carrierCollection.split(";")));
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.custom_textview, list);
listView_CarrierCollection.setAdapter(arrayAdapter);
Log.d("debug", "log 2");
}
everything works, but only after my devices' screen has turned off and has being turned on again or after i close and reopen the app. The logs instead are prompted instantly to logcat, but the listView only contains the data after reopening the app.
Am i missing something out? Every hint would be appreciated!
EDIT:
Finally got it to work - turned out it had nothing to do with the posted code above. I had some listeners, that were trying to update a TextField in a Fragment. It seems as if MyFragment.textfield.setText("test"); blocked any further operations in some way. Surrounding it with runOnUiThread(new Runnable(){ ... }) solved it for me and got the whole thing to work.
Nevertheless thank you for your ideas and help!
Late to the party but may help someone else in the future
In my case, I wasn't calling notifyDataSetChanged() when i was updating my mutable array list. Therefore it was only working when i was tuning sceen off and on again. But after calling notifyDataSetChanged() it worked as usual.
Hope it helps ;)
I am doing this:
// Member variable
List<String> items = null;
// in onCreate
items = new ArrayList<String>();
// later on in a Task (onPostExecute)
items.add(NewItem);
adapter.notifyDataSetChanged();
My List is in Alphabetical order. When I add an item, it simply puts it at the bottom. Any way to put it in the proper place?
(Yes it will be in proper order the second time you come back to this page, but not on adding it)
Edit: I am first putting it in order through a SQL script call.
My suggestion to your answer is that, as and when you add an item on ListView try to set the adapter again on the list at the time of adding item.
this way you get the refreshed data on your ListView.
I decided to research any methods for ArrayList and did not find any. I did find this, however:
items.add(NewItem);
Collections.sort(items);
Worked perfectly! I had to import Collections into the project.
I am banging my head for the last couple days in order to get this done but Im unable to. Someone please help me out!
Let me not tell u the whole thing and will try to explain it simply n clearly.
Im having 1 ArrayList. I am trying to replicate that into another one and trying to delete an item at a particular index. But this not only deletes the item in the replicated ArrayList but also the original ArrayList.
For ex:
var DuplicateList:ArrayList = new ArrayList();
DuplicateList = OriginalList;
DuplicateList.removeItemAt(2);
The above not only deletes the "Item 3" at Index-2 in the DuplicateList but also in the OriginalList.
I just need some workaround with this approach as this is the only way by which whatever I typed inside the controls present in an ItemRenderer of a FLEX List control that uses the OriginalList as a dataProvider is RETAINED, when I change the dataProvider of the List Control from OriginalList to DuplicateList. The following approach does not retain all the data.
var DuplicateList:ArrayList = new ArrayList();
DuplicateList.addAll(OriginalList);
DuplicateList.removeItemAt(2);
ListCntrl.dataProvider = DuplicateList;
Thanks for your help in advance...
A very, very important thing to understand:
ActionScript3 uses references to objects. Because of that, the two variables in this line of code refer to the exact same instance of an ArrayList:
DuplicateList = OriginalList;
So, when you remove an item from one reference, it is gone from the next. If you want two separate instances of ArrayList, then you need to clone it like you are suggesting later in your code.
So far, so good... but why is your ListCntrl retaining the data from the OriginalList? That doesn't make any sense at all. If you remove an item from DuplicateList and then use it as the data provider, then that item shouldn't be there. I think there is more to this story...
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.