ViewPager skip views on return leaving blank - java

I'm making an app with 4 main Views. I want that all of them stay on a LIST menu on top (That's ok for now).
Using Fragments, I have the ability to change the view without actualy going to other activity, but since one of my Views have a ViewPager, it's NOT working at all (When I first load the view, the content is OK, but on the seccond time, views on the ViewPager disapear, and appear only if I go 2 index positions away, and go back) (See picture, shown for the first load time, and seccond)
Note that the ViewPager IS NOT to show de menu's items, it's in fact, part of the Fragment of the current menu item (in this case, "Simula'c~ao")
My question is: Is this a known issue, is there a simple way to fix it, or I must do it in another way? I already searched for this problem on the internet, but nothing worked for me (invalidating, setting up the on getItemPosition to return POSITION_NONE...)
I have looked into the ViewPager class, and everything seems to be OK, I have modified it, so that everytime I render the views, it forces to render everything, but neither this way worked.
I have tried to set visibility to GONE and VISIBLE
I have tried to detach and attach the adapter
Tried to cache the views, and return cached.
One thing that semmed to work: Changing the orientation of the Phone. That worked.
Tried lots of things that I even remember... I'm a little furious with this, because the past 24 hours didn't helped me to solve this "mistery" at all. I hope that some of you can =]
My code:
https://www.dropbox.com/s/u4mlxr3k6ta9yrm/MainActivity.java
https://www.dropbox.com/s/2dqfnzjs2wl89hj/SimulationFragment.java
Views:
https://www.dropbox.com/s/d6ruc1zjovqu6ob/activity_main.xml
https://www.dropbox.com/s/lp1iea13klr77iq/activity_simulation.xml
https://www.dropbox.com/s/1mkl3jqmo7g4wh8/item_simulation.xml

Well, after long hours trying to discover what the hell was this about, #anup-cowkur guided me to a path that would solve my problem.
At first, I tought that the problem was on the PageView, I downloaded the support library, edited, changed LOTS of things, but the problem was not there.
In fact, the problem is on the FragmentPagerAdapter. He uses a sort of "caching" for each of the ViewPager fragment. Because of that, he wasn't "notified" when I returned to the view, causing the last fragments shown to not "actualy" exist on the parents view (in this case, the main fragment, that holds my others fragments from the ViewPager).
Since they are registered on the FragmentManager, what I did was hack into the FragmentPagerAdapter, implementing this method:
FragmentPagerAdapter.java
public void clear(ViewGroup container){
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
for(int i = 0; i < getCount(); i++){
final long itemId = getItemId(i);
// Do we already have this fragment?
String name = "android:switcher:" + container.getId() + ":" + itemId;
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if(fragment != null){
mCurTransaction.detach(fragment);
}
}
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
}
And then, call it on my "onCreate":
myPagerAdapter.clear(mViewPager);
done. All fragments are FORCED to be removed from the FragmentManager, causing the "cache" to disapear.
It's not the best solution, but the only one that worked.
EDIT
You can find the hole file here:
http://pastebin.com/07adWVrr

You are using a FragmentStatePagerAdapter. This adapter uses fragments inside the ViewPager. You have this ViewPager inside another parent Fragment. So you have Fragments inside a Fragment. Nested fragments are not supported. This is why you are having problems. See: Why it is not possible to use ViewPager within a Fragment? It actually is
Your best bet is to use a normal PagerAdapter instead of a FragmentStatePagerAdapter. This uses regular views instead of Fragments and should work fine.

If the issue occur when it is necessary to make more than one swipe to obtain get the page on screen, this code solves it:
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);

Related

Manage textview and switches inside tab fragments

So guys my question is simple, i'm migrating my app layout to android tabview.
I had all the code of the switches and textviews inside my activity_main.xml layout file.
Now i made 3 layout fragments resource xml files and i migrated everything there, plus i included the layout app bar in the activity_amin file
I left all the java codes of the layout elements inside MainActivity.java without changing anything.
Now the app crashes becouse all the layout elements declared inside the fragment layout files return null.
Do i have to set the layout elemnts codes inside the frgament java associated files?
Thank you
You should definitely use the Fragment.java-classes for addressing the gui-components of a fragment.
If you need a refresh for how to work with fragments you can read thru the codelab here: https://codelabs.developers.google.com/codelabs/advanced-android-training-fragments/index.html?index=..%2F..index#0
Best
Sebi
That's simple you probably working inside onCreateView of the fragment
try to work inside the onActivityCreate, because onCreateView the view is not ready and every thing will return null, so if you work on :
Kotlin:
override fun onActivityCreated
Java :
#Override
public void onActivityCreated
that dosen't happen.

Viewpager with listviews

Has anybody had any luck with a view pager switching between fragments that contain listviews? In particular, the listviews I am working with inflate two separate layouts to get the desired effect. However, to my understanding this is causing the viewpager to disappear as well as the tabhost. I believe this to be so because it is working with other fragments that only inflate once.
Edit 1:
I was trying to see what would happen if I used one of the fragments that showed the tabhost and used the viewpager first. I would switch views and see the correct next one. However, shortly thereafter one of the fragments that does not show the tabhost or use the viewpager, for some odd reason, would load up.
Edit 2:
It's weird it is not even loading up on the right page. It should load up on 3 but instead it loads up on 2 and replaces the former screen that was actually supposed to be there.
Adding listviews to two fragments is very easy.
In short, you want to have a main activity that's the viewpager itself. Next, the viewpager is going to host two tabs (can be as many as you want, really) which will both contain separate layouts...each with a listview of its own.
Code
The first thing we need to do is add some classes. I've made a GitHub Gist of 4 classes that I'd like you to implement into your project. You'll need to change the package name and R class to meet your project's needs.
Gist: https://gist.github.com/Andrew-Quebe/b3e9f1d0f8223ba2f8df
Second, we need to make our host activity. This is what will show the tabs and toolbar. See this next Gist as I don't want to spam up this answer with tons of code.
Gist: https://gist.github.com/Andrew-Quebe/8add2fc064397ab8efe4
You've probably gotten an error in the MainActivity.java file due to a missing ViewPagerAdapter class. That's up next!
Gist: https://gist.github.com/Andrew-Quebe/fd70ee97c2e00d72f025
And finally, the tabs that'll show our listviews!
Gist: https://gist.github.com/Andrew-Quebe/3e2a87706c98a69e7353
My apologies for taking so long in my response...I actually took the time to build all this code and error check it for you. I had an example of tabs once before but it was outdated...you weren't the only reason I made all this code. The full project can be found on GitHub here: https://github.com/Andrew-Quebe/SlidingTabsExample
Hope this helps!
Edit:
Download the sample APK to see how everything looks: https://github.com/AMQTech/SlidingTabsExample/blob/master/APKs/Sample.apk?raw=true
First of all I would like to apologize. I pointed you all in the wrong way. I did some research and as it turns out you cannot have the fragment container (frame layout) in the activity layout already. All I had to do was put the fragment container into a different layout and inflate it when the time came to switch to another fragment class and that fixed it. Thanks to everyone.

My detail fragment still exists when I'm in portrait

In a master detail flow, when I go from landscape to portrait, my detail fragment is still there.
What's the best place and time (lifecycle callback) to get rid of it? I only have to get rid of it because my menu items and actionbar title are coming from the detail fragment, in portrait mode, and so it doesn't make any sense.
In the onCreate method of your activity, you could try that:
DetailFragment detailFrag = getFragmentManager().findFragmentByTag
if( <your logic to see if portrait> && detailFrag !=null && detailFrag.isVisible()){
<Remove the Fragment using a normal fragment transaction>
}
Short answer would be onCreate
And there are multiple things you would need to know
When screen orientation change, which is one of the configuration changes, which will trigger Activity recreation.
You can stop Activity recreation by setting onConfigChange, but do NOT do this unless this is a special app, e.g. Camera
Activity recreate is trying to help you, and your case is exactly where it is needed, and you can do the correct setup in onCreate
There are multiple ways to handle the different orientation, the basic way would be to use different layout, e.g. for your layout, say activity_main.xml, you can define a similar xml with the same name, under layout-land folder. When you setContentView(R.layout.activity_main), Android will select the right layout for you depending on your configuration.
In your case, you are switching between 2 fragments and 1 fragment, there are additional works you need to handle for the fragment transaction. However, this would depends on your existing FragmentTransaction and this will go too broad to go on, so I will stop here.

Change fragment content when page changed, ViewPager

I have a ViewPager, that i'm populating with fragments which has a listview inside. The point is that i have to show a really big amount of data, and i need to make pages, so i only request littel amounts of data.
My problem is that i need to call an asynctask to retrieve the data when the page is changed, and fill the listview of this page, how can i do this? How can i change that listview in the onPostExecute of the task?
PS: i have used an eclipse template for tabs + swipe activity, so im not posting my code.
I'm not sure I got your problem right, but the first thing that comes to my mind, is that I would use an AsyncTaskLoader instead of a simple AsyncTask. From my (limited) experience, loaders solve a lot of problems when it comes to Fragment/Activity lifecycle/configuration changes.
Loaders guide (Android Developers)
No matter what method you are using to get the data, changing the content of the list view in page B after loading the data in page A shouldn't be much of a problem: you have plenty of options, from simply saving the data for page B in the Activity (then changing the page with setCurrentItem and intercepting the page change event with setOnPageChangeListener),
to a more elegant approach employing a SQLite database (which btw would allow you to do some caching on the results, if possible).
Oh, and let's not forget that, if you are using an implementation of the abstract class FragmentPagerAdapter you can probably pass the data directly from one page to the other, as this PagerAdapter implementation
represents each page as a Fragment that is persistently kept in the fragment manager as long as the user can return to the page.
(just use getItem(int) to get a reference to the page you need. I never tried this myself, though).
Hope this helps
EDIT I just found out that getting a reference to the current Fragment shown in the ViewPager is tricky if you are not using a FragmentPagerAdapter: if this was the root of your problem, information about how it can be done can be found here:
Update data in ListFragment as part of ViewPager
Retrieve a Fragment from a ViewPager
Communication between ViewPager and current Fragment

Adding tablet support: Fragments and Activities for Master/Detail (Android)

I'm implementing a fragment hierarchy similar to the one described in Fragments (Android Developers).
In adition in tablets in portrait the app should behave as in the second case. My problem is to handle the transaction from an orientation to other.
The first idea I considered was:
From landscape-to-portrait:When the activity A goes to portrait: Remove the fragment B to the view. Start activity B for result passing the propper values for recover the original fragment B state
From portrait-to-landscape: When the activity B goes to portrait. finishes (with the fragment 2 status in the result). The activity A with the result restores and adds the fragment B to its layout.
But this solution is pretty complex and I think it provably is not a nice idea. The alternative solution I have considered is only to have an Activity. That activity layout is:
<FrameLayout>
<LinearLayout>
<Fragment A>
<Fragment B>
<Slot>
For small devices:
The app removes the fragment B and when a item is selected add to the backstack the fragment to the "Slot"
For tablets:
Using fragmentTransactions the fragment B is moved from Its position to the "Slot" using the backstack to behave properly to the orientation changes
I think the second option sounds better but, is the correct way of doing this?
Thanks
If you want my advice, I'd say it depends on way too much factors. I think you should stick with what you find manageable enough. It depends too on how complex your app's screen flow is.
Keeping it in one activity is, for me, a good idea if you don't have that much fragments to manage. An advantage of this approach is that you don't need to fiddle around with the life cycle of two different activities.
Anyway, finding the implementation complex is in a way an indicator that what you're planning won't be manageable for you in the future.
Hope that helps!
I dont get why would you want to do it in such a complicated way. Have one activity on tablets, two activites on phone. Have first activity implement a listener that would fire if list fragment's item was clicked. The activity knows if it is inside single or dual pane mode, so inside that onItemSelected callback method, have it either start a new activity in case of a single pane mode, or replace a fragment, in case of a tablet.
You can also see this, using Master/Detail template when creating a new project.

Categories