国际惯例,先上地址
https://github.com/razerdp/BasePopup
PS:效果图都放在了github,github有着我继承该类做出来的popupWindow
//2016-01-15 目前只写了两个PopupWindow
效果图:
普通的放大缩小:
从下方弹出:
通常情况下,面对各种浮动窗口,选择窗口什么的,我们通常都是使用popupWindow,但是很多时候我们都希望popupWindow可以在弹出的时候带有动画,但是就popup本身而言,使用的动画是在是太不舒服不自由了。
通常情况下,我们弄个popupWindow的动画都是这么玩的
popupWindow.setAnimationStyle(R.style.PopMenuAnimation);
我们还得去styles.xml弄弄我们的进入/退出动画,这多不自然啊,而且说好的控制呢对吧
于是这次我们就来打造一个通用的popupWindow,让我们可以随心自由的设置我们的popupWindow
这次我们要实现的popupWindow起码要实现以下几个要求{
public abstract class BasePopupWindow implements ViewCreate {
private static final String TAG = "BasePopupWindow";
//元素定义
protected PopupWindow mPopupWindow;
//popup视图
protected View mPopupView;
protected Activity mContext;
//是否自动弹出输入框(default:false)
private boolean autoShowInputMethod = false;
private OnDismissListener mOnDismissListener;
public BasePopupWindow(Activity context) {
mContext = context;
mPopupView = getPopupView();
mPopupView.setFocusable(true);
mPopupView.setFocusableInTouchMode(true);
//默认占满全屏
mPopupWindow =
new PopupWindow(mPopupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//指定透明背景,点击外面相关
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
//无需动画
mPopupWindow.setAnimationStyle(0);
}
public BasePopupWindow(Activity context, int w, int h) {
mContext = context;
mPopupView = getPopupView();
mPopupView.setFocusable(true);
mPopupView.setFocusableInTouchMode(true);
//默认占满全屏
mPopupWindow = new PopupWindow(mPopupView, w, h);
//指定透明背景,点击外面相关
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
//无需动画
mPopupWindow.setAnimationStyle(0);
}
/**
* Created by 大灯泡 on 2016/1/14.
*/
public interface ViewCreate {
View getPopupView();
View getAnimaView();
}
//------------------------------------------抽象-----------------------------------------------
public abstract Animation getAnimation();
public abstract AnimationSet getAnimationSet();
public abstract View getInputView();
//------------------------------------------showPopup-----------------------------------------------
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.RIGHT | Gravity.CENTER_HORIZONTAL, 0, 0);
}
//传递了res
if (res != 0 && v == null) {
mPopupWindow.showAtLocation(mContext.findViewById(res), Gravity.RIGHT | Gravity.CENTER_HORIZONTAL, 0, 0);
}
//什么都没传递,取顶级view的id
if (res == 0 && v == null) {
mPopupWindow.showAtLocation(mContext.findViewById(android.R.id.content),
Gravity.RIGHT | Gravity.CENTER_HORIZONTAL,
0,
0
);
}
if (getAnimation() != null && getAnimaView() != null) {
getAnimaView().startAnimation(getAnimation());
}
//ViewHelper.setPivotX是包nineoldAndroid的方法,用于兼容低版本的anima以及方便的view工具
if (getAnimation() == null && getAnimationSet() != null && getAnimaView() != null &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ViewHelper.setPivotX(getAnimaView(), getAnimaView().getMeasuredWidth() / 2.0f);
ViewHelper.setPivotY(getAnimaView(), getAnimaView().getMeasuredHeight() / 2.0f);
getAnimationSet().start();
}
//自动弹出键盘
if (autoShowInputMethod && getInputView() != null) {
InputMethodUtils.showInputMethod(getInputView(), 150);
}
}
/**
* Created by 大灯泡 on 2016/1/14.
* 显示键盘d工具类
*/
public class InputMethodUtils {
/** 显示软键盘 */
public static void showInputMethod(View view) {
InputMethodManager imm = (InputMethodManager) view.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
/** 显示软键盘 */
public static void showInputMethod(Context context) {
InputMethodManager imm = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
/** 多少时间后显示软键盘 */
public static void showInputMethod(final View view, long delayMillis) {
// 显示输入法
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
InputMethodUtils.showInputMethod(view);
}
}, delayMillis);
}
}
package razerdp.basepopup.basepopup;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.util.Log;
import android.view.Gravity;
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.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.PopupWindow;
import com.nineoldandroids.view.ViewHelper;
import razerdp.basepopup.utils.InputMethodUtils;
/**
* Created by 大灯泡 on 2016/1/14.
* 通用的popupWindow
*/
public abstract class BasePopupWindow implements ViewCreate {
private static final String TAG = "BasePopupWindow";
//元素定义
protected PopupWindow mPopupWindow;
//popup视图
protected View mPopupView;
protected Activity mContext;
//是否自动弹出输入框(default:false)
private boolean autoShowInputMethod = false;
private OnDismissListener mOnDismissListener;
public BasePopupWindow(Activity context) {
mContext = context;
mPopupView = getPopupView();
mPopupView.setFocusable(true);
mPopupView.setFocusableInTouchMode(true);
//默认占满全屏
mPopupWindow =
new PopupWindow(mPopupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//指定透明背景,back键相关
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
//无需动画
mPopupWindow.setAnimationStyle(0);
}
public BasePopupWindow(Activity context, int w, int h) {
mContext = context;
mPopupView = getPopupView();
mPopupView.setFocusable(true);
mPopupView.setFocusableInTouchMode(true);
//默认占满全屏
mPopupWindow = new PopupWindow(mPopupView, w, h);
//指定透明背景,back键相关
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
mPopupWindow.setFocusable(true);
mPopupWindow.setOutsideTouchable(true);
//无需动画
mPopupWindow.setAnimationStyle(0);
}
//------------------------------------------抽象-----------------------------------------------
public abstract Animation getAnimation();
public abstract AnimationSet getAnimationSet();
public abstract View getInputView();
//------------------------------------------showPopup-----------------------------------------------
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.RIGHT | Gravity.CENTER_HORIZONTAL, 0, 0);
}
//传递了res
if (res != 0 && v == null) {
mPopupWindow.showAtLocation(mContext.findViewById(res), Gravity.RIGHT | Gravity.CENTER_HORIZONTAL, 0, 0);
}
//什么都没传递,取顶级view的id
if (res == 0 && v == null) {
mPopupWindow.showAtLocation(mContext.findViewById(android.R.id.content),
Gravity.RIGHT | Gravity.CENTER_HORIZONTAL,
0,
0
);
}
if (getAnimation() != null && getAnimaView() != null) {
getAnimaView().startAnimation(getAnimation());
}
//ViewHelper.setPivotX是包nineoldAndroid的方法,用于兼容低版本的anima以及方便的view工具
if (getAnimation() == null && getAnimationSet() != null && getAnimaView() != null &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ViewHelper.setPivotX(getAnimaView(), getAnimaView().getMeasuredWidth() / 2.0f);
ViewHelper.setPivotY(getAnimaView(), getAnimaView().getMeasuredHeight() / 2.0f);
getAnimationSet().start();
}
//自动弹出键盘
if (autoShowInputMethod && getInputView() != null) {
InputMethodUtils.showInputMethod(getInputView(), 150);
}
}
public void setAdjustInputMethod(boolean needAdjust) {
if (needAdjust) {
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
} else {
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
}
}
public void setAutoShowInputMethod(boolean autoShow) {
this.autoShowInputMethod = autoShow;
if (autoShow) {
setAdjustInputMethod(true);
} else {
setAdjustInputMethod(false);
}
}
public void setBackPressEnable(boolean backPressEnable){
if (backPressEnable){
mPopupWindow.setBackgroundDrawable(new ColorDrawable());
}else {
mPopupWindow.setBackgroundDrawable(null);
}
}
//------------------------------------------Getter/Setter-----------------------------------------------
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();
}
});
}
}
//------------------------------------------状态控制-----------------------------------------------
public void dismiss() {
try {
mPopupWindow.dismiss();
} catch (Exception e) {
Log.d(TAG, "dismiss error");
}
}
//------------------------------------------Anima-----------------------------------------------
/**
* 生成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;
}
/**
* 生成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;
}
//------------------------------------------Interface-----------------------------------------------
public interface OnDismissListener {
void onDismiss();
}
}
import android.view.View;
/**
* Created by 大灯泡 on 2016/1/14.
*/
public interface ViewCreate {
View getPopupView();
View getAnimaView();
}
import android.content.Context;
import android.os.Handler;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
/**
* Created by 大灯泡 on 2016/1/14.
* 显示键盘d工具类
*/
public class InputMethodUtils {
/** 显示软键盘 */
public static void showInputMethod(View view) {
InputMethodManager imm = (InputMethodManager) view.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
/** 显示软键盘 */
public static void showInputMethod(Context context) {
InputMethodManager imm = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
/** 多少时间后显示软键盘 */
public static void showInputMethod(final View view, long delayMillis) {
// 显示输入法
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
InputMethodUtils.showInputMethod(view);
}
}, delayMillis);
}
}