Android 简单封装一个精美、好用的菜单型PopupWindow

先上效果图:

就是这样一个菜单型的PopupWindow,现在说下是怎么弄的,

先看一个布局文件,这个布局文件

package cn.edu.jxufe.popupwindowdemo;

import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class PopupWindowUtil {

    private ListView listView;
    private PopupWindow window;
    //窗口在x轴偏移量
    private int xOff = 0;
    //窗口在y轴的偏移量
    private int yOff = 0;

    public PopupWindowUtil(Context context, List<String> datas) {

        window = new PopupWindow(context);
        //ViewGroup.LayoutParams.WRAP_CONTENT,自动包裹所有的内容
        window.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        window.setFocusable(true);
        //点击 back 键的时候,窗口会自动消失
        window.setBackgroundDrawable(new BitmapDrawable());

        View localView = LayoutInflater.from(context).inflate(R.layout.lv_pw_menu, null);
        listView = (ListView) localView.findViewById(R.id.lv_pop_list);

        listView.setAdapter(new MyAdapter(context, datas));
        listView.setTag(window);
        //设置显示的视图
        window.setContentView(localView);
    }

    public void setItemClickListener(AdapterView.OnItemClickListener listener) {
        listView.setOnItemClickListener(listener);
    }

    public void dismiss() {
        window.dismiss();
    }

    /**
     * @param xOff x轴(左右)偏移
     * @param yOff y轴(上下)偏移
     */
    public void setOff(int xOff, int yOff) {
        this.xOff = xOff;
        this.yOff = yOff;
    }

    /**
     * @param paramView 点击的按钮
     */
    public void show(View paramView, int count) {
        //该count 是手动调整窗口的宽度
        window.setWidth(paramView.getWidth() * count);
        //设置窗口显示位置, 后面两个0 是表示偏移量,可以自由设置
        window.showAsDropDown(paramView, xOff, yOff);
        //更新窗口状态
        window.update();
    }

    class MyAdapter extends BaseAdapter {

        private Context context;
        private List<String> mDatas;

        public MyAdapter(Context context, List<String> datas) {
            this.context = context;
            if (datas == null) {
                datas = new ArrayList<>();
            }
            mDatas = datas;
        }

        @Override
        public int getCount() {
            return mDatas.size();
        }

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

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView tvItem;
            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.lv_item_pw_menu, null);
                tvItem = (TextView) convertView.findViewById(R.id.tv_item_pw_menu);
                convertView.setTag(tvItem);
            } else {
                tvItem = (TextView) convertView.getTag();
            }
            tvItem.setText(getItem(position) + "");
            return convertView;
        }
    }
}

再看看Activity中是怎么调用的

public class MenuActivity extends Activity {

    private Context context = this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);
    }
    //菜单按钮onClick事件
    public void menuClick(View view) {
        final List<String> items = new ArrayList<>();
        items.add("第一项");
        items.add("第二项");
        items.add("第三项");
        items.add("第四项");

        final PopupWindowUtil popupWindow = new PopupWindowUtil(context, items);
        popupWindow.setItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                popupWindow.dismiss();
                Toast.makeText(context, "你点击了" + items.get(position), Toast.LENGTH_SHORT).show();
            }
        });
        //根据后面的数字 手动调节窗口的宽度
        popupWindow.show(view, 4);
    }
}

接下来是布局文件 lv_item_pw_menu

ListView的item布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:gravity="center_vertical"
    android:layout_width="match_parent"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:background="@android:color/transparent"
    android:layout_marginBottom="8dp"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="match_parent"
        android:gravity="center"
        android:drawablePadding="3dp"
        android:padding="7dp"
        android:text="测试数据"
        android:id="@+id/tv_item_pw_menu"
        android:textSize="18sp"
        android:layout_height="wrap_content" />

</RelativeLayout>

窗口的布局 lv_pw_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:background="@drawable/menu"
    android:layout_height="match_parent"
    android:paddingBottom="15.0dip"
    android:paddingLeft="6.0dip"
    android:paddingRight="6.0dip"
    android:paddingTop="20.0dip">

    <ListView
        android:id="@+id/lv_pop_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@null"
        android:scrollbars="none" />
</LinearLayout>

就这样,以后就可以直接在activity中调用,且无需在工具类中修改

附上链接,只有代码和图片:

http://download.csdn.net/detail/chang_1134/9516120

时间: 2024-10-09 16:47:10

Android 简单封装一个精美、好用的菜单型PopupWindow的相关文章

Android简单封装类似JQuery异步请求

在android开发中经常会使用异步请求数据,通常会使用handler或者AsyncTask去做,handler 配合message 使用起来比较麻烦,AsyncTask 线程池只允许128个线程工作,会有溢出的问题,(当然一般情况不会有那么多线程同时工作的)所以写了这个代码,还望高手指正! [Java]代码 01 package com.xbl.task; 02 03 import java.io.BufferedReader; 04 import java.io.InputStream; 0

用XHR简单封装一个axios

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible"

Swift:简单封装一个工具类模板

创建模板类(封装一个类)新建一个名字叫做 Product 的类 Product.swift File 的内容 class Product { var name: String var description: String var price: Double var stock: Int init(name: String, description: String, price: Double, stock: Int) { self.name = name self.description =

简单封装一个ajax插件

function ajax(options) { options = options || {}; options.type = options.type || 'get'; options.type = options.data || {}; options.dataType = options.dataType || 'text'; //IE6以下无法使用 let xhr = new XMLHttpRequest(); // 数据修改 let arr = []; for (let name

C 封装一个通用链表 和 一个简单字符串开发库

引言 这里需要分享的是一个 简单字符串库和 链表的基库,代码也许用到特定技巧.有时候回想一下, 如果我读书的时候有人告诉我这些关于C开发的积淀, 那么会走的多直啊.刚参加工作的时候做桌面开发, 服务是C++写,界面是C#写.那时候刚进去评级我是中级,因为他问我关于系统锁和信号量都答出来.开发一段 时间,写C#也写的很溜.后面招我那个人让我转行就写C++和php,那时候就开始学习C++有关知识. 后面去四川工作了,开发安卓,用eclipse + java语法 + android jdk,开发前端,

Android ToolBar 的简单封装

使用过 ToolBar 的朋友肯定对其使用方法不陌生,因为其用法很简单,如果对 ActionBar 使用比较熟练的人来说,ToolBar 就更容易了!不过,相信大家在使用的过程中都遇到过这样一个问题,需要在每一个我们要使用的 xml 中添加 ToolBar 这个控件,比如我需要在 MainActivity中使用 ToolBar,则他的 xml 文件需要这样写, <RelativeLayout xmlns:android="http://schemas.android.com/apk/res

Android简单的编写一个txt阅读器(没有处理字符编码),适用于新手学习

本程序只是使用了一些基本的知识点编写了一个比较简单粗陋的txt文本阅读器,效率不高,只适合新手练习.所以大神勿喷. 其实想到编写这种程序源自本人之前喜欢看小说,而很多小说更新太慢,所以本人就只能找一个完本的.txt小说下载下来,有没有网络都可以看,当然现在不看那玩意了. 废话就不说了,程序中使用到的有4个类,5个xml文件,其中3个布局文件.String.xml.AndroidManifest.xml. 先看效果图吧(虽然很丑):     下面就上代码吧,本人都注释好了,由于本人技术还不行,注释

从零封装一个Android大图查看器

背景: 大图查看器是许多app的常用功能,主要使用场景是用户点击图片,然后启动一个新界面来展示图片的完整尺寸,并能通过手势移动图片以及放大缩小.当然,上面说的是最基本的功能,实际使用中还要包括:如果是本地图片应该可以移除,如果是网络图片,应提供一个保存到本地的功能等. 本文为什么叫封装一个大图查看器,而不是叫做编写一个大图查看器呢?因为大图查看器的最核心功能,展示图片以及手势操控我们使用了一个开源库来完成,这个开源库叫做subsampling-scale-image-view,这个开源库非常靠谱

Android中网络框架的简单封装

个人博客 http://www.milovetingting.cn Android中网络框架的简单封装 前言 Android作为一款主要应用在移动终端的操作系统,访问网络是必不可少的功能.访问网络,最基本的接口有:HttpUrlConnection,HttpClient,而在后续的发展中,出现了Volley,OkHttp,Retrofit等网络封装库.由于各种原因,在实际的项目开发中,我们可能会需要在项目的版本迭代中,切换网络框架.如果对于网络框架没有好的封装,那么当需要切换网络框架时,可能就会