My app uses a tabLayout which is defined in the main_activity layout. I then have a separate layout file per tab to place all the views for that tab.
In the tab layout files, I’d like to constrain a view to the bottom edge of the tabs. I don’t know how to do this as the tabLayout is defined in another layout file, and it doesn’t have a fixed height (and I don't really want it to), so I can’t just use the same dimension in the tab layout file.
I’ve seen that there’s an tag that you can use to pull content in from other layouts, but this doesn’t feel right, I don’t need the whole layout to be duplicated within the tab, I essentially just need to know the height of it.
Here’s my main_activity layout which contains the tabLayout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColour"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/toolbar">
<android.support.design.widget.TabItem
android:id="#+id/CostTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/cost" />
<android.support.design.widget.TabItem
android:id="#+id/costTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/distance" />
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/tabMenu"
/>
</android.support.constraint.ConstraintLayout>
You should populate the adapter for ViewPager with Fragments for each tabLayout you have or use plain views as adapter items. You can find more info in developer guide here: https://developer.android.com/guide/navigation/navigation-swipe-view
Related
Being new to android development and working on approach of navigating user to multiple fragments within an activity, I came across a doubt regarding including a layout file within multiple(not all) fragments using as:
<include layout="#layout/toolbar_layout" />
toolbar_layout.xml :
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="#style/appBarLayout"
android:id="#+id/inboxAppBar"
android:elevation="2dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
app:menu="#menu/actionbar_icon_menu"
android:id="#+id/inboxToolbar"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize">
<androidx.appcompat.widget.SearchView
app:queryHint="Search here..."
app:iconifiedByDefault="false"
app:commitIcon="#drawable/ic_launcher_foreground"
android:theme="#style/searchView"
style="#style/searchViewStyle"
app:queryBackground="#color/transparent"/>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#color/white"
android:id="#+id/InboxTabLayout"
app:tabMode="scrollable"
app:tabIndicatorFullWidth="false"
app:tabTextAppearance="#style/TabTextStyle"
/>
</com.google.android.material.appbar.AppBarLayout>
Which gives output shown below, after adding NavigationButton programatically:
Now that I had to use Ids of Toobar and TabLayout for adding NavigationUp button and setting up ViewPager2 respectively in all fragments, I had to include above layout.
Its working absolutely fine but I needed to know if reusing Ids for setting up eventListeners and other things separately in all fragments code could cause any problem since we are referencing same Id in all fragments for different tasks.
Also, kindly mention the right approach of doing what I intend to do.
I have a layout that contains a tree of views like below:
- ConstraintLayout
-- TextView
- WebView
- TabLayout (1) (3 tabs)
- ViewPager (1)
- TabLayout (2) (4 tabs)
- ViewPager (2)
When user scrolls to ViewPager (1), TabLayout (1) will stick at top and able to interact like below GIF in Huobi app. And if user scrolls more to ViewPager (2), it will push TabLayout (1) out and TabLayout (2) will be sticked on top.
I tried some articles like (https://stackoverflow.com/a/44327350 -- It creates fake view and not able to interact header) and libs like (https://github.com/emilsjolander/StickyScrollViewItems -- quite too long no update) but i don't feel it good.
Any good practice on this? I see many apps used it but not sure will Google supports it natively and not sure what I missed.
Any help would be appreciated. Thanks.
Update 13/12/2021
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_color">
// Header
<include
android:id="#+id/layout_header"
layout="#layout/layout_header" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/wvChart"
android:layout_width="match_parent"
android:layout_height="#dimen/webview_height" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl1"
android:layout_width="match_parent"
android:layout_height="#dimen/tablayout_height"
style="#style/TabLayoutStyle"
app:layout_constraintTop_toBottomOf="#id/wvChart"
app:tabTextAppearance="#style/TabLayoutTextStyle"/>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/vpg1"
android:minHeight="#dimen/viewpager_market_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_color"
app:layout_constraintTop_toBottomOf="#id/tl1"/>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl2"
android:layout_width="match_parent"
android:layout_height="#dimen/tablayout_height"
style="#style/TabLayoutStyle"
app:layout_constraintTop_toBottomOf="#id/vpg1"
app:tabTextAppearance="#style/TabLayoutTextStyle"/>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/vpg2"
android:minHeight="#dimen/viewpager_market_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_color"
app:layout_constraintTop_toBottomOf="#id/tl2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</layout>
I am currently using this lib StickyScrollView, it works as expected but contains minor bugs. I still want to find other stable way. Thanks.
As I had no source code from you, I just started to make an own little project to achieve that. First of all you need to take a CoordinatorLayout as base frame. In that you use an AppBarLayout that is the parent of a CollapsingToolbarLayout and in that you can put your content (here e.g. TextView). The second Toolbar in it needs to be pinned (app:layout_collapseMode="pin")
Below that you will continue with the NestedScrollView to have no glitches etc., for a smooth UX.
There you go with your activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="#6200EA"
app:layout_scrollFlags="scroll|snap|exitUntilCollapsed"
app:title="Collapsing Toolbar">
<TextView
android:layout_width="250dp"
android:layout_height="40dp"
android:layout_gravity="center|end"
android:layout_marginBottom="15dp"
android:scaleType="centerCrop"
android:text="Trade your Bitcoins here:"
android:textSize="18sp"
android:textStyle="bold"
app:layout_collapseMode="parallax" />
<Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Collapsed Toolbar:
Extended Toolbar:
I think now you should have a good inspiration how to design further. It's the same principal. In terms of time I just made a ruff version. In your shown GIF it's just an additional Toolbar at the top, that's normally known as "DarkActionbar" in themes.xml. And the RecyclerView (in your example "Order Book") will be added as a child in NestedScrollView. Cheers!
i want to create fixed navigation layout, but there is a problem when i rotate device, margin-top of this layout is more than it has to be, so the question - how can i find height of this dark-blue header ( to use it as margin ), or maybe there is another way
<RelativeLayout
android:layout_width="match_parent"
android:layout_marginTop="55dp"
android:layout_height="80dp"
android:background="#drawable/panel_border"
android:layout_alignParentTop="true">
If I were you, I would go with this:
android:layout_marginTop="?attr/actionBarSize"
This attribute indicates correct height of the ActionBar / Toolbar.
The Toolbars height may be different for different APIs and that's the reason you should use ?android:attr or ?attr (when using support library).
? means that it comes from internal Android resources.
Let the android support library do it for you. Like this
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<! -- Your View -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/panel_border"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
take a look at this
The version of my constraint layout is 1.0.0-alpha8 . After I have included a toolbar in my layout , there is space in both left and right side of the toolbar, like the image below
Here is the code for my toolbar
<?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:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary">
</android.support.v7.widget.Toolbar>
Which I have included in my layout in following way
<include
layout="#layout/toolbar_top"
android:id="#+id/topPanel"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
I didn't used any additional padding or margin in my root element of the layout file .
Another stange thing is if I compile or build the program my code automatically changed, like
<include
layout="#layout/toolbar_top"
android:id="#+id/topPanel"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
Change to
<include
layout="#layout/toolbar_top"
android:id="#+id/topPanel"
android:layout_height="wrap_content"
android:layout_width="368dp"/>
And the guideline also add some additional value which I didn't write, like layout_editor_absoluteX automatically added .
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline1"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.15"
tools:layout_editor_absoluteX="58dp"/>
First, you should update to ConstraintLayout beta 4.
Now, the root problem you have is that you are using match_parent on the toolbar -- this isn't supported by ConstraintLayout. You need to add:
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
and use 0dp instead of match_parent:
<include
layout="#layout/toolbar_top"
android:id="#+id/topPanel"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
Note that you can create those attributes easily by doing right-click on the component, and picking
On Android Studio 2.2 you need to hold the key to create the constraints, on Android Studio 2.3 it creates the constraints by default.
I'm looking for a custom TabLayout. The icon of the Tab in the middle needs a margin to overlay the content. Please check out the image below.
What I've tried so far
Tab.setCustomView() with a margin. That doesn't overlay the content though.
Looked for TabLayout libraries that give such flexibility. Didn't find anything that fits my need.
Re-invent the wheel?
Since I don't need any complicated scrolling functionality, I could develop my own TabLayout with a couple ViewGroups,TextView and ImageView. Before I have to do that:
Do you know of any library that would do that?
How would you approach it?
Any help would be greatly appreciated!
I achieved that by the combination of a custom library and the floating action button.
The library: MagicIndicator on GitHub
I set the icon of the middle fragment to an empty icon and positioned the floating action button in the middle to overlay the TabLayout. It looks like this:
My activity layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
android:layout_marginBottom="50dp"
app:layout_behavior="#string/appbar_scrolling_behavior" />
<net.lucode.hackware.magicindicator.MagicIndicator
android:id="#+id/magic_indicator"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/light_gray"
android:layout_gravity="bottom" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:layout_margin="10dp"
app:srcCompat="#drawable/add_icon"
app:backgroundTint="#color/colorPrimary"/>
</android.support.design.widget.CoordinatorLayout>