popupWindow控件可以在任意位置弹出,比Dialog灵活,而且popupWindow还可以自定义弹出动画,更加美观,灵动。
下面是效果图1,从按钮底下弹出按钮,并且点击按钮外便可取消。
下面是从页面最底部弹出以及从最底部取消效果图
xml布局
主要的activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">
<Button
android:id="@+id/id_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="从当前按钮下面弹出"/>
<Button
android:id="@+id/id_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginLeft="10dp"
android:text="从页面底部弹出两个textview"/>
</LinearLayout>
要弹出来的两个xml文件
(1)从按钮底部弹出的xml文件,popup_dropdown.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/id_dropdown_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是从上面按钮点击后弹出的"/>
</LinearLayout>
(2)从页面底部弹出的xml的文件,popup_bottom.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="wrap_content"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="确认"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="取消"/>
</LinearLayout>
(3)弹出动画所需要的xml文件
style.xml
<style name="Animation_Bottom_Dialog">
<item name="android:windowEnterAnimation">@anim/bottom_dialog_enter</item>
<item name="android:windowExitAnimation">@anim/bottom_dialog_exit</item>
</style>
bottom_dialog_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration = "255"
android:fromYDelta="100%"
android:toYDelta="0%"
android:interpolator = "@android:anim/accelerate_decelerate_interpolator"/>
bottom_dialog_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration = "255"
android:fromYDelta="0%"
android:toYDelta="100%"
android:interpolator = "@android:anim/accelerate_decelerate_interpolator"/>
android:duration 动画运行时间,时间单位为毫秒
android:fromYDelta 动画开始时y轴上的坐标
android:toYDelta 动画结束后y轴上的坐标
android:interpolator 动画效果,定义动画的变化率,可以有加速,减速,重复,弹跳等等
代码逻辑:
package com.gentle.popupwindow;
import android.app.AlertDialog;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.TestLooperManager;
import android.text.Layout;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button btnDown;
private Button btnBottom;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnDown = findViewById(R.id.id_down);
btnDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDropPopupWindow();
}
});
btnBottom = findViewById(R.id.id_bottom);
btnBottom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showBottomPopupWindow();
}
});
}
/*从按钮底部弹出*/
private void showDropPopupWindow(){
/*将xml资源加载成一个view对象*/
View popupView = LayoutInflater.from(this).inflate(R.layout.popup_dropdowm,null);
/*根据view创建一个popup弹窗,弹窗大小根据view的自身控件大小*/
PopupWindow popupWindow = new PopupWindow(popupView, LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
/*点击弹出控件之外的地方取消弹出,该选项需要设置背景颜色才能生效*/
popupWindow.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
/*弹出位置在btnDown控件下面弹出,100为x轴偏移量,0为y轴偏移量*/
popupWindow.showAsDropDown(btnDown,100,0);
}
private void showBottomPopupWindow(){
View popupBottomView = LayoutInflater.from(this).inflate(R.layout.popup_bottom,null);
PopupWindow popupWindowBottom = new PopupWindow(popupBottomView,LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
popupWindowBottom.setOutsideTouchable(true);
popupWindowBottom.setBackgroundDrawable(new ColorDrawable(0xff00ff00));
/*设置动画样式*/
popupWindowBottom.setAnimationStyle(R.style.Animation_Bottom_Dialog);
/*设置显示位置,参数1获取目前windos最顶层的view,参数2说明动画的原定位置从底部,0,0分为x,y轴偏移量*/
popupWindowBottom.showAtLocation(getWindow().getDecorView(), Gravity.BOTTOM,0,0);
}
}
声明;本人的代码逻辑完全是参考github上开源源码:
https://github.com/ansen666/PopupWindow,并无抄袭之意,仅仅是参考学习。