这个要实现这个效果可以分几步进行
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);}@Overridepublic void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST));}}2.自定义PopupWindow的布局文件
<?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:gravity="right"><ImageViewandroid:id="@+id/arrow_up"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="28dp"android:src="@drawable/arrow_up_white"android:visibility="visible"/><com.widget.MyListViewandroid:id="@+id/lv_list"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="@dimen/normal_margin8"android:layout_marginTop="-1dp"android:layout_marginBottom="-1dp"android:dividerHeight="0dp"android:layout_marginLeft="@dimen/normal_margin8"android:layout_marginRight="@dimen/normal_margin8"android:scrollbars="none"android:background="@drawable/custom_white"android:divider="@null"></com.widget.MyListView><ImageViewandroid:id="@+id/arrow_down"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="28dp"android:src="@drawable/arrow_down_white"android:visibility="visible"/></LinearLayout>2.PopupWindow弹出动画以及消失动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"><scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:fromXScale="0.0"android:toXScale="1.0"android:fromYScale="0.0"android:toYScale="1.0"android:pivotX="90%"android:pivotY="0%"android:fillAfter="false"android:duration="300" ></scale></set>popshow_operation_anim_up.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"><scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:fromXScale="0.0"android:toXScale="1.0"android:fromYScale="0.0"android:toYScale="1.0"android:pivotX="90%"android:pivotY="100%"android:fillAfter="false"android:duration="250" ></scale></set>消失动画是渐隐动画可以自己定义,同理。
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;List<TypeSelect> typeSelectlist = 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<TypeSelect> 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的Viewthis.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() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {if (isShowing()) {dismiss();}onItemListener.OnItemListener(position, typeSelectlist.get(position));}});this.setOnDismissListener(new OnDismissListener() {@Overridepublic void onDismiss() {if (backgroundView != null) {backgroundView.setVisibility(View.GONE);}}});}//设置数据public void setDataSource(List<TypeSelect> 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.代码中的用法
CustomOperationPopWindow customOperationPopWindow = new CustomOperationPopWindow(this, operationTypeSelectlist);customOperationPopWindow.setOnItemMyListener(new CustomOperationPopWindow.OnItemListener() {@Overridepublic void OnItemListener(int position, TypeSelect typeSelect) {//此处实现列表点击所要进行的操作}});2.
textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {customOperationPopWindow.showPopupWindow(textView);//可以传个半透明view v_background过去根据业务需要显示隐藏}});5.最终实际效果
以上代码为几乎主要全部代码,主要是PopupWindow的用法,思路清晰一步一步实现很简单。
以上所述是小编给大家介绍的Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!