I'm using a layout with an AppBarLayout containing a Toolbar and a TabLayout, a ViewPager and a FloatingActionMenu.
My problem is that using an AppBarLayout causes other Views inside the CoordinatorLayout to not match the entire screen when using layout_height=match_parent, instead this other Views match what's left of the parent excluding the AppBarLayout. This behavior is perfect for my ViewPager, because otherwise its content would be covered by the AppBarLayout, but I need my FloatingActionMenu to match the entire screen, so that when my menu opens I can dim the screen.
So my question is: How do I make it so my FloatingActionMenu takes over the entire screen?
My XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
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:fitsSystemWindows="true"
tools:context="com.example.Home">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppBaseTheme.ToolbarPopup"
app:theme="#style/AppBaseTheme.Toolbar">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabTextAppearance="#style/AppBaseTheme.TabText"
app:theme="#style/AppBaseTheme.Toolbar"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/home_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<com.example.FloatingActionMenu
android:id="#+id/fam"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom|end"
android:padding="#dimen/fab_margin"
app:menu_backgroundColor="#BB8b8b8b">
<com.example.FloatingActionButton
android:id="#+id/fab"
style="#style/MenuButtonsStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</com.example.FloatingActionMenu>
Using a RelativeLayout as my root view or using a LinearLayout to hold my Toolbar and TabLayout would solve my problem, but I need to use CoordinatorLayout and AppBarLayout to add scrolling functionality.
EDIT:
After testing in different devices I found out that this problem only happens on newer versions, as you can see in the next photos.
On API 19:
On API 23:
The problem was that I wasn't specifying an android:elevation for my FloatingActionMenu, so the AppBarLayout was appearing on top of the Menu
Related
The Recyclerview has a ViewHolder that contains TextView typically. The text content is selectable and when long press the text opening a selection menu. The notifyItemChanged function is calling from outside of the Adapter for resize the Textview font. The text selection menu available before resizing but after that the items not selectable. Don't open text selection menu when long press. There are no any request disallowing to event but the issue occurs after the notifyItemChanged.
Edit:
The problem is the TextView xml that item view of the Recyclerview:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:textSize="15sp" />
The problem is solving if the android:layout_width of TextView is WRAP_CONTENT, but it must be MATCH_PARENT, what does that have to do with anything?
Recyclerview:
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.ReadBookActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.drawerlayout.widget.DrawerLayout>
Edit-2:
All of my text content wrapping many spans and there is RelativeSizeSpan for font size. It's editing when changing font size. And notifying the item with notifyItemChanged(i). The problem sametimes don't occuring with using notifyDataSetChanged() withoud using Wrap_Content in the item.
Edit-3: The problem stems from editing RelativeSizeSpan completely, because it's renewing with new size when the changing font size. Removed renewing and it's using Textview.setTextSize() now, no problem.
So, reading the documentation for DrawerLayout it explicitly states:
To use a DrawerLayout, position your primary content view as the first
child with width and height of match_parent and no <layout_gravity>.
Add drawers as child views after the main content view and set the
layout_gravity appropriately. Drawers commonly use match_parent for
height with a fixed width.
So basically your DrawerLayout CANNOT only contain 1 view, it needs to have your main content first, then your RecyclerView or whatever, and the RecyclerView needs to have a fixed width or potentially wrap_content. Items inside the RecyclerView can now be whatever you want.
Here is an example:
activity_main.xml: (NB notice RecyclerView is not the first item and it has a layout_width of wrap_content)
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</androidx.drawerlayout.widget.DrawerLayout>
app_bar_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">
<include layout="#layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/main_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right|end"
android:layout_margin="16dp"
android:elevation="#dimen/elevation"
app:srcCompat="#drawable/ic_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
I haven't actually tested this myself but it should work as I have the exact same setup except, I'm using a NavigationView instead of a RecyclerView simply because I have a set amount of items in my drawer.
I have a RecyclerView inside two tabs.
The problem is: When I scroll to the top of the list and then trying to swipe horizontally to the next tab, no horizontal movement happens for a while.
"That happens only when scrolling to the top or the end of the list".
Hint: I'm using CollapsingToolbarLayout.
I tried to make setNestedScrollingEnabled() to be (false).
That fixes the problem of horizontal swiping but will disable collapsing.
enter image description here
XML file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
......>
<android.support.design.widget.CoordinatorLayout
android:id="#+id/my_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:expandedTitleGravity="top"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:contentInsetStartWithNavigation="0dp"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#null"
android:src="#drawable/dictionary" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:tabGravity="fill"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed">
<! Two tabs here >
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
...../>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
....../>
</android.support.v4.widget.DrawerLayout>
Java snippet:
mRecyclerView = mRootView.findViewById(R.id.list);
mRecyclerView.setHasFixedSize(true);
// For linear displaying.
mLayoutManager = new LinearLayoutManager(mRootView.getContext());
mRecyclerView.setNestedScrollingEnabled(true);
mRecyclerView.setLayoutManager(mLayoutManager);
WordsAdapter mAdapter = new WordsAdapter(mWords, this);
mRecyclerView.setAdapter(mAdapter);
You should check out detecting gestures. Your problem is caused by the RecyclerView intercepting the touch events with slight vertical movement. If you were to move your finger perfectly horizontal, you could switch between tabs, but a normal swiping motion has some vertical component. To solve your problem, you could add an onTouchListener to your RecyclerView where you only intercept touch events which are mostly vertical. That way the horizontal swipes will be delivered to the TabView below.
This problem solved by just adding: viewPager.requestDisallowInterceptTouchEvent(false);
Java snippet:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
viewPager.requestDisallowInterceptTouchEvent(false);
return super.dispatchTouchEvent(ev);
}
This is a basic model of my XML:
<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"
android:id="#+id/background_colour"
>
<android.support.design.widget.AppBarLayout
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:id="#+id/profile_screen_appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true"
android:minHeight="150dp"
>
<android.support.design.widget.CollapsingToolbarLayout
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
android:id="#+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:expandedTitleMarginTop="32dp"
app:expandedTitleMarginBottom="32dp"
app:expandedTitleMarginEnd="4dp"
app:expandedTitleMarginStart="32dp"
android:minHeight="100dp"
>
<android.support.v7.widget.Toolbar
android:minHeight="100dp"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:background="#color/fab_material_red_500"
>
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/blue"
>
<!-- the ViewPager is programatically set to be have the height and width equivalent to that of the screen width of the device --> <com.example.heavymagikhq.MyViewPager
android:padding="0dp"
android:fitsSystemWindows="true"
android:id="#+id/viewPager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_scrollFlags="scroll|enterAlways"/>
/>
</RelativeLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_marginTop="15dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/profile_info_recycler"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
The problem
At the moment some of the content in the RecyclerView is slightly off screen and I am able to reveal it by scrolling. The problem is that although only a slight amount of content is off screen the entire screen scrolls up until only the RecyclerView's content is showing at the top of the screen below the CollapsingToolbarLayout at a collapsed height equivalent to that of the Toolbar . I've tried adding android:layout_gravity="fill_vertical" to the RecyclerView but this didn't solve the issue
A Note
When the CollapsingToolbarLayout's height is set to 625dp the screen doesn't scroll at all, but, when I set it to 626dp the content of the screen scrolls until the CollapsingToolbarLayout is collapsed to the height of a Toolbar, so this extra 1dp of height makes the screen go from not scrolling to scrolling much more than 1dp. The 625dp figure is presumably related to the device's (Nexus 7 2013) screen size. Also, regardless of what minHeight I set the CollapsingToolbarLayout to, the CollapsingToolbarLayout always collapses at the height equaivalent to a Toolbar's.
My Question in a nutshell
How can I make it so the screen only scrolls to reveal the content that is not on screen/beyond the content of the RecyclerView?
Thanks in advance.
I found solution,you can set "minHeight" for AppBarLayout childView, and set app:layout_scrollFlags="scroll|exitUntilCollapsed"
I have been following these probably outdated instructions to insert (test) ads to my android project. After I have recompiled the project on a virtual Nexus 5 phone, the app works, but no add-banner is shown.
Maybe there is a problem with the layout file, as my layout file does not look like the example layout file. Here are the relevant parts of my layout file to include the ad-banner:
<?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"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
</android.support.design.widget.AppBarLayout>
<LinearLayout
...
...
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
ads:adSize="BANNER"
ads:adUnitId="#string/banner_ad_unit_id">
</com.google.android.gms.ads.AdView>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Is the problem related to the layout? How else to figure out why the ad banner is not shown?
In a discussion with the OP, it turned out that the CoordinatorLayout and the AdView were both inside a LinearLayout, and the CoordinatorLayout was pushing the AdView off of the screen because its height was "match_parent"
By changing the CoordinatorLayout height to 0dp, and weight to 1, it will grow to fill the remaining space above the AdView instead of taking the entire screen.
android:layout_height="0dp"
android:layout_weight="1"
I think you should be using:
xmlns:ads="http://schemas.android.com/apk/res-auto"
instead of:
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
In the Image below
Quetion 1:
I want to change the color of Blue color underbar and the text color of Text (eg. FlashCards) in Sliding Tab Layout.
How can I change that?
Also I want to change the space coming after Name : 'MyAccount'
Question 2:
When I slide the Tab,the heading at the top of toolbar(Flashcards) should change.
Any Idea how to do that.
My XML File for layout looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/tool_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="#color/colorPrimary"
>
<TextView
android:id="#+id/text_home_screeen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#color/windowBackground"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="10dp"
android:text="#string/back_title"/>
</android.support.v7.widget.Toolbar>
<com.example.ojasjuneja.chem.SlidingTabLayout
android:id="#+id/sliding_tab"
android:background="#color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.example.ojasjuneja.chem.SlidingTabLayout>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</android.support.v4.view.ViewPager>
</LinearLayout>
you need to add PagerSlidingTabStrip in your XML
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
and in java file add below code..
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) rootView.findViewById(R.id.tabs);
tabs.setViewPager(view_pager);
tabs.setTextColor(Color.parseColor("#ffffff"));
tabs.setIndicatorColor(getActivity().getResources().getColor(R.color.sky_blue_color));
Question 2 When i slide the Tab,the heading at the top of toolbar(Flashcards) should change. Any Idea how to do that. My XML File for layout looks like this:
You need to add one line in each fragment below OnCreate() for example
My List Fragment
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("MY LISTS");
My Account Fragment
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("My Account");