封装的一个android底部操作弹出窗

首先看效果



调用方式也非常的简单如下:

 //操作需要用到的图片icon
        final int itemIconIds[] = new int[] { R.drawable.p_trends_comment,
                R.drawable.p_trends_forward, R.drawable.p_trends_share,
                R.drawable.p_trends_delete };
        
        final String itemDescs[] = new String[] { "评  论", "转  发", "共  享",
                "删  除" };
        
        //获得屏幕的高度,设置ListView的最大高度,动态设置ListView的高度
        WindowManager windowManager = this.getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        int screenHeight = display.getHeight();
        
        showBtn = (Button) this.findViewById(R.id.show);
        
        new PathPopupWindowDialog(this, screenHeight, showBtn).create(itemIconIds,
                itemDescs,
                new ResponseListener());

PathPopupWindowDialog的参数说明:

构造函数中第一个参数“this”是Context,第二个"screenHeight"是屏幕的高度,本来是要根据内容的增加,来不断调整dialog的高度的,暂时看来是不需要了,第三个参数"showBtn"是用来触发此dialog的一个按钮,其实是PopupWindow的showAtLocation需要的parentView

create方法中的参数分别是dialog中每一个item需要的图标和对应的文字,以及单击每一个条目需要触发的事件,内容形式示例如下:

private class ResponseListener implements AdapterView.OnItemClickListener
    {
        @Override
        public void onItemClick(AdapterView<?> adapter, View view, int id,
                long position)
        {
            System.out.println(view + "----");
            @SuppressWarnings("unchecked")
            HashMap<String, Object> map = (HashMap<String, Object>) adapter.getItemAtPosition((int) position);
            Toast.makeText(Android_test_02Activity.this,
                    map.get("text").toString(),
                    1000).show();
        }
    }

其中PathPopupWindowDialog的源码如下:

package com.king.demo;

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

import android.content.Context;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.SimpleAdapter;

/**
 * path dialog组件 <br/>
 * <br/>
 * <b>示例:<br/>
 * new PathPopupWindowDialog(Context context, int screenHeight, View showBtn)<br/>
 *     .create(int itemIconIds[],String itemDescs[],
 * AdapterView.OnItemClickListener listener);<br/>
 * <br/>
 * 参数说明:<br/>
 * context ---- 一般是activity<br/>
 * screenHeight ---- 屏幕高度<br/>
 * showBtn ---- 用来PopupWindow展示,例如Button,点击此button会显示dialog<br/>
 * itemIconIds ---- ListView中每一个item的图标<br/>
 * itemDescs ---- ListView中每一个item的图标对应的说明<br/>
 * listener ---- ListView中每一个item需要响应的操作,需要用户自己实现。<br/>
 * 关于ListView中的值是通过SimpleAdapter设置的,其中SimpleAdapter接收的List<HashMap<String,
 * Object>><br/>
 * map中存放的key是图标是"icon"[ITEM_ICON]和文本是"text"[ITEM_TEXT],用户在实现listener的时候可能需要用到
 * </b>
 * 
 * @author kingzhang
 * 
 */
public class PathPopupWindowDialog
{
    
    public static final String ITEM_ICON = "icon";
    
    public static final String ITEM_TEXT = "text";
    
    /**
     * popupWindow
     */
    private PopupWindow popupWindow;
    
    /**
     * 确定dialog需要的context
     */
    private Context context;
    
    /**
     * 手机屏幕的高度
     */
    private int screenHeight;
    
    /**
     * 确定触发该dialog的view组件,也是创建popupwindow必须的参数
     */
    private View parentView;
    
    public PathPopupWindowDialog(Context context, int screenHeight,
            View parentView)
    {
        this.context = context;
        this.screenHeight = screenHeight;
        this.parentView = parentView;
    }
    
    /**
     * 创建PopupWindow
     * 
     * @param itemIconIds
     *            ListView中的图标
     * @param itemDescs
     *            ListView中图标对应的描述
     * @param responseListener
     *            响应listview中的item click listener 事件
     */
    public void create(int itemIconIds[], String itemDescs[],
            AdapterView.OnItemClickListener responseListener)
    {
        LayoutInflater inflater = LayoutInflater.from(context);
        View popupView = inflater.inflate(R.layout.p_trends_option_popup, null);
        //popupView.se
        
        //从popu.xml中获得其中的组件
        ListView listView = (ListView) popupView.findViewById(R.id.path_popupwindow_listview);
        
        //获得popup中最外层的layout
        //LinearLayout linearLayout = (LinearLayout) popupView.findViewById(R.id.p_dynamic_popup_layout);
        
        //设置ListView中的参数属性
        this.setListViewParamters(listView,
                itemIconIds,
                itemDescs,
                responseListener);
        
        //获得屏幕的高度,设置ListView的最大高度,动态设置ListView的高度
        //this.setListViewHeightBasedOnChildren(listView, screenHeight);
        
        //生成PopupWindow对象
        popupWindow = new PopupWindow(popupView, LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT, true);
        
        //设置PopupWindow对象需要属性参数
        popupWindow.setAnimationStyle(R.style.path_popwindow_anim_enterorout_window);
        popupWindow.setFocusable(true);
        popupWindow.setTouchable(true);
        
        //设置popupwindow以外的区域是否可以触摸
        popupWindow.setOutsideTouchable(true);
        
        //显示popupwindow
        parentView.setOnClickListener(new ShowPopupWindowListener());
        
        // 设置android返回事件,用来隐藏popupwindow
        // 不给LinearLayout设置的原因是因为给其加上后,ListView不能获得焦点
        this.setBackListener(listView);
        
    }
    
    /**
     * 设置ListView里面的参数属性
     * 
     * @param listView
     * @param itemIconIds
     *            ListView中的图标
     * @param itemDescs
     *            ListView中图标对应的描述
     * @param responseListener
     *            响应listview中的item click listener 事件
     */
    private void setListViewParamters(ListView listView, int itemIconIds[],
            String itemDescs[], AdapterView.OnItemClickListener responseListener)
    {
        
        // 给popu.xml中ListView设置值
        List<HashMap<String, Object>> itemList = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < itemDescs.length; i++)
        {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put(ITEM_ICON, itemIconIds[i]);
            map.put(ITEM_TEXT, itemDescs[i]);
            itemList.add(map);
        }
        
        SimpleAdapter simpleAdapter = new SimpleAdapter(context, itemList,
                R.layout.p_trends_option_popup_item, new String[] { "icon",
                        "text" }, new int[] { R.id.path_dynamic_popu_item_icon,
                        R.id.path_dynamic_popu_item_textView });
        listView.setFocusable(true);
        listView.requestFocus();
        listView.setAdapter(simpleAdapter);
        listView.setItemsCanFocus(true);
        listView.setDividerHeight(0);
        //设置ListView中的item点击事件
        listView.setOnItemClickListener(responseListener);
    }
    
    /**
     * 给parentView设置onclicklistener事件,用于显示popupwindow
     * 
     * @author kingzhang
     * 
     */
    private class ShowPopupWindowListener implements View.OnClickListener
    {
        @Override
        public void onClick(View v)
        {
            popupWindow.showAtLocation(parentView, Gravity.BOTTOM, 0, 0);
            popupWindow.update();
        }
    }
    
    /**
     * 为PopupWindow中的最外层的布局设置onkeylistener事件 用来隐藏弹出的popupwindow
     * 
     * @param layout
     *            为PopupWindow中的最外层的布局
     * @param pw
     *            PopupWindow
     */
    private void setBackListener(View view)
    {
        view.setOnKeyListener(new View.OnKeyListener()
        {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event)
            {
                if (event.getAction() == KeyEvent.ACTION_DOWN
                        && keyCode == KeyEvent.KEYCODE_BACK)
                {
                    popupWindow.dismiss();
                }
                return false;
            }
        });
    }
    
    /**
     * 动态设置listview的高度
     * 
     * @param listView
     *            需要配置的ListView
     * @param screenHeight
     *            屏幕的高度
     * @param imageHeight
     *            imageHeight
     * @param viewHeight
     *            viewHeight
     */
    private void setListViewHeightBasedOnChildren(ListView listView,
            int screenHeigh)
    {
        //获取ListView对应的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null)
        {
            return;
        }
        int totalHeight = 0;
        for (int i = 0, len = listAdapter.getCount(); i < len; i++)
        {
            //listAdapter.getCount()返回数据项的数目
            View listItem = listAdapter.getView(i, null, listView);
            
            //计算子项View 的宽高
            listItem.measure(0, 0);
            
            //统计所有子项的总高度
            totalHeight += listItem.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        
        //listView.getDividerHeight()获取子项间分隔符占用的高度
        int listViewHeight = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        
        //如果总体高度大于屏幕高度,则用屏幕高度
        if (listViewHeight > screenHeight)
        {
            //此处的30是实验所得出的结果
            params.height = screenHeight - 75;
        }
        //否则设置为计算出来的高度
        else
        {
            params.height = listViewHeight;
        }
        listView.setLayoutParams(params);
    }
}

布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/p_dynamic_popup_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" 
    android:paddingTop="30dip">
	
    <!-- 显示的高度跟这个LinearLayout的background的大小有关,以及和item里面的backgroud有关 -->
    <!-- 用来显示popupwindow中的列表项 -->
	
	<ImageView 
	    android:id="@+id/title_bg"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:src="@drawable/top"
	    android:scaleType="fitXY"/>
	
    <ListView
        android:id="@+id/path_popupwindow_listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="10dip"
        android:paddingRight="10dip" 
        android:background="@drawable/bg"
        android:cacheColorHint="#00000000"/>
    
    <ImageView
        android:id="@+id/bottom_bg"
        android:src="@drawable/bottom"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"/>
</LinearLayout>

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

    <ImageView
        android:id="@+id/path_dynamic_popu_item_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:scaleType="centerInside"/>

    <TextView
        android:id="@+id/path_dynamic_popu_item_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="10dip"
        android:gravity="center"
        android:textColor="@android:color/white"
        android:textSize="22sp"/>

</LinearLayout>


剩下的就是所用的图片背景如下:




用到的动画效果的xml文件如下:

enter window

<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator" >

    <translate
        android:duration="300"
        android:fromXDelta="0.0"
        android:fromYDelta="100%"
        android:toXDelta="0.0"
        android:toYDelta="0.0" />

</set>

out window

<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/decelerate_interpolator">
    <translate
        android:duration="400"
        android:fromXDelta="0.0"
        android:fromYDelta="0.0"
        android:toXDelta="0.0"
        android:toYDelta="100%" />
</set>

style文件外为:

<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<resources>
    <style name="path_popwindow_anim_enterorout_window">
        <item name="android:windowEnterAnimation">@anim/p_trends_enter_window</item>
 		<!-- 指定显示的动画xml -->
        <item name="android:windowExitAnimation">@anim/p_trends_out_window</item>
 		<!-- 指定消失的动画xml -->
    </style>
</resources>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值