編輯:關於Android編程
Android中有一種可以放置在任何位置的一種彈出窗口PopupWindow,比Dialog更加靈活方便,但是作者在使用過程中遇到過幾個問題,今天來總結一下。
首先先來說一下怎麼來放置一個PopupWindow,PopupWindow總共提供了三個方法:
showAsDropDown(View anchor):相對某個控件的位置(正左下方),無偏移
showAsDropDown(View anchor, int xoff, int yoff):相對某個控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相對於父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以設置偏移或無偏移
這幾個方法的區別詳細大家從字面意思上也能理解大概了,這邊就不細說了,不清楚的可以自己測試一下。
下面主要講講作者本人在使用過程中遇到的一些問題
1、PopupWindow創建方法
第一種創建方法:
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // 引入窗口配置文件 View view = inflater.inflate(R.layout.pop_view, null); // 創建PopupWindow對象 /***創建模式一****/ pop = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); //設置點擊窗口外邊窗口消失 pop.setOutsideTouchable(true); // 設置此參數獲得焦點,否則無法點擊 pop.setFocusable(true);
第二種創建方法:
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // 引入窗口配置文件 View view = inflater.inflate(R.layout.pop_view, null); // 創建PopupWindow對象 /***創建模式二****/ pop = new PopupWindow(this); pop.setContentView(view); pop.setWidth(LayoutParams.WRAP_CONTENT); pop.setHeight(LayoutParams.WRAP_CONTENT); //設置點擊窗口外邊窗口消失 pop.setOutsideTouchable(true); // 設置此參數獲得焦點,否則無法點擊 pop.setFocusable(true);
這兩種方式有什麼區別呢,這個區別我也是在很偶然的情況下發現的,如果你代碼中不加這句代碼:
pop.setBackgroundDrawable(new BitmapDrawable());
那 pop.setBackgroundDrawable(new BitmapDrawable());那句代碼又是其什麼作用呢,就是為PopupWindow設置一個背景,因為按照第二種方式創建PopupWindow,PopupWindow會默認加上一個灰色的背景框,如果想去掉這個背景框,就可以使用這句代碼,但是,到了這邊就出現第二個問題:
2、setBackgroundDrawable()問題
可能有人覺得既然是去掉背景框,就可以用setBackgroundDrawable(null)來做,這也是作者一開始的做法,但是按照第二種方式創建PopupWindow,如果采用setBackgroundDrawable(null)這種寫法,就會出現點擊其他區域PopupWindow不會消失問題,Oh,MyGod,這是為什麼呢,這也是作者一直疑惑的地方,國內國外轉了一圈也沒看到有人回答這個問題的原因,只說了解決方法,就是使用setBackgroundDrawable(new BitmapDrawable())這樣的寫法就可以避免這種問題,OK,沒有辦法,我也只能知其然不知其所以然了
3、獲取PopupWindow寬高問題
作者在創建PopupWindow的時候沒有給PopupWindow設置固定的寬高,於是在獲取PopupWindow寬高的時候問題就出現了,我使用LayoutParams.WRAP_CONTENT來設置PopupWindow的寬高,本意是想讓PopupWindow自適應大小,但是當我使用下面兩句代碼獲取PopupWindow的寬高的時候,得到的值竟然是-2,why?
System.out.println("pop寬度="+pop.getWidth()); System.out.println("pop高度="+pop.getHeight());後來查了一圈才發現原來返回的就是LayoutParams.WRAP_CONTENT的值-2,而沒有返回PopupWindow展現時的寬度和高度值,看來這個PopupWindow是你設置時給他什麼值,他就返回什麼值,雖然你設置了LayoutParams.WRAP_CONTENT,但是你獲取的時候PopupWindow並不是返回他展現的最終值,而僅僅是返回你給他的值,因此我就想,我先將所要展現的布局的大小算出來,再設置給PopupWindow,那得到的就是正確的值了,不多說,上代碼:
//如果想獲取PopupWindow對象實際布局大小的值,則可以采用如下代碼: view.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); int viewWidth = view.getMeasuredWidth(); int viewHeight = view.getMeasuredHeight(); pop.setWidth(viewWidth); pop.setHeight(viewHeight);
問題講的差不多了,這些看似是小問題,但是當時出現的時候還是費了作者不少時間來排查和解決,接下來就給出我的全部測試代碼:
activity_main.xml
package com.example.popupwindowdemo; import android.app.Activity; import android.content.Context; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.PopupWindow; public class MainActivity extends Activity { /** Called when the activity is first created. */ private PopupWindow pop; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // LayoutInflater inflater = LayoutInflater.from(this); LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // 引入窗口配置文件 View view = inflater.inflate(R.layout.pop_view, null); // 創建PopupWindow對象 /***創建模式一****/ // pop = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); /***創建模式二****/ pop = new PopupWindow(this); pop.setContentView(view); // //如果PopupWindow對象設置的寬度或者高度都為LayoutParams.WRAP_CONTENT,則getWidth()返回的就是LayoutParams.WRAP_CONTENT的值,即-2 // pop.setWidth(LayoutParams.WRAP_CONTENT); // pop.setHeight(LayoutParams.WRAP_CONTENT); // //如果想獲取PopupWindow對象實際布局大小的值,則可以采用如下代碼: view.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); int viewWidth = view.getMeasuredWidth(); int viewHeight = view.getMeasuredHeight(); pop.setWidth(viewWidth); pop.setHeight(viewHeight); System.out.println("pop寬度="+pop.getWidth()); System.out.println("pop高度="+pop.getHeight()); // 此參數必須設置,如果不設置,則在模式一下,則出現點擊其他區域PopupWindow不會消失問題,在模式二下,PopupWindow會出現灰色邊框 pop.setBackgroundDrawable(new BitmapDrawable()); // pop.setBackgroundDrawable(null); //設置點擊窗口外邊窗口消失 pop.setOutsideTouchable(true); // 設置此參數獲得焦點,否則無法點擊 pop.setFocusable(true); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(pop.isShowing()) { // 隱藏窗口,如果設置了點擊窗口外小時即不需要此方式隱藏 pop.dismiss(); } else { // 顯示窗口 pop.showAsDropDown(v); } } }); } }
現在許多APP應用都需要實現地圖功能,能夠很好的對自己所在的位置進行定位。因此,我嘗試著使用下百度地圖實現將自己的位置顯示出來。這裡我使用百度為我們提供的“百
最近在研究android自定義控件屬性,學到了TypedArray以及attrs。大家也可以結合《理解Android中的自定義屬性》這篇文章進行學習,後續一篇還有應用。1
一.概述平時做項目跟使用第三方類庫的時候經常會用到工廠模式.什麼是工廠模式,簡單來說就是他的字面意思.給外部批量提供相同或者不同的產品,而外部不需要關心工廠是如何創建一個
在這篇文章中,我將向大家展示如何從相冊截圖。先看看效果圖:上一篇文章中,我就拍照截圖這一需求進行了詳細的分析,試圖讓大家了解Android本身的限制,以及我們應當采取的實