PopupWindow 使用

昨天马失前蹄,为了做一个小键盘,耽误了两个小时,记录一下心路历程

1.关于需求与选择

需求:

点击一个按钮,弹出一个小键盘(类似于输入法键盘)

选择:

(1)方案一:KeyboardView

       这是百度之后选的第一个方案,试用之后发现,点击每个按键都会闪现一个小空白框(可能是提示按键字符之类的,具体没有验证),后来试着把KeyboardView放在一个PopupWindow里面后,点击KeyboardView,应用崩溃,错误提示(addWindow Error)。大意是说,PopupWindow是subWindow,不能在subWindow里面再继续addWindow。

(2)方案二:Button + PopupWindow

       放弃KeyboardView之后,乖乖在xml里面放了N个Button,问题点就在PopupWindow的弹出,下面记录一下使用的Tips。

2.PopupWindow的创建

(1)页面设计

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3     android:id="@+id/keypad_dialog"
  4     android:layout_width="match_parent"
  5     android:orientation="vertical"
  6     android:layout_height="wrap_content">
  7     <LinearLayout
  8         android:layout_width="match_parent"
  9         android:layout_height="wrap_content"
 10         android:weightSum="3">
 11         <Button
 12             android:layout_width="match_parent"
 13             android:layout_height="wrap_content"
 14             android:text="1"
 15             android:id="@+id/btn1"
 16             android:layout_weight="1"
 17             android:soundEffectsEnabled="true"/>
 18         <Button
 19             android:layout_width="match_parent"
 20             android:layout_height="wrap_content"
 21             android:text="2"
 22             android:id="@+id/btn2"
 23             android:layout_weight="1"
 24             android:soundEffectsEnabled="true"/>
 25         <Button
 26             android:layout_width="match_parent"
 27             android:layout_height="wrap_content"
 28             android:text="3"
 29             android:id="@+id/btn3"
 30             android:layout_weight="1"
 31             android:soundEffectsEnabled="true"/>
 32     </LinearLayout>
 33     <LinearLayout
 34         android:layout_width="match_parent"
 35         android:layout_height="wrap_content"
 36         android:weightSum="3">
 37         <Button
 38             android:layout_width="match_parent"
 39             android:layout_height="wrap_content"
 40             android:text="4"
 41             android:id="@+id/btn4"
 42             android:layout_weight="1"
 43             android:soundEffectsEnabled="true"/>
 44         <Button
 45             android:layout_width="match_parent"
 46             android:layout_height="wrap_content"
 47             android:text="5"
 48             android:id="@+id/btn5"
 49             android:layout_weight="1"
 50             android:soundEffectsEnabled="true"/>
 51         <Button
 52             android:layout_width="match_parent"
 53             android:layout_height="wrap_content"
 54             android:text="6"
 55             android:id="@+id/btn6"
 56             android:layout_weight="1"
 57             android:soundEffectsEnabled="true"/>
 58     </LinearLayout>
 59     <LinearLayout
 60         android:layout_width="match_parent"
 61         android:layout_height="wrap_content"
 62         android:weightSum="3">
 63         <Button
 64             android:layout_width="match_parent"
 65             android:layout_height="wrap_content"
 66             android:text="7"
 67             android:id="@+id/btn7"
 68             android:layout_weight="1"
 69             android:soundEffectsEnabled="true"/>
 70         <Button
 71             android:layout_width="match_parent"
 72             android:layout_height="wrap_content"
 73             android:text="8"
 74             android:id="@+id/btn8"
 75             android:layout_weight="1"
 76             android:soundEffectsEnabled="true"/>
 77         <Button
 78             android:layout_width="match_parent"
 79             android:layout_height="wrap_content"
 80             android:text="9"
 81             android:id="@+id/btn9"
 82             android:layout_weight="1"
 83             android:soundEffectsEnabled="true"/>
 84     </LinearLayout>
 85     <LinearLayout
 86         android:layout_width="match_parent"
 87         android:layout_height="wrap_content"
 88         android:orientation="horizontal"
 89         android:weightSum="3">
 90         <Button
 91             android:layout_width="match_parent"
 92             android:layout_height="match_parent"
 93             android:layout_margin="3dp"
 94             android:text="Cancel"
 95             android:textAllCaps="false"
 96             android:background="#FF0000"
 97             android:id="@+id/btnCancel"
 98             android:layout_weight="1"
 99             android:soundEffectsEnabled="true"/>
100         <LinearLayout
101             android:layout_width="match_parent"
102             android:layout_height="wrap_content"
103             android:orientation="vertical"
104             android:layout_weight="1"
105             android:weightSum="2">
106             <Button
107                 android:layout_width="match_parent"
108                 android:layout_height="wrap_content"
109                 android:text="0"
110                 android:id="@+id/btn0"
111                 android:layout_weight="1"
112                 android:soundEffectsEnabled="true"/>
113             <Button
114                 android:layout_width="match_parent"
115                 android:layout_height="wrap_content"
116                 android:text="Clear"
117                 android:layout_margin="3dp"
118                 android:textAllCaps="false"
119                 android:background="#FFFF00"
120                 android:id="@+id/btnClear"
121                 android:layout_weight="1"
122                 android:soundEffectsEnabled="true"/>
123         </LinearLayout>
124 
125         <Button
126             android:layout_width="match_parent"
127             android:layout_height="match_parent"
128             android:text="Enter"
129             android:layout_margin="3dp"
130             android:textAllCaps="false"
131             android:id="@+id/btnEnter"
132             android:layout_weight="1"
133             android:background="#00FF00"
134             android:soundEffectsEnabled="true"/>
135     </LinearLayout>
136 
137 </LinearLayout>


(2)逻辑设置

 1 package com.pax.dialogtest;
 2 
 3 import android.content.Context;
 4 import android.graphics.drawable.BitmapDrawable;
 5 import android.util.Log;
 6 import android.view.Gravity;
 7 import android.view.LayoutInflater;
 8 import android.view.MotionEvent;
 9 import android.view.View;
10 import android.view.ViewGroup;
11 import android.widget.Button;
12 import android.widget.PopupWindow;
13 
14 /**
15  * Created by yanina on 12/12/2016.
16  */
17 
18 public class KeyPadDialog extends PopupWindow implements View.OnClickListener{
19     private View parent;
20 
21     public KeyPadDialog(Context context, View parent){
22         super(context);
23         this.parent = parent;
24 
25         //set content view
26         LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
27         View contentView = layoutInflater.inflate(R.layout.keypad_dialog, null);
28         setContentView(contentView);
29 
30         //set width and height
31         setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
32         setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
33 
34         //
35         setOutsideTouchable(false); //
36         setFocusable(false); // Not allow to dismiss PopupWindow by touching outside
37         setTouchable(true);
38         setTouchInterceptor(new View.OnTouchListener() {
39 
40             @Override
41             public boolean onTouch(View v, MotionEvent event) {
42                 return false;
43             }
44         });
45 //        this.setBackgroundDrawable(new BitmapDrawable());
46 
47         contentView.findViewById(R.id.btn0).setOnClickListener(this);
48         contentView.findViewById(R.id.btn1).setOnClickListener(this);
49         contentView.findViewById(R.id.btn2).setOnClickListener(this);
50         contentView.findViewById(R.id.btn3).setOnClickListener(this);
51         contentView.findViewById(R.id.btn4).setOnClickListener(this);
52         contentView.findViewById(R.id.btn5).setOnClickListener(this);
53         contentView.findViewById(R.id.btn6).setOnClickListener(this);
54         contentView.findViewById(R.id.btn7).setOnClickListener(this);
55         contentView.findViewById(R.id.btn8).setOnClickListener(this);
56         contentView.findViewById(R.id.btn9).setOnClickListener(this);
57         contentView.findViewById(R.id.btnCancel).setOnClickListener(this);
58         contentView.findViewById(R.id.btnClear).setOnClickListener(this);
59         contentView.findViewById(R.id.btnEnter).setOnClickListener(this);
60     }
61 
62     public void show(){
63         // Show at bottom of parent
64         this.showAtLocation(parent, Gravity.BOTTOM,0,0);
65         Log.d("DialogTest","ShowDialog");
66     }
67 
68 
69     @Override
70     public void onClick(View view) {
71         Log.d("DialogTest","key: "+((Button)view).getText());
72         switch (view.getId()){
73             case R.id.btn0:
74             case R.id.btn1:
75             case R.id.btn2:
76             case R.id.btn3:
77             case R.id.btn4:
78             case R.id.btn5:
79             case R.id.btn6:
80             case R.id.btn7:
81             case R.id.btn8:
82             case R.id.btn9:
83                 break;
84             case R.id.btnCancel:
85                 break;
86             case R.id.btnClear:
87                 break;
88             case R.id.btnEnter:
89                 break;
90             default:
91                 break;
92         }
93     }
94 }

注意点:

PopupWindow通过设置一些属性,可以控制是否通过点击外部区域来使窗口消失。
1 // Not allow to dismiss PopupWindow by touching outside
2 setFocusable(false);
3 setTouchable(true);
4 setOutsideTouchable(false);

三个属性这样设置就可以达到一定的效果。

这样PopupWindow在触摸到外部区域后也不会消失。当然外部区域还是可以接收touch事件的,比如外部区域中的Button还是可以被点击。

3.MainActivity

package com.pax.dialogtest;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private View mView;
    KeyPadDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mView = layoutInflater.inflate(
                R.layout.activity_main, null);
        setContentView(mView);
        Button button = (Button)findViewById(R.id.buttonPanel);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog = new KeyPadDialog(MainActivity.this,mView);
                dialog.show();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();

    }
}

4.效果图

11

原文地址:https://www.cnblogs.com/tt2015-sz/p/6169476.html