updating recyclerView in onResume (); - android

I have encountered some problems in "recreating" an adapter from the recyclerView in the onResume method.
Basically, this is my scheme.
MainActivit  -ViewPager
   - fragment A (has a recyclerView)
   - fragment B (nop)
   - fragment C (nop)
   - fragment D (it has the same recyclerView as the framgnet A)
onResume I always call for
> myCustomAdapter adapter = new myCustomAdapter (
> mListItems,getContext(),ParseUser.getCurrentUser().getObjectId(),
> "type");
> recyclerView.setAdapter(adapter);
but this causes some problems, like when I go back to MainActivity from another activity. For example.
Activityt A
 - click on item in recylerView
 - start Activity B
Activity B
user does some actions, sees some news, and returns to Activity A.
Activity A
recreates the adapter and set recyclerView.setAdapter (new Adapter);
this is slow, causes a delay of 2 seconds after onBackPressed is pressed in Activity B.
I also have a setMenuVisibility method that also does the same thing as onResume, because as informed in fragment D, I have the recyclerView in fragment A, so if a user makes some change in the recyclerView that is in fragment D, I need update the recyclerView of fragment A when the user returns to it.
Why the same recyclerView in Fragment D is in Fragment A?
We can consider the following, in fragment A, I have a recyclerView that contains only the "user interests", and in fragment D, I have user information such as user name, photo, etc ... and also the "user interests".
Conclusion: The problem is when I return from Activity B to Activity A, and when I alternate between fragment A and fragment D in viewPager, this causes a delay for the re-creation of the adapter.
What should I do in this situation?
I apologize for this horrible English, I'm using google translator.

It is a Scope Problem. You need to define adapter in somewhere class member.
If you want the data presented in Fragment A and Fragment D different, then make adapter as a member of each other, and init it in each Fragment.onCreate(). So it won't recreate adapter evert time. (Make sure ViewPager has enough cache number, or it will still recreate the whole non-cached Fragment)
If you want the FragmentA and FragmentD display identical data or part of the same data, create adapter in MainActivity.onCreate and pass it as parameters into FragmentA, FragmentD.
It is not need to recreate adapter every time onResume because it's really a heavy job. No need to change any view layer attributes. Make sure the data(adapter) which you want to share is in the same scope or can pass to it.
For example:
//MainActivity
private Adapter adapter;
void onCreate(Bundle savedInstanceState){
//...other stuff
adapter = new myCustomAdapter (mListItems,getContext(),ParseUser.getCurrentUser().getObjectId(), "type");
}
public Adapter getAdapter(){ return adapter;}
//FragmentA or FragmentD
void onCreateView(){
MainActivity activity = (MainActivity) getActivity(); //This fragment should be created with `MainActivity`
recyclerView.setAdapter(activity.getAdapter());
}

Do not set set image using "src" attribute of ImageView when dealing with large images or multiple small images
Use an image loading library like Glide or Picasso.
The following snippet is for Glide v4
Glide.with(context).load(<url_or_res_id>).into(imageView)
You can pass url as string. Or if you are loading images from drawable, you can pass its resource id (eg. R.drawable.image_id)

Related

Is it a good practice to start a fragment from an adapter?

I have an activity with fragment A. Fragment A hosts a list in recyclerview which requires an adapter. When an item from the list is clicked I want to open another fragment, say B, showing additional details about the item.
I can open fragment B in three ways:
From the recyclerview adapter itself where I will have the item position etc.
From fragment A using callback from the adapter, since the adapter has all the required info like position, object etc.
From the activity, again using callback. If i do from the activity, i will have to add callback interface from adapter to fragment A, and finally to the activity. Looks too much.
I want to know what is the best way to open fragment B.
Hey its not good practice to start the fragment from adaptor. because it will be very complex to find the container of fragment. so please always try to start the fragment from main activity which will be parent of all fragment.I hope its help you.
Option 2 is always good approach->
2. From fragment, A using callback from the adapter, since the adapter has all the required info like position, object etc.
"According to MVC pattern adapter is always used for binding view with lists. So adapter should always independent from the fragment so the Single Responsibility Principle will always be handled. So, there should be no dependency from the adapter to fragment but fragment to the adapter. When you call fragment or activity from adapter it will create a cyclic dependency with one another so memory will not clear until you finish the apps. You can call any callback method of the fragment from the adapter which method will call the desired fragment you want."

Can I add a fragment to a FragmentActivity outside of whats in the viewpager?

I'm new to fragments. I have an activity that extneds FragmentActivity and uses the ViewPager to swipe between fragments.
Within one of the fragments I want to launch a new fragment that is "outside" of whats in the view pager. Is it possible to add a fragment like this or do I need to start a new activity with the fragment.
Now I have it launch a new activity but it is very slow.
Activity A
Fragment A
Fragment B
Fragment C
Activity B
Fragment D
Fragment A
So fragment A can launch acitvity B to get to fragment D but ideally it would be cool if I could just inject fragment D in Activity A
Hope that makes sense.
Yes, you can, but I strongly suggest you avoid it, unless you have a good reason to do so.
The ViewPager is (I assume) hosted in your Activity. The ViewPager obtains its views from its adapter. (A FragmentStateAdapter or similar). So you could tell the activity to change its layout (and or hide the Viewpager and show another FrameLayout) or you can simply launch another Activity that contains a single fragment. This is also fine.
Messing with the ViewPager/Adapter is usually complicated and you may waste time trying to make it work.
On the other hand, you could add the Fragment to the ViewPager's Adapter and use the getType of the adapter to return a different type of Fragment.
So you could do (pseudo code):
mPagerAdapter.addFragmentDToTheDataAtPositionZero(); //longFancyName ;)
mPagerAdapter.notifyDataSetChanged();
mViewPager.setCurrentItem(0, false);
that'd add Fragment D to the "top" of the viewpager and will switch to it.
Your Adapter then has to use an Interface to determine what type of fragment must be instantiated…
The getItem of the adapter would look like… (again, pseudocode)
#Override
public Fragment getItem(final int i) {
final FragmentTypeInterface f = yourData.get(i);
if (f.isD()) {
return FragmentD.newInstance();
} else {
return OtherFragment.newInstance();
}
}
And so forth… :)

Refreshing a fragment view from MainActivity

So I currently have an app that has 4 tabs (fragments). They are fragments A,B,C,D, in that order.
Fragment A is the first view opened (along with B because viewPager loads the view before and after the current view).
When I click a button in Fragment A, it sends Data back to MainActivity and then sends that data out to Fragments B and C.
However, this is where the issue comes into play. Since Fragment B was already called, the View isn't updated once I click the button and send the data over, but Fragment C is because the view wasn't called before.
Is there any way that I can remedy this?
You can do it a few ways right.
Just set the data to the fragment and have it update its views
Have all the fragments like B and C register themselves to recieve data from the MainActivity and when MainActivity gets it's data set you tell all the registered receivers of the new data
Recreate the fragment
Use an event bus and tell all subsribers of the new data and MainActivity, Fragment B would get notified of new data. Fragment C would get its data when created by MainActivity
I think this list is pretty endless tbh
The key here is the fragments need to fetch the data from the actvitiy aswell as be updated by the activity. In which case you need to break your UI update behaviour out of onCreateView and into its own updateUI() function. updateUI(MyData) can then be called from onCreateView and also called in a setMyData() on the fragment. Just make sure you check the isAdded flag in setMyData.
This pretty much says it all:
http://developer.android.com/training/basics/fragments/communicating.html
I used a simple fragment communicator that allows the activity to call the fragment, and the same for a fragment to talk to the activity.
You can change the views with the new data based on calling the method from within the activity. The way I do it is set the fragments in the activity then pass them into the page adapter this way I can call the methods within the fragment and implement the fragmentcommunicator interface on the fragments.
You can honestly even avoid the interface if you want, but if you are going to include the same method in all the fragments to talk to them it is easiest.
If you show code, I can show you a quick example.

ViewPager with Fragment reload at first and last page

I'm trying to create a ViewPager with six fragments but only 2nd fragment to 5th fragment contain data that I want to show and the first fragment and the last fragment I want to be used to reload the data and set the position to the 2nd fragment again. The overall flow is like this :
1st (reload and go back to 2nd) <- 2nd fragment <-> 5th fragment -> 6th fragment (same with 1st)
what I've tried is I create a callback from the 1st fragment and 6th fragment like this
public static class callbackFragmentLoading implements callbackFragmentLoad {
#Override
public void onLoading() {
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(2,false);
}
}
and I passed the callback to the fragment constructor so I can called the onLoading function in the onActivityCreated. But I everytime I do it the application will be force closed and the logcat shows
recursive entry to executependingtransactions
is there any way to do this? or my method for doing it is wrong?
Thank You
is there any way to do this? or my method for doing it is wrong?
Messing with callbacks between Fragments of a ViewPager isn't probably such a good idea. Instead I would do it like this:
Don't load any data(like with a Loader) in the Fragments from the ViewPager, instead let the FragmentActivity do it(and the Fragments will get it through methods from the Activity).
Your two loading fragments(position 0 and 5) will call in their onResume method a reload action on the parent Activity(like a Loader restart)
At this moment the Activity will load/reload the data and when that finishes it will set the ViewPager to the correct items(either 1 or 4)
in the onResume method of the data fragments you'll refresh the fragment's data(here you may need to use some sort of signaling system because you'll need to duplicate the refresh code in the onCreateView(some fragments may have their view destroyed if they are far apart from the current visible position)).
As I don't know many things about the inner data fragment I've written a basic skeleton sample(without the data loading in the activity).

How do I make a list loader to reload from a detail Activity in Android

I have a ListFragment, which data is loaded by a SimpleCursorLoader(own imlementation; it loads with a curser and does not use URI).
When an item in the list is selected. I either start up a new activity (detail activity) or I show what is selected in the detail fragment next to the ListFragment. Depending on the screen size.
If the detail fragment is added to the ListActivity, I have figured out how to reload the list. I assign an interface to the ListActivity and call it from the detail fragment, when the change is happening. And in the list fragment I reload the list using getLoaderManager().restartLoader(0, null, this);
Now my problem is, if the detail activity is loaded, I don't have access to methods on the ListActivity. I could probably implement some observer pattern. But there must be a best practice for this.
How do you make a ListFragment reload the list, when a detail fragment has changed the data in the database.
Try moving your list creation code to onResume. That way it runs on activity creation and every time you go away from the activity and come back.

Categories

Resources