效果图
第一种(图一)基本使用
分装一个设置的类 WrapPopupWindow
package com.zhh.android.demo.tools;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
/**
* Created by 16838 on 2019/1/5.
*/
public class WrapPopupWindow {
// 设置布局
public static View createView(Context context,int resource){
View view = LayoutInflater.from(context).inflate(resource, null, false);
return view;
}
// 设置popupWindow
public static PopupWindow setPopupWindow(View view){
//1.构造一个PopupWindow,参数依次是加载的View,宽高
final PopupWindow popupWindow = new PopupWindow(view,
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
//设置加载动画
// popupWindow.setAnimationStyle(R.style.AnimBottom);
//这些为了点击非PopupWindow区域,PopupWindow会消失的,如果没有下面的
//代码的话,你会发现,当你把PopupWindow显示出来了,无论你按多少次后退键
//PopupWindow并不会关闭,而且退不出程序,加上下述代码可以解决这个问题
popupWindow.setTouchable(true);
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
// 这里如果返回true的话,touch事件将被拦截
// 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss
// 拦截后,泡泡窗口子控件的点击事件等,失效
}
});
popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000)); //要为popWindow设置一个背景才有效
return popupWindow;
}
}
Activity中调用
private void setPopopWindow(){
// 设置布局
View view = WrapPopupWindow.createView(context, R.layout.item_popup_wrap);
// 拿到设置后的 PopupWindow 对象
final PopupWindow popupWindow = WrapPopupWindow.setPopupWindow(view);
// 展示
popupWindow.showAsDropDown(buttonShow,50,0);
Button btn_xixi = (Button) view.findViewById(R.id.btn_xixi);
Button btn_hehe = (Button) view.findViewById(R.id.btn_hehe);
btn_xixi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
Toast.makeText(context, "嘻嘻", Toast.LENGTH_SHORT).show();
}
});
btn_hehe.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
Toast.makeText(context, "呵呵", Toast.LENGTH_SHORT).show();
}
});
}
PopupWindow的布局文件 item_popup_wrap.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"
android:background="@drawable/ic_pop_bg"
>
<Button
android:id="@+id/btn_xixi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="嘻嘻"
android:textSize="18sp" />
<Button
android:id="@+id/btn_hehe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="呵呵"
android:textSize="18sp" />
</LinearLayout>
ok,讲完了
第二种(图二)底部滑入
封装一个设置的类 MatchPopupWindow
package com.zhh.android.demo.tools;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
/**
* Created by 16838 on 2019/1/5.
*/
public class MatchPopupWindow {
// 设置布局
public static View createView(Context context,int resource){
View view = LayoutInflater.from(context).inflate(resource, null, false);
return view;
}
// 设置popupWindow
public static PopupWindow setPopupWindow(View view){
// 构造一个PopupWindow,参数依次是加载的View,宽高
final PopupWindow popupWindow = new PopupWindow(view,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
// 点击空白处关闭
popupWindow.setOutsideTouchable(true);
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
// 这里如果返回true的话,touch事件将被拦截
// 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss
// 拦截后,泡泡窗口子控件的点击事件等,失效
}
});
return popupWindow;
}
}
在activity中调用
private void setPopup(){
// 从底部划入必须拿到系统内置的这个控件,在展示的时候传入
View parent = ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0);
// 泡泡窗口的布局文件
View view = MatchPopupWindow.createView(context, R.layout.item_popup_bottom);
// 实例化泡泡窗口对象,并且设置宽高
final PopupWindow popupWindow = MatchPopupWindow.setPopupWindow(view);
// 设置出入动画
popupWindow.setAnimationStyle(R.style.AnimBottom);
// 展示位置
popupWindow.showAtLocation(parent, Gravity.BOTTOM, 0, 0);
backgroundAlpha(0.5f);
// 拿到里面的子控件
Button button1 = (Button) view.findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
backgroundAlpha(1f);
}
});
}
/**
* 设置遮罩层
* @param f
*/
private void backgroundAlpha(float f) {
WindowManager.LayoutParams lp =getWindow().getAttributes();
lp.alpha = f;
getWindow().setAttributes(lp);
}
动画 res ---- values----styles.xml
<!--泡泡窗口的 出入动画-->
<style name="AnimBottom" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
<item name="android:windowExitAnimation">@anim/push_bottom_out</item>
</style>
push_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="250"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="250"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
push_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="250"
android:fromYDelta="0"
android:toYDelta="100%p" />
<alpha
android:duration="250"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
PopupWindow的布局文件 item_popup_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true"
>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭"
/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="内容2"
/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="内容3"
/>
</LinearLayout>
</RelativeLayout>
ok,讲完了
第三种(图三)菜单样式
封装一个设置的类 MatchPopupWindow 和上面一样
在activity中调用
package com.zhh.android.demo.activity;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.zhh.android.R;
import com.zhh.android.demo.tools.MatchPopupWindow;
import java.util.ArrayList;
import java.util.List;
/**
* 写一个泡泡窗口的例子
*/
public class PopupWindowActivity extends Activity {
private Context context;
// 标题栏的布局
private RelativeLayout relativeLayout1;
private RelativeLayout relativeLayout2;
// 标题栏的文字
private TextView textView1;
private TextView textView2;
// 标题栏的图片
private ImageView imageView1;
private ImageView imageView2;
// 存放TextView的数组
private List<TextView> tvList = new ArrayList<>();
// 存放imageView的数组
private List<ImageView> ivList = new ArrayList<>();
// 遮罩层
private View zhezhaoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup_window);
context = PopupWindowActivity.this;
zhezhaoView = findViewById(R.id.view);
relativeLayout1 = (RelativeLayout)findViewById(R.id.relativeLayout1);
relativeLayout2 = (RelativeLayout)findViewById(R.id.relativeLayout2);
textView1 = (TextView)findViewById(R.id.textView1);
textView2 = (TextView)findViewById(R.id.textView2);
imageView1 = (ImageView)findViewById(R.id.imageView1);
imageView2 = (ImageView)findViewById(R.id.imageView2);
tvList.add(textView1);
tvList.add(textView2);
ivList.add(imageView1);
ivList.add(imageView2);
relativeLayout1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 第一个
setPopup(R.id.textView1);
}
});
relativeLayout2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 点击第二个
setPopup(R.id.textView2);
}
});
}
private void setPopup(final int id) {
// 拿到view
View view = MatchPopupWindow.createView(context, R.layout.item_popup_layout);
// 泡泡窗口的设置
final PopupWindow popupWindow = MatchPopupWindow.setPopupWindow(view);
// 展示
popupWindow.showAsDropDown(relativeLayout1, 0, 1);
zhezhaoView.setVisibility(View.VISIBLE);
// 监听泡泡窗口消失
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
// 全部变暗
for (int i = 0; i < tvList.size(); i++) {
tvList.get(i).setTextColor(Color.parseColor("#666666"));
ivList.get(i).setImageResource(R.mipmap.xlico_off);
zhezhaoView.setVisibility(View.GONE);
}
}
});
// 展示的泡泡窗口的点亮,标题上面的字和图片
for(int i = 0; i < tvList.size(); i++) {
if(tvList.get(i).getId()==id) {
// 展示泡泡窗口的点亮
tvList.get(i).setTextColor(Color.parseColor("#0078d7"));
ivList.get(i).setImageResource(R.mipmap.xlico);
}else{
// 其余的变暗
tvList.get(i).setTextColor(Color.parseColor("#666666"));
ivList.get(i).setImageResource(R.mipmap.xlico_off);
}
}
// 拿到泡泡窗口中子控件的点击事件
final TextView tvSon1 = (TextView) view.findViewById(R.id.tvSon1);
final TextView tvSon2 = (TextView) view.findViewById(R.id.tvSon2);
final TextView tvSon3 = (TextView) view.findViewById(R.id.tvSon3);
final TextView tvSon4 = (TextView) view.findViewById(R.id.tvSon4);
tvSon1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
// 展示的泡泡窗口的点亮,上面的字和图片
for (int i = 0; i < tvList.size(); i++) {
if (tvList.get(i).getId() == id) {
// 设置标题的值
tvList.get(i).setText(tvSon1.getText() + "");
zhezhaoView.setVisibility(View.GONE);
}
}
}
});
tvSon2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
// 展示的泡泡窗口的点亮,上面的字和图片
for (int i = 0; i < tvList.size(); i++) {
if (tvList.get(i).getId() == id) {
// 设置标题的值
tvList.get(i).setText(tvSon2.getText() + "");
}
}
}
});
tvSon3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
// 展示的泡泡窗口的点亮,上面的字和图片
for(int i = 0; i < tvList.size(); i++) {
if(tvList.get(i).getId()==id) {
// 设置标题的值
tvList.get(i).setText(tvSon3.getText() + "");
}
}
}
});
tvSon4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
// 展示的泡泡窗口的点亮,上面的字和图片
for (int i = 0; i < tvList.size(); i++) {
if (tvList.get(i).getId() == id) {
// 设置标题的值
tvList.get(i).setText(tvSon4.getText() + "");
}
}
}
});
}
}
Activity布局 activity_popup_window.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zhh.android.demo.activity.PopupWindowActivity"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:background="#CCC"
>
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#fff"
>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_centerInParent="true"
android:textColor="#666666"
android:text="服务地区"
android:maxEms="4"
android:ellipsize="end"
android:singleLine="true"
/>
<ImageView
android:id="@+id/imageView1"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toEndOf="@+id/textView1"
android:layout_toRightOf="@+id/textView1"
android:src="@mipmap/xlico_off" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/relativeLayout2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#fff"
android:layout_marginLeft="1dp"
>
<TextView
android:id="@+id/textView2"
android:textSize="14sp"
android:layout_centerInParent="true"
android:textColor="#666666"
android:text="擅长领域"
android:maxEms="4"
android:ellipsize="end"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/imageView2"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toEndOf="@+id/textView2"
android:layout_toRightOf="@+id/textView2"
android:src="@mipmap/xlico_off" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc"
>
</LinearLayout>
<!-- 遮罩层,在代码中显示隐藏即可-->
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CC777777"
android:visibility="gone"
>
</View>
</LinearLayout>
PopupWindow的布局文件 item_popup_layout.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="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#ccc"
>
<TextView
android:id="@+id/tvSon1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="跳转到下一页"
android:gravity="center"
android:background="#FFFFFF"
/>
<TextView
android:id="@+id/tvSon2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="泡泡窗口2"
android:gravity="center"
android:background="#FFFFFF"
android:layout_marginTop="1dp"
/>
<TextView
android:id="@+id/tvSon3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="泡泡窗口3"
android:gravity="center"
android:background="#FFFFFF"
android:layout_marginTop="1dp"
/>
<TextView
android:id="@+id/tvSon4"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="泡泡窗口4"
android:gravity="center"
android:background="#FFFFFF"
android:layout_marginTop="1dp"
/>
</LinearLayout>
</LinearLayout>
ok,讲完了
源码下载
MyPopupWindow ---- app
https://download.csdn.net/download/zhaihaohao1/10901493
参考文章
https://blog.csdn.net/zhaihaohao1/article/details/53444569