您的位置:首页 > 移动开发 > 微信开发

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

2017-10-27 20:09 381 查看
首先感谢提供了一些思路 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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐