android自定义PopWindow底部显示

最近开发一款留言板手机客户端,需要到对话框来确认用户操作,但是系统自带的对话框很丑,不想用,所以就自定义PopWindow,想怎么显示就怎么显示,而且还方便添加显示动态,和背景图片。下面,我就来分享一下我的学习经验。
1、什么是popWindow?(1、2是博主网上找的)
popWindow就是对话框的一种方式!此文讲解的android中对话框的一种使用方式,它叫popWindow。
2、popWindow的特性
Android的对话框有两种:PopupWindow和Dialog。它们的不同点在于:
Dialog的位置固定,而PopupWindow的位置可以随意。
PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
3、PopWindow中控件的监听
PopWindow已经添加到布局中去了,那么问题来了,我要怎么通过自定义的控件来处理同级容器中的事件?其实很简单,博主在这里分享两种,第一种是通过接口:在PopWindow同级容器中实现自定义的相应接口,然后在传入到PopWindow对象中,在PopWindow对象中组件的监听事件中通过接口回调来实现控制;第二种方法就是:在继承于PopWindow的类中添加一个返回PopWindow布局的View的共有方法getPopWindowView(),在同级容器中定义PopWindow中控件的引用,然后将引用通过getPopWindowView().findViewById(R.id.xxx)指向相应的控件对象,最后在通过引用添加监听事件。
4、手机虚拟按键存在与否对底部滑出PopWindow的影响
当存在虚拟按键时候如果底部滑出相对于同级容器中的某个组件,则显示不完全,没有虚拟按键则不存在这种问题。怎么解决呢?其实很简单,只需要通过相对于父级容器位置来显示。即用showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等)。
5、点击PopWindow外部消失问题
在继承与PopWindow的类中必须实现setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))这个方法来设置背景色才行,否则不行,当然我这里设置的全透明,只显示背景图片。

这里我就直接略过具体的PopWindow显示效果的xml文件了,直接上主要代码

一、MainActivity类:

package com.example.mypopwindowdemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener{

    private Button pop_under_button;
    private Button bottom_popwindow;
    private Button left,right;
    private View buttonPopView;
    private MyPopWindowBottomShow myPopWindowBottomShow;//屏幕底部popwindow
    private MyButtonPopwindow myButtonPopwindow;//按钮下popwindow
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pop_under_button = (Button) findViewById(R.id.pop_under_button);
        bottom_popwindow = (Button) findViewById(R.id.bottom_popwindow);
        pop_under_button.setOnClickListener(this);
        bottom_popwindow.setOnClickListener(this);
        myPopWindowBottomShow = new MyPopWindowBottomShow(this, new BottomPopWindow());
        myButtonPopwindow = new MyButtonPopwindow(this, R.layout.under_button_pop_window, new PoPUnderListener());

        buttonPopView = myButtonPopwindow.getPopWindowView();
        left = (Button) buttonPopView.findViewById(R.id.left);
        right = (Button) buttonPopView.findViewById(R.id.right);

        left.setOnClickListener(new OnClickListener() {//对象外部添加监听事件

            @Override
            public void onClick(View arg0) {
                myButtonPopwindow.dismiss();
                Toast.makeText(MainActivity.this, "左边测试", Toast.LENGTH_SHORT).show();
            }
        });
        right.setOnClickListener(new OnClickListener() {//对象外部添加监听事件

            @Override
            public void onClick(View arg0) {
                myButtonPopwindow.dismiss();
                Toast.makeText(MainActivity.this, "右边测试", Toast.LENGTH_SHORT).show();
            }
        });



    }
    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
        case R.id.pop_under_button:
            if(myButtonPopwindow.isShowing()){
                myButtonPopwindow.dismiss();
            }else{
                myButtonPopwindow.showAsDropDown(pop_under_button);//popwindow放在pop_under_button下面
            }
            break;

        case R.id.bottom_popwindow:
            if(myPopWindowBottomShow.isShowing()){
                myPopWindowBottomShow.dismiss();
            }else{
//              myPopWindowBottomShow.showAsDropDown(bottom_popwindow);//popwindow放在子控件bottom_popwindow下面Ps:如果手机有虚拟按键的话popwindow将显示不完全(这个问题困扰了博主很久很久,希望你不要走弯路)
                myPopWindowBottomShow.showAtLocation(MainActivity.this.findViewById(R.id.main), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);//这种方式无论有虚拟按键还是没有都可完全显示,因为它显示的在整个父布局中
            }
            break;
        }
    }

    class PoPUnderListener implements MyPopWindowListener{//实现按钮下的接口

        @Override
        public void firstItem() {

            Toast.makeText(MainActivity.this, "左边按钮", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void secondItem() {

            Toast.makeText(MainActivity.this, "右边按钮", Toast.LENGTH_SHORT).show();
        }

    }

    class BottomPopWindow implements MyPopWindowListener{//实现底部弹出的接口

        @Override
        public void firstItem() {
            Toast.makeText(MainActivity.this, "上边按钮", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void secondItem() {
            Toast.makeText(MainActivity.this, "下边按钮", Toast.LENGTH_SHORT).show();
        }
    }

}

二、MyButtonPopwindow类实现按钮下显示PopWindow:

package com.example.mypopwindowdemo;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.PopupWindow;

/**
 * Created by Administrator on 2015/8/12.
 */
public class MyButtonPopwindow extends PopupWindow implements View.OnClickListener{
    private Button album;
    private Button take_photo;
    private LayoutInflater layoutInflater;
    private int layoutId;
    private Context context;
    private View view;
    private MyPopWindowListener popWindowChooseOnlyListener;

    public MyButtonPopwindow(Context context,int layoutId,MyPopWindowListener popWindowChooseOnlyListener){
        this.context = context;
        layoutInflater = LayoutInflater.from(context);
        this.layoutId = layoutId;
        this.popWindowChooseOnlyListener = popWindowChooseOnlyListener;
        init();
    }

    private void init() {
        view = layoutInflater.inflate(layoutId,null);//加载布局文件
//        album = (Button) view.findViewById(R.id.left);
//        take_photo = (Button) view.findViewById(R.id.right);
        setContentView(view);

        DisplayMetrics dm=new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        setWidth(dm.widthPixels * 2 / 3);

        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
//        album.setOnClickListener(this);
//        take_photo.setOnClickListener(this);
        setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        setFocusable(true);
        setOutsideTouchable(true);

    }

    @Override
    public void onClick(View v) {//注释掉,是因为想在该对象外面注册按钮监听器
//        switch (v.getId()){
//            case R.id.left:
//                popWindowChooseOnlyListener.firstItem();
//                dismiss();
//                break;
//            case R.id.right:
//                popWindowChooseOnlyListener.secondItem();
//                dismiss();
//                break;
//
//        }
    }

    public View getPopWindowView() {
        // TODO Auto-generated method stub
        return view;
    }

}

三、MyPopWindowBottomShow类,实现底部显示的的PopWindow:

package com.example.mypopwindowdemo;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.PopupWindow;

public class MyPopWindowBottomShow extends PopupWindow implements OnClickListener{
    private LayoutInflater layoutInflater;
    private MyPopWindowListener myPopWindowListener;
    private View popView;
    private Button firstButton;
    private Button secondButton;

    public MyPopWindowBottomShow(Context context,MyPopWindowListener myPopWindowListener){
        this.myPopWindowListener = myPopWindowListener;
        this.layoutInflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        init();
    }

    private void init(){
        popView = layoutInflater.inflate(R.layout.bottom_pop_window, null);
        firstButton = (Button) popView.findViewById(R.id.on);
        secondButton = (Button) popView.findViewById(R.id.under);
        firstButton.setOnClickListener(this);
        secondButton.setOnClickListener(this);

        //把View添加到PopWindow中
        this.setContentView(popView);
        //设置SelectPicPopupWindow弹出窗体的宽
        this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        //设置SelectPicPopupWindow弹出窗体的高
        this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        //设置SelectPicPopupWindow弹出窗体可点击
        this.setFocusable(true);
        //设置SelectPicPopupWindow弹出窗体动画效果
        this.setAnimationStyle(R.style.BottomPopWindowAnimation);

//        this.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//实例化一个ColorDrawable颜色为透明

      //实例化一个ColorDrawable颜色为半透明
            ColorDrawable dw = new ColorDrawable(0xb0000000);
            //设置SelectPicPopupWindow弹出窗体的背景
            this.setBackgroundDrawable(dw);
        popView.setOnTouchListener(new OnTouchListener() {//设置背景区域外为点击消失popwindow
            public boolean onTouch(View v, MotionEvent event) {

                int height = popView.findViewById(R.id.pop_layout).getTop();
                int y=(int) event.getY();
                if(event.getAction()==MotionEvent.ACTION_UP){
                    if(yreturn true;
            }
        });
    }

    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
        case R.id.on:
            myPopWindowListener.firstItem();
            break;

        case R.id.under:
            dismiss();
            myPopWindowListener.secondItem();
            break;
        }
    }
}

四、MyPopWindowListener接口:

package com.example.mypopwindowdemo;

public interface MyPopWindowListener {
    public void firstItem();//第一个按钮按下时
    public void secondItem();//第二个按钮按下时
}

下面就来真机运行图:

1、按钮下的PopWindow:

android自定义PopWindow底部显示_第1张图片

2、有背景图的下滑出PopWindow:

android自定义PopWindow底部显示_第2张图片

3、无背景色的下滑出PopWindow(在代码中已经注释掉,要不要,看个人喜好):

android自定义PopWindow底部显示_第3张图片

好了主要代码和图片就这些。

更多博主文章分享:

继承与View在画布上画出贪吃蛇贪吃蛇android源码分享

手机弹幕实现

PopWindow源码下载

你可能感兴趣的:(android)