弹窗,可以使用PopupWindow方式,也可以自己制作一个PopupWindow,下面分说两种方式:
(一)自己制作一个PopupWindow,实际是一个activity,关键是加入自定义的theme
效果图如下:

(1)自定义弹窗activity类SelectPicPopupWindow.java
package com.example.picpopupwindow;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
public class SelectPicPopupWindow extends Activity {
private Button btn_cancel;
private LinearLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alert_dialog);
btn_cancel = (Button) this.findViewById(R.id.btn_cancel);
layout = (LinearLayout) findViewById(R.id.pop_layout);
// 添加选择窗口范围监听可以优先获取触点,即不再执行onTouchEvent()函数,点击其他地方时执行onTouchEvent()函数销毁Activity
layout.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "提示:点击窗口外部关闭窗口!",
Toast.LENGTH_SHORT).show();
}
});
// 添加按钮监听
btn_cancel.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
}
// 实现onTouchEvent触屏函数但点击屏幕时销毁本Activity
@Override
public boolean onTouchEvent(MotionEvent event) {
finish();
return true;
}
}
(2) 布局文件alert_dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/pop_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/shape_half_rounded"
android:gravity="center_horizontal"
android:orientation="vertical" >
<Button
android:id="@+id/btn_take_photo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginTop="20dip"
android:background="@drawable/btn_style_alert_dialog_button"
android:text="拍照"
android:textStyle="bold" />
<Button
android:id="@+id/btn_pick_photo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginTop="5dip"
android:background="@drawable/btn_style_alert_dialog_button"
android:text="从相册选择"
android:textStyle="bold" />
<Button
android:id="@+id/btn_cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginTop="15dip"
android:background="@drawable/btn_style_alert_dialog_cancel"
android:text="取消"
android:textColor="#ffffff"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
(3)弹出层的半圆角背景,可以使用.9文件,也可以使用shape制作的半圆角背景shape_half_rounded.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#CCCCCC" />
<corners
android:bottomLeftRadius="0px"
android:bottomRightRadius="0px"
android:topLeftRadius="10px"
android:topRightRadius="10px" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
</shape>
(4)按钮点击效果(图片附件有)
btn_style_alert_dialog_button.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/btn_style_alert_dialog_button_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/btn_style_alert_dialog_button_normal"/>
</selector>
btn_style_alert_dialog_cancel.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/btn_style_alert_dialog_button_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/btn_style_alert_dialog_cancel_normal"/>
</selector>
使用很简单:
(1)MainActivity.java
package com.example.picpopupwindow;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView photo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
photo = (ImageView) this.findViewById(R.id.text);
// 把文字控件添加监听,点击弹出自定义窗口
photo.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//使用startActivityForResult启动SelectPicPopupWindow当返回到此Activity的时候就会调用onActivityResult函数
startActivity(new Intent(MainActivity.this,SelectPicPopupWindow.class));
}
});
}
}
(2)简单的布局文件(就一张图,一点击就弹出选择菜单)activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@drawable/app_panel_friendcard_icon"
/>
</RelativeLayout>
(3)AndroidManifest.xml(关键是使用了自定义的theme)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.picpopupwindow"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SelectPicPopupWindow" android:theme="@style/MyDialogStyleBottom" />
</application>
</manifest>
(4)关键的主题styles.xml:
<resources>
<style name="AppTheme" parent="android:Theme.Light" />
<style name="AnimBottom" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
<item name="android:windowExitAnimation">@anim/push_bottom_out</item>
</style>
<!-- 想实现Dialog方式可以继承 parent="android:Theme.Dialog" ,想当成普通的activity可以继承 parent="android:Theme.Light"-->
<style name="MyDialogStyleBottom" parent="android:Theme.Light">
<item name="android:windowAnimationStyle">@style/AnimBottom</item>
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上,Dialog才会将它设置为true,默认是false的,所以不是想实现Dialog浮现方式,可以不用写这个item -->
<!--
<item name="android:windowIsFloating">false</item>
-->
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 全屏,如果设置为true,并且android:windowIsFloating也设置为false之后,才会看到全屏效果,
即手机本身的小通知图标栏都消息掉。
我测试过,将android:windowIsFloating设置为true,和将style的继承parent设置为android:Theme.Dialog效果是一样的,都不会全屏,且左右两边有空间
默认是false,所以不想全屏,可以不写这个item
-->
<item name="android:windowFullscreen">false</item>
</style>
</resources>
这里特别要注意的是android:windowIsFloating设置,如果设置为true,那么左右两边怎么都会有较大的空隙,死也不会全屏。
(5) 进入退出动画:
push_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fromYDelta="100%p"
android:toYDelta="0"
/>
</set>
push_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑出式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fromYDelta="0"
android:toYDelta="50%p" />
</set>
就这样简单实现了弹出层,源代码见PicPopupWindow.zip。
(二)继承PopupWindow的方式来实现一个想要的弹出窗口:
(1)SelectPicPopupWindow.java(布局alert_dialog跟上面一样的)
package com.example.picpopupwindow;
import android.app.Activity;
import android.content.Context;
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.LayoutParams;
import android.widget.Button;
import android.widget.PopupWindow;
public class SelectPicPopupWindow extends PopupWindow {
private Button btn_take_photo, btn_pick_photo, btn_cancel;
private View mMenuView;
public SelectPicPopupWindow(Activity context,OnClickListener itemsOnClick) {
super(context);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMenuView = inflater.inflate(R.layout.alert_dialog, null);
btn_take_photo = (Button) mMenuView.findViewById(R.id.btn_take_photo);
btn_pick_photo = (Button) mMenuView.findViewById(R.id.btn_pick_photo);
btn_cancel = (Button) mMenuView.findViewById(R.id.btn_cancel);
//取消按钮
btn_cancel.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//销毁弹出框
dismiss();
}
});
//设置按钮监听
btn_pick_photo.setOnClickListener(itemsOnClick);
btn_take_photo.setOnClickListener(itemsOnClick);
//设置SelectPicPopupWindow的View
this.setContentView(mMenuView);
//设置SelectPicPopupWindow弹出窗体的宽
this.setWidth(LayoutParams.FILL_PARENT);
//设置SelectPicPopupWindow弹出窗体的高
this.setHeight(LayoutParams.WRAP_CONTENT);
//设置SelectPicPopupWindow弹出窗体可点击,点击就消失的功能,也是这里设置的
this.setFocusable(true);
//设置SelectPicPopupWindow弹出窗体动画效果
this.setAnimationStyle(R.style.AnimBottom);
//实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0x00000000);
//设置SelectPicPopupWindow弹出窗体的背景
this.setBackgroundDrawable(dw);
/**
* mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框
*/
mMenuView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int height = mMenuView.findViewById(R.id.pop_layout).getTop();
int y=(int) event.getY();
if(event.getAction()==MotionEvent.ACTION_UP){
if(y<height){
dismiss();
}
}
return true;
}
});
}
}
(2) 使用时,这里要指定在哪个控件的哪个方向上显示自定义的popupWindow:
package com.example.picpopupwindow;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class MainActivity extends Activity {
//自定义的弹出框类
SelectPicPopupWindow menuWindow;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) this.findViewById(R.id.text);
//把文字控件添加监听,点击弹出自定义窗口
tv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//实例化SelectPicPopupWindow
menuWindow = new SelectPicPopupWindow(MainActivity.this, itemsOnClick);
//显示窗口
menuWindow.showAtLocation(MainActivity.this.findViewById(R.id.main), Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0); //设置layout在PopupWindow中显示的位置
menuWindow.setBackgroundDrawable(getResources().getDrawable(R.color.half_transparent));
}
});
}
//为弹出窗口实现监听类
private OnClickListener itemsOnClick = new OnClickListener(){
public void onClick(View v) {
menuWindow.dismiss();
switch (v.getId()) {
case R.id.btn_take_photo:
break;
case R.id.btn_pick_photo:
break;
default:
break;
}
}
};
}
自定义的PopupWindow这里不用在AndroidManifest.xml里进行配置,直接使用,所以不用定主题,效果跟第一种自已使用activity制作的一样,代码见PicPopupWindow2.zip
本文介绍两种实现自定义弹窗的方法:一是通过创建一个带有特定主题的Activity;二是利用PopupWindow类。这两种方法均详细展示了如何设置弹窗样式、监听器及动画效果。
204

被折叠的 条评论
为什么被折叠?



