Android 仿IOS的PopupWindow和通用BasePopupWindow搭建
截圖

pw.png
實現
1、BasePopupWindow.java
1.1、實現動態載入不同layout
1.2、動態配置是否彈出後背景半透明,關閉時候恢復(監聽ondismiss,靠window類來變色)
1.3、一些基礎性的方法抽象方法
1.4、為了更加複雜的樣式和動效,可以繼續擴充套件此類
/** * Created by wujn on 2018/10/29. * Version : v1.0 * Function: base popuwindow */ public abstract class BasePopupWindow extends PopupWindow implements View.OnClickListener{ /** * 上下文 */ private Context context; /** * 最上邊的背景檢視 */ private View vBgBasePicker; /** * 內容viewgroup */ private LinearLayout llBaseContentPicker; public BasePopupWindow(Context context) { super(context); this.context = context; View parentView = View.inflate(context, R.layout.base_popup_window_picker, null); vBgBasePicker = parentView.findViewById(R.id.v_bg_base_picker); llBaseContentPicker = (LinearLayout) parentView.findViewById(R.id.ll_base_content_picker); /*** * 添加布局到介面中 */ llBaseContentPicker.addView(View.inflate(context, bindLayout(), null)); setContentView(parentView); //設定PopupWindow彈出窗體的寬 this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); //設定PopupWindow彈出窗體的高 this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); //在PopupWindow裡面就加上下面程式碼,讓鍵盤彈出時,不會擋住pop視窗。 this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); setFocusable(true);//設定獲取焦點 setTouchable(true);//設定可以觸控 setOutsideTouchable(true);//設定外邊可以點選 ColorDrawable dw = new ColorDrawable(0xffffff); setBackgroundDrawable(dw); //設定SelectPicPopupWindow彈出窗體動畫效果 this.setAnimationStyle(R.style.BottomDialogWindowAnim); initView(parentView); initListener(); initData(); vBgBasePicker.setOnClickListener(this); //是否需要螢幕半透明 setBackgroundHalfTransition(isNeedBackgroundHalfTransition()); } /** * 初始化佈局 * * @return */ protected abstract int bindLayout(); /** * 初始化view * * @param parentView */ protected abstract void initView(View parentView); /** * 初始化資料 */ protected abstract void initData(); /** * 初始化監聽 */ protected abstract void initListener(); /** * 為了適配7.0系統以上顯示問題(顯示在控制元件的底部) * * @param anchor */ @Override public void showAsDropDown(View anchor) { if (Build.VERSION.SDK_INT >= 24) { Rect rect = new Rect(); anchor.getGlobalVisibleRect(rect); int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom; setHeight(h); } super.showAsDropDown(anchor); if(isNeedBgHalfTrans){ backgroundAlpha(0.5f); } } /** * 展示在螢幕的底部 * * @param layoutid rootview */ public void showAtLocation(@LayoutRes int layoutid) { showAtLocation(LayoutInflater.from(context).inflate(layoutid, null), Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0); if(isNeedBgHalfTrans){ backgroundAlpha(0.5f); } } /** * 最上邊檢視的點選事件的監聽 * * @param v */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.v_bg_base_picker: dismiss(); break; } } /** * 是否設定背景半透明 * */ public boolean isNeedBackgroundHalfTransition(){ return false; } private boolean isNeedBgHalfTrans = false; private void setBackgroundHalfTransition(boolean isNeed){ isNeedBgHalfTrans = isNeed; if(isNeedBgHalfTrans){ this.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { backgroundAlpha(1f); } }); } } /** * 設定新增螢幕的背景透明度 * @param bgAlpha */ private void backgroundAlpha(float bgAlpha) { WindowManager.LayoutParams lp = ((Activity)context).getWindow().getAttributes(); lp.alpha = bgAlpha; //0.0-1.0 ((Activity)context).getWindow().setAttributes(lp); } }
2、base_popup_window_picker.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <View android:id="@+id/v_bg_base_picker" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <LinearLayout android:id="@+id/ll_base_content_picker" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="vertical" /> </LinearLayout>
3、進入和退出時候的動畫style
<!--animanation--> <!-- 底部的dialog彈出的動畫樣式--> <style name="BottomDialogWindowAnim" parent="android:Animation"> <item name="android:windowEnterAnimation">@anim/popup_bottom_enter_anim</item> <item name="android:windowExitAnimation">@anim/popup_bottom_exit_anim</item> </style>
進入動畫:popup_bottom_enter_anim.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="200" android:fromYDelta="100%p" android:toYDelta="0" /> <alpha android:duration="200" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>
退出動畫:popup_bottom_exit_anim.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromYDelta="0" android:toYDelta="50%p" /> <alpha android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>
4、仿IOS的layout:popup_window_album_or_camera.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_shape_corner_white" android:orientation="vertical"> <Button android:id="@+id/btnCamera" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:text="拍照" android:textColor="@color/dodgerblue" android:textSize="@dimen/normal_text_size" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/gray_1" /> <Button android:id="@+id/btnAlbum" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:text="從相簿中選擇" android:textColor="@color/dodgerblue" android:textSize="@dimen/normal_text_size" /> </LinearLayout> <LinearLayout android:layout_marginTop="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_shape_corner_white" android:orientation="vertical"> <Button android:id="@+id/btnCancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:text="@string/cancel" android:textColor="@color/dodgerblue" android:textSize="@dimen/normal_text_size" /> </LinearLayout> </LinearLayout>
item的背景style
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/white" /> <corners android:radius="6dp"/> <stroke android:width="1dp" android:color="@color/gray_1" /> </shape>
5、仿IOS的popuwindow類:AlbumOrCameraPopupWindow
public class AlbumOrCameraPopupWindow extends BasePopupWindow { private Button btnCamera; private Button btnAlbum; private Button btnCancel; private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener; public AlbumOrCameraPopupWindow(Context context,OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener) { super(context); this.onCameraOrAlbumSelectListener = onCameraOrAlbumSelectListener; } @Override public boolean isNeedBackgroundHalfTransition(){ return true; } @Override protected int bindLayout() { return R.layout.popup_window_album_or_camera; } @Override protected void initView(View parentView) { btnCamera = (Button) parentView.findViewById(R.id.btnCamera); btnAlbum = (Button) parentView.findViewById(R.id.btnAlbum); btnCancel = (Button) parentView.findViewById(R.id.btnCancel); } @Override protected void initData() { } @Override protected void initListener() { btnCamera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); if(onCameraOrAlbumSelectListener != null){ onCameraOrAlbumSelectListener.OnSelectCamera(); } } }); btnAlbum.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); if(onCameraOrAlbumSelectListener != null){ onCameraOrAlbumSelectListener.OnSelectAlbum(); } } }); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); } }
選擇相機或者相簿的監聽介面
public interface OnCameraOrAlbumSelectListener { public void OnSelectCamera(); public void OnSelectAlbum(); }
6、具體使用
private AlbumOrCameraPopupWindow ACWindow; private void initListener(){ ACWindow = new AlbumOrCameraPopupWindow(this, onCameraOrAlbumSelectListener); btnIosPopupWindow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(ACWindow != null && !ACWindow.isShowing()){ ACWindow.showAtLocation(R.layout.activity_view_popup_window); } } }); } /**選擇相機或者相簿*/ private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener = new OnCameraOrAlbumSelectListener() { @Override public void OnSelectCamera() { LogUtil.i("OnSelectCamera..."); ToastUtil.showShort(instance, "相機"); } @Override public void OnSelectAlbum() { LogUtil.i("OnSelectAlbum..."); ToastUtil.showShort(instance, "從相簿中選擇"); } };
朝CV工程師又進一步~~~:laughing: