How to toggle layout_behavior behavior on and off programmatically? - android

Let’s pretend the simple case for simplicity. I have a FloatingActionButton on which I add a layout_behavior. I need to be able to enable or disable the behavior programmatically. How do I do that? I originally add the behavior through xml
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/mine"
app:backgroundTint="#color/colorPrimary"
app:layout_anchor="#id/default_message"
app:layout_anchorGravity="end|bottom"
app:layout_behavior=“mywidget.ScrollingFABBehavior"/>

You can retrieve the LayoutParams via
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) fab.getLayoutParams();
And that point you can either set the behavior directly with setBehavior():
params.setBehavior(null);
Or get your instance of behavior and call a method to have it disable itself (that you make):
ScrollingFABBehavior behavior =
(ScrollingFABBehavior) params.getBehavior();
// This is a method you write
behavior.setEnabled(false);

Related

Android : Unhide a snapped toolbar programmatically

The toolbar is hidden when the screen is scrolled :
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|snap">
How can I unhide it programmatically (i.e. when I click a button) ?
Probably you wrap Toolbar inside AppBarLayout. In that case you have to get AppBarLayout.LayoutParams and need to invoke setScrollFlags() with 0 to stop the scroll. Check below:
Toolbar toolbar = findViewById(R.id.toolbar);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
params.setScrollFlags(0);
You can use one of them
1. without animation
getSupportActionBar().show();
2. With animation
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start();

Shadow problem Floating Action Button (api = 19)

I had a problem with FAB shadow on API <= 19. I used compatElevation= 0f and shadow disappeared. But it appears again during onClick and looks strange:
XML code:
<android.support.design.widget.FloatingActionButton
android:id="#+id/RateBtn"
android:layout_width="#dimen/backet_Btn_size"
android:layout_height="#dimen/backet_Btn_size"
android:elevation="0dp"
app:elevation="0dp"
android:clickable="true"
android:focusable="true"
android:src="#drawable/star_rate2"
app:backgroundTint="#color/w"
app:layout_constraintEnd_toEndOf="#+id/langBtn2"
app:layout_constraintStart_toStartOf="#+id/langBtn2"
app:layout_constraintTop_toTopOf="#+id/SettingsBtn"
app:rippleColor="#color/grey_700" />
Code:
var fb = view?.findViewById(R.id.RateBtn) as FloatingActionButton
val lp =it.layoutParams
if (lp !=null){
lp.width= size_fb
lp.height=size_fb
it.customSize=size_fb
it.layoutParams= lp
}
I think there is some problem when I try to change FAB size programmatically. When I set size in xml, everything is ok
use this code
android:elevation="0dp"
app:elevation="0dp"
Override the default elevation of the FAB by adding
android:elevation="0dp"
Java
setStateListAnimator(null);
XML
android:stateListAnimator="#null"

Android : How to set gravity of Floating Action Button Programmatically?

I want to move the position of Floating action button programmatically at a certain place in some fragment because sometimes the floating action is covering the important contents of that fragment. I got the reference of floating action button in the activity and stored it in a static variable.I am trying to change its gravity in the onResume method of the fragment.
As you can see in the image that fab is covering y-axis so I want to move it to the END.
Image for the reference.
The code in the onResume method of the fragment(not working):
override fun onResume() {
super.onResume()
val params : CoordinatorLayout.LayoutParams = BaseActivity.fab!!.layoutParams as CoordinatorLayout.LayoutParams
params.anchorGravity = GravityCompat.END
BaseActivity.fab!!.layoutParams = params
}
XML file of main activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.mandar.hackerthon_app.Activities.BaseActivity"
tools:showIn="#layout/app_bar_base">
<FrameLayout
android:id="#+id/frameBaseFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:scaleType="center"
android:elevation="10dp"
app:backgroundTint="#color/common_google_signin_btn_text_dark_default"
app:srcCompat="#mipmap/ic_connection_on_round" />
</android.support.design.widget.CoordinatorLayout>
In your XML file, add the app:layout_anchor property for FloatingActionButton, as layout_anchorGravity is only taken into account if you specify an anchor view.
In your case, this anchor may be #id/frameBaseFragment. Note that if you want to move FloatingActionButton to the bottom-end of its CoordinatorLayout parent, you may instead change the value of layoutGravity.
Also, it is strongly discouraged to store references to Views in static variables as it prevents the associated Activity from being garbage-collected, causing huge memory leaks. This might also be the cause of your problem.
fab does not have a gravity property but other layouts do. So an approach I found was to wrap the fab I have in another layout:
// ... FloatingActionButton fab defined somewhere ...
val fabHolder = LinearLayout(this.context) // layout type irrelevant
fabHolder.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
fabHolder.gravity = Gravity.END or Gravity.BOTTOM // bottom-right
fabHolder.addView(fab)
relView.addView(fabHolder)
This replaces the following line of code:
relView.addView(fab)

Floating Action Button does not responds when it clicked/touched

I am using a floating action button(FAB) in my application to show Dialogs, everything is worked just fine when I tested my app in Xperia Z with Lopllipop 5.1.1.
However, the problem is when tested my app in ASUS Zenfone 6 with KitKat 4.4.2 and in Xperia C with Jelly Bean 4.2.2, the FAB loaded perfectly but the FAB does not show the Dialogs, seems like it does not responds when I touched it.
For the record, my min sdk version is 16.
What i want to ask is why this is happening? Is there anything wrong with my code, or maybe with the android version or API level?
Please take a look at my code. Here the XML code:
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_add_account"
android:visibility="invisible"
android:clickable="true"/>
and here how I declare and set the listener for the FAB:
FloatingActionButton fab;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
fab = (FloatingActionButton) getActivity().findViewById(R.id.fab);
...
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDialog();
}
});
...
}
The thing that made me confused is how it is worked in Xperia Z but it does not worked in ASUS Zenfone 6?
The problem in here is that I declared the FAB before the declaration of listView. Somehow by relocating the declaration of FAB after the the declaration of listView it will solved the problem.
From:
<android.support.design.widget.FloatingActionButton
...
...
.../>
<ListView
...
...
.../>
To:
<ListView
...
...
.../>
<android.support.design.widget.FloatingActionButton
...
...
.../>
Just as simple as that.
Programmatically bringing the FAB to front should also work:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.bringToFront();
fab.setOnClickListener... //etc
Just add clickable and focusable and set both to "true" in FAB (floating action button) in xml file
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:clickable="true"
android:focusable="true"
/>
This enable floating button to receive click events and make clickable

FloatingActionButton setVisibility() not working

I can't hide my FloatingActionButton. Here is my code:
XML:
<CoordinatorLayout>
<AppBarLayout android:id="#+id/appbar">
<CollapsingToolbarLayout>
<ImageView/>
<android.support.v7.widget.Toolbar />
</CollapsingToolbarLayout>
</AppBarLayout>
<NestedScrollView />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
app:layout_anchor="#id/appbar"
app:layout_anchorGravity="bottom|right|end"/>
</CoordinatorLayout>
And I'm calling:
fab.clearAnimation();
fab.setVisibility(View.GONE);
I'm trying to hide the FAB, but it seems that setVisibility + clearAnimation does not work if the FAB is in a CoordinatorLayout.
Even if I call fab.clearAnimation, the animation is still triggered. Can anyone help me?
Use show and hide methods to show and hide the Floating Action Button
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
// To show the Floating Action Button
fab.show();
// To hide the Floating Action Button
fab.hide();
For FloatingActionButton the setVisibility() method will give you an error while building with the latest Gradle 6.x and build-tool 28.x.x and is not encouraged any more. Instead, use:
fab.hide() // fab.setVisibility(View.GONE)
fab.show() // fab.setVisibility(View.VISIBLE)
Note: Succesfully tested on Android Studio 3.4.1, Gradle 6.0 and
build-tool 28.0.1
If your issue is the animation, you could try invalidating the FAB Behavior. As for the visibility, you should null the anchor you have set in your layout:
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setBehavior(null); //should disable default animations
p.setAnchorId(View.NO_ID); //should let you set visibility
fab.setLayoutParams(p);
fab.setVisibility(View.GONE); // View.INVISIBLE might also be worth trying
//to bring things back to normal state
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setBehavior(new FloatingActionButton.Behavior());
p.setAnchorId(R.id.appbar);
fab.setLayoutParams(p);
I ran into exactly the same issue. It would seem that Google's Android team doesn't want you to have control of the visibility when the FloatingActionButton is anchored to an AppBarLayout, as discussed in this issue - FloatingActionButton Ignores View Visibility
It looks like a viable fix is wrapping the FAB in a FrameLayout and setting the visibility on the wrapper instead, like this:
<android.support.design.widget.FrameLayout
android:id="#+id/fab_container"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="invisible">
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/fab_icon"/>
</android.support.design.widget.FrameLayout>
You may however wish to consider whether this is the ideal behaviour. Google advocates recommend that the FAB be visible as soon as the screen is created. If you're hiding it for longer than required to animate it in, consider showing a disabled state instead.
you can disable it and make it semitransparent like this
fab.setEnabled(false);
fab.setClickable(false);
fab.setAlpha(0.3f);
FloatingActionButton layers = (FloatingActionButton) findViewById(R.id.layers);
layers.hide();
It works for me, setVisibility doesn't work for FloatingActionButton as it belongs to another viewGroup that doesn't have setVisibility method.

Categories

Resources