Update Listview visible view (row) from another activity - java

Hi there.
H have a list view that populated by MyCustomAdapter. in my Custom Adapter, I retrieve data from server by json and keep them in ArrayList<HashMap<String, String>>
MyCustomAdapter constructor is like this:
public MyCustomAdapter(Activity a, ArrayList<HashMap<String, String>> d){
mActivity = a;
mData = d;
mInflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
and in my getView I retrieve data From mData and set them to views like Title, Description and so on that you can see in image.
I want update my listview data in back time when user goes to edit activity and edit some data there.
How can do that?
In Google+ app when you read a post and like that on post activity, when you back to list of all posts, that post like button was updated!! I want something like this
thanks for any help :)

Since you are using an ArrayList<HashMap<String, String>> an not a cursor/contentprovider your adapter won't be automatically notified automatically by changes on the underlying data.
One way is to use something like Otto (http://square.github.io/otto/) or any event bus to pass events, to notify your activities of some changes on the underlying data.
Your first activity should subscribe to the data update event, and then on your second activity you should send this activity together with the new data

Related

Photo doesn't change when i update recyclerview

I am trying to update the data in 'onresume' when I come back to my main activity from different activities but its photo is not updating without scrolling the list.
they don't work;
detailRecyclerAdapter.notifyDataSetChanged();
detailRecyclerView.invalidate();
You have to update the recycler view by passing updated data into the adapter by creating a setter method into the adapter.
fun setResultItem(arrResultItem: java.util.ArrayList<ResultsItem>) {
arrayList = ArrayList()
arrayList.addAll(arrResultItem)
notifyDataSetChanged()
}
Now, please update recycler view from activity by,
adapter.setResultItem(updatedList)

Deleting a View in a class method

In my activity I try to call a method from a class but it's not getting the right values.
This is ActivityTwo:
int id = intent.getIntExtra("id", 0);
LayoutInflater inflater = getLayoutInflater();
View mainActivity = inflater.inflate(R.layout.activity_main, null);
LinearLayout eventsLayout = mainActivity.findViewById(R.id.eventsLayout);
Log.d("ACTIVITY_eventlayout", String.valueOf(eventsLayout)); // gives the layout perfectly
Event.RemoveSpecific(eventsLayout, id);
finish();
This is the class(Event) with the method:
public static void RemoveSpecific(LinearLayout layout, int id){
View event = layout.findViewById(id);
Log.d("INSIDE_removespecific", String.valueOf(event));// event is null
layout.removeView(event);
}
And in my MainActivity it's working fine:
LinearLayout eventsLayout = findViewById(R.id.eventsLayout);
View event = eventsLayout.findViewById(id);
//Log.d("MAIN_event", String.valueOf(event1)); // gives it perfectly
eventsLayout.removeView(event);
I also add this view in my MainActivity and use .setId(id) to give it the right id. So my question is, why is the View in my class method null, while I pass the right LinearLayout from my activityTwo?
Where does the id come from?
I have the Event class which contains an id, name, date, & description. This class also has a static ArrayList called eventsList. Whenever the user creates a new reminder I create a new Event using my class and giving it an id as Event.eventsList().size() (after adding it to my eventsList [so the first event id is always 1]), then I create a new View and pass the recently created Event details and use setId() to give it an id [1]. Then in this View I have a button which has an onClickListener which passes the given View id and the LinearLayout (where the View was added) to my Event.removeSpecific() method.
App flow:
The user clicks a button in MainActivity to create an event, then the button click then use startActivityForResult() with an intent to open a new Activity where the user puts in a name,description and date for the event, then I create an intent with putExtra() methods and then use setResult(RESULT_OK, resultintent) to send the data back to MainActivity. Now when the MainActivity gets the data back I use .getStringExtra() to create a new Event object with the data and add it to may Event.eventsList ArrayList, then I use the following:
LayoutInflater inflater = getLayoutInflater();
View event_Exmaple = inflater.inflate(R.layout.event_example, null);
and set the textView's with the data I got, and use event_example.setId(Event.eventsList.size()) to give it an id.
After that I add this to my LinearLayout (which I declared already in the MainActivity):
eventsLayout.addView(event_example)
Now I mentioned that the Event class has a date field. I use that to set up an alarm with AlarmManager. With the AlarmManager I send the current Event object's data through the intent and when the user gets the notification it opens up a new Activity which gets the given Event object data (with intent.putExtra()'s) and that's the part where the user clicks on a Button. I want to remove the given Event object's View from my LinearLayout in the MainActivity XML.
well since you didn't share where the id value come from (from where the intent gets its data/how you put the values in it/where the values come from), I assumed this solution :
whenever I use a 'switch' statement with View Ids it tells me a very important warning which is
Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them in switch case statements
that means that view Ids doesn't have a stable id in some cases that you shouldn't consider them to be final.
I guess in your case when you get an id to your event view and then inflate the layout view, the inflate procedure involve changing the 'int' id value of the event view so whenever you query the old id it returns null since the event view inside the inflated layout view now has a new 'int' id value.
I don't know why it works in main activity since you didn't share full code where you get the id from.
so I guess the only solution is that you should find a way to get a fresh copy of the id after you inflate the view you want to work on in the method.
Update
the problem is with this block of code
View mainActivity = inflater.inflate(R.layout.activity_main, null);
everytime you inflate a new layout view thinking that you have the one used by main activity back there but instead you're creating an entirely new one with new views and new Id's.
that would be why you could get the view in main activity but you can't get it from a newly inflated view.
Update
if you need to remove this item using the id and have a static array stored in the view custom class, call a getter on the static array and remove the item from it instead of trying to remove the view itself.
a better implementation of the whole situation is to store these events in a database using room instead of the static array, that way you could delete/add/edit any event anytime with just one line of code, if you're willing to do this you can start by reading the developers documentation of room.

RecyclerView doesn't refresh after modifying database's row

I am programming an app for Android. I uploaded it to GitHub: app
I have a ViewPager (MainActivity.java) controlling two Fragments. On the first Fragment (FirstFragment.java) you can add People (People.java) which appears on the RecyclerView (also on FirstFragment.java). When you click one of the list items on the RecyclerView its details (name and id) appear on the second fragment (SecondFragment.java). The SecondFragment.java also contains a button you can delete the selected People with.
To store the People objects I used a List of People and managed it with the methods in PeopleLab.java. The program was working fine: I could add/remove People objects to the list and it appeared on the RecyclerView fine.
After that, I decided to replace the List with a database. It only meant creating the database (the 3 files in database folder) and editing the already existing and two new methods in PeopleLab.java. The other files remained untouched.
The database is working as expected (checked it with sqlite3), I can add/remove People like before and the queries work. My only problem is that the changes don't appear on the RecyclerView. But if I close and reopen the app, the changes appear.
It's like the RecyclerView doesn't care about the database in runtime, only do when the app starts (or closes, not sure).
Do you have any idea what could cause the problem? My only guess is I miss something about how Android apps handle databases.
P.S.: sorry for my English.
You do call notifyDataSetChanged() on the adapter but you don't provide any new data for that adapter.
In your FirstFragment :
private void updateUI() {
PeopleLab peopleLab = PeopleLab.get(getActivity());
List<People> peoples = peopleLab.getPeople();
if(mAdapter == null) {
mAdapter = new PeopleAdapter(peoples);
mRecyclerView.setAdapter(mAdapter);
} else {
// You actually have to change your dataset
mAdapter.changeDataSet(peoples);
}
}
And in your Adapter :
public void changeDataSet(List<People> people) {
this.mPeoples = people;
notifyDataSetChanged();
}
This some brutal way to do it though.
It would be better to notify your adapter on insertion / removal calling notifyItemInserted(int itemPosition) or notifyItemRemoved(int itemPosition). (And refreshing your dataset, by the way)
It will not work automatically.You can either use to notify the adapter the underlying data has been changed so that adapter can fetch and reload the data.It can be done using adapter.notifyDataSetChanged()
Or use can use CursorLoader to achieve the same

Load recent apps into GridView

I am creating a feature inside my Android app that will allow users to see their 6 last used apps in a gridview with only the application image. So far I have tried this:
//Load recent used apps
ActivityManager result = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
ArrayList<RecentTaskInfo> apps = (ArrayList<RecentTaskInfo>) result.getRecentTasks(10, ActivityManager.RECENT_WITH_EXCLUDED);
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, apps);
recentappsGridView.setAdapter(adapter);
But this only shows a lot of text in each row and column. How can I fix this/make it happen? Please note that I am already using a ListView within the same activity with a method for its click events.
Create a subclass of ArrayAdapter. Override getView(). Set up your cells to be images, not TextView. Use resolveActivityInfo() on the Intent you get from baseIntent in the RecentTaskInfo to get an ActivityInfo object. Use icon on ActivityInfo to populate your cell.
I haven't tried that recipe, but it should get you closer.

android listview pagination implementation

Hi am working on an android application. And am using a listview in some of my activities.
The problem is all of my listviews displayed are much longer so that the user needs to scroll the whole list to go for the last item.
Am trying to implement a pagination for this, like at first say only 20 items need to displayed on the listview. And at the end of my listview i need a titlebar which have next & previous buttons and on clicking on next button the listview will load the next records from 21st to 40 and so on.
Am using java rest webservice to load the listview.
Can anyone give me a good suggestion for solving my problem.?
Solution 1:
You can load all the data at once if its not TOO MUCH, store it locally & then you can navigate in that locally stored data. Define some variables like StartPoint & EndPoint & get the desired data from that stored data. Increment decrement the values of StartPoint & EndPoint by using the PreviouButton & NextButton.
Solution 2:
Get only the desired data from your data source for example 10 records each time when a Navigation button is clicked.
I suggest than you load list data in a custom Adapter class that extends BaseAdapter class. Like #oriolpons suggested, you should add a footer view, and when you click on button next call some method that is fetching next for example 20 rows, and then add them in your adapter object and call notifyDataSetChanged().
For example
private OnClickListener mListener = new OnClickListener() {
public void onClick(View v) {
ArrayList<YourObject> al = getSomeData(int startRow, int endRow);
MyCustomAdapter adapter = new MyCustomAdapter();
for(YourObject a : al)
adapter.add(a);
getListView.setAdapter(adapter);
notifyDataSetChanged();
}
};
Hope this helps.
The easiest solution is to add a footer view to the listview. And on the item click listener you can see if it is the last position (load more items), or not
//add the footer before adding the adapter, else the footer will not load!
View footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listfooter, null, false);
this.getListView().addFooterView(footerView);
#Tijo . Refer this site http://www.androidhive.info/2012/03/android-listview-with-load-more-button/. You can have a button which would call the execute method of Async task and that will load the remaining list for you.

Categories

Resources