国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

自定義控件(仿PopupWindow篇)

2019-11-09 17:35:17
字體:
來源:轉載
供稿:網友

自定義控件實現方式

自定義控件實現方式原生PopupWindow實現方式自定義仿PopupWindow實現方式代碼塊結束語

本文中初步討論了關于原生PopupWindow實現方式,自定義仿PopupWindow樣式實現以及注意細節 基于Android Studio API 23開發 - 原生PopupWindow樣式實現方式 - 自定義仿PopupWindow實現方式 - 結束語


原生PopupWindow實現方式

在PopupWindow中的實現思路建樹:

前提:在一個布局中心繪制PopupWindow,設置根布局背景為半透明–》實現類似Dialog的樣式

1.彈出必須要有一個相應的樣式View

View view = LayoutInflater.from(context).inflate(R.layout.public_pop, null);

2.彈窗必須設置寬高,可選設置出現和隱藏動畫

PopupWindow window = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, isForce); window.setAnimationStyle(R.style.pop_style_fade);

3.彈窗的點擊事件處理

//這里必須要注意將內容里的根布局的點擊事件設為null,不然就會發生點擊內容布局pop也會消失,在測試時必須用真機的返回鍵測試//當需求為點擊PopupWindow外部消失時//要讓點擊PopupWindow之外的地方PopupWindow消失你需要調用 window.setBackgroundDrawable(new ColorDrawable(0)); window.setOutsideTouchable(false); window.setFocusable(true); contentLayout.setOnClickListener(null); //實現根布局的點擊事件,點擊外部消失 parentLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { window.dismiss(); } });//當需求為點擊PopupWindow外部不消失時,點擊返回退出程序--》應用場景:強制更新//相當于整個根布局一直獲取著焦點不會釋放 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.顯示當前界面

//第一個參數是activity中的根布局 window.showAtLocation(anchorLayout, Gravity.CENTER, 0, 0);

即可顯示一個原生態的PopupWindow,設計效果如圖: 這里寫圖片描述

自定義仿PopupWindow實現方式

需求前提:使用popupwindow不能簡單實現從當前界面的哪個控件下方滑入滑出(需要計算高度并且需要單個在代碼中實現動畫效果,過程比較繁瑣并且容易出錯)

思想建樹: 1 需要當前界面的View來進行自定義動畫的開啟和關閉

2 需要實現開啟動畫和關閉動畫的對象–》ObjectAnimator

3 需要實現點擊事件(用于內部item的點擊后響應關閉pop的操作),并且暴露開啟和關閉的方法由外部調用(用于處理一些外部點擊事件)

同時需要暴露一個boolean對象用于外部判斷當前的狀態

實現前提,要求,關鍵:

前提:在當前的activity中確保這個對象的唯一性

要求:仿照dialog的設計樣式使用使用build初始化當前數據–》AlertDialog.Builder builder=new AlertDialog.Builder(this); //先得到構造器

關鍵:1. 在自定義控件中使用public static class 傳遞初始化的對象—-》上下文以及當前動畫的界面—》return new 當前的對象初始化對象中要實現的對象 2. 當前的界面需要有FrameLayout—》作用:將自定義的View對象填充進當前界面(注意:這里一定要是布局里面的frameLayout,不能是根布局,并且填充的FrameLayout需要設置大?。?/p>

代碼塊

//該類是借鑒GitHub上的自定義控件內容public class EyepetizerMenuAnimation implements View.OnClickListener { PRivate View mEyepetizerMenuView; private Context mContext; public static ObjectAnimator mMenuOpenAnimation; public static ObjectAnimator mMenuCloseAnimation; private DecelerateInterpolator mInterpolator; public static boolean mIsMenuClose = true; private static final String TRANSLATION = "translationY"; public EyepetizerMenuAnimation(EyepetizerMenuBuilder builder) { this.mContext = builder.context; this.mEyepetizerMenuView = builder.eyepetizerMenuView; this.mInterpolator = new DecelerateInterpolator(); this.mMenuOpenAnimation = buildMenuOpenAnimation(); this.mMenuCloseAnimation = buildMenuCloseAnimation(); mEyepetizerMenuView.setVisibility(View.GONE); } @Override public void onClick(View v) { if (mIsMenuClose) { open(); }else { close(); } } public static void open() { mIsMenuClose = false; AnimatorSet set = new AnimatorSet(); set.playTogether( mMenuOpenAnimation); set.start(); } public static void close() { mIsMenuClose = true; AnimatorSet set = new AnimatorSet(); set.playTogether( mMenuCloseAnimation);//mActionMenuAnimation set.start(); } private ObjectAnimator buildMenuOpenAnimation() { ObjectAnimator menuOpenAnimation = ObjectAnimator.ofFloat( mEyepetizerMenuView, TRANSLATION, -Utils.getScreenHeight(mContext), 0); menuOpenAnimation.setInterpolator(mInterpolator); menuOpenAnimation.setDuration(350); menuOpenAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); mEyepetizerMenuView.setVisibility(View.VISIBLE); } }); return menuOpenAnimation; } private ObjectAnimator buildMenuCloseAnimation() { ObjectAnimator menuCloseAnimation = ObjectAnimator.ofFloat( mEyepetizerMenuView, TRANSLATION, 0, -Utils.getScreenHeight(mContext)); menuCloseAnimation.setInterpolator(mInterpolator); menuCloseAnimation.setDuration(350); menuCloseAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mEyepetizerMenuView.setVisibility(View.GONE); } }); return menuCloseAnimation; } public static class EyepetizerMenuBuilder { private View eyepetizerMenuView; private Context context; public EyepetizerMenuBuilder(Context context, View eyepetizerMenuView) { this.eyepetizerMenuView = eyepetizerMenuView; this.context = context; } public EyepetizerMenuAnimation build() { return new EyepetizerMenuAnimation(this); } }}

在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) { //截斷透明背景點擊事件 } }); root_fl.addView(mEyepetizerMenuView); new EyepetizerMenuAnimation.EyepetizerMenuBuilder( getActivity(), mEyepetizerMenuView) .build(); //添加完成后就可以關閉菜單 EyepetizerMenuAnimation.close(); //添加完成后就可以開啟菜單 EyepetizerMenuAnimation.open();

結束語

對于原生PopupWindow滿足所有基本要求,但是當滑入滑出的要求出現的時候很多新手都會被計算高度隱藏困惑并且也不能用Dialog實現,因為在界面中是PopupWindow彈出時是部分半透明。結合多方面因素考慮還是需要自定義一個為了適應界面不同,動畫相同的情況—》使用聯動的方式(即界面由外部傳入,內部獲取界面進行動畫效果(內部只控制界面開啟和關閉))。本人習慣使用Dialog代替一般需求的PopupWindow,個人感覺Dialog比較好用,自定義Dialog詳見: http://blog.csdn.net/wyh_healer/article/details/54891235


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 繁昌县| 洛川县| 彰武县| 无棣县| 涟源市| 河北省| 清涧县| 萍乡市| 富平县| 巴林右旗| 饶河县| 陆良县| 区。| 鲜城| 越西县| 肇庆市| 东平县| 上虞市| 无为县| 廉江市| 九龙城区| 康马县| 靖宇县| 舟曲县| 余干县| 高尔夫| 虹口区| 白玉县| 安多县| 繁峙县| 荆州市| 彝良县| 钟祥市| 封开县| 高安市| 武川县| 安化县| 西和县| 塔城市| 常州市| 青州市|