截圖
實(shí)現(xiàn)
1、BasePopupWindow.java
1.1井厌、實(shí)現(xiàn)動(dòng)態(tài)加載不同layout
1.2秒赤、動(dòng)態(tài)配置是否彈出后背景半透明,關(guān)閉時(shí)候恢復(fù)(監(jiān)聽ondismiss痹愚,靠window類來變色)
1.3富岳、一些基礎(chǔ)性的方法抽象方法
1.4蛔糯、為了更加復(fù)雜的樣式和動(dòng)效,可以繼續(xù)擴(kuò)展此類
/**
* Created by wujn on 2018/10/29.
* Version : v1.0
* Function: base popuwindow
*/
public abstract class BasePopupWindow extends PopupWindow implements View.OnClickListener{
/**
* 上下文
*/
protected Context context;
/**
* 最上邊的背景視圖
*/
private View vBgBasePicker;
/**
* 內(nèi)容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);
//設(shè)置PopupWindow彈出窗體的寬
this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
//設(shè)置PopupWindow彈出窗體的高
this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
//在PopupWindow里面就加上下面代碼窖式,讓鍵盤彈出時(shí)蚁飒,不會(huì)擋住pop窗口。
this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
setFocusable(true);//設(shè)置獲取焦點(diǎn)
setTouchable(true);//設(shè)置可以觸摸
setOutsideTouchable(true);//設(shè)置外邊可以點(diǎn)擊
ColorDrawable dw = new ColorDrawable(0xffffff);
setBackgroundDrawable(dw);
//設(shè)置SelectPicPopupWindow彈出窗體動(dòng)畫效果
this.setAnimationStyle(R.style.BottomDialogWindowAnim);
initView(parentView);
initData();
initListener();
vBgBasePicker.setOnClickListener(this);
//是否需要屏幕半透明
setBackgroundHalfTransition(isNeedBackgroundHalfTransition());
}
/**
* 初始化布局
*
* @return
*/
protected abstract int bindLayout();
/**
* 初始化view
*
* @param parentView
*/
protected abstract void initView(View parentView);
/**
* 初始化數(shù)據(jù)
*/
protected abstract void initData();
/**
* 初始化監(jiān)聽
*/
protected abstract void initListener();
/**
* 為了適配7.0系統(tǒng)以上顯示問題(顯示在控件的底部)
*
* @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);
}
}
/**
* 最上邊視圖的點(diǎn)擊事件的監(jiān)聽
*
* @param v
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.v_bg_base_picker:
dismiss();
break;
}
}
/**
* 是否設(shè)置背景半透明
* */
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);
}
});
}
}
/**
* 設(shè)置添加屏幕的背景透明度
* @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淮逻、進(jìn)入和退出時(shí)候的動(dòng)畫style
<!--animanation-->
<!-- 底部的dialog彈出的動(dòng)畫樣式-->
<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>
進(jìn)入動(dòng)畫: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>
退出動(dòng)畫: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();
}
});
}
}
選擇相機(jī)或者相冊的監(jiān)聽接口
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);
}
}
});
}
/**選擇相機(jī)或者相冊*/
private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener = new OnCameraOrAlbumSelectListener() {
@Override
public void OnSelectCamera() {
LogUtil.i("OnSelectCamera...");
ToastUtil.showShort(instance, "相機(jī)");
}
@Override
public void OnSelectAlbum() {
LogUtil.i("OnSelectAlbum...");
ToastUtil.showShort(instance, "從相冊中選擇");
}
};
朝CV工程師又進(jìn)一步~~~??
2018/11/05 更新: BasePopupWindow.java 優(yōu)化:
- 1、先initData在initListener 强窖,比較好一點(diǎn)
- 2凸椿、protected context,子類有可能也需要用到翅溺,有時(shí)候需要加recyleview