package com.xjf.repository.framework.basepopup;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.PopupWindow;
import com.xjf.repository.R;
import java.lang.reflect.Field;
/**
* -----------------------------------------------------------------
* User:xijiufu
* Email:xjfsml@163.com
* Version:1.0
* Time:2017/4/18--0:41
* Function:抽象通用popupwindow的父类
* ModifyHistory:
* -----------------------------------------------------------------
*/
public abstract class BasePopupWindow implements BasePopup {
private static final String TAG = "BasePopupWindow";
//元素定义
protected PopupWindow mPopupWindow;
//popup视图
protected View mPopupView;
protected View mAnimaView;
protected View mDismissView;
protected Activity mContext;
//是否自动弹出输入框(default:false)
private boolean autoShowInputMethod = false;
private OnDismissListener mOnDismissListener;
//anima
protected Animation curExitAnima;
protected Animator curExitAnimator;
protected Animation curAnima;
protected Animator curAnimator;
private boolean isExitAnimaPlaying = false;
private boolean needPopupFadeAnima = true;
public BasePopupWindow(Activity context) {
initView(context, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
public BasePopupWindow(Activity context, int w, int h) {
initView(context, w, h);
}
private void initView(Activity context, int w, int h) {
mContext = context;
mPopupView = getPopupView();
mPopupView.setFocusableInTouchMode(true);
//默认占满全屏
mPopupWindow = new PopupWindow(mPopupView, w, h);
//指定透明背景,back键相关
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
//默认是渐入动画
mPopupWindow.setAnimationStyle(R.style.PopupAnimaFade);
//=============================================================为外层的view添加点击事件,并设置点击消失
mAnimaView = getAnimaView();
mDismissView = getClickToDismissView();
if (mDismissView != null) {
mDismissView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
if (mAnimaView != null) {
mAnimaView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
}
//=============================================================元素获取
curAnima = getShowAnimation();
curAnimator = getShowAnimator();
curExitAnima = getExitAnimation();
curExitAnimator = getExitAnimator();
}
//------------------------------------------抽象-----------------------------------------------
/**
* PopupWindow展示出来后,需要执行动画的View.一般为蒙层之上的View
*/
protected abstract Animation getShowAnimation();
/**
* 设置一个点击后触发dismiss PopupWindow的View,一般为蒙层
*/
protected abstract View getClickToDismissView();
/**
* 设置展示动画View的属性动画
*/
public Animator getShowAnimator() {
return null;
}
/**
* 设置一个拥有输入功能的View,一般为EditTextView
*/
public View getInputView() {
return null;
}
/**
* 设置PopupWindow销毁时的退出动画
*/
public Animation getExitAnimation() {
return null;
}
/**
* 设置PopupWindow销毁时的退出属性动画
*/
public Animator getExitAnimator() {
return null;
}
/**
* popupwindow是否需要淡入淡出
*/
public void setNeedPopupFade(boolean needPopupFadeAnima) {
this.needPopupFadeAnima = needPopupFadeAnima;
mPopupWindow.setAnimationStyle(needPopupFadeAnima ? R.style.PopupAnimaFade : 0);
}
public boolean getNeedPopupFade() {
return this.needPopupFadeAnima;
}
/**
* 设置popup的动画style
*/
public void setPopupAnimaStyle(int animaStyleRes) {
if (animaStyleRes > 0) {
mPopupWindow.setAnimationStyle(animaStyleRes);
}
}
//------------------------------------------showPopup-----------------------------------------------
/**
* 调用此方法时,PopupWindow将会显示在DecorView
*/
public void showPopupWindow() {
try {
tryToShowPopup(0, null);
} catch (Exception e) {
Log.e(TAG, "show error");
e.printStackTrace();
}
}
public void showPopupWindow(int res) {
try {
tryToShowPopup(res, null);
} catch (Exception e) {
Log.e(TAG, "show error");
e.printStackTrace();
}
}
public void showPopupWindow(View v) {
try {
tryToShowPopup(0, v);
} catch (Exception e) {
Log.e(TAG, "show error");
e.printStackTrace();
}
}
//------------------------------------------Methods-----------------------------------------------
private void tryToShowPopup(int res, View v) throws Exception {
//传递了view
if (res == 0 && v != null) {
mPopupWindow.showAtLocation(v, Gravity.CENTER, 0, 0);
}
//传递了res
if (res != 0 && v == null) {
mPopupWindow.showAtLocation(mContext.findViewById(res), Gravity.CENTER, 0, 0);
}
//什么都没传递,取顶级view的id
if (res == 0 && v == null) {
mPopupWindow.showAtLocation(mContext.findViewById(android.R.id.content), Gravity.CENTER, 0, 0);
}
if (curAnima != null && mAnimaView != null) {
mAnimaView.clearAnimation();
mAnimaView.startAnimation(curAnima);
}
if (curAnima == null && curAnimator != null && mAnimaView != null) {
curAnimator.start();
}
//自动弹出键盘
if (autoShowInputMethod && getInputView() != null) {
getInputView().requestFocus();
InputMethodUtils.showInputMethod(getInputView(), 150);
}
}
/**
* PopupWindow是否需要自适应输入法,为输入法弹出让出区域
*
* @param needAdjust <br>
* ture for "SOFT_INPUT_ADJUST_RESIZE" mode<br>
* false for "SOFT_INPUT_ADJUST_NOTHING" mode
*/
public void setAdjustInputMethod(boolean needAdjust) {
if (needAdjust) {
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
} else {
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
}
}
/**
* 当PopupWindow展示的时候,这个参数决定了是否自动弹出输入法
* 如果使用这个方法,您必须保证通过 <strong>getInputView()<strong/>得到一个EditTextView
*/
public void setAutoShowInputMethod(boolean autoShow) {
this.autoShowInputMethod = autoShow;
if (autoShow) {
setAdjustInputMethod(true);
} else {
setAdjustInputMethod(false);
}
}
/**
* 这个参数决定点击返回键是否可以取消掉PopupWindow
*/
public void setBackPressEnable(boolean backPressEnable) {
if (backPressEnable) {
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
} else {
mPopupWindow.setBackgroundDrawable(null);
}
}
/**
* 这个方法封装了LayoutInflater.from(context).inflate,方便您设置PopupWindow所用的xml
*
* @param resId reference of layout
* @return root View of the layout
*/
public View getPopupViewById(int resId) {
if (resId != 0) {
return LayoutInflater.from(mContext).inflate(resId, null);
} else {
return null;
}
}
protected View findViewById(int id) {
if (mPopupView != null && id != 0) {
return mPopupView.findViewById(id);
}
return null;
}
/**
* 是否允许popupwindow覆盖屏幕(包含状态栏)
*/
public void setPopupWindowFullScreen(boolean needFullScreen) {
fitPopupWindowOverStatusBar(needFullScreen);
}
/**
* 这个方法用于简化您为View设置OnClickListener事件,多个View将会使用同一个点击事件
*/
protected void setViewClickListener(View.OnClickListener listener, View... views) {
for (View view : views) {
if (view != null && listener != null) {
view.setOnClickListener(listener);
}
}
}
private void fitPopupWindowOverStatusBar(boolean needFullScreen) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
Field mLayoutInScreen = PopupWindow.class.getDeclaredField("mLayoutInScreen");
mLayoutInScreen.setAccessible(true);
mLayoutInScreen.set(mPopupWindow, needFullScreen);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
//------------------------------------------Getter/Setter-----------------------------------------------
/**
* PopupWindow是否处于展示状态
*/
public boolean isShowing() {
return mPopupWindow.isShowing();
}
public OnDismissListener getOnDismissListener() {
return mOnDismissListener;
}
public void setOnDismissListener(OnDismissListener onDismissListener) {
mOnDismissListener = onDismissListener;
if (mOnDismissListener != null) {
mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
mOnDismissListener.onDismiss();
}
});
}
}
//------------------------------------------状态控制-----------------------------------------------
/**
* 取消一个PopupWindow,如果有退出动画,PopupWindow的消失将会在动画结束后执行
*/
public void dismiss() {
try {
if (curExitAnima != null && mAnimaView != null) {
if (!isExitAnimaPlaying) {
curExitAnima.setAnimationListener(mAnimationListener);
mAnimaView.clearAnimation();
mAnimaView.startAnimation(curExitAnima);
isExitAnimaPlaying = true;
}
} else if (curExitAnimator != null) {
if (!isExitAnimaPlaying) {
curExitAnimator.removeListener(mAnimatorListener);
curExitAnimator.addListener(mAnimatorListener);
curExitAnimator.start();
isExitAnimaPlaying = true;
}
} else {
mPopupWindow.dismiss();
}
} catch (Exception e) {
Log.d(TAG, "dismiss error");
}
}
/**
* 直接消掉popup而不需要动画
*/
public void dismissWithOutAnima() {
try {
if (curExitAnima != null && mAnimaView != null) mAnimaView.clearAnimation();
if (curExitAnimator != null) curExitAnimator.removeAllListeners();
mPopupWindow.dismiss();
} catch (Exception e) {
Log.d(TAG, "dismiss error");
}
}
//------------------------------------------Anima-----------------------------------------------
private Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
mPopupWindow.dismiss();
isExitAnimaPlaying = false;
}
@Override
public void onAnimationCancel(Animator animation) {
isExitAnimaPlaying = false;
}
@Override
public void onAnimationRepeat(Animator animation) {
}
};
private Animation.AnimationListener mAnimationListener = new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mPopupWindow.dismiss();
isExitAnimaPlaying = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
};
/**
* 生成TranslateAnimation
*
* @param durationMillis 动画显示时间
* @param start 初始位置
*/
protected Animation getTranslateAnimation(int start, int end, int durationMillis) {
Animation translateAnimation = new TranslateAnimation(0, 0, start, end);
translateAnimation.setDuration(durationMillis);
translateAnimation.setFillEnabled(true);
translateAnimation.setFillAfter(true);
return translateAnimation;
}
protected Animation hideTranslateAnimation(int start, int end, int durationMillis){
Animation translateAnimation = new TranslateAnimation(0, 0, start, end);
translateAnimation.setDuration(durationMillis);
translateAnimation.setFillEnabled(true);
translateAnimation.setFillAfter(true);
return translateAnimation;
}
/**
* 生成ScaleAnimation
*/
protected Animation getScaleAnimation(float fromX,
float toX,
float fromY,
float toY,
int pivotXType,
float pivotXValue,
int pivotYType,
float pivotYValue) {
Animation scaleAnimation = new ScaleAnimation(fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType,
pivotYValue
);
scaleAnimation.setDuration(300);
scaleAnimation.setFillEnabled(true);
scaleAnimation.setFillAfter(true);
return scaleAnimation;
}
/**
* 生成自定义ScaleAnimation
*/
protected Animation getDefaultScaleAnimation() {
Animation scaleAnimation = new ScaleAnimation(0f, 1f, 0f, 1f, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f
);
scaleAnimation.setDuration(300);
scaleAnimation.setInterpolator(new AccelerateInterpolator());
scaleAnimation.setFillEnabled(true);
scaleAnimation.setFillAfter(true);
return scaleAnimation;
}
/**
* 生成默认的AlphaAnimation
*/
protected Animation getDefaultAlphaAnimation() {
Animation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
alphaAnimation.setDuration(300);
alphaAnimation.setInterpolator(new AccelerateInterpolator());
alphaAnimation.setFillEnabled(true);
alphaAnimation.setFillAfter(true);
return alphaAnimation;
}
/**
* 从下方滑动上来
*/
protected AnimatorSet getDefaultSlideFromBottomAnimationSet() {
AnimatorSet set = null;
set = new AnimatorSet();
if (mAnimaView != null) {
set.playTogether(
ObjectAnimator.ofFloat(mAnimaView, "translationY", 250, 0).setDuration(400),
ObjectAnimator.ofFloat(mAnimaView, "alpha", 0.4f, 1).setDuration(250 * 3 / 2)
);
}
return set;
}
//------------------------------------------Interface-----------------------------------------------
public interface OnDismissListener {
void onDismiss();
}
}