冲刺2-5

今天星期控件的设计已经可以告一段落了,

floatpopup。java

package com.example.classpai;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.Message;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.os.Handler;

public class FloatPopup  extends PopupWindow implements FloatPopupItem.OnItemClickListener{
    //设置悬浮按钮尺寸
    //设置悬浮按钮尺寸
    private int size = Util.dp2px(50);
    private int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
    private int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
    //触发移动事件的最小距离
    private int touchSlop = new ViewConfiguration().getScaledTouchSlop();
    //记录当前手指实时位置
    private float curX,curY;
    //记录手指按下时的位置
    private float lastX,lastY;
    //设置当前悬浮按钮的显示位置
    private float showX,showY;
    //记录当前悬浮按钮显示状态
    private boolean showMenu = false;
    //记录当前悬浮按钮显示位置
    private boolean showLeft = true;
    private FloatPopupItem item;
    private Activity context;
    private OnClickListener onClickListener;
    private Handler handler;
    private Message message;

    private static FloatPopup floatPopup;

    public static FloatPopup getInstance(){
        if(floatPopup==null){
            floatPopup = new FloatPopup(Util.getContext());
        }
        return floatPopup;
    }

    public void show(){
        if(!floatPopup.isShowing()){
            floatPopup.showAtLocation(Util.getContext().getWindow().getDecorView(),
                    Gravity.NO_GRAVITY,0,0);
            floatPopup.setOnClickListener((OnClickListener) Util.getContext());
        }
    }

    @SuppressLint("HandlerLeak")
    public FloatPopup(Context context) {
        this.context = (Activity) context;
        item = new FloatPopupItem(context);
        item.setOnItemClickListener(this);
        handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //接受到消息,说明用户在规定时间没有操作悬浮按钮,这个时候还要判断下子选项是否展开,
                //选项没有展开,那么就让悬浮按钮变小,靠边站
                if(!showMenu){
                    toSmallIcon(msg.arg1,msg.arg2);
                }
            }
        };
        message = handler.obtainMessage();
        message.what = 0;

        ImageView iv = new ImageView(context);
        iv.setMinimumWidth(size);
        iv.setMinimumHeight(size);
        iv.setImageDrawable(context.getResources().getDrawable(R.mipmap.dayday));
        setContentView(iv);
        setWidth(size);
        setHeight(size);
        setFocusable(false);
        setBackgroundDrawable(new ColorDrawable(0x00000000));
        setOutsideTouchable(false);
        setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                curX = event.getRawX();
                curY = event.getRawY();
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        lastX = event.getRawX();
                        lastY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
//                        float ddx = lastX - curX;
//                        float ddy = lastY - curY;
//                        if(Math.abs(ddx)<touchSlop && Math.abs(ddy)<touchSlop){
//                            return true;
//                        }
                        /*如果当前手指在Y轴上的位置小于按钮的一半时,这个时候按钮的上边沿已经最靠边了。
                        想想一下当Y刚好等于临界值size/2,按钮会在什么位置,就会理解这里为什么做判断了。*/
                        if(curY<size/2){
                           /*在MotionEvent.ACTION_MOVE里面去update按钮的位置,是因为手指每次的移动都会消费
                            move事件,你移动很长的一段路程,在move事件里就会分解成一小段一小段的位移。*/
                            update((int)event.getRawX() - size/2,0);
                            /*在M这里和上边是一样的道理,当Y=临界值screenHeight-size/2时,说明按钮已经接近下边缘了*/
                        }else if(curY>screenHeight-size/2){
                            update((int)event.getRawX() - size/2,screenHeight-size);
                        }else{
                            /*常规情况。但是这里为什么要减去size/2呢(还有上边)?
                            我们设置的位置对于按钮来说是它的左上角,这里减去size/2只是为了让我们的参考点移
                            动到按钮的中心位置,另外,滑动的时候会消除掉一顿一顿的情况,不信你试试没有减掉
                            size/2时是什么样子*/
                            update((int)event.getRawX() - size/2,(int)event.getRawY()-size/2);
                        }

                        /*当开始移动的时候要判断下子项是否展开,如果展开,关闭之后再移动*/
                        if(item.isShowing()){
                            item.dismiss();
                            showMenu = !showMenu;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        /*这里就很好理解了,当我们手指抬起时,如果抬起的位置靠近左边(curX<screenWidth/2),
                            抬起之后就让按钮滚到左边去,否则,到右边乖乖站好*/
                        if(curX<screenWidth/2){
                            showLeft = true;
                            showX = 0;
                            showY = event.getRawY()-size/2;
                        }else{
                            showLeft = false;
                            showX = screenWidth-size;
                            showY = event.getRawY()-size/2;
                        }
                        update((int) showX,(int) showY);

                        /*这里是处理点击事件的,当手指按钮和抬起之间的距离小于touchSlop时,
                        我们认为这是一次点击事件,并根据showMenu的值处理显示或者隐藏子项*/
                        float dx = lastX - curX;
                        float dy = lastY - curY;
                        if(Math.abs(dx)<touchSlop && Math.abs(dy)<touchSlop){
                            if(!showMenu){
                                showMenu();
                            }else{
                                hideMenu();
                            }
                            showMenu = !showMenu;
                        }

                        handler.removeMessages(0);

                        message = handler.obtainMessage();
                        message.what = 0;
                        message.arg1 = (int) showX;
                        message.arg2 = (int) showY;
                        /*手指抬起5s内没有操作的话,让图标变小*/
                        handler.sendMessageDelayed(message,5000);
                        break;
                }
                return true;
            }
        });
    }

    private void toSmallIcon(int curx,int cury){
        if(showLeft){
            update(curx,cury,size/2,size/2);
        }else{
            update(curx+size/2,cury,size/2,size/2);
        }
    }

    private void hideMenu() {
        if(item!=null){
            item.dismiss();
        }
    }

    private void showMenu(){
        /*这里为什么加,为什么减,自己拿尺子比着屏幕量吧,打字好累...*/
        if(showLeft){
            item.showAtLocation(context.getWindow().getDecorView(),Gravity.NO_GRAVITY,(int)(showX+size),(int)showY);
        }else{
            item.showAtLocation(context.getWindow().getDecorView(),Gravity.NO_GRAVITY,(int)(showX-item.width),(int)showY);
        }
    }

    @Override
    public void update(int x, int y) {
        this.update(x,y,size, size);
    }

    @Override
    public void update(int x, int y, int width, int height) {
        super.update(x, y, width, height);
    }

    /**
     * 这里用了两个接口把子项item的点击事件传到FloatPopup的onClick(int i)方法里面统一处理,
     * 因为我们只对外暴露FloatPopup
     * @param i
     */
    @Override
    public void onItemClick(int i) {
        if(onClickListener!=null){
            onClickListener.onClick(i);
        }
    }

    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public interface OnClickListener{
        void onClick(int i);
    }

    public void release(){
        handler.removeMessages(0);
        message = null;
        handler = null;
        dismiss();
        floatPopup = null;
    }
}

floatpopupitem.java

package com.example.classpai;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

public class FloatPopupItem extends PopupWindow implements View.OnClickListener {
    public int width;
    private int height = Util.dp2px(50);
    private OnItemClickListener onItemClickListener;


    public  FloatPopupItem(Context context) {
        LinearLayout layout = new LinearLayout(context);
        layout.setOrientation(LinearLayout.HORIZONTAL);
        layout.setGravity(Gravity.CENTER_VERTICAL);
        for (int i = 0; i < 5; i++) {
            ImageView iv = new ImageView(context);
            iv.setMinimumWidth(height);
            iv.setMinimumHeight(height);
            iv.setImageDrawable(context.getResources().getDrawable(fuQiu(i)));
            iv.setTag(i);
            layout.addView(iv);
            width+=height;
            iv.setOnClickListener(this);
        }
        setContentView(layout);
        setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
        setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
        setBackgroundDrawable(new ColorDrawable(0x00000000));
        setOutsideTouchable(false);
    }

    //悬浮球图片判断函数
    private int fuQiu(int n){
        int type;
        switch (n){
            case 0:{
                type =  R.mipmap.one;
                break;
            }
            case 1:{
                type = R.mipmap.two;
                break;
            }
            case 2:{
                type = R.mipmap.three;
                break;
            }
            case 3:{
                type =  R.mipmap.four;
                break;
            }
            case 4:{
                type =  R.mipmap.five;
                break;
            }
            default:{
                type =  R.mipmap.ic_launcher;
            }
        }
        return type;
    }

    interface OnItemClickListener{
        void onItemClick(int i);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public void onClick(View v) {
        int tag = (int) v.getTag();
        if(onItemClickListener!=null){
            onItemClickListener.onItemClick(tag);
        }
    }
}

明天添加一个分页功能

 

 

posted @ 2019-06-01 07:00  铁大团队  阅读(159)  评论(0编辑  收藏  举报