一.摘要
弹窗通常用于提示用户进行某种操作,比如:点击分享按钮,弹窗分享对话框;双击返回按钮,弹窗退出对话框;下载文件,提示下载对话框等等,分享对话框/退出对话框/下载对话框,都可以直接使用AlertDialog实现,类似的效果如下图:
二.AlertDialog基础知识
AlertDialog无法直接通过new关键字获取对象,调用方法:new AlertDialog.Builder.create()获取AlertDialog对象,这个时候容易让人疑惑的是:如何设置对话框的属性?比如:对话框标题,对话框消息,对话框按钮等等
设置对话框属性的两种方式
第一种:设置AlertDialog对象属性,具体代码如下:
- private void showDialog() {
- AlertDialog mDialog = null;
- mDialog = new AlertDialog.Builder(this).create();;
- mDialog.setIcon(R.drawable.ic_launcher);
- mDialog.setTitle("系统提示");
- mDialog.setMessage("你确定要退出吗?");
- mDialog.setButton(DialogInterface.BUTTON_POSITIVE,"确定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- finishMyself();
- }
- });
- mDialog.setButton(DialogInterface.BUTTON_NEGATIVE,"取消", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Toast.makeText(MainActivity.this, "再按一次退出程序", (int) touchTime)
- .show();
- }
- });
- mDialog.show();
- }
第二种:设置Builder对象属性,具体代码如下:
- private void showDialog() {
- AlertDialog mDialog = null;
- Builder mBuilder = new AlertDialog.Builder(this);
- mBuilder.setIcon(R.drawable.ic_launcher);
- mBuilder.setTitle("系统提示");
- mBuilder.setMessage("你确定要退出吗?");
- mBuilder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
- mBuilder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Toast.makeText(MainActivity.this, "再按一次退出程序", (int) touchTime)
- .show();
- }
- });
- mDialog = mBuilder.create();//创建AlertDialog对象
- mDialog.show();//显示创建的AlertDialog
- }
这两种方式的对话框展示默认属性——对话框水平垂直居中显示,对话框与左右窗体之间有一小段距离,效果图如下:
如何修改默认对话框属性?
如何修改AlertDialog对话框默认属性,然后实现对话框内容宽度布满屏幕,高度根据内容自适应,类似文章开头点击分享按钮,从底部弹出弹窗的效果。首先创建AlertDialog对话框,然后自定义对话框的布局View,最后设置Window对象属性。
设置Window对象屏幕宽度/高度的三种方式
第一种方式:setLayout()
获得Window对象后,设置Window对象的布局参数,即调用setLayout(int width,int height)方法,width取值:android.view.WindowManager.LayoutParams.MATCH_PARENT/android.view.WindowManager.LayoutParams.WRAP_CONTENT,同理height取值:android.view.WindowManager.LayoutParams.MATCH_PARENT/android.view.WindowManager.LayoutParams.WRAP_CONTENT,具体代码如下:
- View view = getLayoutInflater().inflate(R.layout.popup_dialog, null);
- AlertDialog mDialog = new AlertDialog.Builder(this).create();
- mDialog.show();// 显示创建的AlertDialog,并显示,必须放在Window设置属性之前
- /**
- *设置mDialog窗口属性:MATCH_PARENT/WRAP_CONTENT
- *
- */
- Window window =mDialog.getWindow();
- window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
- window.setLayout(android.view.WindowManager.LayoutParams.MATCH_PARENT,
- android.view.WindowManager.LayoutParams.WRAP_CONTENT);
第二种方式:setAttributes()
获得Window对象后,设置Window对象的属性值,即调用setAttributes(LayoutParams)方法,LayoutParams的width变量取值:android.view.WindowManager.LayoutParams.MATCH_PARENT/android.view.WindowManager.LayoutParams.WRAP_CONTENT,同理height变量取值:android.view.WindowManager.LayoutParams.MATCH_PARENT/android.view.WindowManager.LayoutParams.WRAP_CONTENT,具体代码如下:
- View view = getLayoutInflater().inflate(R.layout.popup_dialog, null);
- AlertDialog mDialog = new AlertDialog.Builder(this).create();
- mDialog.show();// 显示创建的AlertDialog,并显示,必须放在Window设置属性之前
- Window window =mDialog.getWindow();
- window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
- WindowManager.LayoutParams mParams = window.getAttributes();
- mParams.width = android.view.WindowManager.LayoutParams.MATCH_PARENT;
- mParams.height = android.view.WindowManager.LayoutParams.WRAP_CONTENT;
- window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
- window.setAttributes(mParams);
第三种方式:setLayout()
具体代码如下:
- View view = getLayoutInflater().inflate(R.layout.popup_dialog, null);
- AlertDialog mDialog = new AlertDialog.Builder(this).create();
- mDialog.show();// 显示创建的AlertDialog,并显示,必须放在Window设置属性之前
- Window window =mDialog.getWindow();
- window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
- WindowManager manager = getWindowManager();
- Display display = manager.getDefaultDisplay();
- int width = display.getWidth();//获取当前屏幕宽度
- int height = 300;//自定义高度值,比如:300dp
- window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
- window.setLayout(width, height);
三.弹窗动画基础知识
Android的基本动画包括:渐变动画/平移动画/缩放动画/旋转动画/组合动画,更多内容可以参考《Android代码绘制虚线、圆角、渐变和阴影效果图》,点击“分享”按钮,弹窗从底部弹窗,再次点击弹窗消失,设置的动画——平移动画,代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <!--enter_dialog_anim.xml,弹窗进入动画-->
- <translate xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="300"
- android:fromYDelta="100%">
- </translate>
- <?xml version="1.0" encoding="utf-8"?>
- <!--exit_dialog_anim.xml,弹窗退出动画-->
- <translate xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="300"
- android:toYDelta="100%" >
- </translate>
在style.xml文件中添加Window进入和退出分别引用的动画类型,代码如下:
- <!-- 分享功能弹窗动画 -->
- <style name="popup_style" parent="android:Animation">
- <item name="@android:windowEnterAnimation">@anim/enter_dialog_anim</item>
- <item name="@android:windowExitAnimation">@anim/exit_dialog_anim</item>
- </style>
在Window属性设置中调用setContentView()指定View对象,同时调用setWindowAnimations()指定添加的动画,代码如下:
- window.setContentView(view);//这一步必须指定,否则不出现弹窗
- window.setWindowAnimations(R.style.popup_style); // 添加动画
四.自定义弹窗:MyDialogActivity
自定义MyDialogActivity实现AlertDialog同样的功能,点击“分享按钮”,从窗口底部弹出弹窗,点击“取消”弹窗消息,最终效果和AlertDialog实现的弹窗效果一模一样,如下图:
开发步骤:
1.定义布局popup_main.xml。popup_main.xml定义弹窗最终展示的样子,可以放置多个平台的分享按钮,比如:微信/微博/空间/人人等,代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <!-- 底部弹窗布局 -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/transparent"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/share_weibo_tv"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/share_padding"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:text="@string/weibo" />
- <TextView
- android:id="@+id/share_weixin_tv"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/share_padding"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:text="@string/weixin" />
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/share_kongjian_tv"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/share_padding"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:text="@string/kongjian" />
- <TextView
- android:id="@+id/share_qq_tv"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/share_padding"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:text="@string/qq" />
- </LinearLayout>
- <Button
- android:id="@+id/cancel_btn"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="@dimen/activity_vertical_margin"
- android:background="@drawable/btn_bg"
- android:text="@string/cancel" />
- </LinearLayout>
2.定义Theme样式。Theme样式定义在style.xml文件中,在AndroidManifest.xml文件中的
- <!-- MyDialogActivity自定义Threme -->
- <style name="Theme.CustomDialog" parent="@android:style/Theme.Dialog">
- <item name="android:windowNoTitle">true</item>
- <!-- 设置title -->
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:windowFrame">@null</item>
- <!-- 设置边框 -->
- <item name="android:windowIsTranslucent">true</item>
- <!-- 设置半透明 -->
- <item name="android:windowFullscreen">true</item>
- <!-- 设置全屏 -->
- </style>
- <activity android:name="MyDialogActivity" android:theme="@style/Theme.CustomDialog"/>
3.实现MyDialogActivity具体功能。
- package cn.teachcourse.main;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- 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.TextView;
- /*
- @author postmaster@teachcourse.cn
- @date 创建于:2016-4-14
- */
- public class MyDialogActivity extends Activity implements OnClickListener {
- private View view;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- view = getLayoutInflater().inflate(R.layout.popup_main, null, false);
- setContentView(view);
- initView();
- }
- private void initView() {
- Window window = getWindow();
- window.setLayout(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
- android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
- window.setGravity(Gravity.BOTTOM);
- window.setWindowAnimations(R.style.popup_style); // 添加动画
- TextView weibo_tv = (TextView) view.findViewById(R.id.share_weibo_tv);
- TextView weixin_tv = (TextView) view.findViewById(R.id.share_weixin_tv);
- TextView qq_tv = (TextView) view.findViewById(R.id.share_qq_tv);
- TextView kongjian_tv = (TextView) view
- .findViewById(R.id.share_kongjian_tv);
- Button cancel_btn = (Button) view.findViewById(R.id.cancel_btn);
- // 添加控件事件
- weibo_tv.setOnClickListener(this);
- weixin_tv.setOnClickListener(this);
- qq_tv.setOnClickListener(this);
- kongjian_tv.setOnClickListener(this);
- cancel_btn.setOnClickListener(this);
- // 调整图片的大小/位置
- abjustDrawablePos(weibo_tv, R.drawable.share_weibo);
- abjustDrawablePos(weixin_tv, R.drawable.share_weixin);
- abjustDrawablePos(kongjian_tv, R.drawable.share_kongjian);
- abjustDrawablePos(qq_tv, R.drawable.share_qq);
- }
- /**
- * 添加图标和调整位置
- *
- * @param tv
- * @param draw
- */
- @SuppressLint("ResourceAsColor")
- private void abjustDrawablePos(TextView tv, int draw) {
- Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), draw);
- mBitmap = centerSquareScaleBitmap(mBitmap, 250);
- Drawable drawable = new BitmapDrawable(mBitmap);
- drawable.setBounds(0, 48, 0, 48);// 设置图片的边界
- tv.setTextColor(R.color.fontcolor);
- tv.setCompoundDrawables(null, drawable, null, null);// setCompoundDrawables()和setBounds()方法一起使用
- // 添加TextView图标
- tv.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
- tv.setCompoundDrawablePadding(10);// 设置图片和text之间的间距
- if (mBitmap != null) {
- mBitmap = null;
- drawable = null;
- }
- }
- /**
- *
- * @param bitmap
- * 原图
- * @param edgeLength
- * 希望得到的正方形部分的边长
- * @return 缩放截取正中部分后的位图。
- */
- public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength) {
- if (null == bitmap || edgeLength <= 0) {
- return null;
- }
- Bitmap result = bitmap;
- int widthOrg = bitmap.getWidth();
- int heightOrg = bitmap.getHeight();
- if (widthOrg >= edgeLength && heightOrg >= edgeLength) {
- // 压缩到一个最小长度是edgeLength的bitmap
- int longerEdge = (int) (edgeLength * Math.max(widthOrg, heightOrg) / Math
- .min(widthOrg, heightOrg));
- int scaledWidth = widthOrg > heightOrg ? longerEdge : edgeLength;
- int scaledHeight = widthOrg > heightOrg ? edgeLength : longerEdge;
- Bitmap scaledBitmap;
- try {
- scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth,
- scaledHeight, true);
- } catch (Exception e) {
- return null;
- }
- // 从图中截取正中间的正方形部分。
- int xTopLeft = (scaledWidth - edgeLength) / 2;
- int yTopLeft = (scaledHeight - edgeLength) / 2;
- try {
- result = Bitmap.createBitmap(scaledBitmap, xTopLeft, yTopLeft,
- edgeLength, edgeLength);
- scaledBitmap.recycle();
- } catch (Exception e) {
- return null;
- }
- }
- return result;
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- /**
- * 点击分享图标,弹出分享界面
- */
- case R.id.share_to_btn:
- break;
- case R.id.share_weibo_tv:
- break;
- case R.id.share_weixin_tv:
- break;
- case R.id.share_qq_tv:
- break;
- case R.id.share_kongjian_tv:
- break;
- case R.id.cancel_btn:
- finish();
- break;
- default:
- break;
- }
- }
- }
4.弹出弹窗,调用startActivity(this,MyDialogActivity.class)。
当前文章价值8.17元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)