欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android控件PopupWindow模仿ios底部弹窗

程序员文章站 2024-03-04 11:39:17
前言 在h5火热的时代,许多框架都出了底部弹窗的控件,在h5被称为弹出菜单actionsheet,今天我们也来模仿一个ios的底部弹窗,取材于苹果qq的选择头像功能。...

前言

在h5火热的时代,许多框架都出了底部弹窗的控件,在h5被称为弹出菜单actionsheet,今天我们也来模仿一个ios的底部弹窗,取材于苹果qq的选择头像功能。

正文

废话不多说,先来个今天要实现的效果图

Android控件PopupWindow模仿ios底部弹窗

整个popupwindow的开启代码

private void openpopupwindow(view v) {
  //防止重复按按钮
  if (popupwindow != null && popupwindow.isshowing()) {
    return;
  }
  //设置popupwindow的view
  view view = layoutinflater.from(this).inflate(r.layout.view_popupwindow, null);
  popupwindow = new popupwindow(view, relativelayout.layoutparams.match_parent,
      relativelayout.layoutparams.wrap_content);
  //设置背景,这个没什么效果,不添加会报错
  popupwindow.setbackgrounddrawable(new bitmapdrawable());
  //设置点击弹窗外隐藏自身
  popupwindow.setfocusable(true);
  popupwindow.setoutsidetouchable(true);
  //设置动画
  popupwindow.setanimationstyle(r.style.popupwindow);
  //设置位置
  popupwindow.showatlocation(v, gravity.bottom, 0, navigationheight);
  //设置消失监听
  popupwindow.setondismisslistener(this);
  //设置popupwindow的view点击事件
  setonpopupviewclick(view);
  //设置背景色
  setbackgroundalpha(0.5f);
}

步骤分析:

popupwindow的布局
popupwindow的创建
popupwindow添加动画效果
popupwindow设置背景阴影
popupwindow监听点击事件
获取navigationbar的高度

popupwindow的布局:在layout中,设计我们需要的布局

<?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="wrap_content" android:orientation="vertical">

  <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:background="@drawable/popup_shape" android:orientation="vertical">

    <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="16dp" android:text="你可以将照片上传至照片墙" android:textcolor="#666" android:textsize="14sp" />

    <view android:layout_width="match_parent" android:layout_height="0.1px" android:background="#888" />

    <textview android:id="@+id/tv_pick_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="16dp" android:text="从手机相册选择" android:textcolor="#118" android:textsize="18sp" />

    <view android:layout_width="match_parent" android:layout_height="0.1px" android:background="#888" />

    <textview android:id="@+id/tv_pick_zone" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="16dp" android:text="从空间相册选择" android:textcolor="#118" android:textsize="18sp" />
  </linearlayout>

  <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:background="@drawable/popup_shape">

    <textview android:id="@+id/tv_cancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="16dp" android:text="取消" android:textcolor="#118" android:textsize="18sp" android:textstyle="bold" />
  </linearlayout>
</linearlayout>

其效果是:

Android控件PopupWindow模仿ios底部弹窗

popupwindow的创建:这个创建与我们普通的控件创建方法是一样的

//设置popupwindow的view
view view = layoutinflater.from(this).inflate(r.layout.view_popupwindow, null);
popupwindow = new popupwindow(view, relativelayout.layoutparams.match_parent,
        relativelayout.layoutparams.wrap_content);

popupwindow添加动画效果:我们创建一个anim文件夹,创建我们的out和in动画效果,然后在style添加我们的动画

<?xml version="1.0" encoding="utf-8"?>
<!--进入动画-->
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" android:fromydelta="100%" android:toydelta="0" android:duration="200"/>

<?xml version="1.0" encoding="utf-8"?>
<!--退出动画-->
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" android:fromydelta="0" android:toydelta="100%" android:duration="200"/>

<!--弹窗动画-->
<style name="popupwindow"> <item name="android:windowenteranimation">@anim/window_in</item> <item name="android:windowexitanimation">@anim/window_out</item> </style>

//设置动画
popupwindow.setanimationstyle(r.style.popupwindow);

popupwindow设置背景阴影:弹窗打开时设置透明度为0.5,弹窗消失时设置透明度为1

//设置屏幕背景透明效果
public void setbackgroundalpha(float alpha) {
  windowmanager.layoutparams lp = getwindow().getattributes();
  lp.alpha = alpha;
  getwindow().setattributes(lp);
}

popupwindow监听点击事件:监听我们popupwindow里面控件的点击事件

//设置popupwindow的view点击事件
setonpopupviewclick(view);

private void setonpopupviewclick(view view) {
  textview tv_pick_phone, tv_pick_zone, tv_cancel;
  tv_pick_phone = (textview) view.findviewbyid(r.id.tv_pick_phone);
  tv_pick_zone = (textview) view.findviewbyid(r.id.tv_pick_zone);
  tv_cancel = (textview) view.findviewbyid(r.id.tv_cancel);
  tv_pick_phone.setonclicklistener(this);
  tv_pick_zone.setonclicklistener(this);
  tv_cancel.setonclicklistener(this);
}

获取navigationbar的高度:这里需要适配有些手机没有navigationbar有些手机有,这里以存在navigationbar来演示
int resourceid = getresources().getidentifier("navigation_bar_height", "dimen", "android");
navigationheight = getresources().getdimensionpixelsize(resourceid);

对存在navigationbar的手机上,设置其popupwindow的出现位置
//设置位置
popupwindow.showatlocation(v, gravity.bottom, 0, navigationheight);

对没有navigationbar的手机上,设置其popupwindow的出现位置
//设置位置
popupwindow.showatlocation(v, gravity.bottom, 0, 0);

源码

github:https://github.com/androidhensen/iospopupwindow

public class mainactivity extends appcompatactivity implements view.onclicklistener, popupwindow.ondismisslistener {

  private button bt_open;
  private popupwindow popupwindow;
  private int navigationheight;

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);

    bt_open = (button) findviewbyid(r.id.bt_open);
    bt_open.setonclicklistener(this);

    int resourceid = getresources().getidentifier("navigation_bar_height", "dimen", "android");
    navigationheight = getresources().getdimensionpixelsize(resourceid);
  }

  @override
  public void onclick(view v) {
    switch (v.getid()) {
      case r.id.bt_open:
        openpopupwindow(v);
        break;
      case r.id.tv_pick_phone:
        toast.maketext(this, "从手机相册选择", toast.length_short).show();
        popupwindow.dismiss();
        break;
      case r.id.tv_pick_zone:
        toast.maketext(this, "从空间相册选择", toast.length_short).show();
        popupwindow.dismiss();
        break;
      case r.id.tv_cancel:
        popupwindow.dismiss();
        break;
    }
  }

  private void openpopupwindow(view v) {
    //防止重复按按钮
    if (popupwindow != null && popupwindow.isshowing()) {
      return;
    }
    //设置popupwindow的view
    view view = layoutinflater.from(this).inflate(r.layout.view_popupwindow, null);
    popupwindow = new popupwindow(view, relativelayout.layoutparams.match_parent,
        relativelayout.layoutparams.wrap_content);
    //设置背景,这个没什么效果,不添加会报错
    popupwindow.setbackgrounddrawable(new bitmapdrawable());
    //设置点击弹窗外隐藏自身
    popupwindow.setfocusable(true);
    popupwindow.setoutsidetouchable(true);
    //设置动画
    popupwindow.setanimationstyle(r.style.popupwindow);
    //设置位置
    popupwindow.showatlocation(v, gravity.bottom, 0, navigationheight);
    //设置消失监听
    popupwindow.setondismisslistener(this);
    //设置popupwindow的view点击事件
    setonpopupviewclick(view);
    //设置背景色
    setbackgroundalpha(0.5f);
  }

  private void setonpopupviewclick(view view) {
    textview tv_pick_phone, tv_pick_zone, tv_cancel;
    tv_pick_phone = (textview) view.findviewbyid(r.id.tv_pick_phone);
    tv_pick_zone = (textview) view.findviewbyid(r.id.tv_pick_zone);
    tv_cancel = (textview) view.findviewbyid(r.id.tv_cancel);
    tv_pick_phone.setonclicklistener(this);
    tv_pick_zone.setonclicklistener(this);
    tv_cancel.setonclicklistener(this);
  }

  //设置屏幕背景透明效果
  public void setbackgroundalpha(float alpha) {
    windowmanager.layoutparams lp = getwindow().getattributes();
    lp.alpha = alpha;
    getwindow().setattributes(lp);
  }

  @override
  public void ondismiss() {
    setbackgroundalpha(1);
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。