PopupWindow 使用详解(二) Popwindow 制作常见花哨效果

帝都几日降温,终于被撂倒了。but 只要一息尚存就得不断进步!于是,写出 《PopupWindow 使用详解》的第二篇 笔记,先奉上 第一篇链接: 《PopupWindow 使用详解(一) 中文API 文档 赠送 ListPopupWindow 中文 API》 。下面给大家展示一下制作的效果gif。
PopupWindow  效果演示
下面进行一个样式一个样式的肢解哈,对了,所有效果笔者都没有制作载入动画和退出动画。有需要的小伙伴可以通过 这个方法 public void setAnimationStyle(int animationStyle) 进行设置,也是很简单、很常用的。

效果一、图片选取功能(带阴影)

照片选取样图

1、布局设置

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/ll_pic"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/shape_pic_select"android:gravity="bottom"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginStart="5dp"android:layout_marginEnd="5dp"android:orientation="vertical"><Buttonandroid:id="@+id/btn_pic_photo"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="1dp"android:background="#ffffff"android:text="相  册"android:textColor="#3c3c3c"android:textSize="16sp" /><Buttonandroid:id="@+id/btn_pic_camera"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="1dp"android:background="#ffffff"android:text="拍  照"android:textColor="#3c3c3c"android:textSize="16sp" /><Buttonandroid:id="@+id/btn_pic_cancel"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="1dp"android:background="#ffffff"android:text="取  消"android:textColor="#3c3c3c"android:textSize="16sp" /></LinearLayout>
</LinearLayout>

2、Java 逻辑代码

  /*** 照片选择器*/@SuppressLint("InflateParams")private void showPicSelect() {view = LayoutInflater.from(this).inflate(R.layout.item_pic_select, null, false);LinearLayout llPop = view.findViewById(R.id.ll_pic);Button btnCamera = view.findViewById(R.id.btn_pic_camera);Button btnPhoto = view.findViewById(R.id.btn_pic_photo);Button btnCancel = view.findViewById(R.id.btn_pic_cancel);btnCamera.setOnClickListener(this);btnPhoto.setOnClickListener(this);btnCancel.setOnClickListener(this);llPop.setOnClickListener(this);myPop = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);myPop.setBackgroundDrawable(new ColorDrawable());myPop.showAtLocation(rlMain, Gravity.BOTTOM, 0, 0);}@Overridepublic void onBackPressed() {if (myPop.isShowing()) {myPop.dismiss();} else {super.onBackPressed();}}

3、实现思路

之前笔者看了看网上百度来的答案,实现阴影效果的思路大概是,当 PopupWindow 弹出时将 Activity 设置为半透明,但是这种思路的弊端是 Activity 透明了,你懂得,你可以在 A Activity 界面直接看到了 桌面或者是 B Activity 界面的东西,很蛋疼。
笔者的思路是:为 PopupWindow 设置一个半透明的背景色,然后监听这不背景 layout 的点击事件,和物理键的返回事件。否则会出现点击无效果的现象。具体逻辑如上。

二、仿qq和微信的长按置顶删除功能

效果展示

1、布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/ll_qq"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:background="@drawable/shape_qq"android:orientation="horizontal"tools:ignore="UselessParent"><TextViewandroid:id="@+id/tv_delete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="删除"android:textColor="#ffffff"android:textSize="16sp" /><Viewandroid:layout_width="2dp"android:layout_height="match_parent"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:background="#666666" /><TextViewandroid:id="@+id/tv_be_top"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="置顶"android:textColor="#ffffff"android:textSize="16sp" /></LinearLayout><ImageViewandroid:id="@+id/iv_three"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/ll_qq"android:layout_centerHorizontal="true"android:background="@null"android:layout_marginTop="-5dp"android:contentDescription="@string/app_name"android:src="@mipmap/ic_three" />
</RelativeLayout>

2、Java 逻辑

 /*** 仿qq 产生水滴按钮*/@SuppressLint("InflateParams")private void showQq() {view = LayoutInflater.from(this).inflate(R.layout.item_qq, null, false);TextView tvTop = view.findViewById(R.id.tv_be_top);TextView tvDelete = view.findViewById(R.id.tv_delete);tvDelete.setOnClickListener(this);tvTop.setOnClickListener(this);myPop = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);myPop.setBackgroundDrawable(new ColorDrawable());myPop.setOutsideTouchable(true);myPop.getContentView().measure(0, 0);myPop.showAsDropDown(cvMain, (cvMain.getWidth() - myPop.getContentView().getMeasuredWidth()) / 2,-(cvMain.getHeight() + myPop.getContentView().getMeasuredHeight()));}

3、实现思路

这个其实没什么好说的,但是需要注意的两点是:(1)、ui 一定要有的或者是自己会个ps 也行,仔细看笔者布局,有一个地方,设置 margin 属性居然用了 负值 否则无法保证 下面的shape 背景与三角标进行无缝衔接;(2)、注意这个方法一定要设置即便是不设置值 public void setBackgroundDrawable(Drawable background) 否则会导致 public void setOutsideTouchable(boolean touchable) 这个方法不起作用,即出现点击 PopupWindow 外部区域无法隐藏 PopupWindow 的尴尬局面

三、实现悬浮图片轮播

图片轮播效果

1、布局代码

<!--布局 1-->
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#00000000"app:cardCornerRadius="10dp"><android.support.v4.view.ViewPagerandroid:id="@+id/vp_pop"android:layout_width="200dp"android:layout_height="300dp"android:background="#48BAFF" /></android.support.v7.widget.CardView><!--布局 2-->
<?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:gravity="center"android:orientation="vertical"><ImageViewandroid:layout_width="200dp"android:layout_height="300dp"android:contentDescription="@string/app_name"android:src="@mipmap/pic_1" />
</LinearLayout>

2、Java 逻辑代码

 /*** 轮播效果*/@SuppressLint("InflateParams")private void showPager() {views = new ArrayList<>();view = LayoutInflater.from(this).inflate(R.layout.item_pager, null, false);ViewPager vpPop = view.findViewById(R.id.vp_pop);picView01 = LayoutInflater.from(this).inflate(R.layout.item_pop_vp_01, null, false);picView02 = LayoutInflater.from(this).inflate(R.layout.item_pop_vp_02, null, false);picView03 = LayoutInflater.from(this).inflate(R.layout.item_pop_vp_03, null, false);picView04 = LayoutInflater.from(this).inflate(R.layout.item_pop_vp_04, null, false);views.add(picView01);views.add(picView02);views.add(picView03);views.add(picView04);vpPop.setAdapter(new MyPopAdapter());myPop = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);myPop.setOutsideTouchable(true);//悬浮效果myPop.setElevation(5);myPop.setBackgroundDrawable(new ColorDrawable(0x00ffffff));myPop.showAtLocation(rlMain, Gravity.CENTER, 0, 0);}/*** 配置  adapter*/class MyPopAdapter extends PagerAdapter {@Overridepublic int getCount() {return views.size();}@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object o) {return view == o;}@NonNull@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {container.addView(views.get(position));return views.get(position);}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {container.removeView(views.get(position));}}@Overrideprotected void onDestroy() {super.onDestroy();if (views != null) {views.remove(picView01);views.remove(picView02);views.remove(picView03);views.remove(picView04);}if (myPop.isShowing()) {myPop.dismiss();}}

3、实现思路及注意事项

首先,加载图片需要进行相关处理,比如说用过Picasso 或者是 Glide 等框架,当然了也可将进行自己压缩;

其次,由于为了突出美观,笔者用了一个 CardView 可以设置圆角,但是 CardView 的阴影属性失效了,为了凸显层次感可以设置 PopupWindow 的这个方法 public void setElevation(float elevation) 该方法可以是你感觉出一种悬浮的效果;

最后,没用的 view 需要进行清理,否则会留在内存哦。

四、向下弹出水滴效果

向下弹出效果

1、布局源码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@+id/iv_beauty"android:layout_toEndOf="@+id/iv_beauty"android:src="@mipmap/ic_right" /><ImageViewandroid:id="@+id/iv_beauty"android:layout_width="150dp"android:layout_height="200dp"android:background="#669"android:src="@mipmap/pic_5" />
</RelativeLayout>

2、Java 逻辑

  /*** 向下弹出*/@SuppressLint("InflateParams")private void showDown() {view = LayoutInflater.from(this).inflate(R.layout.item_anywhere, null, false);myPop = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);myPop.setBackgroundDrawable(new ColorDrawable());myPop.setOutsideTouchable(true);myPop.getContentView().measure(0, 0);myPop.showAsDropDown(btnPopDown, -((myPop.getContentView().getMeasuredWidth() - btnPopDown.getWidth()) / 2), 0);}

3、注意事项

这个没什么可说的了,和 上面 小标题二 相同 ,具体查看上方即可。

五、实现屏幕右侧向左弹出

实现效果

1、布局代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@+id/iv_beauty"android:layout_toEndOf="@+id/iv_beauty"android:src="@mipmap/ic_right" /><ImageViewandroid:id="@+id/iv_beauty"android:layout_width="150dp"android:layout_height="200dp"android:background="#669"android:src="@mipmap/pic_5" />
</RelativeLayout>

2、Java 逻辑代码

 /*** 向左弹出*/@SuppressLint("InflateParams")private void showStart() {view = LayoutInflater.from(this).inflate(R.layout.item_pop_start, null, false);myPop = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);myPop.setBackgroundDrawable(new ColorDrawable());myPop.setOutsideTouchable(true);myPop.getContentView().measure(0, 0);myPop.showAsDropDown(fabStart, -(myPop.getContentView().getMeasuredWidth()), -(fabStart.getHeight() / 2 + myPop.getContentView().getMeasuredHeight()));}

3、注意事项

这里比较复杂的 就是 PopupWindow 的锚点位置 为 其寄生的 控件的 左下角,而 Popwindow 的起始点为 左上角,但是 PopupWindow 默认不超出界面。这就导致了 PopupWindow 明明在 控件则左侧,但是却无法到达自己的想要位置。
所以 对于该现象,我们只能 在计算偏移量的时候 需要向左 移动 (控件长度+PopupWindow的长度 +其他长度)

六、实现需要获取焦点的控件使用

效果展示

1、布局代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#00000000"app:cardCornerRadius="10dp"><RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#00000000"android:padding="10dp"><TextViewandroid:id="@+id/tv_name_p"android:layout_width="wrap_content"android:layout_height="40dp"android:gravity="center_vertical"android:text="账户:"android:textSize="16sp" /><EditTextandroid:layout_width="200dp"android:layout_height="40dp"android:layout_toEndOf="@+id/tv_name_p"android:background="@null"android:gravity="center_vertical"android:inputType="number"android:paddingStart="10dp"android:paddingEnd="10dp"android:singleLine="true"android:textSize="16sp"tools:text="123" /><TextViewandroid:id="@+id/tv_password_p"android:layout_width="wrap_content"android:layout_height="40dp"android:layout_below="@+id/tv_name_p"android:gravity="center_vertical"android:text="密码:"android:textSize="16sp" /><EditTextandroid:layout_width="200dp"android:layout_height="40dp"android:layout_below="@+id/tv_name_p"android:layout_toEndOf="@+id/tv_password_p"android:background="@null"android:gravity="center_vertical"android:inputType="numberPassword"android:paddingStart="10dp"android:paddingEnd="10dp"android:singleLine="true"android:textSize="16sp"tools:text="123" /></RelativeLayout>
</android.support.v7.widget.CardView>

2、逻辑代码

 /*** 向右弹出 输入框*/@SuppressLint("InflateParams")private void showEnd() {view = LayoutInflater.from(this).inflate(R.layout.item_end_input, null, false);myPop = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);myPop.setBackgroundDrawable(new ColorDrawable(0x00ffffff));myPop.setElevation(10);myPop.setOutsideTouchable(true);myPop.setFocusable(true);myPop.getContentView().measure(0, 0);myPop.showAsDropDown(fadEnd, (int) (fadEnd.getWidth() * 1.3), -((fadEnd.getHeight() + myPop.getContentView().getMeasuredHeight()) / 2));}

3、注意事项

这里一定要 设置该方法 public void setFocusable(boolean focusable) 否则 在切换EditText 的时候只是光标进行了移动,但是 无法召唤软键盘。

七、总结

1、笔者认为,上面的大概可以满足比较简单的开发需求了,笔者很菜,这些已经足可以满足笔者了目前;
2、关于偏移量这个会涉及导到一些小小的计算和一点点逻辑想法,所以不要只是做 cv 战士,作为文雅的程序员,我们还是需要有点自己的想法的哈;
3、代码上传 github 地址为:PopupWindow
4、希望可以帮到你,批评和建议,望各位大佬留言,小生在这里谢过了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

近距离无线通信技术对比

定义&#xff1a;无线通信是利用电磁波信号在自由空间中传播的特性进行信息交换的一种通信方式。 优点&#xff1a;成本低、无物理线路&#xff0c;不受工业环境限制&#xff0c;环境适应能力强&#xff1b; 故障诊断简单&#xff0c;可远程诊断&#xff0c;扩展性强&#xff…

看不清的融资迷局 二线玩家字节跳动在打什么主意?

互联网似乎对离经叛道者总是多一分关注&#xff0c;吃瓜心态随着时间的推进越来越浓烈。 其中&#xff0c;今日头条成了“看热闹”时代最佳的“演员”之一&#xff0c;供看客消遣&#xff1a;其母公司字节跳动一个融资传闻从8月炒到了10月&#xff0c;即便是媒体通过信源确认这…

第3章-动态基础分析实验

Lab 3-1 Question: 1.先对文件使用PEID进行查壳,显示文件被加壳处理过 2.使用Dependency Walker查看文件导入函数&#xff0c;文件只有一个DLL而且只有一个导入函数Exitprocess 3.使用Strings程序查看字符串&#xff0c;发现可疑字符串。 4.动态分析前期准备 4.1 对系统进行初始…

C语言变长数组data[0]【总结】

C语言变长数组data[0]【总结】 1、前言 今天在看代码中遇到一个结构中包含char data[0]&#xff0c;第一次见到时感觉很奇怪&#xff0c;数组的长度怎么可以为零呢&#xff1f;于是上网搜索一下这样的用法的目的&#xff0c;发现在linux内核中&#xff0c;结构体中经常用到data…

Excel 转为 MySQL 语句

一、方法 一、假设你的表格有A、B、C三列数据&#xff0c;希望导入到你的数据库中表格table&#xff0c;对应的字段分别是col1、col2、col3 二、在你的表格中增加一列&#xff0c;利用excel的公式自动生成sql语句&#xff0c;具体方法如下&#xff1a; 1、增加一列&#xff08;…

CentOS7下安装zookeeper3.4.9

获取zookeeper官方安装包 1 wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz 解压该文件包 1 tar zxf zookeeper-3.4.9.tar.gz 进入conf文件夹并创建新配置文件 1 cd zookeeper-3.4.9/conf 2 vi zoo.cfg 在config文件中加…

union 和 struct 的区别与联系

union &#xff08; 共用体&#xff09;&#xff1a;构造数据类型,也叫联合体 用途&#xff1a;使几个不同类型的变量共占一段内存(相互覆盖) struct ( 结构体 )&#xff1a;是一种构造类型 用途&#xff1a; 把不同的数据组合成一个整体——自定义数据类型 主要区别&#x…

Android系统中标准Intent的使用

Android系统用于Activity的标准Intent 1.根据联系人ID显示联系人信息 Intent intentnew Intent(); intent.setAction(Intent.ACTION_VIEW);//显示联系人信息 intent.setData(Uri.parse("content://contaccts/people/492")); startActivity(intent); 2.根据联系人ID显…

开关电源简介

1. 基本分类 DC-DC BULK电源 DC-DC BOOST电源 DC-DC BULK/BOOST电源 DC-DC BOOST/BYPASS电源 2. 典型拓扑结构 BULK电路拓扑 降压型电源 串联关系在开关管S导通时&#xff0c;二极管VD负极电压高于正极反偏截止&#xff0c;此时电流经过电感L向电容和负载供电&#x…

电感基础与选型介绍

电感是一种常见的被动元件&#xff0c;常用在LC振荡电路、中低频的滤波电路&#xff0c;DCDC能量转换电路中&#xff0c;其应用频率一般不超过50MHz。 1.电感的主要作用 通直流&#xff0c;阻交流阻交流变化&#xff0c;保持电流稳定----楞次定律滤波 2.电感的主要分类 3.电…

[题解]Codeforces Round #519 - B. Lost Array

【题目】 B. Lost Array 【描述】 Bajtek有一个数组x[0],x[1],...,x[k-1]但被搞丢了&#xff0c;但他知道另一个n1长的数组a&#xff0c;有a[0]0&#xff0c;对i1,2,...,n。由此可以找到数组x[0],x[1],...,x[k-1]的一些可能情况&#xff0c;即满足这个关系的数组x[0],x[1],...,…

LeetCode 24 Swap Nodes in Pairs (交换相邻节点)

题目链接&#xff1a; https://leetcode.com/problems/swap-nodes-in-pairs/?tabDescriptionProblem: 交换相邻的两个节点如上图所示&#xff0c;递归进行交换。从最尾端开始&#xff0c;当最尾端只有一个节点时&#xff0c;停止交换否则执行 swap(head.next) 参考代码&#x…

Netra基于Rdk平台的软件框架设计

Netra&#xff08;DM8168&#xff09;处理器是个多核处理器&#xff0c;每个核之间相互独立却又相互关联&#xff0c;如何高效简洁地利用每个核完成一套系统功能是非常关键的&#xff0c;RDK这套软件平台就是针对这种多核平台设计的一套多通道视频应用方案&#xff0c;主要用于…

电感啸叫原因与应对措施

大部分硬件工程师应该都遇到过,PCBA上电后出现“滋滋滋”的叫声,其声响或大或小,或时有时无,或深沉或刺耳,或变化无常者皆有。该现象我们称为“啸叫”,一般分为电感啸叫和电容啸叫。 其中电感啸叫最为常见,尤其在DCDC电路中,大部分是因为 器件参数选择不合理 导致的。…

Android Fragment完全解析,关于碎片你所需知道的一切

我们都知道&#xff0c;Android上的界面展示都是通过Activity实现的&#xff0c;Activity实在是太常用了&#xff0c;我相信大家都已经非常熟悉了&#xff0c;这里就不再赘述。 但是Activity也有它的局限性&#xff0c;同样的界面在手机上显示可能很好看&#xff0c;在平板上就…

图像--摄像头组成与基本参数

基本组成 Sensor: 图象传感器 FPC: 电路板 IR:红外滤波片 Holder:基座 Lens:镜头 其他 核心部件&#xff1a;1- SENSOR 2- LENS Sensor参数 类别 指标 参考 备注 Sensor 厂家 sony 三星 OV 格科微由原厂提供完整规格书和型号 低像素需要注意 分辨率 0.3MP (VGA)模组…

1.I2C协议

1.I2C协议2条双向串行线&#xff0c;一条数据线SDA&#xff0c;一条时钟线SCL。SDA传输数据是大端传输&#xff0c;每次传输8bit&#xff0c;即一字节。支持多主控(multimastering)&#xff0c;任何时间点只能有一个主控。总线上每个设备都有自己的一个addr&#xff0c;共7个bi…

图像--摄像头数据输出格式与传输接口

一、 数据输出格式 RAW data 格式: CMOS 在将光信号转换为电信号时的电平高低的原始记录&#xff0c;单纯地将没有进行任何处理的图像数据&#xff0c;即摄像元件直接得到的电信号进行数字化处理而得到的。 每个pixel只能感光R光或者B光或者G光&am…

怎么建立微信生态用户增长模型?

微信最新数据及中国网民最新数据概述截止到2018年&#xff0c;移动网民用户增长放缓&#xff0c;接近人口大盘。微信作为全国移动网民的一款超级应用&#xff0c;在移动网民的***率超过90%。微信最近一年的新增用户主要来自中老年用户群体和乡镇用户群体***。易观最新发布的8月…