Android PopupWindow实现带背景阴影的下滑选择框
来源:互联网 发布:基金投资组合 知乎 编辑:程序博客网 时间:2024/05/18 00:29
先上图:
效果还是很丝滑的,这里动画主要用到了属性动画。实现逻辑很简单,动画都是在popupwindow调用showAsDropDown()
和dismiss()
时执行。这里主要是注意退出动画的实现,在dismiss()
中执行动画是无效的,需要在动画执行完毕后再执行super.dismiss();
可拓展能力强,可以结合自身需求实现不同的效果。
以下是源码:
PopupWindow :
public class TypeSelectWindow extends PopupWindow { private Activity activity; private BDBaseAdapter bdBaseAdapter = null; View contentView;//弹出框的根布局,可以监听其点击事件,达到点击阴影消失弹框的效果 GridView gridView; public TypeSelectWindow(Activity activity){ this.activity = activity; initDatas(); initView(); } private void initView(){ this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT); contentView = LayoutInflater.from(activity).inflate(R.layout.join_popup_layout,null); gridView = contentView.findViewById(R.id.gridView); bdBaseAdapter = new BDBaseAdapter<String>(activity,listDatas,R.layout.join_select_item) { @Override public void convert(BDViewHolder helper, String item, int position) { ((TextView)helper.getView(R.id.text)).setText(item); } }; gridView.setAdapter(bdBaseAdapter); this.setContentView(contentView);//设置布局 this.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); this.setAnimationStyle(R.style.SelectPopupWindow); this.setOutsideTouchable(true); this.setFocusable(true); } /** * 模拟数据 */ List<String> listDatas = new ArrayList<>(); private void initDatas(){ listDatas.clear(); for (int i = 0;i<10;i++){ listDatas.add("menu"+i); } } //显示 public void showPopupWindow(View parent) { if (!this.isShowing()) { this.showAsDropDown(parent,0,0); //执行进入动画,这里主要是执行列表下滑,背景变半透明在setAnimationStyle(R.style.SelectPopupWindow);中实现 AnimationUtil.createAnimation(true,contentView,gridView,null); } else { dismissPopup(); } } //消失 public void dismissPopup(){ super.dismiss();// 调用super.dismiss(),如果直接dismiss()会一直会调用下面的dismiss() } @Override public void dismiss() { //执行推出动画,列表上滑退出,同时背景变透明 AnimationUtil.createAnimation(false,contentView,gridView , new AnimationUtil.AnimInterface() { @Override public void animEnd() { dismissPopup();//动画执行完毕后消失 } }); }}
AnimationUtil:
public class AnimationUtil { //动画持续时间 public final static int ANIMATION_IN_TIME=500; public final static int ANIMATION_OUT_TIME=500; /** * @param isIn 动画类型,进入或消失 * @param rootView 根布局,主要用来设置半透明背景 * @param target 要移动的view * @param animInterface 动画执行完毕后的回调 */ public static void createAnimation(final boolean isIn, final View rootView, final View target, final AnimInterface animInterface){ final int toYDelta = ViewUtils.getViewMeasuredHeight(target);//测量布局高度 ValueAnimator valueAnimator = ValueAnimator.ofFloat(isIn?-toYDelta:0,isIn?0:-toYDelta); valueAnimator.setDuration(isIn?ANIMATION_IN_TIME:ANIMATION_OUT_TIME); valueAnimator.setRepeatCount(0); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float currentValue = (Float) animation.getAnimatedValue(); target.setY(currentValue); if (!isIn){//因为在setAnimationStyle(R.style.SelectPopupWindow);设置了进入动画,所以执行进入动画时不再设置 rootView.setAlpha(1-Math.abs(currentValue)/animation.getDuration()); } } }); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (animInterface!=null){ animInterface.animEnd(); } } }); valueAnimator.start(); } public interface AnimInterface{ void animEnd(); }}
ViewUtils
public class ViewUtils { /** * 获取控件的高度 */ public static int getViewMeasuredHeight(View view) { calculateViewMeasure(view); return view.getMeasuredHeight(); } /** * 获取控件的宽度 */ public static int getViewMeasuredWidth(View view) { calculateViewMeasure(view); return view.getMeasuredWidth(); } /** * 测量控件的尺寸 */ private static void calculateViewMeasure(View view) { int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); view.measure(w, h); }}
style.xml
这里我只设置了进入的背景渐变的动画,列表的滑动动画我在AnimationUtil中实现了,在上面的AnimationUtil中也可以实现进入动画,这样也更统一,看个人喜好。
<style name="SelectPopupWindow"> <item name="android:windowEnterAnimation">@anim/p_in</item> </style>
p_in.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:duration="500" android:fromAlpha="0" android:toAlpha="1"/></set>
布局部分就是简单的gridview,布局可以有多种方式来实现。可以直接用View标签来实现阴影效果。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="vertical" android:background="#88000000" android:layout_height="match_parent"> <GridView android:id="@+id/gridView" android:scrollbars="none" android:numColumns="3" android:background="@color/white" android:layout_width="match_parent" android:layout_height="wrap_content"/></RelativeLayout>
执行:
JoinTypeSelectWindow joinTypeSelectWindow = new JoinTypeSelectWindow(getActivity()); joinTypeSelectWindow.showPopupWindow(targetView);
————— 完 ——————
一个小小的源码链接
阅读全文
0 0
- Android PopupWindow实现带背景阴影的下滑选择框
- Android开发之带阴影的PopupWindow
- Android 给控件设置带阴影背景
- 在Android中实现阴影效果 背景阴影
- Android PopupWindow实现,类似于iOS的选择栏
- 弹出PopupWindow背景变暗的实现
- android popupwindow的实现
- Android PopupWindow弹出窗口的完美实现(实现弹出背景变暗效果)
- Android 局部带阴影的网络加载框
- Android阴影背景
- Android 阴影背景
- css实现的带阴影的表格
- 带阴影的浮动窗体的实现
- 实现带阴影弹出窗口的技术
- CSS实现带阴影效果的三角形
- android 带文字阴影的按钮
- Android-实现底部弹出PopupWindow并让背景逐渐变暗
- Android实现底部弹出PopupWindow背景逐渐变暗效果
- linux下在ctags不能正常使用,cstag:找不到tag
- 软件策划流程
- Css-基础
- Deeplearning-吴恩达-卷积神经网络-第二周作业01-Convolution Networks(keras)
- Python学习笔记(基础学习)
- Android PopupWindow实现带背景阴影的下滑选择框
- Spark 读取CSV 解析单元格多行数值问题
- 【实战】android的多线程下载
- android 路由框架搭建
- Spring整合ElasticJob 关闭Tomcat容器时内存泄漏
- Hdu 6240 01分数规划
- JSONObject类之解析json
- Mysql语句注意事项
- 调用函数求数组中的元素和,并统计数组中奇数的个数