Android开发之PopupWindow

 

/*

*  Android开发之PopupWindow

*

*  Created on: 2011-8-8

*  Author: blueeagle

*  Email: liujiaxiang@gmail.com

*/

聪明的人善于总结,记录,不知道这是谁说的了,反正要当一个聪明人,我得先学会总结,记录。最近在Android的学习过程中,发现 PopupWindow也是值得研究一番的一个东东,因此拿过来说道说道。与其相似的就归纳到一起说道吧,那就是AlertDialog和Toast。

PopupWindow

java.lang.Object

↳ android.widget.PopupWindow

手册中,对PopupWindow的描述是这样的:它是一个弹出的窗口,可以用来显示一个任意的视图。弹出窗口是当前活动上出现一个浮动容器。

PopupWindow的性质,其实就是我们通常所说的“模态对话框”。只有在其退出之后,才可以进行外部线程的操作。下面对其进行详细说明。

简单的PopupWindow

Android开发之PopupWindow

Android开发之PopupWindow

如图所示,通过主Activity中的一个按钮来触发弹出窗口操作。这个窗口什么都不干,就是显示一句话:“*的Android开发者”。为了增加可见性,我设置了不同的背景色加以区分。

源码如下:

  1. /*
  2. *  Android开发之PopupWindow、AlertDialog和Toast
  3. *  PopWinEx.java
  4. *  Created on: 2011-8-8
  5. *  Author: blueeagle
  6. *  Email: liujiaxiang@gmail.com
  7. */
  8. package com.blueeagle;
  9. import android.app.Activity;
  10. import android.os.Bundle;
  11. import android.view.View;
  12. import android.widget.Button;
  13. import android.widget.PopupWindow;
  14. public class PopWinEx extends Activity {
  15. /** Called when the activity is first created. */
  16. Button MyButton;
  17. PopupWindow pw;
  18. View myView;
  19. @Override
  20. public void onCreate(Bundle savedInstanceState) {
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.main);
  23. MyButton = (Button)findViewById(R.id.myButton);
  24. MyButton.setOnClickListener(new Button.OnClickListener(){
  25. @Override
  26. public void onClick(View v) {
  27. // TODO Auto-generated method stub
  28. myView = getLayoutInflater().inflate(R.layout.pop,null);
  29. pw = new PopupWindow(myView,500,200,true);
  30. pw.showAsDropDown(MyButton);
  31. }
  32. });
  33. }
  34. }

我们给PopupWindow和主界面,分别定义一个layout。对应的XML文件如下:

  1. pop.xml
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. android:background="#ffff00"
  8. >
  9. <TextView
  10. android:id="@+id/mytextview"
  11. android:layout_width="fill_parent"
  12. android:layout_height="wrap_content"
  13. android:text="@string/hello"
  14. />
  15. </LinearLayout>
  16. main.xml
  17. <?xml version="1.0" encoding="utf-8"?>
  18. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  19. android:orientation="vertical"
  20. android:layout_width="fill_parent"
  21. android:layout_height="fill_parent"
  22. android:background="#ff00ff"
  23. >
  24. <Button
  25. android:id="@+id/myButton"
  26. android:layout_width="fill_parent"
  27. android:layout_height="wrap_content"
  28. android:text="@string/hello"
  29. />
  30. </LinearLayout>

说明:这里值得注意的是,我们要给弹出窗口设置焦点,pw = new PopupWindow(myView,500,200,true);这句中的true表示弹出窗口可以获得焦点。如果弹出窗口没有获得焦点的时候,不断点击按钮的,最终程序将退出,这时是因为内存耗尽的原因,可以通过查看log得到。

 

有一定布局的PopupWindow

Android开发之PopupWindow

Android开发之PopupWindow

Android开发之PopupWindow

如图所示,同样是通过主Activity中的一个按钮来触发弹出窗口操作。但是现在这个弹出窗口可以进行一些操作,因为其具有了一定的布局,目前我们暂且其可以进行的操作为:

1.       可编辑功能

2.       可传递信息

3.       弹出窗口上再次弹出窗口

4.       可以取消当前弹出窗口

为了增加可见性,我依然设置了不同的背景色加以区分。

源码如下:

  1. /*
  2. *  Android开发之PopupWindow、AlertDialog和Toast
  3. *  PopWinEx.java
  4. *  Created on: 2011-8-9
  5. *  Author: blueeagle
  6. *  Email: liujiaxiang@gmail.com
  7. */
  8. package com.blueeagle;
  9. import android.app.Activity;
  10. import android.app.AlertDialog;
  11. import android.content.Context;
  12. import android.os.Bundle;
  13. import android.view.Gravity;
  14. import android.view.LayoutInflater;
  15. import android.view.View;
  16. import android.view.View.OnClickListener;
  17. import android.widget.Button;
  18. import android.widget.EditText;
  19. import android.widget.PopupWindow;
  20. import android.widget.TextView;
  21. public class PopWinEx extends Activity {
  22. /** Called when the activity is first created. */
  23. Button MyButton;
  24. Button MyExit;
  25. @Override
  26. public void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.main);
  29. MyButton = (Button)findViewById(R.id.myButton);
  30. MyExit = (Button)findViewById(R.id.myExit);
  31. MyButton.setOnClickListener(new clickEvent());
  32. MyExit.setOnClickListener(new ExitEvent());
  33. }
  34. class clickEvent implements OnClickListener {
  35. @Override
  36. public void onClick(View v) {
  37. // TODO Auto-generated method stub
  38. if(v==MyButton) {
  39. showPopWindow(PopWinEx.this,MyButton);
  40. }
  41. }
  42. }
  43. class ExitEvent implements OnClickListener {
  44. @Override
  45. public void onClick(View v) {
  46. // TODO Auto-generated method stub
  47. if(v==MyExit) {
  48. finish();
  49. }
  50. }
  51. }
  52. private void showPopWindow(Context context, View parent) {
  53. // TODO Auto-generated method stub
  54. final PopupWindow pw;
  55. View myView;
  56. LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  57. myView = inflater.inflate(R.layout.pop, null);
  58. Button pop_OK = (Button)myView.findViewById(R.id.button_ok);
  59. Button pop_Cancel = (Button)myView.findViewById(R.id.button_cancel);
  60. final EditText pop_User = (EditText)myView.findViewById(R.id.edittext);
  61. final EditText pop_Password = (EditText)myView.findViewById(R.id.password);
  62. pw = new PopupWindow(myView,500,200,true);
  63. pop_OK.setOnClickListener(new OnClickListener(){
  64. @Override
  65. public void onClick(View v) {
  66. showPop_PopWindow();
  67. // TODO Auto-generated method stub
  68. }
  69. private void showPop_PopWindow() {
  70. // TODO Auto-generated method stub
  71. View myView1;
  72. myView1 = getLayoutInflater().inflate(R.layout.pop1,null);
  73. TextView User_Is = (TextView)myView1.findViewById(R.id.useris);
  74. TextView Password_Is = (TextView)myView1.findViewById(R.id.passwordis);
  75. User_Is.setText(pop_User.getText().toString());
  76. Password_Is.setText(pop_Password.getText().toString());
  77. final PopupWindow pw_pw;
  78. pw_pw = new PopupWindow(myView1,500,200,true);
  79. Button pop_pop_OK = (Button)myView1.findViewById(R.id.button_ok1);
  80. Button pop_pop_Cancel = (Button)myView1.findViewById(R.id.button_cancel1);
  81. pop_pop_Cancel.setOnClickListener(new OnClickListener(){
  82. @Override
  83. public void onClick(View v) {
  84. pw_pw.dismiss();//
  85. }
  86. });
  87. pop_pop_OK.setOnClickListener(new OnClickListener(){
  88. @Override
  89. public void onClick(View v) {
  90. AlertDialog.Builder my_ADialog =new AlertDialog.Builder(PopWinEx.this);
  91. my_ADialog.setTitle("我是弹出对话框的弹出对话框");
  92. my_ADialog.setMessage("怎么样?学会了吗?");
  93. my_ADialog.show();
  94. }
  95. });
  96. pw_pw.showAtLocation(myView1.findViewById(R.id.button_ok1), Gravity.CENTER, 200, 200);
  97. }
  98. });
  99. pop_Cancel.setOnClickListener(new OnClickListener(){
  100. @Override
  101. public void onClick(View v) {
  102. pw.dismiss();//
  103. }
  104. });
  105. pw.showAsDropDown(MyButton);
  106. }
  107. }

我们给PopupWindow,弹出窗口的弹出窗口和主界面,分别定义一个layout。对应的XML文件如下:

  1. main.xml
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. android:background="#ff00ff"
  8. >
  9. <Button
  10. android:id="@+id/myButton"
  11. android:layout_width="fill_parent"
  12. android:layout_height="wrap_content"
  13. android:text="@string/hello"
  14. />
  15. <Button
  16. android:id="@+id/myExit"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content"
  19. android:text="退出程序"
  20. />
  21. </LinearLayout>
  22. pop1.xml
  23. <?xml version="1.0" encoding="utf-8"?>
  24. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  25. android:orientation="vertical"
  26. android:layout_width="fill_parent"
  27. android:layout_height="fill_parent"
  28. android:background="#ffff00"
  29. >
  30. <TextView
  31. android:id="@+id/mytextview"
  32. android:layout_width="wrap_content"
  33. android:layout_height="wrap_content"
  34. android:text="@string/hello"
  35. />
  36. <TextView
  37. android:text="您输入的账号是:"
  38. android:layout_width="180dip"
  39. android:layout_height="wrap_content"
  40. />
  41. <TextView
  42. android:id="@+id/useris"
  43. android:layout_width="wrap_content"
  44. android:layout_height="wrap_content"
  45. />
  46. <TextView
  47. android:text="您输入的密码是:"
  48. android:layout_width="180dip"
  49. android:layout_height="wrap_content"
  50. />
  51. <TextView
  52. android:id="@+id/passwordis"
  53. android:layout_width="wrap_content"
  54. android:layout_height="wrap_content"
  55. />
  56. <LinearLayout
  57. android:orientation="horizontal"
  58. android:layout_width="fill_parent"
  59. android:layout_height="fill_parent"
  60. android:background="#ffff00"
  61. >
  62. <Button
  63. android:id="@+id/button_ok1"
  64. android:layout_width="wrap_content"
  65. android:layout_height="wrap_content"
  66. android:text="确定"
  67. />
  68. <Button
  69. android:id="@+id/button_cancel1"
  70. android:layout_width="wrap_content"
  71. android:layout_height="wrap_content"
  72. android:text="取消"
  73. />
  74. </LinearLayout>
  75. </LinearLayout>
  76. pop.xml
  77. <?xml version="1.0" encoding="utf-8"?>
  78. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  79. android:orientation="vertical"
  80. android:layout_width="fill_parent"
  81. android:layout_height="fill_parent"
  82. android:background="#ffff00"
  83. >
  84. <TextView
  85. android:id="@+id/mytextview"
  86. android:layout_width="wrap_content"
  87. android:layout_height="wrap_content"
  88. android:text="@string/hello"
  89. />
  90. <TextView
  91. android:id="@+id/mytextview"
  92. android:layout_width="wrap_content"
  93. android:layout_height="wrap_content"
  94. android:text="账号"
  95. />
  96. <EditText
  97. android:id="@+id/edittext"
  98. android:layout_width="180dip"
  99. android:layout_height="wrap_content"
  100. />
  101. <TextView
  102. android:layout_width="wrap_content"
  103. android:layout_height="wrap_content"
  104. android:text="密码"
  105. />
  106. <EditText
  107. android:id="@+id/password"
  108. android:layout_width="180dip"
  109. android:layout_height="wrap_content"
  110. android:password="true"
  111. />
  112. <LinearLayout
  113. android:orientation="horizontal"
  114. android:layout_width="fill_parent"
  115. android:layout_height="fill_parent"
  116. android:background="#ffff00"
  117. >
  118. <Button
  119. android:id="@+id/button_ok"
  120. android:layout_width="wrap_content"
  121. android:layout_height="wrap_content"
  122. android:text="确定"
  123. />
  124. <Button
  125. android:id="@+id/button_cancel"
  126. android:layout_width="wrap_content"
  127. android:layout_height="wrap_content"
  128. android:text="取消"
  129. />
  130. </LinearLayout>
  131. </LinearLayout>

说明:这里值得注意的是,弹出窗口上再次弹出窗口需要将调用findViewById函数的视图明确。然后将相应的变量设置成final类型。弹出窗口其实是一个View,这个View需要用     LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

myView = inflater.inflate(R.layout.pop, null);来进行索引。找到相应的xml布局文件,来安排弹出窗口是什么样的。当然,在实际开发中,可能会遇见没有xml布局文件的View,这怎么办呢?直接new出来就可以了,比如:

mView = new PopView(mContext, 800, 400);

PopupWindow pw= new PopupWindow(mView,800,400,true);

这里我没有对string做特别的处理,因为时间比较紧张。这并不是一个好的编程习惯。希望大家把语言类的东西都放在string里去,不要硬写在程序代码里。

PopupWindow的特殊效果

Android开发之PopupWindow

PopupWindow的效果可以做的很炫,可以有边框,圆角,透明,渐变色,动画等。下面逐一来实现。

比如我要在上面的例子中实现这些操作,即可添加一个语句:

myView.setBackgroundResource(R.drawable.round_win);

当然,最主要的就是round_win.xml里面所写的内容了:

  1. round_win.xml
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:shape="rectangle">
  5. <gradient android:startColor="#e0000fff" android:endColor="#e000ff00"
  6. android:angle="90" /><!--背景颜色渐变 -->
  7. <stroke android:dashWidth="2dp" android:dashGap="2dp"
  8. android:width="2dp" android:color="#ff0000"></stroke>
  9. <!--描边 -->
  10. <corners android:bottomRightRadius="5dp"
  11. android:bottomLeftRadius="5dp" android:topLeftRadius="5dp"
  12. android:topRightRadius="5dp" /><!--设置圆角-->
  13. </shape>

当然,最主要的就是round_win.xml里面所写的内容了。对于上面,这条 shape 的定义,分别为渐变,在gradient
中startColor属性为开始的颜色,endColor 为渐变结束的颜色,下面的 angle 是角度。接下来是
stroke可以理解为边缘,dashWidth 表示宽度,dashGap 表示断续;corners 为拐角这里radius
属性为半径,最后是相对位置属性 padding。

android:color 是一个16 进制颜色。这个颜色由RGB 值指定,可带Alpha 。必须以“# ”开头,后面跟随Alpha-Red-Green-Blue。Alpha表示的是透明度,0为全透明,ff为全不透明。

以上完成了弹出窗口的边框,渐变色,透明,圆角等操作。

下面进行有意思的动画操作。

先设置一下弹出窗口的进入和退出的xml文件。首先要在res目录下建立文件夹anim,里面建立动画描述文件。如下所示:

  1. ani_in.xml
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <set xmlns:android="http://schemas.android.com/apk/res/android">
  4. <translate android:interpolator="@android:anim/accelerate_decelerate_interpolator"
  5. android:fromYDelta="-100"
  6. android:toYDelta="0"
  7. android:duration="1000"
  8. android:fillEnabled="true"
  9. android:fillAfter="true"
  10. />
  11. <scale android:fromXScale="0.6" android:toXScale="1.0"
  12. android:fromYScale="0.6" android:toYScale="1.0" android:pivotX="50%"
  13. android:pivotY="50%" android:duration="2000" />
  14. <alpha android:interpolator="@android:anim/decelerate_interpolator"
  15. android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="2000" />
  16. </set>
  17. ani_out.xml
  18. <?xml version="1.0" encoding="utf-8"?>
  19. <set xmlns:android="http://schemas.android.com/apk/res/android"
  20. android:oneshot="true"
  21. >
  22. <translate android:interpolator="@android:anim/accelerate_decelerate_interpolator"
  23. android:fromYDelta="0"
  24. android:toYDelta="-100"
  25. android:duration="1000"
  26. android:fillEnabled="true"
  27. android:fillAfter="true"
  28. />
  29. <scale android:fromXScale="1.0" android:toXScale="0.4"
  30. android:fromYScale="1.0" android:toYScale="0.4" android:pivotX="50%"
  31. android:pivotY="50%" android:duration="2000" />
  32. <alpha android:interpolator="@android:anim/decelerate_interpolator"
  33. android:fromAlpha="1.0"
  34. android:toAlpha="0.0"
  35. android:duration="2000"
  36. />
  37. </set>

在Values文件夹中建立style.xml文件如下:

style.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <style name="mytheme" parent="@android:style/Theme.Light">
  4. <item name="android:windowNoTitle"> true </item>
  5. </style>
  6. <style name="PopupAnimation" parent="android:Animation">
  7. <item name="android:windowEnterAnimation">@anim/ani_in</item>
  8. <item name="android:windowExitAnimation">@anim/ani_out</item>
  9. </style>
  10. </resources>

最后在Activity代码文件中加入:

pw.setAnimationStyle(R.style.PopupAnimation);

动画效果就出来了,怎么样?很炫吧

 
上一篇:Android开发之旅: Intents和Intent Filters(理论部分)


下一篇:Android开发之Java必备基础