我们打开QQ空间的时候有个箭头按钮点击之后弹出PopupWindow会根据位置的变化显示在箭头的上方还是下方,比普通的PopupWindow弹在屏幕中间显示好看的多。
先看QQ空间效果图:
这个要实现这个效果可以分几步进行
1.第一步自定义PopupWindow,实现如图的样式,这个继承PopupWindow自定义布局很容易实现
2.得到点击按钮的位置,根据位置是否在屏幕的中间的上方还是下方,将PopupWindow显示在控件的上方或者下方
3.适配问题,因为PopupWindow上面的操作列表是动态的所以要自定义listView
4.动画效果+背景变暗
通过步骤分析,我们就很清晰的了解我们要做什么,话不多说,从第一步开始吧
下面自定义PopupWindow实现效果
1.重写listView,重新计算高度(一般也应用于解决ScrollView嵌套listView只显示一行的问题)
public class MyListView extends ListView { public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } public MyListView(Context context) { super(context); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST)); } }
2.自定义PopupWindow的布局文件
2.PopupWindow弹出动画以及消失动画
popshow_operation_anim_down.xml
popshow_operation_anim_up.xml
消失动画是渐隐动画可以自己定义,同理。
3.重写PopupWindow了
public class CustomOperationPopWindow extends PopupWindow { private Context context; private View conentView; private View backgroundView; private Animation anim_backgroundView; private MyListView listView; private TypeSelectPopuAdapter selectAdapter; ImageView arrow_up, arrow_down; ListtypeSelectlist = new ArrayList<>(); int[] location = new int[2]; private OnItemListener onItemListener; private AdapterView.OnItemClickListener onItemClickListener; public interface OnItemListener { public void OnItemListener(int position, TypeSelect typeSelect); } ; public void setOnItemMyListener(OnItemListener onItemListener) { this.onItemListener = onItemListener; } public CustomOperationPopWindow(Context context) { this.context = context; initView(); } public CustomOperationPopWindow(Context context, List typeSelectlist) { this.context = context; this.typeSelectlist = typeSelectlist; initView(); } private void initView() { this.anim_backgroundView = AnimationUtils.loadAnimation(context, R.anim.alpha_show_anim); LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.conentView = inflater.inflate(R.layout.view_operation_popupwindow, null); // 设置SelectPicPopupWindow的View this.setContentView(conentView); // 设置SelectPicPopupWindow弹出窗体的宽 this.setWidth(LayoutParams.MATCH_PARENT); // 设置SelectPicPopupWindow弹出窗体的高 this.setHeight(LayoutParams.WRAP_CONTENT); // 设置SelectPicPopupWindow弹出窗体可点击 this.setFocusable(true); this.setOutsideTouchable(true); // 刷新状态 this.update(); // 实例化一个ColorDrawable颜色为半透明 ColorDrawable dw = new ColorDrawable(0000000000); // 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作 this.setBackgroundDrawable(dw); // 设置SelectPicPopupWindow弹出窗体动画效果 this.setAnimationStyle(R.style.operation_popwindow_anim_style_up); this.listView = (MyListView) conentView.findViewById(R.id.lv_list); this.arrow_up = (ImageView) conentView.findViewById(R.id.arrow_up); this.arrow_down = (ImageView) conentView.findViewById(R.id.arrow_down); //设置适配器 this.selectAdapter = new TypeSelectPopuAdapter(context, typeSelectlist, R.layout.item_operation_popu); this.listView.setAdapter(selectAdapter); this.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { if (isShowing()) { dismiss(); } onItemListener.OnItemListener(position, typeSelectlist.get(position)); } }); this.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { if (backgroundView != null) { backgroundView.setVisibility(View.GONE); } } }); } //设置数据 public void setDataSource(List typeSelectlist) { this.typeSelectlist = typeSelectlist; this.selectAdapter.notifyDataSetChanged(); } /** * 没有半透明背景 显示popupWindow * * @param */ public void showPopupWindow(View v) { v.getLocationOnScreen(location); //获取控件的位置坐标 //获取自身的长宽高 conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); if (location[1] > MainApplication.SCREEN_H / 2 + 100) { //MainApplication.SCREEN_H 为屏幕的高度,方法可以自己写 this.setAnimationStyle(R.style.operation_popwindow_anim_style_up); arrow_up.setVisibility(View.GONE); arrow_down.setVisibility(View.VISIBLE); this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()); } else { this.setAnimationStyle(R.style.operation_popwindow_anim_style_down); arrow_up.setVisibility(View.VISIBLE); arrow_down.setVisibility(View.GONE); this.showAsDropDown(v, 0, 0); } } /** * 携带半透明背景 显示popupWindow * * @param */ public void showPopupWindow(View v, View backgroundView) { this.backgroundView = backgroundView; v.getLocationOnScreen(location); //获取控件的位置坐标 //获取自身的长宽高 conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); backgroundView.setVisibility(View.VISIBLE); //对view执行动画 backgroundView.startAnimation(anim_backgroundView); if (location[1] > MainApplication.SCREEN_H / 2 + 100) { //若是控件的y轴位置大于屏幕高度的一半,向上弹出 this.setAnimationStyle(R.style.operation_popwindow_anim_style_up); arrow_up.setVisibility(View.GONE); arrow_down.setVisibility(View.VISIBLE); this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()); //显示指定控件的上方 } else { this.setAnimationStyle(R.style.operation_popwindow_anim_style_down); //反之向下弹出 arrow_up.setVisibility(View.VISIBLE); arrow_down.setVisibility(View.GONE); this.showAsDropDown(v, 0, 0); //显示指定控件的下方 } } /** * 显示popupWindow 根据特殊要求高度显示位置 * * @param */ public void showPopupWindow(View v, View backgroundView,int hight) { this.backgroundView = backgroundView; v.getLocationOnScreen(location); //获取自身的长宽高 conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); backgroundView.setVisibility(View.VISIBLE); //对view执行动画 backgroundView.startAnimation(anim_backgroundView); if (location[1] > MainApplication.SCREEN_H / 2 + 100) { this.setAnimationStyle(R.style.operation_popwindow_anim_style_up); arrow_up.setVisibility(View.GONE); arrow_down.setVisibility(View.VISIBLE); this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()-hight); } else { this.setAnimationStyle(R.style.operation_popwindow_anim_style_down); arrow_up.setVisibility(View.VISIBLE); arrow_down.setVisibility(View.GONE); this.showAsDropDown(v, 0, 0); } } }
4.代码中的用法
1.
CustomOperationPopWindow customOperationPopWindow = new CustomOperationPopWindow(this, operationTypeSelectlist); customOperationPopWindow.setOnItemMyListener(new CustomOperationPopWindow.OnItemListener() { @Override public void OnItemListener(int position, TypeSelect typeSelect) { //此处实现列表点击所要进行的操作 } });
2.
textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { customOperationPopWindow.showPopupWindow(textView);//可以传个半透明view v_background过去根据业务需要显示隐藏 } });
5.最终实际效果
以上代码为几乎主要全部代码,主要是PopupWindow的用法,思路清晰一步一步实现很简单。
以上所述是小编给大家介绍的Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!