先上效果图
这里的主要思想是,让popupwindow不获取焦点,然后在activity中处理各个点击事件,另外用两个属性动画来实现.请看下面代码
有哥们可能会问,不让popupwindow获取焦点会不会影响view的点击等,我下边就是使用点击事件,并且还实现了夜间模式
public class HomePopupWindowManager implements View.OnClickListener{
public static final int DURATION_START = 200;
public static final int DURATION_END = 200;
private Context mContext;
private PopupWindow pw;
private View contentView;
@BindView(R.id.id_ll_root)
RelativeLayout id_ll_root;
@BindView(R.id.id_ll_empty)
LinearLayout id_ll_empty;
@BindView(R.id.id_ll_content)
LinearLayout id_ll_content;
@BindView(R.id.id_share)
ImageTextViewGroup id_share;
@BindView(R.id.id_clean_cache)
ImageTextViewGroup id_clean_cache;
@BindView(R.id.id_add_shortcut)
ImageTextViewGroup id_add_shortcut;
@BindView(R.id.id_night_mode)
ImageTextViewGroup id_night_mode;
@BindView(R.id.id_check_update)
ImageTextViewGroup id_check_update;
@BindView(R.id.id_feedback)
ImageTextViewGroup id_feedback;
@BindView(R.id.id_about)
ImageTextViewGroup id_about;
@BindView(R.id.id_exit)
ImageTextViewGroup id_exit;
//平移的高度
private int translationY = MetricsUtils.dip2px(180);
private int emptyHeight = MetricsUtils.dip2px(45);
//退出动画
private ObjectAnimator mContentHiddrenAnim;
private ObjectAnimator mHeadHiddrenAnim;
//开始动画
private ObjectAnimator mContentStartAnim;
private ObjectAnimator mHeadStartAnim;
public HomePopupWindowManager(Context context) {
this.mContext = context;
init();
startAnim();
exitAnim();
}
private void init() {
contentView = LayoutInflater.from(mContext).inflate(R.layout.layout_home_more, null);
ButterKnife.bind(this, contentView);
pw = new PopupWindow(contentView, RelativeLayout.LayoutParams.MATCH_PARENT, MobileScreenUtils.getScreenHeight(mContext) - emptyHeight);
pw.setOutsideTouchable(true);//设置点击其他区域也会消失
}
public void showPopupWindow(View rootView) {
if (pw != null) {
enterStartAnim();
// 显示 -emptyHeight
pw.showAtLocation(rootView, Gravity.NO_GRAVITY, 0, -emptyHeight);
}
}
/**
* 判断是否正在显示
*
* @return
*/
public boolean isShow() {
if (pw != null) {
return pw.isShowing();
}
return false;
}
@OnClick({R.id.id_ll_empty, R.id.id_share, R.id.id_clean_cache,
R.id.id_add_shortcut, R.id.id_night_mode, R.id.id_check_update,
R.id.id_feedback, R.id.id_about, R.id.id_exit})
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.id_ll_empty:
exitStartAnim();
break;
case R.id.id_share:
//分享
break;
case R.id.id_clean_cache:
//清除缓存
exitAnim();
break;
case R.id.id_add_shortcut:
//添加桌面快捷方式
break;
case R.id.id_night_mode:
//夜间模式
boolean modeNight = SharedPreferencesHelper.getInstance(mContext).getBoolean(SharedPreferencesHelper.SP_KEY_MODE_NIGHT,false);
if(modeNight){
//白天模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
((MainActivity)mContext).getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
SharedPreferencesHelper.getInstance(mContext).putBoolean(SharedPreferencesHelper.SP_KEY_MODE_NIGHT,false);
}else{
//使用夜间模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
((MainActivity)mContext).getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
SharedPreferencesHelper.getInstance(mContext).putBoolean(SharedPreferencesHelper.SP_KEY_MODE_NIGHT,true);
}
((MainActivity)mContext).recreate();
break;
case R.id.id_check_update:
//检查更新
break;
case R.id.id_feedback:
//意见反馈
break;
case R.id.id_about:
exitStartAnim();
break;
case R.id.id_exit:
exitStartAnim();
break;
}
}
/**
* 开始退出动画
*/
public void exitStartAnim() {
mContentHiddrenAnim.start();
mHeadHiddrenAnim.start();
}
/***
* 开始进入动画
*/
private void enterStartAnim() {
mContentStartAnim.start();
mHeadStartAnim.start();
}
/***
* popupwindow进入动画
*/
public void startAnim() {
if (mContentStartAnim == null && mHeadStartAnim == null) {
mContentStartAnim = ObjectAnimator.ofFloat(id_ll_content, "translationY",
translationY, 0);
mHeadStartAnim = ObjectAnimator.ofFloat(id_ll_empty, "alpha", 0f, 1f);
mContentStartAnim.setDuration(DURATION_START);
mHeadStartAnim.setDuration(DURATION_START);
}
}
/***
* popupwindow退出动画
*/
public void exitAnim() {
if (mContentHiddrenAnim == null && mHeadHiddrenAnim == null) {
mContentHiddrenAnim = ObjectAnimator.ofFloat(id_ll_content,
"translationY", 0, translationY);
mHeadHiddrenAnim = ObjectAnimator.ofFloat(id_ll_empty, "alpha", 1f, 0f);
mHeadHiddrenAnim.setDuration(DURATION_END);
mContentHiddrenAnim.setDuration(DURATION_END);
mContentHiddrenAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// 等待动画执行完毕关闭popupwindow
pw.dismiss();
}
});
}
}
}
在mainActivity中的用法如下
public class MainActivity extends BaseActivity implements View.OnClickListener {
public static final String PATH = "https://www.baidu.com/";
private ImageView iv_back;
private ImageView iv_forward;
private ImageView iv_home;
private ImageView iv_close;
private ImageView iv_more;
private HomePopupWindowManager mPopupWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
private void initEvent() {
iv_back.setOnClickListener(this);
iv_forward.setOnClickListener(this);
iv_home.setOnClickListener(this);
iv_close.setOnClickListener(this);
iv_more.setOnClickListener(this);
}
private void initView() {
iv_back = (ImageView) findViewById(R.id.id_iv_back);
iv_forward = (ImageView) findViewById(R.id.id_iv_forward);
iv_home = (ImageView) findViewById(R.id.id_iv_home);
iv_close = (ImageView) findViewById(R.id.id_iv_close);
iv_more = (ImageView) findViewById(R.id.id_iv_more);
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.id_iv_back:
mPopupWindow.exitStartAnim();
break;
case R.id.id_iv_forward:
mPopupWindow.exitStartAnim();
break;
case R.id.id_iv_home:
mPopupWindow.exitStartAnim();
break;
case R.id.id_iv_close:
mPopupWindow.exitStartAnim();
break;
case R.id.id_iv_more:
if (mPopupWindow == null) {
mPopupWindow = new HomePopupWindowManager(MainActivity.this);
}
if (mPopupWindow.isShow()) {
mPopupWindow.exitStartAnim();
} else {
mPopupWindow.showPopupWindow(v);
}
break;
}
}
@Override
public void onBackPressed() {
if (mPopupWindow != null && mPopupWindow.isShow()) {
mPopupWindow.exitStartAnim();
} else {
super.onBackPressed();
}
}
}
另外注意,当我们需要响应back键并且执行一些动画然后再关闭的时候可以使用下面方法
第一步:先不设置popupwindow的setBackgroundDrawable方法
第二步:获取popupwindow的布局文件的最外层layout,设置它的keyListener
rl_root.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
System.out.println("获取back键");
//执行砸门自己的操作,等操作执行完毕之后再关闭popupwindow,这里可以使用回调
}
return false;
}
});