Android 弹框菜单系列之PopupWindow

2023-03-28 10:26:24

一.效果图:

二.快速实现:

1.PopUpWindowActivity.class:

import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.qd.douyinwu.R;
import com.example.qd.douyinwu.adapter.MyAdapter;
import com.example.qd.douyinwu.adapter.MyListAdapter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class PopUpWindowActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView tv_pop;
    private PopupWindow popupWindow;
    private SharedPreferences sp;
    private ImageView iv_01, iv_02, iv_03;
    private TextView tv_01, tv_02, tv_03;
    private String[] name;
    private List<String> list = new ArrayList<>();
    private PopupWindow popupWindow1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_popupwindow);
        sp = getSharedPreferences("state", MODE_PRIVATE);
        // 初始化时清除保存的状态数据
        SharedPreferences.Editor edit = sp.edit();
        edit.clear();
        edit.commit();
        list.clear();
        list.add("KING");
        list.add("OLPL");
        list.add("CHAIN");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");
        list.add("CHINA");

        initView();

    }
    private void initView() {
        tv_pop = (TextView) findViewById(R.id.tv_pop);
        tv_pop.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_pop:
//                showPopWindow(getView());
                initPopWindow();
                break;

            default:
                break;
        }
    }

    private void showPopWindow(View view) {
        try {

            popupWindow = new PopupWindow(view, LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            popupWindow.setFocusable(true);
            popupWindow.setOutsideTouchable(true);
            ColorDrawable cd = new ColorDrawable(0x00ffffff);// 背景颜色全透明
            popupWindow.setBackgroundDrawable(cd);
            int[] location = new int[2];
            tv_pop.getLocationOnScreen(location);
            popupWindow.setAnimationStyle(R.style.style_pop_animation);// 动画效果必须放在showAsDropDown()方法上边,否则无效
            backgroundAlpha(0.5f);// 设置背景半透明
            popupWindow.showAsDropDown(tv_pop);
            //popupWindow.showAtLocation(tv_pop, Gravity.NO_GRAVITY, location[0]+tv_pop.getWidth(),location[1]);
            popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {

                @Override
                public void onDismiss() {
                    popupWindow = null;// 当点击屏幕时,使popupWindow消失
                    backgroundAlpha(1.0f);// 当点击屏幕时,使半透明效果取消
                }
            });

            if (sp.getInt("flag", 1) == 1) {
                iv_01.setVisibility(View.VISIBLE);
                tv_01.setTextColor(Color.RED);
            } else if (sp.getInt("flag", 2) == 2) {
                iv_02.setVisibility(View.VISIBLE);
                tv_02.setTextColor(Color.RED);
            } else if (sp.getInt("flag", 3) == 3) {
                iv_03.setVisibility(View.VISIBLE);
                tv_03.setTextColor(Color.RED);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //展示列表
    private void showPopWindowListView(View view) {
        try {

            popupWindow = new PopupWindow(view, LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            popupWindow.setFocusable(true);
            popupWindow.setOutsideTouchable(true);
            ColorDrawable cd = new ColorDrawable(0x00ffffff);// 背景颜色全透明
            popupWindow.setBackgroundDrawable(cd);
            int[] location = new int[2];
            tv_pop.getLocationOnScreen(location);
            popupWindow.setAnimationStyle(R.style.style_pop_animation);// 动画效果必须放在showAsDropDown()方法上边,否则无效
//            backgroundAlpha(0.5f);// 设置背景半透明
            popupWindow.showAsDropDown(tv_pop);
            //popupWindow.showAtLocation(tv_pop, Gravity.NO_GRAVITY, location[0]+tv_pop.getWidth(),location[1]);
            popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {

                @Override
                public void onDismiss() {
                    popupWindow = null;// 当点击屏幕时,使popupWindow消失
                    backgroundAlpha(1.0f);// 当点击屏幕时,使半透明效果取消
                }
            });

            if (sp.getInt("flag", 1) == 1) {
                iv_01.setVisibility(View.VISIBLE);
                tv_01.setTextColor(Color.RED);
            } else if (sp.getInt("flag", 2) == 2) {
                iv_02.setVisibility(View.VISIBLE);
                tv_02.setTextColor(Color.RED);
            } else if (sp.getInt("flag", 3) == 3) {
                iv_03.setVisibility(View.VISIBLE);
                tv_03.setTextColor(Color.RED);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 设置popupWindow背景半透明
    public void backgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha;// 0.0-1.0
        getWindow().setAttributes(lp);
    }

    /*
     * 得到popupwindow的View
     */
    private View getView() {
        View view = LayoutInflater.from(PopUpWindowActivity.this).inflate(
                R.layout.layout_pop_item, null);
        iv_01 = (ImageView) view.findViewById(R.id.iv_01);
        iv_02 = (ImageView) view.findViewById(R.id.iv_02);
        iv_03 = (ImageView) view.findViewById(R.id.iv_03);
        tv_01 = (TextView) view.findViewById(R.id.tv_01);
        tv_02 = (TextView) view.findViewById(R.id.tv_02);
        tv_03 = (TextView) view.findViewById(R.id.tv_03);
        RelativeLayout rl_01 = (RelativeLayout) view.findViewById(R.id.rl_01);
        RelativeLayout rl_02 = (RelativeLayout) view.findViewById(R.id.rl_02);
        RelativeLayout rl_03 = (RelativeLayout) view.findViewById(R.id.rl_03);

        rl_01.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                popupWindow.dismiss();
                tv_pop.setText("名称排序");
                saveCurrentState(1);
            }
        });
        rl_02.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                popupWindow.dismiss();
                tv_pop.setText("从高到低排序");
                saveCurrentState(2);

            }
        });
        rl_03.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                iv_03.setVisibility(View.VISIBLE);
                popupWindow.dismiss();
                tv_pop.setText("从低到高排序");
                saveCurrentState(3);
            }
        });
        return view;
    }

    /*
     * 得到popupwindow的View
     */
    private View getViewListView() {
        View view = LayoutInflater.from(PopUpWindowActivity.this).inflate(
                R.layout.layout_pop_item_list, null);
        view.setBackgroundColor(Color.BLUE);

        PopupWindow popupWindow = new PopupWindow(findViewById(R.id.mainLayout), 200, 700);
        popupWindow.setContentView(view);

        TextView textView = (TextView) view.findViewById(R.id.text);
        textView.setText("测试");

        return view;
    }


    private void initPopWindow(){

        View contentView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout_pop_item_list, null);
//        contentView.setBackgroundColor(Color.BLUE);

        popupWindow1 = new PopupWindow(findViewById(R.id.mainLayout), 900, LinearLayout.LayoutParams.WRAP_CONTENT);
        popupWindow1.setContentView(contentView);

        TextView tvMore = (TextView) contentView.findViewById(R.id.tv_more);
        TextView textView = (TextView) contentView.findViewById(R.id.text);
        tvMore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow1.dismiss();
                Toast.makeText(PopUpWindowActivity.this, "更多", Toast.LENGTH_SHORT).show();
            }
        });
        textView.setText("测试");
        openDir();
        ListView listView = (ListView) contentView.findViewById(R.id.list);
        //原生自带布局
//        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, name);
        //自定义布局,只可以设置一个控件的布局
//        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.simple_list_item_popup,R.id.tv_content, name);
        //完全自定义布局
        MyListAdapter mAdapter = new MyListAdapter(this,list);//得到一个MyAdapter对象
        listView.setAdapter(mAdapter);//为ListView绑定Adapter /*为ListView添加点击事件*/
//        listView.setAdapter(adapter);
        mAdapter.setOnClickMyTextView(new MyListAdapter.OnClickMyTextView() {
            @Override
            public void myTextViewClick(int id) {
                Toast.makeText(PopUpWindowActivity.this, "点击了"+id, Toast.LENGTH_SHORT).show();

            }
        });
        popupWindow1.setFocusable(true);
        popupWindow1.showAsDropDown(tv_pop);//显示位置

        popupWindow1.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                popupWindow1.dismiss();
            }
        });
        popupWindow1.setOutsideTouchable(true);
    }

    private void openDir()
    {
        name = new String[]{"12","22","22","22","22","22","22","22"};
//        String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
//        File file  = new File(rootPath);
//        File[] files = file.listFiles();
//        name = new String[files.length];
//        for(int i=0;i<files.length;i++){
//            name[i]=files[i].getName();
//            System.out.println(name[i]);
//        }
    }

    /*
     * 保存当前状态 1-->名称排序 2-->从高到低 3-->从低到高
     */
    private void saveCurrentState(int i) {
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt("flag", i);
        editor.commit();
    }

}

2.activity_popupwindow.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mainLayout"
    android:background="@color/white"
    android:orientation="vertical">

    <!--<TextView-->
        <!--android:id="@+id/tv_pop"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:text="名称排序"-->
        <!--android:textSize="16sp"-->
        <!--android:drawableRight="@drawable/ic_launcher_background"-->
        <!--android:padding="10dp"/>-->
    <TextView
        android:id="@+id/tv_pop"
        android:gravity="center"
        android:layout_gravity="center"
        android:layout_width="100dp"
        android:background="@drawable/shape_black"
        android:layout_height="wrap_content"
        android:text="HI"
        android:textSize="16sp"
        android:padding="10dp"/>
    <View
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#000000"/>
</LinearLayout>

3.style

<!--popMenu分割线的颜色-->
    <style name="popmenuDivier">
        <item name="android:divider">@color/colorAccent</item>
        <item name="android:dividerHeight">1sp</item>
    </style>
    <style name="style_pop_animation">
        <item name="android:windowEnterAnimation">@anim/anim_pop_in</item>
        <item name="android:windowExitAnimation">@anim/anim_pop_out</item>
    </style>

4.xml动画:

anim_pop_in.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="300"
        android:fromXScale="1.0"
        android:fromYScale="0"
        android:pivotX="100%"
        android:pivotY="0%"
        android:toXScale="1.0"
        android:toYScale="1.0"/>

</set>

anim_pop_out.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="300"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="100%"
        android:pivotY="0%"
        android:toXScale="1.0"
        android:toYScale="0.0"/>

</set>

5.弹框布局:layout_pop_item_list.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:background="@color/white"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <LinearLayout
        android:orientation="vertical"
        android:layout_marginBottom="25dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/text"
            android:visibility="gone"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="测试"
            />
        <LinearLayout
            android:background="@drawable/shape_black"
            android:layout_width="match_parent"
            android:layout_height="200dp">
            <ListView
                android:id="@+id/list"
                android:layout_width="fill_parent"
                android:layout_height="200dp"
                />
        </LinearLayout>
        <TextView
            android:id="@+id/tv_more"
            android:gravity="center"
            android:layout_width="fill_parent"
            android:layout_height="25dp"
            android:text="更多数据"
            />
    </LinearLayout>
    <!--<TextView-->
        <!--android:layout_alignParentBottom="true"-->
        <!--android:id="@+id/tv_more"-->
        <!--android:gravity="center"-->
        <!--android:layout_width="fill_parent"-->
        <!--android:layout_height="25dp"-->
        <!--android:text="更多数据"-->
        <!--/>-->
</RelativeLayout>

6.simple_list_item_popup.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">

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

7.适配器

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.qd.douyinwu.R;

import java.util.List;

public class MyListAdapter extends BaseAdapter {
    private List<String> mlist;
    private OnClickMyTextView mOnClickMyTextView;
    private LayoutInflater mInflater;//得到一个LayoutInfalter对象用来导入布局 /*构造函数*/

    public MyListAdapter(Context context,List<String> mlists) {
        this.mInflater = LayoutInflater.from(context);

        mlist = mlists;
    }

    @Override
    public int getCount() {

        return mlist.size();//返回数组的长度
    }

    @Override
    public Object getItem(int position) {
        return mlist.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    /*书中详细解释该方法*/
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        //观察convertView随ListView滚动情况

        Log.v("MyListViewBase", "getView " + position + " " + convertView);
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.layout_pop_item_list2, null);
            holder = new ViewHolder();
            /*得到各个控件的对象*/

            holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
            holder.tvTime = (TextView) convertView.findViewById(R.id.tv_time);
            holder.tvTime.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnClickMyTextView != null){
                        mOnClickMyTextView.myTextViewClick(position);
                    }
                }
            });
//            holder.bt = (Button) convertView.findViewById(R.id.ItemButton);
            convertView.setTag(holder);//绑定ViewHolder对象
        } else {
            holder = (ViewHolder) convertView.getTag();//取出ViewHolder对象
        }
        /*设置TextView显示的内容,即我们存放在动态数组中的数据*/

        holder.tvName.setText(mlist.get(position));
//        holder.text.setText(getDate().get(position).get("ItemText").toString());
//
//        /*为Button添加点击事件*/
//        holder.bt.setOnClickListener(new OnClickListener() {
//
//            @Override
//            public void onClick(View v) {
//                Log.v("MyListViewBase", "你点击了按钮" + position);//打印Button的点击信息
//            }
//        });
        return convertView;
    }/*存放控件*/

    public final class ViewHolder {
        public TextView tvName;
        public TextView tvTime;
    }
    public interface OnClickMyTextView {//创建一个接口类       
        void myTextViewClick(int id);//创建一个回调函数,实例化接口的时候就要具体化这个回调函数,即要有函数体    
    }
    //注册函数    
    public void setOnClickMyTextView(OnClickMyTextView onClickMyTextView){
        this.mOnClickMyTextView = onClickMyTextView;
    }

}

8.layout_pop_item_list2

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tv_name"
        android:gravity="center"
        android:layout_gravity="center"
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:text="测试"
        />

    <View
        android:background="#ccc"
        android:layout_width="1dp"
        android:layout_height="match_parent"/>
    <TextView
        android:id="@+id/tv_time"
        android:gravity="center"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="20200909 12:00:00"
        />
</LinearLayout>

9.shape_black

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!--无圆角边框-->
    <solid android:color="@android:color/white" />
    <!--填充的颜色-->
    <!--描边-->
    <stroke
        android:width="1dp"
        android:color="#ccc" />
</shape>

 

  • 作者:冰糖葫芦三剑客
  • 原文链接:https://blog.csdn.net/shenggaofei/article/details/106600900
    更新时间:2023-03-28 10:26:24