Android中PopupWindow的常见使用

本文介绍了Android中三种PopupWindow的实现方式,包括基本使用、底部滑入效果和菜单样式。详细讲解了如何封装设置类,调用方法,以及使用的布局文件和动画效果。提供了源码下载链接和相关参考文章。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第一种(图一)基本使用
分装一个设置的类 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值