Android FloatingActionButton快速拨号

Sne*_*ton 5 user-interface android android-layout speed-dial

我目前正在使用一个Android应用程序,我在其中使用FloatingActionButton.我想使用的快速拨号有作为描述的旋转/跳出操作按钮的多个动作这个由谷歌在Android的设计页面,或可在保持应用程序的早期版本中可以看出(抱歉,但我只能发布一个链接).我正在使用Android设计支持库专门版本23.1.1(com.android.support:design:23.1.1).我已经使用Google进行了搜索并查看了FloatingActionButton的参考资料,但找不到有关快速拨号的任何信息.

我想知道是否有一种方法可以使用默认的FloatingActionButton轻松实现这一点,或者我是否必须手动编程所有过渡/动画?

另外,我希望按钮旁边有一些标签,如果可能的话,描述动作.

先感谢您!

Ike*_*oëk 12

我在这里加上我的2美分,因为这是我在Googling之后登陆的地方.

我希望帮助像我这样的人来得太晚.

首先,解决方案来自这里,所以不是我的.我只是尝试过它很好用.所以我想我会在一个帖子中与你分享,而不是从那里挖掘代码.

该解决方案使用com.android.support:design:25.3.1库,因此请务必将其添加到build.gradle中,并且需要API 21以上版本.

坏消息是它由几个小动作部分组成:5个动画师,5个绘图加上图标和布局,当然还有代码,好消息是它可以正常工作,高度可定制,不需要MainActivity之外的任何编码.

一些说明:

  • 大型工厂的图像在更多和减号之间变换,并在敲击时旋转.
  • 按钮可以有文本,只要你将文本和每个小工厂放在一个LineaLayout中并将按钮id移动到LinearLayout,这样它就会变得动画而不是fab,但它需要代码隐藏并在必要时显示文本.

这是结果:

在此输入图像描述

所以,成分:

  1. Drawables(res/drawable /).

animated_minus.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    android:height="24dp">

    <group android:name="plus_group" android:pivotX="12" android:pivotY="12">
        <path
            android:name="plus_path"
            android:strokeColor="@android:color/white"
            android:strokeWidth="3"
            android:pathData="M12,0L12,24M0,12,L24,12" />
    </group>
</vector>
Run Code Online (Sandbox Code Playgroud)

animated_plus.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/plus">
    <target
        android:animation="@animator/rotate_clockwise"
        android:name="plus_group" />
    <target
        android:animation="@animator/plus_to_minus"
        android:name="plus_path" />
</animated-vector>
Run Code Online (Sandbox Code Playgroud)

fab_background.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item>
        <shape android:shape="oval">
            <solid android:color="?android:colorAccent" />
        </shape>
    </item>
</ripple>
Run Code Online (Sandbox Code Playgroud)

minus.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    android:height="24dp">
    <group android:name="plus_group" android:pivotX="12" android:pivotY="12">
        <path
            android:name="plus_path"
            android:strokeColor="@android:color/white"
            android:strokeWidth="3"
            android:pathData="M12,12L12,12M0,12,L24,12" />
    </group>
</vector>
Run Code Online (Sandbox Code Playgroud)

plus.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    android:height="24dp">
    <group android:name="plus_group" android:pivotX="12" android:pivotY="12">
        <path
            android:name="plus_path"
            android:strokeColor="@android:color/white"
            android:strokeWidth="3"
            android:pathData="M12,0L12,24M0,12,L24,12" />
    </group>
</vector>
Run Code Online (Sandbox Code Playgroud)
  1. 动画师(res/animator /).

fab_state_list_animator.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:state_enabled="true">
        <set>
            <objectAnimator
                android:propertyName="translationZ"
                android:duration="100"
                android:valueTo="3dp"
                android:valueType="floatType" />
            <objectAnimator
                android:propertyName="elevation"
                android:duration="0"
                android:valueTo="5dp"
                android:valueType="floatType" />
        </set>
    </item>
    <!-- base state -->
    <item android:state_enabled="true">
        <set>
            <objectAnimator
                android:propertyName="translationZ"
                android:duration="100"
                android:valueTo="0"
                android:startDelay="100"
                android:valueType="floatType" />
            <objectAnimator
                android:propertyName="elevation"
                android:duration="0"
                android:valueTo="5dp"
                android:valueType="floatType" />
        </set>
    </item>
    <item>
        <set>
            <objectAnimator
                android:propertyName="translationZ"
                android:duration="0"
                android:valueTo="0"
                android:valueType="floatType" />
            <objectAnimator
                android:propertyName="elevation"
                android:duration="0"
                android:valueTo="0"
                android:valueType="floatType" />
        </set>
    </item>
</selector>
Run Code Online (Sandbox Code Playgroud)

minus_to_plus.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="pathData"
    android:valueFrom="M12,0L12,24M12,12,L12,12"
    android:valueTo="M12,0L12,24M0,12,L24,12"
    android:valueType="pathType"
    android:duration="@android:integer/config_mediumAnimTime" />
Run Code Online (Sandbox Code Playgroud)

plus_to_minus.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="pathData"
    android:valueFrom="M12,0L12,24M0,12,L24,12"
    android:valueTo="M12,0L12,24M12,12,L12,12"
    android:valueType="pathType"
    android:duration="@android:integer/config_mediumAnimTime" />
Run Code Online (Sandbox Code Playgroud)

rotate_anticlockwise.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="rotation"
    android:valueFrom="90"
    android:valueTo="0"
    android:valueType="floatType"
    android:duration="@android:integer/config_mediumAnimTime" />
Run Code Online (Sandbox Code Playgroud)

rotate_clockwise.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="90"
    android:valueType="floatType"
    android:duration="@android:integer/config_mediumAnimTime" />
Run Code Online (Sandbox Code Playgroud)
  1. 布局.(RES /布局/)

fab.xml.所有工厂都在这里宣布.android:src在前3个替换为您自己的图标ImageButtons.

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <RelativeLayout
        android:id="@+id/fab_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:clipChildren="false" >

        <!-- Please note that the @id are defined the first time they're referenced from top to bottom -->
        <ImageButton
            android:id="@+id/fab_action_3"
            style="@style/FloatingActionButton.Mini"
            android:src="@drawable/ic_volume_up_white_24dp"
            android:layout_above="@+id/fab_action_2"
            android:layout_alignEnd="@+id/fab"
            android:contentDescription="@null"
            android:backgroundTint="@color/sa_gray"
            android:width="24dp"
            android:height="24dp"
            android:onClick="fabAction3" />

        <ImageButton
            android:id="@id/fab_action_2"
            style="@style/FloatingActionButton.Mini"
            android:src="@drawable/ic_credit_card_white_24dp"
            android:layout_above="@+id/fab_action_1"
            android:layout_alignEnd="@id/fab"
            android:contentDescription="@null"
            android:backgroundTint="@color/sa_gray"
            android:width="24dp"
            android:height="24dp"
            android:onClick="fabAction2" />

        <ImageButton
            android:id="@id/fab_action_1"
            style="@style/FloatingActionButton.Mini"
            android:src="@drawable/ic_add_shopping_cart_white_24dp"
            android:layout_above="@id/fab"
            android:layout_alignEnd="@id/fab"
            android:contentDescription="@null"
            android:backgroundTint="@color/sa_gray"
            android:width="24dp"
            android:height="24dp"
            android:onClick="fabAction1" />

        <ImageButton
            android:id="@id/fab"
            style="@style/FloatingActionButton"
            android:src="@mipmap/ic_add_w"
            android:layout_alignParentEnd="true"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:visibility="visible"
            android:layout_marginTop="8dp" />

    </RelativeLayout>
</merge>
Run Code Online (Sandbox Code Playgroud)

最后.

  1. 代码(java // MainActivity.java)

a)一些声明:

private static final String TAG = "Floating Action Button";
private static final String TRANSLATION_Y = "translationY";
private ImageButton fab;
private boolean expanded = false;
private View fabAction1;
private View fabAction2;
private View fabAction3;
private float offset1;
private float offset2;
private float offset3;
Run Code Online (Sandbox Code Playgroud)

b)删除在通常的工厂代码MainActivityonCreate:

  FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
Run Code Online (Sandbox Code Playgroud)

并替换为:

final ViewGroup fabContainer = (ViewGroup) findViewById(R.id.fab_container);
fab = (ImageButton) findViewById(R.id.fab);
fabAction1 = findViewById(R.id.fab_action_1);
// insert onClickListener here
fabAction2 = findViewById(R.id.fab_action_2);
// insert onClickListener here
fabAction3 = findViewById(R.id.fab_action_3);
// insert onClickListener here
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        expanded = !expanded;
        if (expanded) {
            expandFab();
        } else {
            collapseFab();
        }
    }
});
fabContainer.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    @Override
    public boolean onPreDraw() {
        fabContainer.getViewTreeObserver().removeOnPreDrawListener(this);
        offset1 = fab.getY() - fabAction1.getY();
        fabAction1.setTranslationY(offset1);
        offset2 = fab.getY() - fabAction2.getY();
        fabAction2.setTranslationY(offset2);
        offset3 = fab.getY() - fabAction3.getY();
        fabAction3.setTranslationY(offset3);
        return true;
    }
});
Run Code Online (Sandbox Code Playgroud)

c)添加支持函数MainActivity(主要是动画代码和3个小工厂的onClick方法):

private void collapseFab() {
    fab.setImageResource(R.drawable.animated_minus);
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playTogether(createCollapseAnimator(fabAction1, offset1),
            createCollapseAnimator(fabAction2, offset2),
            createCollapseAnimator(fabAction3, offset3));
    animatorSet.start();
    animateFab();
}

private void expandFab() {
    fab.setImageResource(R.drawable.animated_plus);
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playTogether(createExpandAnimator(fabAction1, offset1),
            createExpandAnimator(fabAction2, offset2),
            createExpandAnimator(fabAction3, offset3));
    animatorSet.start();
    animateFab();
}

private Animator createCollapseAnimator(View view, float offset) {
    return ObjectAnimator.ofFloat(view, TRANSLATION_Y, 0, offset)
            .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}

private Animator createExpandAnimator(View view, float offset) {
    return ObjectAnimator.ofFloat(view, TRANSLATION_Y, offset, 0)
            .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}

private void animateFab() {
    Drawable drawable = fab.getDrawable();
    if (drawable instanceof Animatable) {
        ((Animatable) drawable).start();
    }
}

public void fabAction1(View view) {
    Log.d(TAG, "Action 1");
    Toast.makeText(this, "Go shopping!", Toast.LENGTH_SHORT).show();
}

public void fabAction2(View view) {
    Log.d(TAG, "Action 2");
    Toast.makeText(this, "Gimme money!", Toast.LENGTH_SHORT).show();
}

public void fabAction3(View view) {
    Log.d(TAG, "Action 3");
    Toast.makeText(this, "Turn it up!", Toast.LENGTH_SHORT).show();
}
Run Code Online (Sandbox Code Playgroud)

d)引用fab.xml布局 res/layout/activity_main.xml

删除fab声明:

<android.support.design.widget.FloatingActionButton
    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"
    app:srcCompat="@android:drawable/ic_dialog_email" />
Run Code Online (Sandbox Code Playgroud)

用...来代替:

<include layout="@layout/fab" />
Run Code Online (Sandbox Code Playgroud)

最后说明:

  1. 随意废弃onClick工厂的代码并替换它 onClickListener.那些应该在评论中说得对 // insert onClickListener here.只需记住删除文件中onClick每个fab 的属性,并删除 (, 和)fab.xml中的最后3个函数.MainActivityfabAction1fabAction2fabAction3
  2. 大多数度量,维度等我把它们放在代码中以避免包含更多文件.
  3. 代码未以任何方式进行优化.

我希望这可以帮助某人,并为文本墙感到抱歉.


Mar*_*ski 5

我想知道是否有办法使用默认的 FloatingActionButton 轻松实现此目的

Design Library 中的 FAB 没有此功能。您需要寻找 3rd 方 FAB(android-arsenal 上有一些可供选择)