android的popupwindow
㈠ android中Dialog和PopupWindow的區別
1. Android的對話框有兩種:PopupWindow和AlertDialog。 它們的不同點在於:AlertDialog的位置固定,而PopupWindow的位置可以隨意 AlertDialog是非阻塞線程的,AlertDialog彈出的時候,後台可是還可以做其他事情的哦。 而PopupWindow是阻塞線程的, 這就意味著在我們退出這個彈出框之前,程序會一直等待 PopupWindow的位置按照有無偏移分,可以分為偏移和無偏移兩種;按照參照物的不同,可以分為相對於某個控制項(Anchor錨)和相對於父控制項。具體如下 showAsDropDown(View anchor):相對某個控制項的位置(正左下方),無偏移 showAsDropDown(View anchor, int xoff, int yoff):相對某個控制項的位置,有偏移 showAtLocation(View parent, int gravity, int x, int y):相對於父控制項的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以設置偏移或無偏移 LayoutInflater layoutInflater = LayoutInflater.from(this); View popupWindow = layoutInflater.inflate(R.layout.popup, null);
㈡ Android彈窗探究之PopupWindow的使用
相對於AlertDialog的使用,PopupWindow的使用也比較簡單,這里主要介紹的是PopupWindow的基礎使用包括在使用過程中的一些注意事項,做個筆記。
方式一:
方式二:
當然,在實際的開發過程中我們並不能僅僅滿足於如何簡單使用,更多的時候我們需要去考慮兼容性與擴展性的問題,所以,在這里,我對PopupWindow做了一個簡單的封裝,如下所示:
創建PopupWindow的管理類,即PopupWindowManager類
新建類來繼承自PopupWindow
最後進行調用:
到這里,popupWindow的簡單使用就完成了。最後來講一下在使用popupWindow的過程中需要注意的幾點。
(1)必須手動給popupWindow設置寬度和高度,否則popupWindow不顯示。
(2)在手機系統的API大於24的時候全屏展示的時候會完全填充整個屏幕,而不是在目標View的下方正常顯示。
(3)在有些手機上面,全屏展示的時候底部會留白,其實是因為StatusBar的高度沒有計算進去,需要我們自己手動計算出去。
(4)當我們設置了setFocusable為true的時候,點擊屏幕事件會交由onTouchListener處理。
㈢ Android基礎 (11) PopupWindow詳解
(1)PopupWindow的使用
(2)自定義一個PopupWindow
(3)PopupWindow的源碼分析
(4)AlertDialog,popupWindow,Activity區別
(5)Activity-Window-View三者的差別
Android的對話框有兩種:PopupWindow和AlertDialog。它們的不同點在於:
PopupWindow的位置按照有無偏移分,可以分為偏移和無偏移兩種;按照參照物的不同,可以分為相對於某個控制項(Anchor錨)和相對於父控制項。具體如下:
showAsDropDown(View anchor):相對某個控制項的位置(正左下方),無偏移
showAsDropDown(View anchor, int xoff, int yoff):相對某個控制項的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相對於父控制項的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以設置偏移或無偏移。
使用詳述: https://blog.csdn.net/xiaanming/article/details/9121383
這里的WRAP_CONTENT可以換成fill_parent 也可以是具體的數值,它是指PopupWindow的大小,也就是contentView的大小,注意popupWindow根據這個大小顯示你的View,如果你的View本身是從xml得到的,那麼xml的第一層view的大小屬性將被忽略。相當於popupWindow的width和height屬性直接和第一層View相對應。
執行了一個attachToAnchor,意思是PopupWindow類似一個錨掛在目標view的下面,這個函數主要講xoff、yoff(x軸、y軸偏移值)、gravity(比如Gravity.BOTTOM之類,指的是PopupWindow放在目標view哪個方向邊緣的位置)這個attachToAnchor有點意思,通過弱引用保存目標view和目標view的rootView(我們都知道:通過弱引用和軟引用可以防止內存泄漏)、這個rootview是否依附在window、還有保存偏差值、gravity
PopupWindow通過為傳入的View添加一層包裹的布局,並重寫該布局的點擊事件,實現點擊PopupWindow之外的區域PopupWindow消失的效果
封裝庫可前往:#### https://github.com/yangchong211/YCDialog
㈣ Android PopupWindow怎麼合理控制彈出位置
Android PopupWindow怎麼合理控制彈出位置
php">privatevoidshowPopupWindow(Viewparent){
if(popupWindow==null){
LayoutInflaterlayoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view=layoutInflater.inflate(R.layout.group_list,null);
lv_group=(ListView)view.findViewById(R.id.lvGroup);
Collections.reverse(groups);
GroupAdaptergroupAdapter=newGroupAdapter(this,groups);
lv_group.setAdapter(groupAdapter);
popupWindow=newPopupWindow(view,200,220);
}
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(true);//設置點擊屏幕其它地方彈出框消失
popupWindow.setBackgroundDrawable(newBitmapDrawable());
WindowManagerwindowManager=(WindowManager)getSystemService(Context.WINDOW_SERVICE);
intxPos=-popupWindow.getWidth()/2
+getCustomTitle().getCenter().getWidth()/2;
popupWindow.showAsDropDown(parent,xPos,4);
lv_group.setOnItemClickListener(newOnItemClickListener(){
@Override
publicvoidonItemClick(AdapterView<?>adapterView,Viewview,
intposition,longid){
loadNew(((StringItem)(groups.get(position))).getId());
if(popupWindow!=null)
popupWindow.dismiss();
}
});
}
只需要設置proupwindows的setOutsideTouchable屬性即可。
以下為示例代碼:
window.showAtLocation(parent, Gravity.RIGHT | Gravity.BOTTOM, 10,10);//顯示位置
第一個參數指定PopupWindow的錨點view,即依附在哪個view上。
第二個參數指定起始點
第三個參數設置以起始點的右下角為原點,向左、上各偏移的像素。
自己看下API
㈤ Android中Popupwindow和Dialog的區別
PopupWindow和Dialog可以實現同樣的效果,默認情況下Dialog可以快速創建對應的dialog對話窗口,只需要簡單的幾句話:
創建Dialog
java">AlertDialogmDialog=null;
mDialog=newAlertDialog.Builder(this).create();;
mDialog.setIcon(R.drawable.ic_launcher);
mDialog.setTitle("系統提示");
mDialog.setMessage("你確定要退出嗎?");
mDialog.setButton(DialogInterface.BUTTON_POSITIVE,"確定",null);
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE,"取消",null);
mDialog.show();PopupWindow創建:需要獲取對應的View
ViewpopupWindow_view=getLayoutInflater().inflate(R.layout.activity_popupwindow_left,null,false);
popupWindow=newPopupWindow(popupWindow_view,200,LayoutParams.MATCH_PARENT,true);PopupWindow創建過程沒有Dialog那麼方便,Dialog創建對象後,設置對應的Title、Message、Button即可;PopupWindow可以創建的彈窗從當前視圖的上下左右方向彈出,效果和Dialog居中顯示有所區別
㈥ android的popupwindow控制項的大小的問題
popUpWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.page2));
設置的是popupwindow(window容器)的背景。
popUpWindow
=
new
PopupWindow(show_popvieView,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
//是將show_popvieView放入容器中,以自適應作為大小,且容器也採用自適應。
綜上,如果你設置大小,導致show_popvieView沾滿整個屏幕,那麼window容器最為底層,設置的背景坑定是看不見的。
建議:背景設置採用設置show_popvieView的背景。如果有多層,可以在內容裡面鑲嵌,最好別直接設置外層popupwindow容器
㈦ Android中Popupwindow和Dialog的區別
除了外觀樣式和顯示的位置的區別之外,他們之間最本質的區別是:
dialog是非阻塞式對話框,popupwindow是阻塞式對話框。也就是說dialog彈出時
後台還可以進行很多的操作,而popupwindow彈出是
後台進程是阻塞的,要一直等待popupwindow
消失
才會進行操作。
㈧ Android Popwindow使用總結
1.基本屬性方法
2.在彈窗出現後讓背景變暗,並在彈窗消失後讓背景還原
3.添加動畫
自定義一個動畫
添加動畫
只有同時設置PopupWindow的背景和可以響應外部點擊事件,它才能「真正」響應外部點擊事件。也就是說,當你點擊PopupWindow的外部或者按下「Back」鍵時,PopupWindow才會消失。
1.在popwindow中嵌套viewpager時候,關於定位問題:首先保證viewpager類是同一個,就是沒有新new一個類。然後在show的時候記得setCurrentItem()一下就好了。
Android PopupWindow使用方法小結
Android中文API——PopupWindow
喵印~~
㈨ Android介面回調總結,以及運用到彈窗PopWindow的Demo實現
最近項目中接觸到介面回調,以及Android彈窗PopWindow組件的使用,現在利用學到的知識自己寫了一個簡單的Demo,練習下在Android下如何運用介面回調,來實現彈窗PopWindow的功能。
1. 定義一個介面:OnSelectItemListener。定義一個方法 void selectItem(String name, int type),作為點擊彈窗的每個Item的回調介面。
2. 自定義彈窗類:MyPopupWindow,其布局文件為popup_window.xml。當在MainActivity調用其構造函數創建對象時,同時執行initPopupWindow()函數,給每個Item設置監聽器,監聽點擊Item時,回調介面函數selectItem("Pop Window A", POP_WINDOW_ITEM_1),該函數在MainActivity中實現。
3. 主Activity: MainActivity。其布局文件為一個Button和一個TextView。監聽Button,每當點擊則彈出PopWindow,呈現三個Item。調用MyPopupWindow類中的方法setOnSelectItemListener(OnSelectItemListener listener),傳入OnSelectItemListener 對象作為參數,同時實現回調介面OnSelectItemListener的方法void selectItem(String name, int type)。
主Activity: MainActivity. Java
[java] view plain
packagecom.lambdroid.callbacktest2;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.TextView;
importandroid.widget.Toast;
//聯系介面的回調以及PopWindow彈窗的簡單使用
{
privateMyPopupWindow myPopupWindow;
privateButton btn_pop_window;
privateTextView tv_display;
protectedContext context;
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context =this;
btn_pop_window = (Button) findViewById(R.id.btn_pop_window);
tv_display = (TextView) findViewById(R.id.tv_display);
//給Button設置事件監聽:彈出彈窗
btn_pop_window.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
myPopupWindow.show(btn_pop_window);
}
});
myPopupWindow =newMyPopupWindow(context);
//實現OnSelectItemListener介面的selectItem方法:對於彈窗三個Item的事件監聽
myPopupWindow.setOnSelectItemListener(newOnSelectItemListener() {
@Override
publicvoidselectItem(String name,inttype) {
//點擊電站列表,彈出彈框
if(myPopupWindow !=null&& myPopupWindow.isShowing()) {
myPopupWindow.dismiss();
}
tv_display.setText(name);
switch(type){
caseMyPopupWindow.POP_WINDOW_ITEM_1:
Toast.makeText(context,"我是彈窗A, 我的英文名是"+ name, Toast.LENGTH_SHORT).show();
break;
caseMyPopupWindow.POP_WINDOW_ITEM_2:
Toast.makeText(context,"我是彈窗B, 我的英文名是"+ name, Toast.LENGTH_SHORT).show();
break;
caseMyPopupWindow.POP_WINDOW_ITEM_3:
Toast.makeText(context,"我是彈窗C, 我的英文名是"+ name, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
});
}
}
activity_main.xml
[html] view plain
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/btn_pop_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="20dp"
android:padding="20dp"
android:text="Pop Window"
android:textSize="20sp"/>
android:id="@+id/tv_display"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="Hello World!"
android:textSize="30sp"/>
自定義彈窗類:MyPopupWindow.java
[java] view plain
packagecom.lambdroid.callbacktest2;
importandroid.app.ActionBar;
importandroid.content.Context;
importandroid.graphics.drawable.ColorDrawable;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.widget.LinearLayout;
importandroid.widget.PopupWindow;
.OnClickListener{
privatePopupWindow mPopWindow;
privateContext mContext;
privateLinearLayout llPop1;
privateLinearLayout llPop2;
privateLinearLayout llPop3;
privateintpw_height;
publicstaticfinalintPOP_WINDOW_ITEM_1 =1;
publicstaticfinalintPOP_WINDOW_ITEM_2 =2;
publicstaticfinalintPOP_WINDOW_ITEM_3 =3;
privateOnSelectItemListener listener;
(OnSelectItemListener listener){
this.listener = listener;
}
publicMyPopupWindow(Context context){
mContext = context;
initPopupWindow();//初始化彈窗
}
publicvoidinitPopupWindow(){
View view = LayoutInflater.from(mContext).inflate(R.layout.popup_window,null);
mPopWindow =newPopupWindow(view, ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT,true);
mPopWindow.setOutsideTouchable(true);
/** 為其設置背景,使得其內外焦點都可以獲得 */
mPopWindow.setBackgroundDrawable(newColorDrawable());
mPopWindow.setFocusable(true);
pw_height = view.getHeight();
llPop1 = (LinearLayout) view.findViewById(R.id.ll_pop_1);
llPop1.setOnClickListener(this);
llPop2 = (LinearLayout) view.findViewById(R.id.ll_pop_2);
llPop2.setOnClickListener(this);
llPop3 = (LinearLayout) view.findViewById(R.id.ll_pop_3);
llPop3.setOnClickListener(this);
}
//監聽三個彈窗的點擊事件
@Override
publicvoidonClick(View v) {
switch(v.getId()){
caseR.id.ll_pop_1:
if(listener !=null) {
listener.selectItem("Pop Window A", POP_WINDOW_ITEM_1);//回調介面
}
break;
caseR.id.ll_pop_2:
if(listener !=null) {
listener.selectItem("Pop Window B", POP_WINDOW_ITEM_2);
}
break;
caseR.id.ll_pop_3:
if(listener !=null) {
listener.selectItem("Pop Window C", POP_WINDOW_ITEM_1);
}
break;
default:
break;
}
}
//顯示彈窗,並設置彈窗基於標題欄的顯示位置
publicvoidshow(View view) {
//popupwindow相對view位置x軸偏移量
View viewTemp = mPopWindow.getContentView();
viewTemp.measure(0,0);
intwidth = viewTemp.getMeasuredWidth();
intxOffset = (view.getWidth() - width) /2;
mPopWindow.showAsDropDown(view, xOffset,0);
}
/**
* 退出popupwindow
*/
publicvoiddismiss() {
if(mPopWindow !=null&& mPopWindow.isShowing()) {
mPopWindow.dismiss();
}
}
/**
* popupwindow是否正在顯示
*/
publicbooleanisShowing() {
if(mPopWindow !=null) {
returnmPopWindow.isShowing();
}
returnfalse;
}
}
popup_window.xml
[html] view plain
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
android:id="@+id/ll_alarm_type"
android:layout_width="120dp"
android:layout_height="130dp"
android:orientation="vertical"
android:background="@drawable/popupwindow"
android:paddingBottom="16dp"
android:paddingTop="16dp">
android:id="@+id/ll_pop_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="窗口 A"
android:textSize="15sp"
android:textColor="#ffffff"/>
android:id="@+id/ll_pop_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="窗口 B"
android:textSize="15sp"
android:textColor="#ffffff"/>
android:id="@+id/ll_pop_3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="窗口 C"
android:textSize="15sp"
android:textColor="#FFFFFF"/>
回調介面:OnSelectItemListener
[java] view plain
packagecom.lambdroid.callbacktest2;
{
voidselectItem(String name,inttype);
}
點擊Button,彈出彈窗,顯示三個Item
點擊第二個Item,通過回調函數,來實現TextView內容的修改,以及彈出Toast
總結
Java回調情形涉及很多,本文屬於介面的非同步回調:當不知道何時會執行介面的回調函數,(通過介面回調來對獲取到的資源的操作)。除此還有線程間的非同步回調(子線程進行耗時操作,操作完畢通知主線程或將數據傳給主線程處理),以及利用介面回調來實現線程間的數據通信等等(Android可以利用Handler來實現)。等下次再舉例說明Java回調函數的其它情形。
㈩ Android PopupWindow 在開發過程中有哪些坑
自Android 4.4起,引入了webView,使用需要注意的事項:
1.多線程
如果你在子線程中調用WebView的相關方法,而不在UI線程,則可能會出現無法預料的錯誤。
所以,當你的程序中需要用到多線程時候,也請使用 runOnUiThread()方法來保證你關於WebView的操作是在UI線程中進行的:
runOnUiThread(newRunnable(){
@Override
publicvoidrun(){
//CodeforWebViewgoeshere
}
});
2.線程阻塞
永遠不要阻塞UI線程,這是開發Android程序的一個真理。雖然是真理,我們卻往往不自覺的
犯一些錯誤違背它,一個開發中常犯的錯誤就是:在UI線程中去等待JavaScript 的回調。
例如:
//
webView.loadUrl("javascript:fn()");while(result==null){
Thread.sleep(100);}
千萬不要這樣做,Android 4.4中,提供了新的Api來做這件事情。 evaluateJavascript() 就是
專門來非同步執行JavaScript代碼的。
3.evaluateJavascript() 方法
專門用於非同步調用JavaScript方法,並且能夠得到一個回調結果。
示例:
mWebView.evaluateJavascript(script,newValueCallback<String>(){
@Override
publicvoidonReceiveValue(Stringvalue){
//TODO
}
});
4.處理 WebView 中 url 跳轉
新版WebView對於自定義scheme的url跳轉,新增了更為嚴格的限制條件。 當你實現了
shouldOverrideUrlLoading() 或 shouldInterceptRequest() 回調,WebView 也只會在跳轉
url是合法Url時才會跳轉。
例如,如果你使用這樣一個url :
<ahref="showProfile"]]>Show Profile</a>
shouldOverrideUrlLoading() 將不會被調用。
正確的使用方式是:
<ahref="example-app:showProfile"]]>Show Profile</a>
對應的檢測Url跳轉的方式:
//TheURLschemeshouldbenon-hierarchical(notrailingslashes)
privatestaticfinalStringAPP_SCHEME="example-app:";
@(WebViewview,String
url){
if(url.startsWith(APP_SCHEME)){
urlData=URLDecoder.decode(url.substring(APP_SCHEME.length()),"UTF-8");
respondToData(urlData);
returntrue;
}
returnfalse;}
當然,也可以這樣使用:
webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA,
null,"UTF-8",null);
5.UserAgent 變化
如果你的App對應的服務端程序,會根據客戶端傳來的UserAgent來做不同的事情,那麼你需
要注意的是,新版本的WebView中,UserAgent有了些微妙的改變:
Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H)
AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0
Mobile Safari/537.36
使用 getDefaultUserAgent()方法可以獲取默認的UserAgent,也可以通過:
mWebView.getSettings().setUserAgentString(ua);
mWebView.getSettings().getUserAgentString();
來設置和獲取自定義的UserAgent。
6.使用addJavascriptInterface()的注意事項
從Android4.2開始。 只有添加 @JavascriptInterface 聲明的Java方法才可以被JavaScript調用,例如:
classJsObject{
@JavascriptInterface
publicStringtoString(){return"injectedObject";}
}
webView.addJavascriptInterface(newJsObject(),"injectedObject");
webView.loadData("","text/html",null);
webView.loadUrl("javascript:alert(injectedObject.toString())");
7.Remote Debugging
新版的WebView還提供了一個很厲害的功能:使用Chrome來調試你運行在WebView中的程序。