ViewPager recache pages - android

When I add page after current page, and flip to it, I see not added page, but cached page.
Is this possible recache pages manually after adding new page if new page is near current page?
P.S. notifyDataSetChanged() in adapter doesn't help.

I apologize as I can't comment so this will have to do as an answer:
This will depend on the adapter you wrote or are using, and the exact method. Namely, if you were using a customized adapter with the appropriate overridden methods [which would be best for anything fairly complicated like this]:
When you add the new fragment/page, add it to the internal list within the page [which should work naturally with the other overridden functions, including getCount()]
Make sure to set up the fragment appropriately and implement its lifecycle accordingly so its data changes. [Ie, this is a possible source for your bug if you're using an adapter] If you merely used the onCreate and other basic lifecycle functions, then it may be an issue where the lifecycle method already occurred so the changes won't be taken place [Possible solution: call a function in this case]
That's the basics of the issue. Without any code for the adapter and how+where it's being used, I can't say much else. Hope this helps.

Related

Using a no-fragment activity instead of a one-fragment activity

While peer reviewing a colleague's code I noticed she created a new Activity and all functionality is just there without a Fragment.
In the old days of Android, this is what we did, but the last few years I and my peers always took the approach that every Activity should have at least one Fragment and no actual code should be written in the Activity apart from loading the Fragment of-course and maybe some higher end procedures.
I want to argue for always using at least one Fragment in every Activity, but I couldn't find compelling arguments about why it is better than a no-fragment Activity.
The out of the box argument I can think of is that it will be easier adding new fragments if needed, but if we know this will never be a necessity, why bother with a single fragment Activity?
Fragment is easier to extend and test, if you are writing another new feature, it is helpful for separating code. And you can also move your fragment code to another place easy.
Of cource, if you are sure that your code is very simple and stable, like demo or temp test code, you can also use Activity without fragment.

fragments best practices

Hello I'm new to the android ecosystem and wanted to inquire about best practices when it comes to defining a fragments content
currently I'm opening a connection to my database aswell as initialising onClick listeners in my fragment's onCreateView but I'm also aware that there exists onViewCreated and onCreate similar to a regular activity, while I'm familiar with where everything is placed in an activity, I'm not as sure about fragments, can someone help me out?
-thanks
onCreateView()
This is the place where you initialize your views (findViewById()) / attach listeners to them.
From android docs:
Called to have the fragment instantiate its user interface view
onCreate()
It's better to move the code that connects to the database here - code that doesn't depend on UI elements.
You can read more in the official docs here.

When (& where) are my fragments created

I'm using the viewpagerindicator library (http://viewpagerindicator.com/) to create some sort of wizard for my android app. It works fine and does exactly what I want.
I would like to "extend" the functionality a bit by having "previous"/"next" buttons in my ActionBar - pretty much as in Android's "Done Bar" tutorial - to step through the wizard. Works like a charm, too.
HOWEVER:
I would like to display information about the "next" & "previous" fragment in the ActionBar's buttons. Information I pass to the fragments that live in the ViewPager at the time of their "creation" (actually at the time of their object instantiation - using the classical "newInstance(...)" approach to create the instance of my fragment, store the parameters in a Bundle and extract them in the fragment's "onCreate" method). The same way the template does it, when you create a new fragment for your project.
So, this information is the thing I actually want to display in my wizards button to know what fragment is next and which was last.
The type of this information is not important for my problem. It could be a String or an icon or an int or ... anything else you want.
However, wherever I've tried to access my fragments data, the fragment has not yet been fully initialized (meaning its "onCreate" method has not been called yet).
I've tried it in the host fragment's "onViewCreated" method, because I thought that's where all its subviews should be initialized already (at least their "onCreate" method should have been called, I thought), but it seems that this is handled differently for ViewPager to retain only the number of fragments in memory that was set by setOffscreenPageLimit.
So, what I'm looking for (and probably just missing) is the correct callback method here. One that is called when the ViewPager's next Fragments have been loaded and initialized. If such a callback exists, I could place my little piece of code there to update the text in my "previous"/"next" buttons within the ActionBar.
Any help, comments, ideas are highly appreciated. If needed, I can also try to attach some code sample to better explain my setup, but I think it should be easy enough to understand what my problem is.
Thanks in advance!
P.S.: I also tried to do this by using EventBus to send "onFragmentInitialized" messages from my fragments within in the ViewPager and the hosting fragment. It actually worked, but it does not seems the proper way to do this.
When a Fragment's onCreate Method is called, its already preparing to be displayed, and practically its past the point where its considered a Next or Previous fragment instead its considered current.
A fragment's onCreateViews method is called after committing a transaction in the FragmentManager. which takes less than 1 sec to bring it in front of the user (depending on the device and runtime environment)
But in your case, your data should be initalized outside the Fragment that uses it, and displayed where ever you want by passing the data itself then displaying whatever you want form it.
decouple your data from android objects (Fragment, Activity ...) and you should be able to load, maintain, access it cleanly and without worrying about their callbacks.
The Fragment's arguments can be read and loaded in its onAttach callback rather than onCreate, the Activity will then (after onAttach is complete) get a onAttachFragment callback with the Fragment as a parameter. However, I doubt onAttachFragment will be called when switching between already loaded pages in the view pager.
If not, you could have the fragment notify the activity (through an interface) that it is now active during its onActivityCreated, onViewCreated or similar method.
But it sounds more like the activity should register as a page changed listener to the ViewPager itself, and update its state depending on the page rather than which fragment is active.
As a side note, ViewPagerIndicator is quite old now (hasn't been updated in 3 years), a more modern approach is the SlidingTabs example from Google, which has been built into a library available here: https://github.com/nispok/slidingtabs

Fragment not instantiating correctly

I'm having a problem instantiating Fragments in my program using the Support Library implementation. Here's a brief description of the task I'm attempting to perform and some of my attempts which haven't yet borne fruit:
The UI of my application is subject to change to meet user preferences. In order to do this, I'm using a Fragment for each different layout and replacing the active Fragment in the UI at a given time as per the user's instructions. Here are some ways I've tried (and failed) to do this:
I've tried adding the Fragments as non-static inner classes in my Activity. This approach worked so long as the user did not rotate the device. As soon as the user rotated the device, the application crashed (this is true for Portrait -> Landscape rotation and for Landscape -> Portrait rotation). Upon checking the issue using the emulator, I was getting an InstantiationException. I checked SO for some help, which led me to:
Implement the Fragment as a static inner class. When the Fragment initiates, it will expand its layout, and then from later in the control flow of the Activity, I can do stuff to the Fragment's subviews (in particular, add listeners to the buttons). Unfortunately this didn't work because I couldn't refer to the Fragment's subviews using [frag_name].getView().findViewById(). Something about referencing static objects in a non-static context. Once again, I checked SO, which led me to:
Implement the Fragment as a separate class altogether from the Activity. This seems to be what the Dev docs on developer.android.com recommend. Upon doing this, everything seems to compile fine, but when I try to refer to the Fragment's subviews (once again, using [frag_name].getView().findViewById()), I get a NullPointerException. When I add System.out.println() statements across my code to find out exactly what is happening, I find that the print statement inside onCreateView in the fragment is never getting fired, which implies that onCreateView is never getting triggered.
So now, I'm stuck. What am I doing wrong? The precise implementation of this isn't as important as learning something from the experience so I can get better at Android development, so if seperate classes are better than static classes or vice-versa, I don't really care which I use.
Thanks.
Figured it out. Turns out that in order to do what I wanted, I had to register the Activity as a Listener to each of the Fragments and pass "ready to enable buttons" messages back and forth between the two. To anyone using this question for further research, the guide on how to do that is located on the Android Developer guide, here: http://developer.android.com/training/basics/fragments/communicating.html

best practices for handling UI events

I have put the all the binding code for UI events on OnCreate(). It has made my OnCreate() huge.
Is there pattern around implementing UI events in android ? Can I add methods in View xml file and then I can put all the handler code somewhere else.
In a nutshell , I think I am asking how can I implement MVVM pattern with android app code ?
Stuff that I do:
Keep all onClick functions in the XML. Avoids a lot of clutter in the Java code.
Initialize event listeners as members of the activity class rather than keeping them in a function. I don't like too many curly braces in my code. Confuses the hell out of me.
If my list adapters get too big I keep them in a separate class rather than as a member of the activity class and then keep all view listeners there in the adapter.
To avoid creating too many onClick functions I sometimes keep one function like onNavigatonClick and then use view.getId() to see which button was clicked. As the XML is not checked for valid function calls, it leads to runtime errors if your function name is wrong.
If a particular view needs a lot of UI interaction code, I create a custom view with a GestureDetector to handle UI interactions.
I guess this is still quite basic as I haven't had much experience with Java yet.
In 1.6 and later you can specify onClick methods in your layout XML file to trim a bit of the fat. I generally just hide it all away in a initUi() method that I have my onCreate method call. This way at least the onCreate is easier to read.
Lots of good answers to this already. :)
If you're using Android 1.6 or later you might find the new fragments API helpful for organizing and partitioning your activities into several logical units.
onCreate is usually the best place for calling setContentView and setting up listeners, but the code for handling the user interractions normally goes in onClick, onTouch, onKey etc. routines.
Maybe if you posted your code we could see what you've done?

Categories

Resources