So I have the coordinate layout as the root layout as I am using a floating Action button.
Here is my xml.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:context=".activities.teacher.TeacherJobBoard"
android:id="#+id/rootLayout_job_board"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/anchor"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/color_black_darker_overlay"
android:layout_gravity="bottom"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/all_night_background"
android:orientation="vertical"
tools:context=".activities.teacher.TeacherJobBoard">
<com.hugocastelani.waterfalltoolbar.WaterfallToolbar
android:id="#+id/teacher_job_board_waterfall_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:final_elevation="15dp">
<androidx.appcompat.widget.Toolbar
android:id="#+id/teacher_job_board_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/tutor_bear_dark_blue"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme" />
</com.hugocastelani.waterfalltoolbar.WaterfallToolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/discretescrollview_teacherJobBoard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</LinearLayout>
<com.github.ybq.android.spinkit.SpinKitView
android:id="#+id/spin_kit_job_board"
style="#style/SpinKitView.Large.WanderingCubes"
android:layout_width="#dimen/_80sdp"
android:layout_height="#dimen/_80sdp"
android:layout_gravity="center_horizontal|center_vertical"
app:SpinKit_Color="#color/color_white" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/extended_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:gravity="center"
style="#style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:onClick="expand"
app:iconSize="#dimen/_12sdp"
android:elevation="#dimen/_5sdp"
android:fontFamily="#font/roboto_light"
android:textColor="#color/white"
android:text="Filter"
app:iconPadding="#dimen/_5sdp"
android:layout_marginBottom="#dimen/_10sdp"
android:layout_marginRight="#dimen/_10sdp"
app:backgroundTint="#color/tutor_bear_dark_blue"
app:iconTint="#color/white"
app:icon="#drawable/ic_filter"
/>
<View
android:id="#+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_black_darker_overlay"
android:visibility="gone"
/>
<include layout="#layout/bottom_filter_dialog"
android:id="#+id/filterSheet"
android:visibility="gone"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I have a simple snack bar in my code like this.
Snackbar.make(binding.getRoot(), "This is main activity", Snackbar.LENGTH_LONG)
.setAction("CLOSE", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
}). show();
Problem is when I show the snack bar , it always appears above a certain height from the bottom of the screen. As if there is some kind of a bottom margin set. This only happens when I use coordinate layout.
Snackbar works fine in other layouts.
Picture of the problem is given as a reference.
Give the root view instead, rootLayout_job_board
CoordinatorLayout rootLayout = findViewById(R.id.rootLayout_job_board);
Snackbar.make(rootLayout), "This is main activity", Snackbar.LENGTH_LONG)
.setAction("CLOSE", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
}). show();
If that doesn't work, try giving GRAVITY using LayoutParams
If that doesn't work, also give margins as 0 in LayoutParams.
Also, if your device is Above 9 then you should consider navigation gestures,
snackbar.isGestureInsetBottomIgnored(false);
See here
Related
I have a Fab which I am using in order to hide or show BottomNavigationBar in my pplication. Everything works fine in andorid 7.0 (1080p), but when I am trying to run the app in android 4.4 (720p), FAB is not visible.
Also, when I am hiding or showing the bottomNavigationBar, I am moving the FAB down and UP respectively, and changing the icon on FAB in order to make it look a little better.
This is my XML code
<RelativeLayout android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end"
android:clickable="true"
app:fabSize="mini"
app:elevation="8dp"
app:rippleColor="#color/colorPrimary"
android:layout_margin="16dp"
app:srcCompat="#drawable/ic_show" />
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- frame layout content -->
</FrameLayout>
<FrameLayout
android:id="#+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:elevation="3dp">
<!-- frame layout content -->
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:background="#color/colorPrimary"
android:iconifiedByDefault="false"
app:itemIconTint="#fff"
app:itemTextColor="#fff"
app:menu="#menu/bottom_bar"/>
</RelativeLayout>
This is the code I have in Activity
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(bottomNavigationView.getVisibility() == View.VISIBLE){
bottomNavigationView.setVisibility(GONE);
fab.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_show));
final ObjectAnimator moveFab
= ObjectAnimator.ofFloat(fab, View.TRANSLATION_Y, fab.getY(), 0);
moveFab.setDuration(300);
moveFab.setInterpolator(new DecelerateInterpolator());
moveFab.start();
}else if(bottomNavigationView.getVisibility() == View.GONE){
bottomNavigationView.setVisibility(View.VISIBLE);
fab.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_hide));
final ObjectAnimator moveFab
= ObjectAnimator.ofFloat(fab, View.TRANSLATION_Y, fab.getY(), -150);
moveFab.setDuration(300);
moveFab.setInterpolator(new DecelerateInterpolator());
moveFab.start();
}
}
});
My log cat says
Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
Am Using something which is not supported by android 4.4 or I am just making any mistake?
I have already gone through many questions with similar titles, Nothing seems relevant.
I am using SnackBar for single line message for related operation.
Snackbar snackBar;
public void showSnackBar(View view){
snackBar = Snackbar.make(view, "Searching for GPS", Snackbar.LENGTH_INDEFINITE);
snackBar.show();
}
In the method isGPSEnabled , i use the method showSnackBar
if(Helper.isGPSEnabled(this)){
showSnackBar(findViewById(android.R.id.content));
}
But I got this,
Why SnackBar allow some space from bottom bar ?
Edit
The layout file :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:drawable/edit_text"
android:divider="#android:drawable/divider_horizontal_textfield"
android:addStatesFromChildren="true">
<LinearLayout android:id="#+id/container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="0dip"
/>
<AutoCompleteTextView android:id="#+id/edit"
android:completionThreshold="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
change 'content' Linear layout_height = "match_parent"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:drawable/edit_text"
android:divider="#android:drawable/divider_horizontal_textfield"
android:addStatesFromChildren="true">
add answer. try this.
in xml linear id change
android:id="#+id/content" to android:id="#+id/parentLinear"
and code
LinearLayout linear = (LinearLayout)findViewById(R.id.parentLinear);
Snackbar.make(linear, "Searching for GPS", Snackbar.LENGTH_INDEFINITE).show();
Please check android.R.id.content view in your layout file.
SnackBar will be shown at the bottom of this view if it is FrameLayout. If you have added padding try removing it.
Can help you better, if you share the layout code.
I want to hide two views (a Viewpager and a LinearLayout) at once when a Button is clicked. I tried using android:animateLayoutChanges="true", but it will always start hiding the Viewpager first and then the LinearLayout, which doesn't look good.
How can I manually hide both views at the same time? I have seen examples like this were the visibility of one view is changed:
myImageView.animate()
.translationY(myImageView.getHeight())
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
myImageView.setVisibility(View.GONE);
}
});
Is there a way to chain two animate() calls of different Viewsto trigger them simultaneously?
EDIT: This is my layout file, the Views I want to hide at the same time are the Viewpagerwith the id viewpager and the LinearLayout with the id ll_indicators:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:animateLayoutChanges="true"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<include
android:id="#+id/tv_statusbar"
layout="#layout/layout_statusbar"
android:layout_width="match_parent"
android:layout_height="#dimen/statusbar_height" />
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:textColor="#color/black"
android:text="#string/some_text"
android:padding="10dp"
android:textSize="#dimen/fontSizeMedium"
android:gravity="center_horizontal"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<LinearLayout
android:id="#+id/ll_indicators"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="#+id/intro_indicator_0"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="#dimen/activity_margin_half"
android:layout_marginRight="#dimen/activity_margin_half"
android:background="#drawable/indicator_unselected" />
<ImageView
android:id="#+id/intro_indicator_1"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="#dimen/activity_margin_half"
android:layout_marginRight="#dimen/activity_margin_half"
android:background="#drawable/indicator_unselected" />
</LinearLayout>
<include
android:id="#+id/ll_login"
android:layout_weight="0"
layout="#layout/item_login"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</include>
</LinearLayout>
Since you didn't post your layout, if you can put your ViewPager and LinearLayout in one layout, (for example inside a RelativeLayout) then you can animate that.
if( A.isShowing && B.isSowing(
A.hide
b.hide
)
Maybe this?
You can either just animate the parent LinearLayout, all Views within will animate with it :
yourLinearLayout.animate().setDuration(300).alpha(0). ...
, or call animate() on two Views simultaneously :
yourImageView.animate().alpha(0). ...
yourLinearLayout.animate().alpha(0). ...
which would look like they are disappearing at the same time.
I already showed my bottom sheet layout with its peek height set to 100dp. But how can I limit my bottom sheet to expand to 500dp only? This is my sample layout:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinator"
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">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
<android.support.v4.widget.NestedScrollView
android:id="#+id/design_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
app:behavior_hideable="true"
app:behavior_peekHeight="100dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#e444ff" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#e444ff" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#e444ff" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_margin="#dimen/activity_horizontal_margin"
app:layout_anchor="#+id/design_bottom_sheet"
app:layout_anchorGravity="top|right|end"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.design.widget.CoordinatorLayout>
In addition to my question, how can I disallow the user from dragging the bottom sheet up and down?
to stop the bottom sheet from moving up the full screen is simple, just set a layout_height for your NestedScrollView to 500dp, also you probably want to set it's layout_gravity="bottom"
<android.support.v4.widget.NestedScrollView
android:id="#+id/design_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="500dp"
android:background="#000000"
android:layout_gravity="bottom"
app:behavior_hideable="true"
app:behavior_peekHeight="100dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#e444ff" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#e444ff" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#e444ff" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
if you don't want the view to be draggable up then you need to set behavior_peekHeight and layout_height to the same values.
And to stop the view from being draggable down is the behavior_hideable flag just set this to false
You can use setMaxHeight method from BottomSheetBehavior (this method should be called before show() method)
bottomSheetDialog.behavior.maxHeight = 1000 // set max height when expanded in PIXEL
bottomSheetDialog.behavior.peekHeight = 400 // set default height when collapsed in PIXEL
You can just set param "maxHeight" to the root viewgroup of your bottom sheet.
android:maxHeight=500dp
Works good with ConstraintLayout as root layout.
If using BottomSheetDialogFragment:
In my case I was using BottomSheetDialogFragment and modified the bottom sheet peek height by getting its reference by override OnCreateDialog method inside my BottomSheetFragment
#NonNull #Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog bottom_dialog = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) bottom_dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
assert bottomSheet != null;
//BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
DisplayMetrics displayMetrics = requireActivity().getResources().getDisplayMetrics();
int height = displayMetrics.heightPixels;
int maxHeight = (int) (height*0.80);
BottomSheetBehavior.from(bottomSheet).setPeekHeight(maxHeight);
}
});
return dialog;
}
Above solutions didn't work for me so I solved it by
1. added app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" in the root view of bottom sheet layout.
2. custom style for bottom sheet:
<style name="AppBottomSheetDialogTheme" parent="Theme.MaterialComponents.BottomSheetDialog">
<item name="bottomSheetStyle">#style/AppModalStyle</item>
</style>
<style name="AppModalStyle" parent="Widget.MaterialComponents.BottomSheet">
<item name="behavior_peekHeight">600dp</item>
</style>
3. And using this in Activity or Fragment by
val mBottomSheetDialog = BottomSheetDialog(this, R.style.AppBottomSheetDialogTheme)
val inflater = this.layoutInflater
val sheetView = inflater.inflate(R.layout.bottom_sheet_layout, null)
mBottomSheetDialog.setContentView(sheetView)
mBottomSheetDialog.show()
For some reason, the accepted answer didn't work for me. Maybe because I'm not using a fragment and a NestedScrollView as the layout inside my BottomSheet. Anyway, in my case, the solution was to limit the size of the CoordinatorLayout:
<ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Your main content here -->
</ConstarintLayout>
<CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="MAX SIZE OF BOTTOM SHEET">
<YourBottomSheetLayout>
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</CoordinatorLayout>
</ConstarintLayout>
I'm currently using the Design Support Library. I've tried implementing the Snackbar with my CoordinatorLayout wraping the entire layout. When the Snackbar is to be displayed, it raises the FAB. But it makes no effort to come down and thereby stays above the translated distance.
It however, does come down when I dismiss the Snackbar by swiping it. So the CoordinatorLayout is aware of the FAB wrapped inside.
.xml
<android.support.design.widget.CoordinatorLayout 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/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/primary"
android:elevation="4dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<com.google.android.gms.ads.AdView
android:id="#+id/ad_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
ads:adSize="BANNER"
ads:adUnitId="#string/banner_ad_unit_id" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/ad_view">
<include layout="#layout/card_view" />
</ScrollView>
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/btn_generate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right|end"
android:layout_margin="16dp"
android:src="#drawable/ic_refresh_white_24dp"
app:elevation="6dp"
app:fabSize="normal"
app:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
.java
Snackbar.make(mCoordinatorLayout, R.string.copied_to_clipboard,
Snackbar.LENGTH_SHORT).show();
If you want to show the Snackbar such that while it showed up, the CoordinatorLayout will be adjusted, then try the code below
findViewById(R.id.btn_generate).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Hello Snackbar", Snackbar.LENGTH_LONG).show();
}
});
You can try the code below, it should work fine. This is how I implement my snackbar in all of my projects and it has never failed me. Study carefully; merry coding ;-) !
Snackbar.make(findViewById(android.R.id.content),"Your text",Snackbar.LENGTH_SHORT).show();
Remember, never forget your show() method, your snackbar is useless without it.
EDIT:
If you're using databinding or viewbinding, you can attach/anchor your SnackBar to any view within your layout by doing something like this:
Snackbar.make(binding.button, message, Snackbar.LENGTH_SHORT).show()
Kindly note that you can still use this approach even if you're not using data/view binding. Just pass the view as the first argument.