直播商城开发Android自定义可移动悬浮按钮

在布局文件添加控件时可使用如下方式:

<android.support.design.widget.FloatingActionButton
       .......
        />

也可使用自定义的包名:
com.example.notepad2.DragFloatActionButton
因为接下来要实现自定义的悬浮按钮,可根据实际情况自定。这里建议使用第二种方法,使用第一种时可能会出现闪退情况

<com.example.notepad2.DragFloatActionButton
      android:id="@+id/fb"
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      app:borderWidth="0dp"
      app:backgroundTint="#FFFFFF"
      app:rippleColor="#008577"
      android:src="@drawable/hao"
      android:layout_alignParentRight="true"
      android:layout_centerVertical="true"
      />

实现自定义悬浮按钮
创建一个DragFloatActionButton类继承FloatingActionButton
在类中覆写 onTouchEvent 函数,捕捉触摸事件,然后利用setX(),setY() 方法将其移动。

而吸附效果,则是利用ObjectAnimator.ofFloat 实现动画。

//左吸附
ObjectAnimator oa=ObjectAnimator.ofFloat(this,"x",getX(),0);
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(500);
oa.start();

使用的构造方法为

 public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)

第一个参数为添加动画的对象
第二个参数为动画属性名称,这里我们使用alpha透明度动画
第三个参数为要改变的值,是可变的,这里我们从1变为0再变为1,也就是从不透明变成透明,然后变回来。
以下是 DragFloatActionButton 类的实现代码:

public class DragFloatActionButton extends FloatingActionButton {

    private int parentHeight;
    private int parentWidth;
    public DragFloatActionButton(Context context) {
        super(context);
    }
    public DragFloatActionButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public DragFloatActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }
    private int lastX;
    private int lastY;
    private boolean isDrag;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                setPressed(true);
                isDrag=false;
                getParent().requestDisallowInterceptTouchEvent(true);
                lastX=rawX;
                lastY=rawY;
                ViewGroup parent;
                if(getParent()!=null){
                    parent= (ViewGroup) getParent();
                    parentHeight=parent.getHeight();
                    parentWidth=parent.getWidth();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if(parentHeight<=0||parentWidth==0){
                    isDrag=false;
                    break;
                }else {
                    isDrag=true;
                }
                //计算手指移动了多少
                int dx=rawX-lastX;
                int dy=rawY-lastY;
                //这里修复一些华为手机无法触发点击事件
                int distance= (int) Math.sqrt(dx*dx+dy*dy);
                if(distance==0){
                    isDrag=false;
                    break;
                }
                float x=getX()+dx;
                float y=getY()+dy;
                //检测是否到达边缘 左上右下
                x=x<0?0:x>parentWidth-getWidth()?parentWidth-getWidth():x;
                y=getY()<0?0:getY()+getHeight()>parentHeight?parentHeight-getHeight():y;
                setX(x);
                setY(y);
                lastX=rawX;
                lastY=rawY;
                Log.i("aa","isDrag="+isDrag+"getX="+getX()+";getY="+getY()+";parentWidth="+parentWidth);
                break;
            case MotionEvent.ACTION_UP:
                if(!isNotDrag()){
                    //恢复按压效果
                    setPressed(false);
                    //Log.i("getX="+getX()+";screenWidthHalf="+screenWidthHalf);
                   /* animate().setInterpolator(new DecelerateInterpolator())
                            .setDuration(500)
                            .start();*/
                    if(rawX>=parentWidth/2){
                      //靠右吸附
                        animate().setInterpolator(new DecelerateInterpolator())
                                .setDuration(500)
                                .xBy(parentWidth-getWidth()-getX())
                                .start();
                    }else {
                      //靠左吸附
                        ObjectAnimator oa=ObjectAnimator.ofFloat(this,"x",getX(),0);
                        oa.setInterpolator(new DecelerateInterpolator());
                        oa.setDuration(500);
                        oa.start();
                    }
                }
               break;
        }
        //如果是拖拽则消s耗事件,否则正常传递即可。
        return !isNotDrag() || super.onTouchEvent(event);
        return ev.getAction() != MotionEvent.ACTION_UP && (mIsDrag || super.onTouchEvent(ev));
    }
    private boolean isNotDrag(){
        return !isDrag&&(getX()==0
                ||(getX()==parentWidth-getWidth()));
    }
}

DragFloatActionButton的使用
在布局文件中添加响应控件后在MainActivity中为其进行绑定

FloatingActionButton imageButton;
imageButton= (DragFloatActionButton)findViewById(R.id.fb);

同时必须 添加按钮点击事件,触发 onTouchEvent 函数
使按钮能被拖拽移动

imageButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
             //添加要响应的内容
             ...........
    }
});

你可能感兴趣的:(技术类)