Transition in navigation drawer android - android

Anyone having idea that how to achieve this type of transition. When we open Navagation drawer full screen is getting animation like this. I also looked at reside menu but here menu is predefined not as i want.
I also tried with NavigationDrawer but not got succeed.
drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
float moveFactor = (linearLayout.getWidth() * slideOffset);
float min = 0.9f;
float max = 1.0f;
float scaleFactor = (max - ((max - min) * slideOffset));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
linearLayout.setTranslationX(moveFactor);
linearLayout.setScaleX(scaleFactor);
linearLayout.setScaleY(scaleFactor);
}
else
{
AnimationSet animSet = new AnimationSet(true);
TranslateAnimation anim = new TranslateAnimation(lastTranslate, moveFactor, 0.0f, 0.0f);
anim.setDuration(0);
anim.setFillAfter(true);
animSet.addAnimation(anim);
ScaleAnimation scale = new ScaleAnimation(1.15f, 1.0f, 1.15f, 1.0f);
scale.setDuration(10);
scale.setFillAfter(true);
animSet.addAnimation(scale);
drawerView.startAnimation(animSet);
lastTranslate = moveFactor;
}
}
#Override
public void onDrawerOpened(View drawerView) {
}
#Override
public void onDrawerClosed(View drawerView) {
}
#Override
public void onDrawerStateChanged(int newState) {
}
});
Thanks in advance

Finally I got my answer through this link for original post. Please have a look here
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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:context="test.pyramidions.com.dynamicview2.MainActivity"
tools:openDrawer="start">
<RelativeLayout
android:id="#+id/holder"
android:layout_width="match_parent"
android:background="#drawable/shadow"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:background="#color/colorAccent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/drawer_menu" />
</android.support.v4.widget.DrawerLayout>
and for MainActivity.java please have a look below
public class MainActivity extends AppCompatActivity {
public TabsPagerAdapter tabsPagerAdapter;
public static ViewPager pager;
int Numboftabs = 2;
Toolbar toolbar;
public NavigationView navigationView;
public DrawerLayout drawer;
View holderView, contentView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
holderView = findViewById(R.id.holder);
contentView = findViewById(R.id.content);
tabsPagerAdapter = new TabsPagerAdapter(getSupportFragmentManager(), Numboftabs);
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(tabsPagerAdapter);
toolbar.setNavigationIcon(new DrawerArrowDrawable(this));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (drawer.isDrawerOpen(navigationView)) {
drawer.closeDrawer(navigationView);
} else {
drawer.openDrawer(navigationView);
}
}
}
);
drawer.setScrimColor(Color.TRANSPARENT);
drawer.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
#Override
public void onDrawerSlide(View drawer, float slideOffset) {
contentView.setX(navigationView.getWidth() * slideOffset);
RelativeLayout.LayoutParams lp =
(RelativeLayout.LayoutParams) contentView.getLayoutParams();
lp.height = drawer.getHeight() -
(int) (drawer.getHeight() * slideOffset * 0.3f);
lp.topMargin = (drawer.getHeight() - lp.height) / 2;
contentView.setLayoutParams(lp);
}
#Override
public void onDrawerClosed(View drawerView) {
}
}
);
}

Drawer behavior is a library use Android DrawerLayout Support library as Parent Class [Easy to migrate], that provide an extra behavior on drawer, such as, move view or scaling view's height while drawer on slide.
If current project use Android DrawerLayout Support library and kinda boring with the effect. Then, just change the layout code and calling necessary method for animation/effect.
Check out github code
Gradle
dependencies {
implementation 'com.infideap.drawerbehavior:drawer-behavior:0.1.5'
}
if the gradle unable to sync, you may include this line in project level gradle,
repositories {
maven{
url "https://dl.bintray.com/infideap2/Drawer-Behavior"
}
}

Related

Drawer handle change Background off the handle

As this question is many times but I am not getting the answer regarding how the change the handle background.
Till now what i got is :
Close Drawer
Open Drawer
When Drawer is Open the handle come inside the drawer and I have kept the drawer full screen.
Now the problem is When drawer is open handle should change its layout from circular android logo to square android logo.
Here is code :
MainActivty :
public class MainActivity extends AppCompatActivity {
DrawerLayout mDrawerLayout;
ListView mDrawerList;
LinearLayout mDrawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
mDrawerLayout = (DrawerLayout) findViewById( R.id.drawer_layout );
mDrawer = findViewById( R.id.drawer );
mDrawerList = (ListView) findViewById( R.id.drawer_list );
String[] list = {"hello", "One"};
if (mDrawerLayout.isDrawerOpen( GravityCompat.END )){
DrawerHandle.attach( mDrawer, R.layout.layout_handle, 0.5f );
}else {
DrawerHandle.attach( mDrawer, R.layout.layout_handle_2, 0.5f );
}
}
}
DrawerHandle.class :
public class DrawerHandle implements DrawerLayout.DrawerListener {
public static final String TAG = "DrawerHandle";
private ViewGroup mRootView;
private DrawerLayout mDrawerLayout;
private View mHandle;
private View mDrawer;
private float mVerticalOffset;
private int mGravity;
private WindowManager mWM;
private Display mDisplay;
private Point mScreenDimensions = new Point();
private OnClickListener mHandleClickListener = new OnClickListener(){
#Override
public void onClick(View v) {
if(!mDrawerLayout.isDrawerOpen(mGravity)) mDrawerLayout.openDrawer(mGravity);
else mDrawerLayout.closeDrawer(mGravity);
}
};
private OnTouchListener mHandleTouchListener = new OnTouchListener() {
private static final int MAX_CLICK_DURATION = 200;
private long startClickTime;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startClickTime = System.currentTimeMillis();
break;
}
case MotionEvent.ACTION_UP: {
if(System.currentTimeMillis() - startClickTime < MAX_CLICK_DURATION) {
v.performClick();
return true;
}
}
}
MotionEvent copy = MotionEvent.obtain(event);
copy.setEdgeFlags(ViewDragHelper.EDGE_ALL);
copy.setLocation(event.getRawX() + (mGravity == Gravity.LEFT || mGravity == GravityCompat.START ? -mHandle.getWidth()/2 : mHandle.getWidth() / 2), event.getRawY());
mDrawerLayout.onTouchEvent(copy);
copy.recycle();
return true;
}
};
private int getDrawerViewGravity(View drawerView) {
final int gravity = ((DrawerLayout.LayoutParams) drawerView.getLayoutParams()).gravity;
return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(drawerView));
}
private float getTranslation(float slideOffset){
return (mGravity == GravityCompat.START || mGravity == Gravity.LEFT) ? slideOffset*mDrawer.getWidth() : -slideOffset*mDrawer.getWidth();
}
private void updateScreenDimensions() {
if (Build.VERSION.SDK_INT >= 13) {
mDisplay.getSize(mScreenDimensions);
} else {
mScreenDimensions.x = mDisplay.getWidth();
mScreenDimensions.y = mDisplay.getHeight();
}
}
public DrawerHandle(DrawerLayout drawerLayout, View drawer, int handleLayout, float handleVerticalOffset) {
mDrawer = drawer;
mGravity = getDrawerViewGravity(mDrawer);
mDrawerLayout = drawerLayout;
mRootView = (ViewGroup)mDrawerLayout.getRootView();
LayoutInflater inflater = (LayoutInflater) mDrawerLayout.getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
mHandle = inflater.inflate(handleLayout, mRootView, false);
mWM = (WindowManager) mDrawerLayout.getContext().getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWM.getDefaultDisplay();
mHandle.setOnClickListener(mHandleClickListener);
mHandle.setOnTouchListener(mHandleTouchListener);
mRootView.addView(mHandle, new FrameLayout.LayoutParams(mHandle.getLayoutParams().width, mHandle.getLayoutParams().height, mGravity));
setVerticalOffset(handleVerticalOffset);
mDrawerLayout.setDrawerListener(this);
}
public static DrawerHandle attach(View drawer, int handleLayout, float verticalOffset) {
if (!(drawer.getParent() instanceof DrawerLayout)) throw new IllegalArgumentException("Argument drawer must be direct child of a DrawerLayout");
return new DrawerHandle((DrawerLayout)drawer.getParent(), drawer, handleLayout, verticalOffset);
}
public static DrawerHandle attach(View drawer, int handleLayout) {
return attach(drawer, handleLayout, 0);
}
#Override
public void onDrawerClosed(View arg0) {
}
#Override
public void onDrawerOpened(View arg0) {
mHandle.setX( 10 );
}
#Override
public void onDrawerSlide(View arg0, float slideOffset) {
float translationX = getTranslation(slideOffset);
mHandle.setTranslationX(translationX);
}
#Override
public void onDrawerStateChanged(int arg0) {
}
public View getView(){
return mHandle;
}
public View getDrawer() {
return mDrawer;
}
public void setVerticalOffset(float offset) {
updateScreenDimensions();
mVerticalOffset = offset;
mHandle.setY(mVerticalOffset*mScreenDimensions.y);
}
}
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
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">
<LinearLayout
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="right"
android:orientation="vertical"
android:padding="20dp"
android:layout_marginRight="-67dp"
android:background="#CCFF0000"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Collection"
android:paddingBottom="20dp"
/>
<ListView
android:id="#+id/drawer_list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:layout_weight="1"
/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.v4.widget.DrawerLayout>
layout_handle.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher_square" />
</android.support.constraint.ConstraintLayout>
layout_handle_2.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="#mipmap/ic_launcher_round" />
</android.support.constraint.ConstraintLayout>
I'm stuck with this problem just help me out.
Kindly let me know your suggestion.
Thank's in advance.

OnOffsetChanged is not working

Trying to make the avatar pic get smaller until disappear by using OnOffsetChanged but it is not working in the fragment. I tried the same way with an activity it worked.
<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:background="#android:color/white"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
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:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleTextAppearance="#style/TextAppearance.AppCompat.Title"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<ImageView
android:layout_width="match_parent"
android:layout_height="220dp"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="#drawable/bg_polygon"
app:layout_collapseMode="parallax" />
<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" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView>
**some code**
</android.support.v4.widget.NestedScrollView>
<com.mikhaellopez.circularimageview.CircularImageView
android:id="#+id/profileImage"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/photo_female_6"
app:civ_border="true"
app:civ_border_width="2dp"
app:layout_anchor="#id/app_bar_layout"
app:layout_anchorGravity="bottom|center" />
I tried to use OnOffsetChangedListener using two ways non of them worked
the first is calling the (AppBarLayout) v.findViewById(R.id.app_bar_layout)).addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener()) to override the method
and the second is by implementing the appbarlayout in the fragmet class
public class ProfileFragment extends Fragment implements
AppBarLayout.OnOffsetChangedListener {
public ProfileFragment() {
// Required empty public constructor
}
public static ProfileFragment newInstance() {
ProfileFragment fragment = new ProfileFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppBarLayout appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar_layout);
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile, container, false);
return inflater.inflate(R.layout.fragment_profile, container, false);
}
private void initComponent(View v) {
final CircularImageView image = v.findViewById(R.id.profileImage);
final CollapsingToolbarLayout collapsing_toolbar = v.findViewById(R.id.collapsing_toolbar);
((AppBarLayout) v.findViewById(R.id.app_bar_layout)).addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
int min_height = ViewCompat.getMinimumHeight(collapsing_toolbar) * 2;
float scale = (float) (min_height + verticalOffset) / min_height;
image.setScaleX(scale >= 0 ? scale : 0);
image.setScaleY(scale >= 0 ? scale : 0);
}
});
}
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
final CircularImageView image;
image = (CircularImageView) getActivity().findViewById(R.id.profileImage);
final CollapsingToolbarLayout collapsing_toolbar = (CollapsingToolbarLayout) getActivity().findViewById(R.id.collapsing_toolbar);
int min_height = ViewCompat.getMinimumHeight(collapsing_toolbar) * 2;
float scale = (float) (min_height + verticalOffset) / min_height;
image.setScaleX(scale >= 0 ? scale : 0);
image.setScaleY(scale >= 0 ? scale : 0);
}
}
and when I debugged the code I found that the method was never called even when I used the CollapsingToolbarLayout.
i solved this problem by adding an "onactivitycreated" method so when i try to get the view i will exist
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
AppBarLayout mAppBarLayout = getView().findViewById(R.id.app_bar_layout);
final CollapsingToolbarLayout collapsing_toolbar = getView().findViewById(R.id.collapsing_toolbar);
final CircularImageView image = getView().findViewById(R.id.profileImage);
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
int min_height = ViewCompat.getMinimumHeight(collapsing_toolbar) * 2;
float scale = (float) (min_height + verticalOffset) / min_height;
image.setScaleX(scale >= 0 ? scale : 0);
image.setScaleY(scale >= 0 ? scale : 0);
}
});
}

I want to Close Navigation Drawer if and only if I click the Button

I have created Navigation Drawer using below code.
activity_inventory.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fab="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:layout_gravity="end"
android:fitsSystemWindows="true">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:visibility="gone" />
<com.example.softeng.animationf.fabdirectory.ActionButton
android:id="#+id/fab_activity_action_button"
style="#style/fab_action_button_style"
android:layout_gravity="bottom|right"
fab:type="MINI"/>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="end">
<RelativeLayout
android:id="#+id/right_navigation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#4D4D4D">
</RelativeLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
DrawerLayout drawerLayout;
NavigationView navigation_view;
ImageView view;
int count = 1;
private boolean isOutSideClicked = false;
RelativeLayout relativeLayout;
private ActionButton actionButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = (ImageView)findViewById(R.id.view);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
drawerLayout.setScrimColor(Color.parseColor("#00000000"));
navigation_view = (NavigationView) findViewById(R.id.navigation_view);
relativeLayout = (RelativeLayout)findViewById(R.id.right_navigation);
actionButton = (ActionButton) findViewById(R.id.fab_activity_action_button);
actionButton.setImageResource(R.drawable.fab_plus_icon);
actionButton.setRippleEffectEnabled(true);
actionButton.setShadowRadius(0);
actionButton.setShadowXOffset(0);
actionButton.setShadowYOffset(0);
actionButton.setButtonColor(Color.parseColor("#0072BA"));
actionButton.setButtonColorPressed(Color.parseColor("#004F80"));
actionButton.setShadowRadius(10);
actionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(count == 1) {
actionButton.moveLeft(200);
actionButton.setImageResource(R.drawable.fab_plus_icon);
drawerLayout.openDrawer(Gravity.RIGHT);
view.setVisibility(View.VISIBLE);
actionButton.bringToFront();
count = count - 1;
}else if(count == 0){
closeFab();
}
else {
}
}
});
}
private void closeFab(){
view.setVisibility(View.GONE);
actionButton.move(new MovingParams(MainActivity.this, 200 , 0));
actionButton.setImageResource(R.drawable.fab_plus_icon);
count = count + 1;
drawerLayout.closeDrawer(Gravity.RIGHT);
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (drawerLayout.isDrawerOpen(navigation_view)) {
View content = findViewById(R.id.drawer_layout);
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
if (!(rect.contains((int) event.getX(), (int) event.getY()))) {
isOutSideClicked = true;
} else {
isOutSideClicked = false;
this.closeFab();
}
}
}
return super.dispatchTouchEvent(event);
}
}
ScreenShot :
Update Code :
if (!(rect.contains((int) event.getX(), (int) event.getY()))) {
isOutSideClicked = true;
this.closeFab();
} else {
isOutSideClicked = false;
}
I When i click on NavigationView anywhere the Drawer is Close. But I want to Close the Drawer if and Only if when i click on Button.
Update :
flow normal screen
click on button
click on outside area
change to this result
In the dispatchTouchEvent() override, it looks like you want to detect clicks that are outside of the NavigationView, and trigger the move on your ActionButton if they are, since the drawer will be closing when that happens. However, your code is actually detecting clicks anywhere within the DrawerLayout, and triggering the move on the wrong condition.
The simplest fix is to change View content = findViewById(R.id.drawer_layout); to View content = findViewById(R.id.navigation_view);, and move the this.closeFab(); line to the if block of the if-else it's in.
View content = findViewById(R.id.navigation_view);
...
if (!(rect.contains((int) event.getX(), (int) event.getY()))) {
isOutSideClicked = true;
this.closeFab();
} else {
isOutSideClicked = false;
}
You can set the lock mode on the drawer
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
and when you want to close it just unlock it.
https://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html#setDrawerLockMode%28int,%20int%29

Circular Reveal not working when FAB gravity is bottom

I am working on morphing a floating action button (FAB) to a toolbar and things work smoothly and perfectly with the following code:
layout file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context="sg.com.saurabh.designlibraryexpirements.ToolbarMorphActivity">
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:layout_marginRight="#dimen/activity_vertical_margin"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:src="#drawable/ic_add" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
style="#style/ToolBarTheme"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="top"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:visibility="invisible"
tools:visibility="visible" />
</FrameLayout>
activity:
package sg.com.saurabh.designlibraryexpirements;
import android.animation.Animator;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
public class ToolbarMorphActivity extends AppCompatActivity {
Toolbar toolbar;
FloatingActionButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toolbar_morph);
toolbar = (Toolbar) findViewById(R.id.toolbar);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(mFabClickListener);
}
private View.OnClickListener mFabClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
fab.animate()
.rotationBy(45)
.setInterpolator(new AnticipateOvershootInterpolator())
.setDuration(250)
.start();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
fab.setVisibility(View.GONE);
}
},50);
revealToolbar();
}
};
private void revealToolbar() {
toolbar.setVisibility(View.VISIBLE);
int x = (int)fab.getX() + fab.getWidth()/2;
int y = (int)fab.getY() + fab.getHeight()/2;
Animator animator = ViewAnimationUtils.createCircularReveal(toolbar, x, y, 0, toolbar.getWidth())
.setDuration(400);
animator.setInterpolator(new FastOutLinearInInterpolator());
animator.start();
}
private void dismissToolbar() {
int x = (int)fab.getX() + fab.getWidth()/2;
int y = (int)fab.getY() + fab.getHeight()/2;
Animator animator = ViewAnimationUtils.createCircularReveal(toolbar, x, y, toolbar.getWidth(), 0)
.setDuration(400);
animator.setInterpolator(new LinearOutSlowInInterpolator());
animator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
toolbar.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
fab.setVisibility(View.VISIBLE);
fab.animate()
.rotationBy(-45)
.setInterpolator(new AccelerateInterpolator())
.setDuration(100)
.start();
}
},200);
}
#Override
public void onBackPressed() {
if(toolbar.getVisibility() == View.VISIBLE) {
dismissToolbar();
}
else
super.onBackPressed();
}
}
The circular reveal works as expected for the above layout. However thing break up when I change the layout_gravity of the fab and toolbar to bottom instead of top. The rotate animation works and then the toolbar just appears without the circular reveal animation. I am completely stumped by how that breaks the circular reveal animation.
The fix for you would be to replace:
private void revealToolbar() {
....
int x = (int)fab.getX() + fab.getWidth()/2;
int y = (int)fab.getY() + fab.getHeight()/2;
....
}
by
private void revealToolbar() {
...
int x = (int)fab.getX() + fab.getWidth()/2;
int y = fab.getHeight()/2;
...
}
The reason is that createCircularReveal is taking parameters centerY and centerX as coordinates of the center of the animating circle, relative to view (i.e. Toolbar, in our case).
See method ViewAnimationUtils.createCircularReveal definition:
........
* #param view The View will be clipped to the animating circle.
* #param centerX The x coordinate of the center of the animating circle, relative to
* <code>view</code>.
* #param centerY The y coordinate of the center of the animating circle, relative to
* <code>view</code>.
* #param startRadius The starting radius of the animating circle.
* #param endRadius The ending radius of the animating circle.
*/

Floating Action Button

I have been trying to use Floating Action Button. I tried to use some of the resources suggested on here and the links were great; however, I couldn't use alot of them because of problems with dependicies. I tried to fix it but it got more messed up. Long story short, I use the following code as a way to bypass dependicies in my bundle. I got the button to work; however, I couldn't figure out how to have options to appear when the button is clicked. I tried on clicklistener and other ways but I always got an error.
public class FloatingActionButton extends View {
Context context;
Paint mButtonPaint;
Paint mDrawablePaint;
Bitmap mBitmap;
boolean mHidden = false;
public FloatingActionButton(Context context) {
super(context);
this.context = context;
init(Color.WHITE);
}
public void init(int color) {
setWillNotDraw(false);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mButtonPaint.setColor(color);
mButtonPaint.setStyle(Paint.Style.FILL);
mButtonPaint.setShadowLayer(10.0f, 0.0f, 3.5f, Color.argb(100, 0, 0, 0));
mDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
setClickable(true);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, (float) (getWidth() / 2.6), mButtonPaint);
canvas.drawBitmap(mBitmap, (getWidth() - mBitmap.getWidth()) / 2,
(getHeight() - mBitmap.getHeight()) / 2, mDrawablePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
setAlpha(1.0f);
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
setAlpha(0.6f);
}
return super.onTouchEvent(event);
}
public void setColor(int color) {
init(color);
}
public void setDrawable(Drawable drawable) {
mBitmap = ((BitmapDrawable) drawable).getBitmap();
invalidate();
}
public void hide() {
if (!mHidden) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1, 0);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1, 0);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(scaleX, scaleY);
animSetXY.setInterpolator(new AccelerateInterpolator());
animSetXY.setDuration(100);
animSetXY.start();
mHidden = true;
}
}
public void show() {
if (mHidden) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 0, 1);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 0, 1);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(scaleX, scaleY);
animSetXY.setInterpolator(new OvershootInterpolator());
animSetXY.setDuration(200);
animSetXY.start();
mHidden = false;
}
}
public boolean isHidden() {
return mHidden;
}
public static class Builder {
private FrameLayout.LayoutParams params;
private final Activity activity;
int gravity = Gravity.BOTTOM | Gravity.RIGHT; // default bottom right
Drawable drawable;
int color = Color.WHITE;
int size = 0;
float scale = 0;
/**
* Constructor using a context for this builder and the
* {#link com.williammora.openfeed.widgets.FloatingActionButton} it creates
* #param context
*/
public Builder(Activity context) {
scale = context.getResources().getDisplayMetrics().density;
// The calculation (value * scale + 0.5f) is a widely used to convert to dps to pixel
// units based on density scale
// see <a href="http://developer.android.com/guide/practices/screens_support.html">
// developer.android.com (Supporting Multiple Screen Sizes)</a>
size = (int) (72 * scale + 0.5f); // default size is 72dp by 72dp
params = new FrameLayout.LayoutParams(size, size);
params.gravity = gravity;
this.activity = context;
}
public Builder withGravity(int gravity) {
this.gravity = gravity;
return this;
}
public Builder withMargins(int left, int top, int right, int bottom) {
params.setMargins((int) (left * scale + 0.5f), (int) (top * scale + 0.5f),
(int) (right * scale + 0.5f), (int) (bottom * scale + 0.5f));
return this;
}
public Builder withDrawable(final Drawable drawable) {
this.drawable = drawable;
return this;
}
public Builder withColor(final int color) {
this.color = color;
return this;
}
public Builder withSize(int size) {
size = (int) (size * scale + 0.5f);
params = new FrameLayout.LayoutParams(size, size);
return this;
}
public FloatingActionButton create() {
final FloatingActionButton button = new FloatingActionButton(activity);
button.setColor(this.color);
button.setDrawable(this.drawable);
params.gravity = this.gravity;
ViewGroup root = (ViewGroup) activity.findViewById(android.R.id.content);
root.addView(button, params);
return button;
}
}
}
FloatingActionButton mFab = new FloatingActionButton.Builder(this)
.withColor(getResources().getColor(R.color.primaryColorDark))
.withDrawable(getResources().getDrawable(R.drawable.ic_launcher))
.withSize(72)
.withMargins(0, 0, 16, 16)
.create();
MainActivity
FloatingActionButton mFab = new FloatingActionButton.Builder(this)
.withColor(getResources().getColor(R.color.primaryColorDark))
.withDrawable(getResources().getDrawable(R.drawable.ic_launcher))
.withSize(72)
.withMargins(0, 0, 16, 16)
.create();
Just put compile 'com.android.support:design:22.2.1' in your module app dependencies.
In your xml:
<android.support.design.widget.FloatingActionButton
style="#style/<your_style>"
android:src="#drawable/<your_icon_src>"
app:layout_anchor="#id/<if using along with list put your listID here>"
app:layout_anchorGravity="bottom|right|end"
android:id="#+id/fab"
/>
In you java:
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
There is no need to create FloatingActionButton by yourself now. The new com.android.support:design:23.0.1 can do that for you. Just follow the below procedure.
1.Add this line compile 'com.android.support:design:23.0.1' in dependencies in your build.gradle in Android Studio
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:23.0.1'
}
2.To create a FloatingActionButton using the following xml file.
<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/YourEventsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Add other elements here-->
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="16dp"
android:src="#drawable/ic_add_white_24dp"
app:elevation="6dp"
app:fabSize="normal"
app:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
In MainActivity in onCreate method set setOnClickListener as follows
FloatingActionButton fab;
fab = (FloatingActionButton) getView().findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do what you want here
}
});
This is how you create a floating action button.
build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:design:23.0.1'
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/viewOne"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.6"
android:background="#android:color/holo_blue_light"
android:orientation="horizontal"/>
<LinearLayout
android:id="#+id/viewTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.4"
android:background="#android:color/holo_orange_light"
android:orientation="horizontal"/>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="#drawable/ic_done"
app:layout_anchor="#id/viewOne"
app:layout_anchorGravity="bottom|right|end"
app:backgroundTint="#FF0000"
app:rippleColor="#FFF" />
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
MainActivity.java
package com.ahotbrew.floatingactionbutton;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton FAB = (FloatingActionButton) findViewById(R.id.fab);
FAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Would you like a coffee?", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Hope that complete example helps someone.
The example is from http://www.ahotbrew.com/android-floating-action-button/
It also shows how to place the button in other locations if interested.
You don't have to create FAB now, its already available, just follow this Link
you need to add
<RelativeLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.FloatingActionButton
android:id="#+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_plus_sign"
app:elevation="4dp"
... />
</RelativeLayout>
and
FloatingActionButton myFab = (FloatingActionButton) myView.findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doMyThing();
}
});
in code behind
For more detail follow :
FloatingActionButton example with Support Library

Categories

Resources