自定義控件實(shí)現(xiàn)方式原生PopupWindow實(shí)現(xiàn)方式自定義仿PopupWindow實(shí)現(xiàn)方式代碼塊結(jié)束語
本文中初步討論了關(guān)于原生PopupWindow實(shí)現(xiàn)方式,自定義仿PopupWindow樣式實(shí)現(xiàn)以及注意細(xì)節(jié) 基于Android Studio API 23開發(fā) - 原生PopupWindow樣式實(shí)現(xiàn)方式 - 自定義仿PopupWindow實(shí)現(xiàn)方式 - 結(jié)束語
在PopupWindow中的實(shí)現(xiàn)思路建樹:
前提:在一個(gè)布局中心繪制PopupWindow,設(shè)置根布局背景為半透明–》實(shí)現(xiàn)類似Dialog的樣式
1.彈出必須要有一個(gè)相應(yīng)的樣式View
View view = LayoutInflater.from(context).inflate(R.layout.public_pop, null);2.彈窗必須設(shè)置寬高,可選設(shè)置出現(xiàn)和隱藏動(dòng)畫
PopupWindow window = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, isForce); window.setAnimationStyle(R.style.pop_style_fade);3.彈窗的點(diǎn)擊事件處理
//這里必須要注意將內(nèi)容里的根布局的點(diǎn)擊事件設(shè)為null,不然就會(huì)發(fā)生點(diǎn)擊內(nèi)容布局pop也會(huì)消失,在測(cè)試時(shí)必須用真機(jī)的返回鍵測(cè)試//當(dāng)需求為點(diǎn)擊PopupWindow外部消失時(shí)//要讓點(diǎn)擊PopupWindow之外的地方PopupWindow消失你需要調(diào)用 window.setBackgroundDrawable(new ColorDrawable(0)); window.setOutsideTouchable(false); window.setFocusable(true); contentLayout.setOnClickListener(null); //實(shí)現(xiàn)根布局的點(diǎn)擊事件,點(diǎn)擊外部消失 parentLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { window.dismiss(); } });//當(dāng)需求為點(diǎn)擊PopupWindow外部不消失時(shí),點(diǎn)擊返回退出程序--》應(yīng)用場(chǎng)景:強(qiáng)制更新//相當(dāng)于整個(gè)根布局一直獲取著焦點(diǎn)不會(huì)釋放 window.setFocusable(true); parentLayout.setFocusable(true); parentLayout.setFocusableInTouchMode(true); parentLayout.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK){ window.dismiss(); System.exit(0); return true; } return false; } });4.顯示當(dāng)前界面
//第一個(gè)參數(shù)是activity中的根布局 window.showAtLocation(anchorLayout, Gravity.CENTER, 0, 0);即可顯示一個(gè)原生態(tài)的PopupWindow,設(shè)計(jì)效果如圖:
需求前提:使用popupwindow不能簡(jiǎn)單實(shí)現(xiàn)從當(dāng)前界面的哪個(gè)控件下方滑入滑出(需要計(jì)算高度并且需要單個(gè)在代碼中實(shí)現(xiàn)動(dòng)畫效果,過程比較繁瑣并且容易出錯(cuò))
思想建樹: 1 需要當(dāng)前界面的View來進(jìn)行自定義動(dòng)畫的開啟和關(guān)閉
2 需要實(shí)現(xiàn)開啟動(dòng)畫和關(guān)閉動(dòng)畫的對(duì)象–》ObjectAnimator
3 需要實(shí)現(xiàn)點(diǎn)擊事件(用于內(nèi)部item的點(diǎn)擊后響應(yīng)關(guān)閉pop的操作),并且暴露開啟和關(guān)閉的方法由外部調(diào)用(用于處理一些外部點(diǎn)擊事件)
同時(shí)需要暴露一個(gè)boolean對(duì)象用于外部判斷當(dāng)前的狀態(tài)實(shí)現(xiàn)前提,要求,關(guān)鍵:
前提:在當(dāng)前的activity中確保這個(gè)對(duì)象的唯一性
要求:仿照dialog的設(shè)計(jì)樣式使用使用build初始化當(dāng)前數(shù)據(jù)–》AlertDialog.Builder builder=new AlertDialog.Builder(this); //先得到構(gòu)造器
關(guān)鍵:1. 在自定義控件中使用public static class 傳遞初始化的對(duì)象—-》上下文以及當(dāng)前動(dòng)畫的界面—》return new 當(dāng)前的對(duì)象初始化對(duì)象中要實(shí)現(xiàn)的對(duì)象 2. 當(dāng)前的界面需要有FrameLayout—》作用:將自定義的View對(duì)象填充進(jìn)當(dāng)前界面(注意:這里一定要是布局里面的frameLayout,不能是根布局,并且填充的FrameLayout需要設(shè)置大小)
在activity中添加view
//frameLayout不能為根布局,是在布局中另外用于填充的frameLayout FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getScreenHeight(getActivity()) * 3 / 5); root_fl.setLayoutParams(layoutParams); mEyepetizerMenuView = LayoutInflater.from(getActivity()).inflate(R.layout.layout_captail_pop_item, null); mEyepetizerMenuView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //截?cái)嗤该鞅尘包c(diǎn)擊事件 } }); root_fl.addView(mEyepetizerMenuView); new EyepetizerMenuAnimation.EyepetizerMenuBuilder( getActivity(), mEyepetizerMenuView) .build(); //添加完成后就可以關(guān)閉菜單 EyepetizerMenuAnimation.close(); //添加完成后就可以開啟菜單 EyepetizerMenuAnimation.open();對(duì)于原生PopupWindow滿足所有基本要求,但是當(dāng)滑入滑出的要求出現(xiàn)的時(shí)候很多新手都會(huì)被計(jì)算高度隱藏困惑并且也不能用Dialog實(shí)現(xiàn),因?yàn)樵诮缑嬷惺荘opupWindow彈出時(shí)是部分半透明。結(jié)合多方面因素考慮還是需要自定義一個(gè)為了適應(yīng)界面不同,動(dòng)畫相同的情況—》使用聯(lián)動(dòng)的方式(即界面由外部傳入,內(nèi)部獲取界面進(jìn)行動(dòng)畫效果(內(nèi)部只控制界面開啟和關(guān)閉))。本人習(xí)慣使用Dialog代替一般需求的PopupWindow,個(gè)人感覺Dialog比較好用,自定義Dialog詳見: http://blog.csdn.net/wyh_healer/article/details/54891235
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注