placing viewpager with sliding tabs inside fragments as a nested format - android

What i am trying to do:
I am using a drawer where i have 10 fragments
Inside one of the fragment i am trying to add view pager with
sliding tabs(that has view pager indicator as per jake wharton)
What is happening:
When i tried to do this i get error as described here in one of my
other stackoverflow question
I am not able to bring the architecture described in the figure
below
Question::
Is placing view pager with sliding tabs not possible inside
fragments ?
If so are there any samples online ? (Jake wharton sample is done
with placing widgets in activity not fragments)
If any other way is available are there any open source library for
this
Note: i am aware nested way is not advised, but i need to get this architecture
Architecture i am trying to get it:

At first, you can try this sample from Google https://developer.android.com/samples/SlidingTabsBasic/project.html. It also contains the SlidingTabLayout class, try it, if you use something different.
This project is similar to your (has the same layout) except navigation drawer.
So, let's do the following things:
your main layout may look like this:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="#+id/drawer"
android:layout_width="#dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#color/drawer_back"
android:gravity="left|center_vertical"
android:orientation="vertical">
<ListView
android:id="#+id/left_drawer"
android:layout_width="#dimen/drawer_width"
android:layout_height="0dip"
android:layout_gravity="left"
android:layout_weight="1"
android:background="#color/drawer_back"
android:choiceMode="singleChoice"
android:clipToPadding="false"
android:divider="#android:color/darker_gray"
android:dividerHeight="1dp" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
For fragment with sliding tabs use the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<yourpackage.slidinglayout.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"/>
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="#drawable/toolbar_shadow" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:layout_marginTop="#dimen/small_padding"
android:background="#android:color/white"/>
</LinearLayout>
After that you should create a Fragments for your ViewPager and etc. but I think, you've already done it.
Fragment with sliding tabs and ViewPager - it's up to you.
On drawer item with sliding tabs clicked, simple use the FragmentTransaction:
mCurrentFragment = new SlidingTabsFragment();
mTransaction.replace(R.id.content_fragment, mCurrentFragment);
mTransaction.commit();

Related

Toolbar hides PagerTitleStrip and part of RecyclerView

Screenshot 1 and
Screenshot 2 of my app
The problem is basically this: The PagerTitleStrip and the RecyclerView go below my Toolbar even though I have set layout_behaviour to my ViewPager.
More detail:
I have a main activity that uses the layout below and then from it I launch fragments. Before trying the CoordinatorLayout + ViewPager and all of the other fancy stuff I just had a FrameLayout in which I displayed my fragments. However, I decided that I want to use
app:layout_scrollFlags="scroll|enterAlways"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
so that my Toolbar disappears when I scroll the recyclerview. I found online that FrameLayout had no behaviour in it to allow me to fix the position of the recyclerView going under the Toolbar and that's why I changed to ViewPager + CoordinatorLayout to manage my fragments.
However, that introduced a few problems. What I want to achieve is - A toolbar with a PagerTitleStrip attached to it, when I scroll the toolbar disappears leaving the PagerTitleStrip visible ideally, maybe it hides as well I don't care that much about that. But I want my Navigation Drawer to keep working and it doesn't. It's like it doesn't exist.
Now, this first layout actually has all of the above features working, but the problem is the strip is below the toolbar and it's not visible unless the Toolbar hides when I scroll. Drawer works. Recycler view items are partially hidden below the Toolbar unfortunately - they don't start scrolling from the right point of the screen even though I have that set - appbar_scrolling_view_behavior
Layout m_drawerlayout.xml for my main activity to inflate:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v4.view.PagerTitleStrip
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:layout_gravity="top"
android:textSize="15sp"
android:textColor="#color/tealfifty"
android:background="#color/teal">
</android.support.v4.view.PagerTitleStrip>
</android.support.v4.view.ViewPager>
<ListView
android:id="#+id/drawer_list"
android:background="#color/tealDark"
android:cacheColorHint="#android:color/transparent"
android:choiceMode="singleChoice"
android:divider="#drawable/list_divider"
android:dividerHeight="1dp"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="#layout/app_bar"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
And this is the code for my app_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/top_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/teal"
app:theme="#style/ToolbarTheme"
app:popupTheme="#style/Green.Overlay.LightPopup"
app:layout_scrollFlags="scroll|enterAlways" >
<Spinner android:id="#+id/spinner"
android:layout_gravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:paddingRight="20dp"
/>
</android.support.v7.widget.Toolbar>
I tried moving elements around, in and out of other components but no success. For example, it seems logical that to make the PagerTitleStrip attached to the Toolbar and share one behaviour I'd have to nest the PagerTitleStrip inside the AppBar layout but PagerTitleStrip has to be a direct child of ViewPager to work...Any suggestions guys about all this? I'm new to all these design functionalities and I researched a lot without success, there are similar topics here but not at all what I need. Seems there's almost nothing on the internet about things I'm trying to do above (there are a few) compared to other basic topics.
If anyone is wondering why I'm using ViewPager when I have no tabs, it's because as I said, FrameLayout has no behaviour allowing me to use a disappearing Toolbar correctly and that's what I found is good to use. I also saw NestedScrollView could be used but I haven't used it ever so... I now want to possibly use the ViewPagerTitle which I guess limits me to ViewPager for the Fragments.
The problem is in the:
<android.support.design.widget.CoordinatorLayout
<android.support.v4.widget.DrawerLayout
Which the DrawerLayout should be the root layout.
Please see: http://developer.android.com/training/implementing-navigation/nav-drawer.html#DrawerLayout
To add a navigation drawer, declare your user interface with a
DrawerLayout object as the root view of your layout. Inside the
DrawerLayout, add one view that contains the main content for the
screen (your primary layout when the drawer is hidden) and another
view that contains the contents of the navigation drawer.
Also, it is not recommended to use ListView instead of NavigationView.
And here is the doc suggested way to do(except that ListView:) ):
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
And also:
However, that introduced a few problems. What I want to achieve is - A
Toolbar with a PagerTitleStrip attached to it, when I scroll the
toolbar disappears leaving the PagerTitleStrip visible ideally, maybe
it hides as well I don't care that much about that. But I want my
Navigation Drawer to keep working and it doesn't.
Check my answer about this one:
https://stackoverflow.com/a/35241363/4409113
You just put your Toolbar inside CollapsingToolbarLayout like this:
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingtoolbarly"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|snap">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<ImageView
android:layout_width="match_parent"
android:layout_height="190dp"
android:minHeight="190dp"
android:scaleType="fitXY"
android:src="#drawable/header"
app:layout_collapseMode="parallax" />
</android.support.design.widget.CollapsingToolbarLayout>
It should collapsed and the Toolbar will be hided after that.And if you want to keep that PagerTitleStrip(Recommended to use TabLayout Nowadays), just put it below the CollapsingToolbarLayout and above the </android.support.design.widget.AppBarLayout> like this:
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="?attr/colorPrimary" />
</android.support.design.widget.AppBarLayout>
That's pretty much it, Goodluck then.

ViewPager with ImageView before tab

I want to create an activity where there's an image view and a view pager right after. I have try some stuff, but the tabs of the viewpager always appear at the top of the screen.
In order what I would like to have:
Action Bar
Image view (here the M)
Tab
Content of the tab (Fragment)
Here's the closest I have got.
Here's my code. (I'm pretty sur I overkilled it, but I was trying stuff)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/profile_image_linear_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ImageView
android:id="#+id/profile_image_view"
android:layout_width="fill_parent"
android:layout_height="200dp" />
</LinearLayout>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_below="#+id/profile_image_linear_layout">
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="match_parent"
tools:context="madduck.ioweyou.ProfileActivity" />
</FrameLayout>
</RelativeLayout>
Thanks in advance !
Use a TabLayout instead of the ActionBar tabs.
https://developer.android.com/reference/android/support/design/widget/TabLayout.html
For this to work you'd need to use the Android Toolbar (which is really just another View with some half-baked additions).
have a layout like this in your activity: (pseudo code)
<TOOLBAR>
<IMAGEVIEW>
<VIEWPAGER WITH TABS>
You'll want to declare your Theme/Styles to make sure your activity contains no action bar (since you will be replacing it with the Toolbar). Also some versions of Android used to crash if you tried to add a Toolbar when there was an ActionBar. Not sure if this was fixed.

layout_weight not working with LinearLayout inside Drawerlayout

I'm struggling with LinearLayout when using DrawerLayout. This is using the Android Studio template for DrawerLayout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:background="#00f"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:background="#f00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
</LinearLayout>
</LinearLayout>
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="com.test.testdrawerlayout.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
The preview in Android Studio shows this:
http://imgur.com/UlPGzJS
However, when running on my Nexus 5, the following shows:
http://imgur.com/w4QeGbB
As you can see, the layout_weight="1" part is not showing at all. When I create a blank project with the inner LinearLayout however, the layout works (with the blue layout taking most of the screen with the red layout at the bottom, just like the preview).
Any ideas would be really appreciated, as I'm completely stumped right now. Thanks in advance.
It appears I was using an older Android SDK platform. Once I went into SDK manager and installed API 19, it worked (with a new project).
Maybe it was a bug in an older implementation?
This is definitely an Android issue (or at least appcompat/design library issue). I've tested with different layouts inside the DrawerLayout, and concluded that the problem was "content_layout" file - the one that is displayed below the drawer.
Only using a clean, plain FrameLayout worked. No CoordinatorLayout, no fragments, no custom layouts nor 3rd-party layouts, just a good old FrameLayout with "match_parent" as width and height.
Inside the drawerlayout you should have a FrameLayout which contains the main content for your screen and you should also have a ListView in most cases to hold the contents of the navigation drawer.
It should be as such:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
Now place your LinearLayout within the FrameLayout. Think of the FrameLayout as the "container" that holds your main screen.
Note that the official Android documentations state that
The main content view (the FrameLayout above) must be the first
child in the DrawerLayout because the XML order implies
z-ordering and the drawer must be on top of the content.
For more reference and information, I would advise you check this link by clicking here.
Please mark this as the answer if it solved your problem. Thank you.
UPDATE:
Okay first, remove "xmlns:android="http://schemas.android.com/apk/res/android"" from your linearlayout. That should only appear once and in the main root xml, in this cause the DrawerLayout.
Next, fix how you are using your weights. Declare a android:weightSum attribute. Think of weightSum as a pie. In this case we set it too 5, so we have 5 pieces of the pie. Anything inside this layout using the android:layout_weight attribute. This first one is set to 4, which will take 4/5ths of the screen. The last one is 1/5th of the screen at the bottom.
Make sure this LinearLayout is still wrapped within the FrameLayout. Your LinearLayout should appear as such:
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="5">
<LinearLayout
android:background="#00f"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"/>
<LinearLayout
android:background="#f00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
</LinearLayout>
</LinearLayout>

ViewPager and FragmentTabHost display content twice

I have tabs that contains Fragment and i want to provide the swipe gesture to move right and left. I'm using it inside of Fragment and inside of activity. I use ViewPager inside of FragmentTabHost both from support.v4 package (need to work on >=API 10). The problem is that the pager starts showing the content from the top of layout and tabhost is showing the tabs first and then the content. Of course i want the second behavior. So what i see is the content twice, one with tabs and one without. Here is my layout xml file. Notice that i have also some other views above the tabhost (#+id/relative_header) so action bar tabs don't fit in this case. I've already try to move pager into realtabcontent or above it with no luck.
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="#+id/relative_header" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+android:id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
I'm not sure but I assume that one of them is incompatible with the other, but i don't know which compination should use to provide swipe gesture between fragments tabs. Any idea about what I'm doing wrong?
Well, i'm writing this answer for anyone will have the same question in future. I misunderstood the role of each layout. ViewPager and TabHost doing more or less the same thing. To enable the swipe gesture i should have used ViewPager. To add tabs to this, i used the library PagerSlidingTabStrip , also on Feb. 14 2014 seems that android team released a native layout for this: PagerSlidingTabStrip . The tricky point was that tabhost has content and tab in the same layout but it cannot provide the swipe gesture.

ScrollView in content of DrawerLayout prevents the drawer to be opened by swiping

When I put ScrollView into the content of a DrawerLayout, I am nolonger able to open the drawer by swiping from the side.
Activity layout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The menu_main content view -->
<FrameLayout
android:id="#android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- The navigation drawer -->
<ListView
android:name="com.gumtree.androidapp.DrawerFragment"
android:id="#+id/drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>
In Activity's onCreate I add a fragment which has following layout:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_height="160dp"
android:layout_width="match_parent"/>
<TextView
android:id="#+id/headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/headline_text_size"
android:padding="#dimen/detail_text_padding"
android:textIsSelectable="false"/>
<TextView
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/description_text_size"
android:padding="#dimen/detail_text_padding"
android:textIsSelectable="false"/>
</LinearLayout>
</ScrollView>
Without the ScrollView everything works fine and I am able to open the drawer by swiping from the side. However when I add the ScrollView, it stops working.
The problem here was silly named ID of FrameLayout used as content container of DrawerLayout. I used system ID (android.R.id.content) which caused that the content fragment was put on the top of all other views - even the drawer.
It also caused fragment's layout to overlap the drawer and - related to this question - blocked the drawer from receiving touch events. The touch events were taken by fragment's ScrollView.
Conclusion: DO NOT USE SYSTEM IDs (android.R.*) WHERE IT IS NOT NEEDED.
I just wanted it to look nice and clean.. Silly me :)

Categories

Resources