編輯:關於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);
}
}
});
}
}
Android中實現百度地圖
現在許多APP應用都需要實現地圖功能,能夠很好的對自己所在的位置進行定位。因此,我嘗試著使用下百度地圖實現將自己的位置顯示出來。這裡我使用百度為我們提供的“百
詳解Android自定義控件屬性TypedArray以及attrs
最近在研究android自定義控件屬性,學到了TypedArray以及attrs。大家也可以結合《理解Android中的自定義屬性》這篇文章進行學習,後續一篇還有應用。1
Android設計模式之工廠模式 Factory
一.概述平時做項目跟使用第三方類庫的時候經常會用到工廠模式.什麼是工廠模式,簡單來說就是他的字面意思.給外部批量提供相同或者不同的產品,而外部不需要關心工廠是如何創建一個
Android實現從相冊截圖的功能
在這篇文章中,我將向大家展示如何從相冊截圖。先看看效果圖:上一篇文章中,我就拍照截圖這一需求進行了詳細的分析,試圖讓大家了解Android本身的限制,以及我們應當采取的實