How to fix 'Horizontal swiping between ViewPager tabs'? - java

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);
}

Related

Making LinearLayout with ListView scrollable

I have a linear layout that looks something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear_layout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical"
tools:context=".activities.EnrolStudentFormActivity">
<include
layout="#layout/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:fitsSystemWindows="true" />
<ListView
android:id="#+id/list_view
android:layout_width="match_pare
android:layout_height="wrap_cont
android:divider="#null"
android:dividerHeight="0dp" />
</LinearLayout>
With a few ImageViews, TextInputLayouts and TextInputEditTexts in between. I want to make this layout scrollable. I tried to make it scrollable with ScrollView and NestedScrollView, but both of them messed the ListView up.
I am also changing the ListView contents dynamically and I have a few TextInputEditTexts inside TextInputLayouts inside the ListView. Resizing the ListView doesn't help much, and I cannot click on the TextInputEditText inside the ListView. It seems that the ScrollView captures the touch input.
Are there any workarounds that will let me have a ListView inside a ScrollView or make the linear layout scrollable while making the TextInputEditText inside the ListView usable?
Use RecyclerView instead of ListView and add NestedScrollView on top:
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="
http://schemas.android.com/apk/res/android"
xmlns:http="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical"
tools:context=".activities.EnrolStudentFormActivity">
<include
layout="#layout/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:fitsSystemWindows="true" />
<android.support.v7.widget.RecyclerView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#null"
android:dividerHeight="0dp" />>
</LinearLayout>
and finally in your code add:
RecyclerView.setNestedScrollingEnabled(false);

Android Tabbed Activity Scrolling

I want to create an Android App. For my main screen I use the Tabbed Activity. It looks like I want. But when I surround my TextView with a ScrollView it only scrolls the text, but it should look like this:
So it should look before I scroll:
And like this after I scrolled:
Here is the Tabbed Activity:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
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"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</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.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
And here the text Fragment:
<RelativeLayout 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.obware.story.Activitys.MainActivity$PlaceholderFragment">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Does anyone know how I can do that?
Since this is a Tablayout, I am assuming that you are using Fragments and a ViewPager. (this still applies even without a viewpager)
In this case, You will have to send an answer to you activity which is base to hide the toolbar. Declare an interface inside you base activity which has the Tab layout.
say :
interface HideToolBarInterface{
public void hideTheToolbar(boolean shouldbehidden);
}
Now implement this interface inside your activity and overrride the abstract method declared.
eg:
public void hideTheToolbar(boolean shouldbehidden){
if(shouldbehidden){
getSupportActionBar().hide(); // if you have set your own toolbar, hide it similarly
}else{
getSupportActionBar().show();
}
}
Now inside your fragments, set a onScrollListener to your ListView or RecyclerView whatever you are using to show the list.
Now when the list is scrolled, you can use the Listeners onScrollChanged, apply you logic to call the interface method to hide the toolbar like:
//on some condition(say SCROLL_STATE_FLING) do the following:
((HideToolbarInterface)getActivity()).hideTheToolbar(true);
//on some other conditon(say SCROLL_STATE_IDLE unhide it:
((HideToolbarInterface)getActivity()).hideTheToolbar(false);
You can check for other options here:
android lollipop toolbar: how to hide/show the toolbar while scrolling?

CoordinatorLayout with RecyclerView leaving empty space at the bottom of the screen

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"

AppBarLayout not allowing other Views to match_parent

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

Android TabLayout scroll up animation with listfragment

I have my main xml set up as such:
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:scrollbars="horizontal"
android:layout_below="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/tab_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<!-- Your Scrollable View -->
<!--<include layout="#layout/cardviews"/>-->
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_note_add_white_48dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_gravity="bottom|right"
app:fabSize="normal" />
In the tutorial that I was following, they implemented a scrolling list of card views which pushed up the tab layout when the list was scrolled.
However, here I have a view pager instead of a list of card views which scrolls horizontally. Within the pages of the view pager, I have a list fragment which contains a vertical list.
Yet, when I scroll this vertical list within the view pager, the tab layout is not pushed up!
How do I get this nested listfragment to interact with the tab layout.
The AppBar only behaves that way if you use a NestedScrollView or a RecyclerView. Both these classes implement NestedScrollingChild, and my guess is that your ListFragment does not use either of these classes for the list functionality.

Categories

Resources