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

Android 弹框菜单系列之PopupWindow

程序员文章站 2022-07-02 14:26:59
...

一.效果图:

Android 弹框菜单系列之PopupWindow

二.快速实现:

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>