PopupWindow实现长按删除

简言:仿微信做了一个对话列表,长按每个列表项弹出popupwindow进行删除操作,最终效果如下:

第一步:制作列表界面,可以是ListView,也可以是RecyclerView,布局大家可以自己设计,本文采用的是ListView

第二步:为ListView添加setOnItemLongClickListener,可以考虑用ButterKnife,在LongClick事件中,我们做两件事:1.被选中的Item背景加深;2.弹出PopupWindow

// 不使用butterKnife
lvChat.setOnItemLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        // 返回true则执行完长按事件不会继续响应click事件,返回false则会产生冒泡,执行完longClick后响应click
        return true;
    }
});

@OnItemLongClick(R.id.lv_chat)
boolean itemLongClick(View view,int Position) {
    // 将当前item及其position放入全局变量
    curItem = view;
    curPosition = Position;
    // 设置当前item的背景颜色
    curItem.setBackgroundColor(Color.parseColor("#e9e9eb"));
    // 显示popupWindow
    showPopupWindow();
    return true;
}

第三步:popupWindow是如何显示的

下为popupWindow中布局的xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:paddingBottom="14dp"
              android:paddingLeft="23dp"
              android:paddingRight="23dp"
              android:paddingTop="14dp">

    <TextView
        android:id="@+id/tv_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:gravity="center"
        android:textColor="#000000"
        android:text="置顶"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_mark"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:gravity="center"
        android:text="已读"
        android:textSize="16sp"
        android:textColor="#000000"/>

    <TextView
        android:id="@+id/tv_delete_chat"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="删除"
        android:textSize="16sp"
        android:textColor="#000000"/>

</LinearLayout>
private void showPopupWindow() {
    // popupWindow中的布局
    View view = LayoutInflater.from(this).inflate(R.layout.operate_chat, null);
    operateWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, true);
    // 只有绘制完后才能获取到正确的popupWindow的宽高
    operateWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    operateWindow.setBackgroundDrawable(getResources().getDrawable(R.mipmap.border_shadow));
    operateWindow.setTouchable(true);
    operateWindow.setOutsideTouchable(true);
    // 获取当前item在window中的坐标
    int[] curPositionInWindow = new int[2];
    curItem.getLocationInWindow(curPositionInWindow);
    // 每个item的高度
    int itemHeight = curItem.getHeight();
    // popupWindow的高度
    final int operateWindowHeight = view.getMeasuredHeight();
    
    int xOff = curItem.getWidth() * 6 / 11;
    int yOffDown = -itemHeight * 3 / 11;
    int yOffUp = -(itemHeight + operateWindowHeight) + itemHeight * 3 / 11;
    // 窗口的宽高
    DisplayMetrics metric = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metric);
    int windowHeight = metric.heightPixels;
    // 判断popupWindow出现在上方还是下方,根据窗口高-item高坐标是否大于item高度加popupWindow高度,从而对应不同的y偏移量
    boolean isShowUp = (windowHeight - curPositionInWindow[1]) < (itemHeight + operateWindowHeight);
    if (isShowUp) {
        operateWindow.showAsDropDown(curItem, xOff, yOffUp);
    } else {
        operateWindow.showAsDropDown(curItem, xOff, yOffDown);
    }
    // 对popupWindow的dismiss监听,关闭时将被选中item的颜色恢复
    operateWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
        @Override
        public void onDismiss() {
            curItem.setBackgroundColor(Color.parseColor("#ffffff"));
        }
    });
    // popupWindow中控件的点击事件
    TextView tvDelete = view.findViewById(R.id.tv_delete_chat);
    tvDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            adapter.remove(chatList.get(curPosition));
            operateWindow.dismiss();
        }
    });
}

总结:

1.功能的实现并不难,但是实现有很多种方法,比如dialog,自定义view等都可以,

2.实现的过程也有很多衍生问题,比如获取getLocationInWindow和getLocationOnScreen的区别,如何获取toolbar和statusbar的高度等

3.本文尝试在点击popupWindow中的控件(比如点击“删除”)设置背景,但并没有生效,原因还在寻找中。。。。



猜你喜欢

转载自blog.csdn.net/qingwangwang/article/details/80636790
今日推荐