仿微信消息根据长按位置显示置顶删除功能菜单栏

首先感谢提供了一些思路 http://www.cnblogs.com/popfisher/p/5608436.html

在adapter中 给Item设置触摸监听,记录触点距离屏幕左上方原点的位置,然后在item的长按监听时间中根据记录的位置计算弹出框在触点的那个方位。然后以item的view为popwindow弹出位置,并且设置偏移量。
主要还有一个问题,不知道微信怎么做到的弹出pop之后限制不滑动listview。
我这边就简单的判断了下popwindow弹出来之后不截取触摸事件。

代码下载地址

效果图如下
这里写图片描述
主要代码先贴一下

public class MainActivity extends AppCompatActivity {

    private PopupWindow mPopupWindow;
    private ListView mListView;

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

    private View getPopupWindowContentView() {
        // 一个自定义的布局,作为显示的内容
        int layoutId = R.layout.popup_content_layout;   // 布局ID
        View contentView = LayoutInflater.from(this).inflate(layoutId, null);
        View.OnClickListener menuItemOnClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(), "Click " + ((TextView) v).getText(), Toast.LENGTH_SHORT).show();
                if (mPopupWindow != null) {
                    mPopupWindow.dismiss();
                }
            }
        };
        contentView.findViewById(R.id.menu_item1).setOnClickListener(menuItemOnClickListener);
        contentView.findViewById(R.id.menu_item2).setOnClickListener(menuItemOnClickListener);
        return contentView;
    }

    private void showPopupWindow(View anchorView) {
        View contentView = getPopupWindowContentView();
        mPopupWindow = new PopupWindow(contentView,
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
        // 如果不设置PopupWindow的背景,有些版本就会出现一个问题:无论是点击外部区域还是Back键都无法dismiss弹框
        mPopupWindow.setBackgroundDrawable(new ColorDrawable());
        // 设置好参数之后再show
        int windowPos[] = PopupWindowUtil.calculatePopWindowPos(anchorView, contentView, x, y);
        mPopupWindow.showAtLocation(anchorView, Gravity.TOP | Gravity.START, windowPos[0], windowPos[1]);
    }

    private void initView() {
        mListView = (ListView) findViewById(R.id.listview);
        mListView.setAdapter(new CustomAdapter());
        mListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (mPopupWindow != null && mPopupWindow.isShowing())
                    return true;
                return false;
            }
        });
    }

    class CustomAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return 20;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHolder viewHolder;
            final View finalConvertView;
            if (convertView == null) {
                convertView = LayoutInflater.from(getBaseContext()).inflate(R.layout.listview_item, null);
                viewHolder = new ViewHolder();
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            finalConvertView = convertView;
            convertView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    showPopupWindow(finalConvertView);
                    return false;
                }
            });
            convertView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();
                    return false;
                }
            });
            convertView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //点击事件
                }
            });
            return convertView;
        }
    }

    int x;
    int y;

    class ViewHolder {
        View moreRoot;
        View moreImgv;
    }
}
public class PopupWindowUtil {
    /**
     * 计算popwindow在长按view 的什么位置显示
     *
     * @param anchorView 长按锚点的view
     * @param popView    弹出框
     * @param onScreenx  锚点距离屏幕左边的距离
     * @param onScreeny  锚点距离屏幕上方的距离
     * @return popwindow在长按view中的xy轴的偏移量
     */
    public static int[] calculatePopWindowPos(final View anchorView, final View popView, int onScreenx, int onScreeny) {
        final int windowPos[] = new int[2];
        final int anchorLoc[] = new int[2];
        // 获取触点在屏幕上相对左上角坐标位置
        anchorLoc[0] = onScreenx;
        anchorLoc[1] = onScreeny;
        //当前item的高度
        final int anchorHeight = anchorView.getHeight();
        // 获取屏幕的高宽
        final int screenHeight = getScreenHeight(anchorView.getContext());
        final int screenWidth = getScreenWidth(anchorView.getContext());
        // 测量popView 弹出框
        popView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        // 计算弹出框的高宽
        final int popHeight = popView.getMeasuredHeight();
        final int popWidth = popView.getMeasuredWidth();
        // 判断需要向上弹出还是向下弹出显示
        // 屏幕高度-触点距离左上角的高度 < popwindow的高度
        // 如果小于弹出框的高度那么说明下方空间不够显示 popwindow,需要放在触点的上方显示
        final boolean isNeedShowUp = (screenHeight - anchorLoc[1] < popHeight);
        // 判断需要向右边弹出还是向左边弹出显示
        //判断触点右边的剩余空间是否够显示popwindow 大于就说明够显示
        final boolean isNeedShowRight = (screenWidth - anchorLoc[0] > popWidth);
        if (isNeedShowUp) {
            //如果在上方显示 则用 触点的距离上方的距离 - 弹框的高度
            windowPos[1] = anchorLoc[1] - popHeight;
        } else {
            //如果在下方显示 则用 触点的距离上方的距离
            windowPos[1] = anchorLoc[1];
        }
        if (isNeedShowRight) {
            windowPos[0] = anchorLoc[0];
        } else {
            //显示在左边的话 那么弹出框的位置在触点左边出现,则是触点距离左边距离 - 弹出框的宽度
            windowPos[0] = anchorLoc[0] - popWidth;
        }
        return windowPos;
    }
    /**
     * 获取屏幕高度(px)
     */
    public static int getScreenHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }
    /**
     * 获取屏幕宽度(px)
     */
    public static int getScreenWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值