使用FloatingActionButton实现可拖拽动态弹出菜单

本文介绍了如何利用Android Design Support Library中的FloatingActionButton设计一个可拖拽的动态菜单,遵循material design原则,通过添加依赖、创建可拖拽的FloatingDraftButton及布局来实现这一功能。
摘要由CSDN通过智能技术生成

Android Design Support Library里面汇集了很多重要的 material design 控件,支持所有 Android 2.1 及后续版本。里面你可以看到 navigation drawer view、floating labels、floating action button、snackbar、tabs,以及一套将它们紧密结合在一起的动作与滚动框架。

在刷新了整个 Android 的用户体验的同时,但要设计出完全符合 material design 哲学的应用,也是一个很大的挑战。

基于FloatingActionButton我设计了一个可拖拽动态弹出效果的功能菜单,其效果如下图所示


第0步:在Android Studio中build.gradle添加依赖:

compile 'com.android.support:design:23.4.0'
compile 'com.jakewharton:butterknife:7.0.1'

第一步:创建可拖拽的FloatingDraftButton 继承FloatingActionButton 实现OnTouchListener方法

import android.content.Context;
import android.support.design.widget.FloatingActionButton;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.cpcn.demo.util.ScreenUtil;
import java.util.ArrayList;


public class FloatingDraftButton extends FloatingActionButton implements View.OnTouchListener{

    int lastX, lastY;
    int originX, originY;
    final int screenWidth ;
    final int screenHeight ;
    private ArrayList<FloatingActionButton> floatingActionButtons = new ArrayList<FloatingActionButton>();

    public FloatingDraftButton(Context context) {
        this(context, null);
    }

    public FloatingDraftButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FloatingDraftButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        screenWidth = ScreenUtil.getScreenWidth(context);
        screenHeight = ScreenUtil.getContentHeight(context);
        setOnTouchListener(this);
    }
    //注册归属的FloatingActionButton 
    public void registerButton(FloatingActionButton floatingActionButton){
        floatingActionButtons.add(floatingActionButton);
    }
    public ArrayList<FloatingActionButton> getButtons(){
        return floatingActionButtons;
    }
    public int getButtonSize(){
        return floatingActionButtons.size();
    }
    //是否可拖拽  一旦展开则不允许拖拽
    public boolean isDraftable(){
        for(FloatingActionButton btn:floatingActionButtons){
            if(btn.getVisibility() == View.VISIBLE ){
                return false;
            }
        }
        return true;
    }
    //当被拖拽后其所属的FloatingActionButton 也要改变位置
    private void slideButton(int l, int t, int r, int b){
        for(FloatingActionButton floatingActionButton:floatingActionButtons){
            floatingActionButton.layout(l, t, r, b);
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(!isDraftable()){
            return false;
        }
        int ea = event.getAction();
        switch (ea) {
            case MotionEvent.ACTION_DOWN:
                lastX = (int) event.getRawX();// 获取触摸事件触摸位置的原始X坐标
                lastY = (int) event.getRawY();
                originX = lastX;
                originY = lastY;
                break;
            case MotionEvent.ACTION_MOVE:
                int dx = (int) event.getRawX() - lastX;
                int dy = (int) event.getRawY() - lastY;
                int l = v.getLeft() + dx;
                int b = v.getBottom() + dy;
                int r = v.getRight() + dx;
                int t = v.getTop() + dy;
                // 下面判断移动是否超出屏幕
                if (l < 0) {
                    l = 0;
                    r = l + v.getWidth();
                }
                if (t < 0) {
                    t = 0;
                    b = t + v.getHeight();
                }
                if (r > screenWidth) {
                    r = screenWidth;
                    l = r - v.getWidth();
                }
                if (b > screenHeight) {
                    b = screenHeight;
                    t = b - v.getHeight();
                }
                v.layout(l, t, r, b);
                slideButton(l,t,r,b);
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                v.postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                int distance = (int) event.getRawX() - originX + (int)event.getRawY() - originY;
                Log.e("DIstance",distance+"");
                if (Math.abs(distance)<20) {
                    //当变化太小的时候什么都不做 OnClick执行
                }else {
 
                    return true;
                }
                break;
        }
        return false;

    }
}

第二步:创建布局layout_floatingmenu.xml

<?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"
    android:orientation="vertical">
    <com.cpcn.demo.widget.Button.FloatingDraftButton
  
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值