昨天马失前蹄,为了做一个小键盘,耽误了两个小时,记录一下心路历程
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(); } }