Android使用Popupwindow实现悬浮菜单功能

下面要实现这样一个功能,点击“+”打开菜单,再次点击或者点击其他地方关闭菜单,点击菜单里内容实现具体功能

这里写图片描述

这里写图片描述

下面是做好的效果图

这里写图片描述

下面分析一下思路,圆形的悬浮按钮实现方法有很多,就不一一细说了,本文就使用ImageView实现了,

弹出的菜单之前思路有两种,第一种,写布局实现,第二种,弹出PopupWindow实现,很明显,第二种效果要更好一些,本文也是使用的PopupWindow,代码如下:

布局文件:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="fan.popmenu.MainActivity">

    <ImageView
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:id="@+id/iv_menu"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/new_bj"
        android:scaleType="fitCenter"
        />

</RelativeLayout>

代码:


package fan.popmenu;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private PopupWindow mMenuPop;
    private ImageView mImageView;

    private int PopWidth;
    private int PopHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = (ImageView) findViewById(R.id.iv_menu);

        //ImageView点击事件
        mImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showLevitateMenu();
            }
        });
    }


    /**
     * 显示悬浮菜单
     */
    private void showLevitateMenu(){

        //动画
        mRotate(mImageView);

        //创建popwindow
        getPopMenu();

        //获取ImageView控件在手机屏幕的位置
        int[] location = new int[2];
        mImageView.getLocationOnScreen(location);
        int x = location[0];
        int y = location[1];

        /**
         * popwindow显示的位置
         * 参数一:基于某控件,一般在popupWindow.showAsDropDown()中比较有用,该处作用不大
         * 参数二:见名知意,写默认即可
         * 参数三:popupWindow在屏幕上显示位置的x坐标
         * 参数四:popupWindow在屏幕上显示位置的y左边
         */
        mMenuPop.showAtLocation(mImageView, Gravity.NO_GRAVITY, mImageView.getLeft()-PopWidth+mImageView.getWidth()/4, y+mImageView.getHeight()/2-PopHeight/2);

    }

    //当前旋转的度数
    private int rotate = 0;
    //每次旋转的度数
    private int rotation = 225;
    //判断顺时针转还是逆时针转
    private boolean rotateDirection = true;

    /**
     * 悬浮菜单动画效果
     * @param v
     */
    private void mRotate(View v) {

        ObjectAnimator animator;

        //判断是顺时针旋转还是逆时针旋转
        if(rotateDirection){
            animator = ObjectAnimator.ofFloat(v, "rotation", rotate,rotate-rotation);
            rotate = rotate+rotation;

        }else{
            animator = ObjectAnimator.ofFloat(v, "rotation", rotate,rotate+rotation);
            rotate = rotate-rotation;
        }

        //持续时间
        animator.setDuration(350);
        animator.start();
        rotateDirection = !rotateDirection;
    }


    /**
     * 获取PopupWindow实例 .分类
     */
    private void getPopMenu() {

        if (null != mMenuPop) {

            //动画
            mRotate(mImageView);
            //关闭
            mMenuPop.dismiss();
            mMenuPop = null;
            return;
        } else {
            //初始化popupWindow弹窗
            initMenuPop();
        }
    }


    /**
     * 初始化popWindow
     */
    private void initMenuPop() {
        // 获取自定义布局文件pop.xml的视图
        View view = View.inflate(MainActivity.this, R.layout.item_pop_levitate_menu, null);

        //测量view的宽高,由于popupwindow没有测量的方法,只能测量内部view的宽高
        int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        view.measure(w, h);
        PopWidth = view.getMeasuredWidth();
        PopHeight = view.getMeasuredHeight();

        //下面这两个必须有!!
        view.setFocusable(true);
        view.setFocusableInTouchMode(true);
        // PopupWindow(布局,宽度,高度) 注意,此处宽高应为-2也就是wrap_content
        mMenuPop = new PopupWindow(view, -2, -2, true);

        // 重写onKeyListener,按返回键消失
        view.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {

                    mRotate(mImageView);
                    mMenuPop.dismiss();
                    mMenuPop = null;
                    return true;
                }
                return false;
            }
        });

        //点击其他地方消失
        view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (mMenuPop != null && mMenuPop.isShowing()) {
                    mRotate(mImageView);
                    mMenuPop.dismiss();
                    mMenuPop = null;
                    return true;
                }
                return false;
            }
        });

        final TextView tv_newClue = (TextView) view.findViewById(R.id.tv_newClue);
        final TextView tv_Edit = (TextView) view.findViewById(R.id.tv_edit);

        //新建线索
        tv_newClue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Toast.makeText(MainActivity.this,"点击了"+tv_newClue.getText().toString(),Toast.LENGTH_SHORT).show();

                mRotate(mImageView);
                mMenuPop.dismiss();
                mMenuPop = null;

            }
        });

        //编辑
        tv_Edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Toast.makeText(MainActivity.this,"点击了"+tv_Edit.getText().toString(),Toast.LENGTH_SHORT).show();

                mRotate(mImageView);
                mMenuPop.dismiss();
                mMenuPop = null;

            }
        });

    }
}

好了,以上就是全部实现过程!求大神指点~

点击下载代码

Android 悬浮菜单,可在launcher或app中使用。示例代码:@Override public void onCreate() {     super.onCreate();     mFloatMenu = new FloatMenu.Builder(this)             .floatLoader(R.drawable.yw_anim_background)             .floatLogo(R.drawable.yw_image_float_logo)             .addMenuItem(android.R.color.transparent, R.drawable.yw_menu_account, Const.MENU_ITEMS[0], android.R.color.black, this)             .addMenuItem(android.R.color.transparent, R.drawable.yw_menu_favour, Const.MENU_ITEMS[1], android.R.color.black, this)             .addMenuItem(android.R.color.transparent, R.drawable.yw_menu_fb, Const.MENU_ITEMS[2], android.R.color.black, this)             .addMenuItem(android.R.color.transparent, R.drawable.yw_menu_msg, Const.MENU_ITEMS[3], android.R.color.black, this)             .addMenuItem(android.R.color.transparent, R.drawable.yw_menu_close, Const.MENU_ITEMS[4], android.R.color.black, this)             .menuBackground(R.drawable.yw_menu_bg)             .onMenuActionListner(this)             .build();     mFloatMenu.show(); } public void showFloat() {     if (mFloatMenu != null)         mFloatMenu.show(); } public void hideFloat() {     if (mFloatMenu != null) {         mFloatMenu.hide();     } } public void destroyFloat() {     hideFloat();     if (mFloatMenu != null) {         mFloatMenu.destroy();     }     mFloatMenu = null; }  private void showRed() {     if (!hasNewMsg) {         mFloatMenu.changeLogo(R.drawable.yw_image_float_logo, R.drawable.yw_menu_msg, 3);     } else {         mFloatMenu.changeLogo(R.drawable.yw_image_float_logo_red, R.drawable.yw_menu_msg_red, 3);     } }
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值