I used Nestedscrollview as Bottomsheetbehaviour but when it changes its state from normal to expanded some of space from toolbar left but when second time state changed from normal to expanded it works fine..
It looks as it leaves space exactly twice of the margin I provide to the sheet in xml. My code looks like this...
MyLayoutFile.xml
<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/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
tools:context=".fragments.StoreLocationDetailsFragment">
<include layout="#layout/toolbar"/>
<FrameLayout
android:id="#+id/mapHolder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize"/>
<include android:id="#+id/nested_scroll_view"
layout="#layout/store_details_scroll_view"/>
</android.support.design.widget.CoordinatorLayout>
store_details_scroll_view.xml
<android.support.v4.widget.NestedScrollView
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:layout_marginTop="?android:attr/actionBarSize"
android:background="#color/colorLightGrey"
android:clipToPadding="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="#dimen/activity_horizontal_margin">
<TextView
android:id="#+id/tvStoreName"
style="#style/styleOswaldBold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/activity_horizontal_margin"
android:text="Adidas Shoes"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Title"/>
<TextView
android:id="#+id/tvAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/sub_title"
android:textAlignment="center"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="#dimen/activity_horizontal_margin"
android:background="#color/colorDarkGrey"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
and code in onClick Function in java file looks like
View bottomSheet = rootLayout.findViewById(R.id.nested_scroll_view);
behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setPeekHeight(new ScreenDimensions(getActivity())
.getHeightWithGivenPercentage(60));
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_COLLAPSED:
behavior.setPeekHeight(0);
break;
case BottomSheetBehavior.STATE_EXPANDED:
break;
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
Here rootlayout is my Coordinator layout. Can anyone suggest me solution of the above problem. Thanks in advance.
Related
I'm trying to make the BottomSheetDialogFragment appear at the top of BottomNavigationView and below the BottomNavigationView, ie with a lower elevation.
The BottomSheetDialogFragment will feature a YouTube-like video player with a RecyclerView and expanding and collapsing the bottomsheet.
I already researched several suggestions and nothing solved. Including Stackoverflow.
I tried the two variants of the Show () method, as per the code below - but none worked.
I can do Expand, Collapsed and other actions, do not worry about it. The problem is to make the BottomSheet behind the BottomNavigationView and above the RecyclerView of the Activity.
CODE ACTIVITY
public class myController extends CommonActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//inflate the layout of the activity
setContentView(R.layout.controller_layout);
//other activity codes
//progressBar = findViewById(R.id.progressBar);
//contains initialization codes for views and recyclerview
//initViews();
}
OPTION 01: It's the CALL that everyone is pointing to BottomSheetDilogFragment, except BottomSheet is over BottomNavigationView
INITIALIZED when clicking on a item (thumbnail) of a RecyclerView in the layout of the activity/fragment
public void initBottomSheet(Bundle b){
VideoViewBottomSheet fragment = new VideoViewBottomSheet();
fragment.setArguments( b );
fragment.show( getSupportFragmentManager(), VideoViewBottomSheet.FRAGMENT_KEY );}
OPTION 02: I tried this option for BottomSheetDilogFragment, in it the BottomSheet is
DOWN of the BottomNavigationView, BUT behave like a NORMAL FRAGMENT and not as BottomSheetDilogFragment, DO NOT EXPAND, DO NOT COLLAPSE, NOTHING.
public void initBottomSheet(Bundle b){
VideoViewBottomSheet fragment = new VideoViewBottomSheet();
fragment.setArguments( b );
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.bottom_sheet_loyout, fragment);
ft.commit();
}
}
CODE BottomSheetFragment
#Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
View view = getView();
final View parent = (View) view.getParent();
final View bottomSheet = dialog.findViewById(R.id.rv_bottom_sheet);
final View videoView = bottomSheet.findViewById(R.id.videoView);
final View bottom_nav_view = getActivity().findViewById(R.id.bottom_nav_view);
final int screenHeight = ViewGroup.LayoutParams.MATCH_PARENT;
final View relativeLayout = getActivity().getWindow().getDecorView().getRootView().findViewById(R.id.relativelayout);
final View coodinatorLayout = getActivity().getWindow().getDecorView().getRootView().findViewById(R.id.coordinatorlayout);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) (parent).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
parent.setFitsSystemWindows(false);
bottomSheet.getLayoutParams().height = screenHeight;
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
final BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) behavior;
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
if (bottomSheetBehavior instanceof BottomSheetBehavior) {
offsetY = 0;
((BottomSheetBehavior) bottomSheetBehavior).setBottomSheetCallback(
new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
if(slideOffset>0.2 ){
bottomSheetBehavior.setHideable(false);
bottomSheetBehavior.setPeekHeight(bottom_nav_view.getHeight()+56 );
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
parent.setPadding(0,0,0,bottom_nav_view.getHeight()+56);
parent.setBackgroundColor(Color.GREEN);
bottom_nav_view.setVisibility(View.VISIBLE);
bottom_nav_view.setBackgroundColor(Color.YELLOW);
}
offsetY = slideOffset;
}
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
}
});
}
}
}
The expected result is a BottoSheet similar to that of the Youtube Player. That is, a BottomSheet that contains a Fragment RecyclerView and Play Videos.
XMLS
mycontroller_layout.xml
-----------------------
<RelativeLayout
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/relativelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:fitsSystemWindows="false"
tools:context=".myController">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinatorlayout"
android:layout_above="#+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:fitsSystemWindows="false">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone" />
<include layout="#layout/content" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bottomsheet"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_below="#+id/coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:elevation="50dp"
android:visibility="visible"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:itemIconTint="#color/colorWhite"
android:background="#color/colorPrimary"
app:menu="#menu/activity_main_bottom" />
</RelativeLayout>
content.xml
-----------
<RelativeLayout
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/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingTop="4dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".RebootController"
tools:showIn="#layout/reboot_controller_layout">
<RelativeLayout
android:id="#+id/containerContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</RelativeLayout>
</RelativeLayout>
bottom_sheet_loyout.xml
-------------------
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/rv_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_nav_view"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:elevation="3dp"
android:fitsSystemWindows="false"
android:orientation="vertical"
app:layout_behavior="#string/bottom_sheet_behavior" >
<RelativeLayout
android:id="#+id/rlVideoView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<VideoView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/srl_swipe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/videoView">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:clipToPadding="false"
android:paddingBottom="56dp"/>
</android.support.v4.widget.SwipeRefreshLayout>
<ProgressBar
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:visibility="gone" />
<!--<LinearLayout
anĂșncio google
</LinearLayout>-->
</RelativeLayout>
</RelativeLayout>
I wonder why such a strange behavior in the app attribute: elevation = "0dp" and how to solve the problem. I use the androidx library. The toolbar is transparent. Shadow remains. When I write an app: elevation = "0dp", the shadow disappears, but the toolbar buttons, including the "back" buttons, stop responding.
I tried to solve it in other ways: android: elevation = "0dp"
programmatically set getSupportActionBar (). setElevation (0); Does not help.
layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="#color/back_gray">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="200dp"/>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/transparent"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:background="#color/transparent"
app:popupTheme="#style/AppTheme.PopupOverlay">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="#+id/iv_like"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="#android:color/transparent"
android:src="#drawable/heart_outline"
android:visibility="visible"/>
<ImageButton
android:id="#+id/iv_shared"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="#android:color/transparent"
android:src="#drawable/shared"
android:visibility="visible" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
.....>
<TextView
........./>
<TextView
........../>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</FrameLayout>
fragment.java:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate( R.layout.fragment_data, container, false );
toolbar = (Toolbar) rootView.findViewById( R.id.toolbar );
MainActivity activity = (MainActivity) getActivity();
if ( activity != null ) {
activity.setSupportActionBar( toolbar );
// activity.getSupportActionBar().setElevation(0);
activity.getSupportActionBar().setDisplayHomeAsUpEnabled( true );
activity.getSupportActionBar().setHomeButtonEnabled( true );
activity.getSupportActionBar().setDisplayShowTitleEnabled( false );
toolbar.setNavigationOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
} );
}
}
Try the below code snippet instead of toolbar.setNavigationOnClickListener
#Override public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home){
getActivity().onBackPressed();
}
return super.onOptionsItemSelected(item);
}
hope this will solve your problem.
thanks
This is just because you have used FrameLayout as a parent - and also removed elevation from AppBarLayout, and due to this, Your ScrollView is overlapping your AppBarLayout as it is written below AppBarLayout. change your root to something else, for eg.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/transparent"
android:theme="#style/AppTheme.AppBarOverlay">
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appBarLayout">
</ScrollView>
</RelativeLayout>
I have this simple layout:
<RelativeLayout 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.support.design.widget.CoordinatorLayout
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ActionBarThemeOverlay">
<include layout="#layout/include_toolbar_actionbar"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/theme_primary"
android:padding="#dimen/keyline_1">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_search_view"
android:focusable="true"
android:focusableInTouchMode="true">
<com.xxxx.ui.widget.CustomSearchView
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:withBackButton="true" />
</FrameLayout>
</FrameLayout>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<LinearLayout
android:id="#+id/methods_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="#dimen/keyline_5">
<com.xxx.ui.widget.ButtonSearchBy
android:id="#+id/search_by_categories"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="#string/search_by_categories"
app:icon="#drawable/ic_by_categories"
app:iconFillColor="#color/grey"
android:visibility="gone"/>
<com.xxx.ui.widget.ButtonSearchBy
android:id="#+id/search_by_recents"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="#string/search_by_recents"
app:icon="#drawable/ic_by_recents"
app:iconFillColor="#color/grey"
android:visibility="gone"/>
</LinearLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
In my Activity, I added this code to disable user scroll on directly CoordinatorLayout:
if (mAppBarLayout.getLayoutParams() != null) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
AppBarLayout.Behavior appBarLayoutBehaviour = new AppBarLayout.Behavior();
appBarLayoutBehaviour.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
#Override
public boolean canDrag(#NonNull AppBarLayout appBarLayout) {
return false;
}
});
layoutParams.setBehavior(appBarLayoutBehaviour);
}
This code works correctly, BUT in the "fragment_container" (FrameLayout), I add a RecyclerView, and if the user scrolls into this list then the Coordinator scrolls too...
I want collapse or expand automatically my CoordinatorLayout, and not to have a link with the RecyclerView scrolling.
I tried this too, but it doesn't work properly:
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (mFragmentContainer.getVisibility() == View.VISIBLE &&
event.getAction() == MotionEvent.ACTION_MOVE) {
Rect fragContainerRect = new Rect();
mFragmentContainer.getHitRect(fragContainerRect);
if (fragContainerRect.contains((int) event.getX(), (int) event.getY())) {
LogUtils.LOGD("XXXX", "move");
mFragmentContainer.dispatchTouchEvent(event);
return true;
}
}
return super.dispatchTouchEvent(event);
}
So how can I do to disable the CoordinatorLayout scrolling when the list scrolls?
Thank you very much guys!
This is what I want to achieve :
I wanted to use AbsoluteLayout but it is deprecated.
So I made a RelativeLayout beneath the blue view in the image above, and then put everything inside a ScrollView, but the hidden view is still 'on' the blue view, and not below it. Also, the screen scrolls, but the hidden part is just cut , and instead I see the my app's default background..
Any ideas?
EDIT :
my current try :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/imageView" />
<LinearLayout
android:id="#+id/centerHolder"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" >
.....
.....
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1000dp"
android:layout_below="#id/main_holder"
android:background="#color/black_color">
</RelativeLayout>
</RelativeLayout>
</ScrollView>
I am taking this from a project of mine which displays a RecyclerView where you can add data if you click on a row - because the click "opens" the bottom sheet.
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/rl_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.fragment.BlockFragment">
<include
android:id="#+id/ll_header"
layout="#layout/layout_header_names" />
<include
android:id="#+id/divider_header"
layout="#layout/layout_divider_horizontal"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="#+id/ll_header" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_block"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/divider_footer"
android:layout_below="#+id/divider_header" />
<include
android:id="#+id/divider_footer"
layout="#layout/layout_divider_horizontal"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#767676"
android:layout_above="#+id/ll_footer" />
<include
android:id="#+id/ll_footer"
layout="#layout/layout_footer_score"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<!-- Here comes my bottom sheet.
It is wrapped inside a FrameLayout, because an include cannot
have a behaviour. The included layout is every layout you
can imagine - mine is a RelativeLayout with two EditTexts
for example. The layout_behaviour is the second important line. -->
<FrameLayout
android:id="#+id/container_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#e3e3e3"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<include layout="#layout/layout_bottom_sheet"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
For the behaviour itself, you'll need to get the FrameLayout (the View with the app:layout_behavior="android.support.design.widget.BottomSheetBehavior").
private BottomSheetBehavior bottomSheetBehavior;
bottomSheetBehavior = BottomSheetBehavior.from((FrameLayout)findViewById(R.id.container_bottom_sheet);
//for the sheet to "peek":
bottomSheetBehavior.setPeekHeight(200);
//now you can set the states:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
It is also possible to set a BottomSheetCallback() in which you can get all the state changes and also the slideOffset!
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_DRAGGING:
case BottomSheetBehavior.STATE_EXPANDED:
break;
case BottomSheetBehavior.STATE_COLLAPSED:
default:
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
I think you should just use LinearLayout to wrap the ImageView and other layouts.
Edited the answer based on comments.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/centerHolder"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" >
.....
.....
</LinearLayout>
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/imageView"
android:layout_alignParentTop="true" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1000dp"
android:layout_below="#+id/centerHolder"
android:background="#color/black_color">
</RelativeLayout>
</RelativeLayout>
</ScrollView>
Just replace your ScrollView with NestedScrollView
Example:
<android.support.v4.widget.NestedScrollView
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">
I realized you need something like this, just tested it out , just copy two files and see how it works.
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;
public class MainActivity extends AppCompatActivity {
LinearLayout movableLL;
boolean mDragLockGained;
float initialTouchPoint;
// int cutoffElevation;
boolean inAnimation;
ScrollView scrollView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = (ScrollView) findViewById(R.id.scrollView);
movableLL = (LinearLayout) findViewById(R.id.mobileLL);
movableLL.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (inAnimation) return true;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDragLockGained = true;
initialTouchPoint = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
performTranslation(event);
initialTouchPoint = event.getRawY();
break;
case MotionEvent.ACTION_UP:
mDragLockGained = false;
performSettlingAnimation();
break;
}
return true;
}
});
}
private void performTranslation(MotionEvent event) {
float newDelta = event.getRawY() - initialTouchPoint;
float currentY = movableLL.getTranslationY();
if (currentY + newDelta > 0) {
movableLL.setTranslationY(currentY + newDelta);
if (scrollView.getTranslationY() + newDelta < 0){
}
scrollView.setTranslationY(scrollView.getTranslationY() + newDelta);
} else {
movableLL.setTranslationY(currentY);
scrollView.setTranslationY(scrollView.getTranslationY());
}
}
final int SETTLE_ANIMATION_DURATION = 300;
private void performSettlingAnimation() {
ObjectAnimator animLl = ObjectAnimator.ofFloat(movableLL, "translationY",
movableLL.getTranslationY(), convertDpToPixels(this, 150));
inAnimation = true;
animLl.setDuration(SETTLE_ANIMATION_DURATION);
animLl.start();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
inAnimation = false;
}
}, SETTLE_ANIMATION_DURATION);//use animationListener here as a best practice and toggle values in
//on animation start and cancel/finish
ObjectAnimator animSv = ObjectAnimator.ofFloat(scrollView, "translationY", scrollView.getTranslationY()
, 0);
animSv.setDuration(SETTLE_ANIMATION_DURATION);
animSv.start();
}
public static int convertDpToPixels(Context context, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()
);
}
}
and the xml......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="Hello There" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="Hello Again" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="WhatsUp" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="See ya" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="#+id/mobileLL"
android:layout_width="match_parent"
android:layout_height="300dp"
android:translationY="150dp"
android:layout_gravity="bottom"
android:background="#android:color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#99ff0000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#990000ff" />
</LinearLayout>
Please let me know if I missed something.
For this purposes the best way is to use BottomSheet from Design Support Library from my point of view.
<?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"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1000dp"
android:background="#android:color/white">
<!-- other layout -->
</RelativeLayout>
</RelativeLayout>
</ScrollView>
<FrameLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_peekHeight="120dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<View
android:layout_width="match_parent"
android:layout_height="240dp"
android:background="#android:color/darker_gray" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
It also possible to combine it with your own a CoordinatorLayout Behavior to change scroll position for your scroll view, if needed.
I have a FAB button in a Coordinator Layout, and I have set snackbars to pop up in the Coordinator Layout. However if a snackbar is visible and I execute an action that triggers another snackbar while the first one is still visible, the FAB button glitches and falls behind the snackbar. Instead of moving with the snackbar.
I have the Coordinator Layout within a Relative Layout though with an adview below the Coordinator Layout.
This is the layout.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/background">
<RelativeLayout
android:id="#+id/circle2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/adView"
android:background="#FFF3E0"
tools:context=".MainActivity"
android:orientation="vertical">
<SurfaceView
android:layout_width="0px"
android:layout_height="0px"
android:visibility="gone" />
<include
android:id="#+id/circle"
layout="#layout/periodictablelayout" />
<include
android:id="#+id/toolbar_actionbar"
layout="#layout/toolbar_default"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="?android:attr/actionBarSize"
/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/periodbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:elevation="3dp"
android:onClick="onClick"
app:layout_anchorGravity="bottom|right|end"
app:layout_anchor="#+id/container2"
android:src="#drawable/ic_view_comfy_white_24dp"
app:backgroundTint="#color/accent"
android:layout_gravity="bottom|end"
app:layout_behavior="ibochemistry.titomo.timetoolay.google.com.ibchemistry.ScrollAwareFABBehaviour" />
</android.support.design.widget.CoordinatorLayout>
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
ads:adSize="BANNER"
ads:adUnitId="#string/banner_ad_unit_id"
app:layout_anchorGravity="bottom" />
</RelativeLayout>
<!-- android:layout_marginTop="?android:attr/actionBarSize"-->
<fragment
android:id="#+id/fragment_drawer"
android:name="ibo.NavigationDrawerFragment"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="#dimen/abc_action_bar_default_height_material"
app:layout="#layout/fragment_navigation_drawer"
tools:layout="#layout/fragment_navigation_drawer" />
How about moving the FAB up with the snackBar. I guess that will fix your problem. Whenever a snackBar is shown do this ,
SnackbarManager.show(
Snackbar.with(getApplicationContext()) // context
.text("This will do something when dismissed") // text to display
.eventListener(new EventListener() {
#Override
public void onShow(Snackbar snackbar) {
myFloatingActionButton.moveUp(snackbar.getHeight());
}
#Override
public void onShown(Snackbar snackbar) {
Log.i(TAG, String.format("Snackbar shown. Width: %d Height: %d Offset: %d",
snackbar.getWidth(), snackbar.getHeight(),
snackbar.getOffset()));
}
#Override
public void onDismiss(Snackbar snackbar) {
myFloatingActionButton.moveDown(snackbar.getHeight());
}
#Override
public void onDismissed(Snackbar snackbar) {
Log.i(TAG, String.format("Snackbar dismissed. Width: %d Height: %d Offset: %d",
snackbar.getWidth(), snackbar.getHeight(),
snackbar.getOffset()));
}
}) // Snackbar's EventListener
, this); // activity where it is displayed
Let me know if it works for you...
Use,
here view - fabView
Snackbar.make(view, "Hello Snackbar", Snackbar.LENGTH_LONG).show();
this will show fab above snackbar
This issue was fixed in support lib 23.1.0 , just update your dependencies and it will fix it.