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.pswp.cn/news/253222.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253222.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253222.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

hbase replication原理分析

本文只是從總體流程來分析replication過程&#xff0c;很多細節沒有提及&#xff0c;下一篇文章準備多分析分析細節。replicationSource啟動過程org.apache.hadoop.hbase.regionserver.HRegionServer#startServiceThreads ->org.apache.hadoop.hbase.replication.regionserv…

8168

http://blog.csdn.net/crushonme/article/details/10287693 http://blog.csdn.net/yangxueble/article/details/10138763

Mysql查詢結果只有一條的情況下把值賦值給變量,再用if else 流程判斷

1 BEGIN 2 set n(SELECT count(day) from log where dayCURDATE()); 3 IF n0 THEN 4 call m_LogInsert(); 5 ELSE 6 call m_LoginCheck(); 7 end if; 8 end 轉載于:https://www.cnblogs.com/mengms/p/7629486.html

近距離無線通信技術對比

定義&#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 對系統進行初始…

如何優化增強第三方庫?

開發中&#xff0c;我們不可避免要使用&#xff0c;別人花很多時間打磨好的輪子&#xff0c;輪子好用&#xff0c;但有時卻無法完全滿足我們的要去&#xff0c;這時我們不可避免的要去修改增強一下這個庫&#xff0c;如何增強&#xff1f; 我認為&#xff0c;一般有兩種修改的方…

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…

Office 2016中Excel的部分快捷方式

【Ctrl下箭頭】 拉到最后一行 【Alt 】一秒求和 【CtrlEnter】 一秒輸入相同數據 【Ctrld】 一秒豎向填充不連續區域 【Ctrlr】 一秒向右填充數據 【Ctrle】 批量提取字符 【Ctrl1】 調出 設置單元格格式窗口 【Ctrlz】 撤銷上一步操作 【Ctrly】 恢復上一步 【F4】 重復上一步…

基于Spring開發的DUBBO服務接口測試

基于Spring開發的DUBBO服務接口測試 知識共享主要內容&#xff1a; 1、 Dubbo相關概念和架構&#xff0c;以及dubbo服務程序開發步驟。 2、 基于Spring開發框架的dubbo服務接口測試相關配置。 3、 spring testjunit和spring testTestNG兩種測試框架腳本編寫方法。 一、 …

ioctl之FIONREAD

在學習ioctl 時常常跟 read, write 混淆。其實 ioctl 是用來設置硬件控制寄存器&#xff0c;或者讀取硬件狀態寄存器的數值之類的。 而read,write 是把數據丟入緩沖區&#xff0c;硬件的驅動從緩沖區讀取數據一個個發送或者把接收的數據送入緩沖區。 ioctl(keyFd, FIONREAD, &a…

電感基礎與選型介紹

電感是一種常見的被動元件&#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],...,…

Python正則替換字符串函數re.sub用法示例(1)

本文實例講述了Python正則替換字符串函數re.sub用法。分享給大家供大家參考&#xff0c;具體如下&#xff1a; python re.sub屬于python正則的標準庫,主要是的功能是用正則匹配要替換的字符串然后把它替換成自己想要的字符串的方法re.sub 函數進行以正則表達式為基礎的替換工作…