Photo doesn't change when i update recyclerview - java

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)

Related

How can I restore the state of an AdapterViewFlipper in a Fragment?

I have a Fragment that shows different view by a AdapterViewFlipper.
The AdapterViewFlipper is being set with MyCustomAdapter that contains 'View 1', 'View 2', 'View 3', and 'View 4', and its in a layout resource file that I inflated in my own Fragment "onCreateView()".
The Problem I'm facing is whenever I rotate my device, the current view in the AdapterViewFlipper goes back to the first view that was added in MyCustomAdapter.
For Example: if the current view in the AdapterViewFlipper is showing 'View 2' and the user rotates the device, it returns back to 'View 1'.
So what I'm trying to do is to restore the current view in the AdapterViewFlipper and its state in the Fragment whenever I rotate my device.
Although I found this method that says I should declare the android:configChanges attribute at the element in the AndroidManifest and it worked like a charm but when I was reading about it Android didn't recommend it.
But this works fine in Activity.
So is there a way I can go through this myself?
So the first thing you need to do, is to make sure you are retaining the fragment itself. And not place a new instance every time your activity is re-created.
You can establish that with a simple check in your onCreate() method.
You can either check if the savedInstance Bundle parameter to onCreate() is null, in that case only you need to replace your fragment OR check if your fragment is already added to your FragmentManager.
if (savedInstanceState == null) {
// This is a brand new activity, and not a re-creation due to config change
getSupportFragmentManager().beginTransaction().replace(id, yourFragmentInstnace, stringTag);
}
OR
if (getSupportFragmentManager().findFragmentByTag(fragmentTag) == null) {
// This is a brand new activity, and not a re-creation due to config change
getSupportFragmentManager().beginTransaction().replace(id, yourFragmentInstnace, fragmentTag);
}
And you also need to call setRetainInstance(true) in your fragment's onCreate() or something.
That will retain the same instance of your fragment during a configuration change.
This should automatically allow your AdapterViewFlipper to maintain its UI state, which is the current item it's showing.
You can find a nice example here

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

Synchronizing RecyclerView's getItemCount() with onCreateViewHolder

This problem has been beaten a million times, but unfortunately, no answer on SO has helped solve my issue.
Fundamentally, my question is that, in a RecyclerView with a CardView in a Fragment, when and where should the following tasks be performed:
Fetching data from a server to the local database on the user's device
Processing the so-fetched local data
Instantiating and setting the RecyclerView's adapter
Calling the RecyclerView's notifyfDataSetChanged()
The RecyclerView in my implementation presently calls back only getItemCount(). onCreateViewHolder() and onBindViewHolder() are never getting called back.
(I have seen this answer and a gazillion more.)
Here is the sequence of how its being done:
An AppCompatActivity instantiates a Fragment
The Fragment's layout contains a RelativeLayout with a toolbar and an include tag for a ViewPager. The ViewPager layout contains another include tag that sets a layout with a RecyclerView in a LinearLayout. The layout XML with the CardView is set in the RecyclerView's adapter:
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
Log.wtf(LOG_TAG, "Inside onCreateViewHolder()");
View myView;
LayoutInflater inflater;
inflater = LayoutInflater.from(parent.getContext());
myItemView = inflater.inflate(R.layout.my_row_layout, parent, false);
MyViewHolder myViewHolderItem = new MyViewHolder(myItemView);
return myViewHolderItem;
}
There's no ScrollView in any layout
The Fragment's onCreate() calls a method to fetch data from a server
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Some cache processing
args = getArguments();
myDBHelper = MyDBHelper.getInstance(getActivity());
Intent intent = getActivity().getIntent();
// Search comes from search intent
if (intent.getBooleanExtra(MyContract.MY_SEARCH_REQUEST, false))
{
...
getDataFromCloud("", true);
getDataFromLocalDB(false, item);
} // of if search intent
// Plain intent
else
{
getDataFromCloud("item", false);
getDataFromLocalDB(true, item);
}
} // of onCreate()
This data gets populated into a local database on the user's device
Another method in the Fragment's onCreate()filters the local data into an ArrayList
This ArrayList is presented in the RecyclerView - CardView combo finally to the user.
notifyDataSetChanged() is called in the Fragment's onActivityCreated(). But the fact is, its not making a difference anywhere it is called from. Also, the adapter is instantiated in the onPostExecute() of the AsyncTask that creates the ArrayList for the CardView from the local database.
Here's the log that results on running the app:
01-03 08:47:34.546 13489-14033/com.my A/MyDBHelper class: Create View-1 query: CREATE VIEW
01-03 08:47:34.562 13489-13489/com.my A/MyFragment: getItemCount: 0
01-03 08:47:34.584 13489-14033/com.my A/MyDBHelper class: Create View-2 query: CREATE TABLE
01-03 08:47:34.638 13489-13489/com.my A/MyFragment: getItemCount: 0
01-03 08:47:34.722 13489-13489/com.my A/MyFragment: getItemCount: 2
01-03 08:47:34.743 13489-13489/com.my A/MyFragment: getItemCount: 2
In the above log, the View-1 query fetches server data and the View-2 query processes the so-fetched local data.
I have log statements in the onCreateViewHolder() and onBindViewHolder(). As evident above, these methods are just not being invoked, despite a positive return from getItemCount(), which is the size of the ArrayList. The app just shows the toolbar, and an empty white card, despite there being two records or items to be shown.
Been staring at these logs for the past couple of days with no progress or clues. Many thanks in advance for your expert advice or pointers (and for saving what's left of my sanity)!
Finally, it was Jared Burrows's advice that drove the last nail in the coffin. BoyOboy, the only way to get it right is fight! (...almost always!)
Though I cannot pin-point what was going wrong, here's what I re-did:
Created a fresh new project with only the RecyclerView - CardView combo in a Fragment. Well worth the time and effort, in terms of the clarity it brought in.
Read-up this very good resource.
Switched back to the ListView implementation of my app, first got the CardView right, into the ListView
With a fresh new understanding of RecyclerView, systematically replaced all the ListView code with the RecyclerView counterpart
In the app, the custom RecyclerAdapter and ViewHolder live in their own, independent classes now
Was stuck for another couple of hours with the "RecyclerView: No Adapter attached; skipping layout” error; nothing was showing up in the Fragment. That's when Jared Burrows's advice pitched in.
The RecyclerView is now looking all hunky dory, waiting to throw up the next challenge: animation!

Update Listview visible view (row) from another activity

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

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