【Android应用开发】EasyDialog 源码解析
示例源码下载 : http://download.csdn.net/detail/han1202012/9115227
EasyDialog 简介 :
-- 作用 : 用于在界面进行一些介绍, 说明;
-- 效果图 :
一. EasyDialog 源码解析
1. 实现原理
实现原理 :
-- EasyDialog 效果 : 在点击后, 会从屏幕外飞入对话框, 飞入恰好能够正好处于特定 View 组件的上方 或者下方;
-- 本质 : 点击按钮弹出的对话框会填充整个屏幕, 背景设置成透明的, 然后会计算组件坐标, 记录坐标位置, 再在弹出的整个对话框中 绘制一个 带小三角对话框的布局, 并让其执行动画;
2. 动画效果总结
(1) 动画实现核心代码
对话框显示小时动画效果实现代码片段 :
private AnimatorSet animatorSetForDialogShow; private AnimatorSet animatorSetForDialogDismiss; private List<Animator> objectAnimatorsForDialogShow; private List<Animator> objectAnimatorsForDialogDismiss; /** * 对话框显示的动画 */ private void onDialogShowing() { if (animatorSetForDialogShow != null && objectAnimatorsForDialogShow != null && objectAnimatorsForDialogShow.size() > 0) { animatorSetForDialogShow.playTogether(objectAnimatorsForDialogShow); animatorSetForDialogShow.start(); } } /** * 对话框消失的动画 */ private void onDialogDismiss() { if (animatorSetForDialogDismiss.isRunning()) { return; } if (animatorSetForDialogDismiss != null && objectAnimatorsForDialogDismiss != null && objectAnimatorsForDialogDismiss.size() > 0) { animatorSetForDialogDismiss .playTogether(objectAnimatorsForDialogDismiss); animatorSetForDialogDismiss.start(); animatorSetForDialogDismiss .addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { dialog.dismiss(); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } else { dialog.dismiss(); } }
(2) AnimatorSet 简介
AnimationSet 与 AnimatorSet 区别 : AnimatorSet 功能较强;
-- AnimatorSet : 执行的是 Animator 动画, 主要是靠改变视图属性产生动画效果;
-- AnimationSet : 执行的是 Animation 动画, 主要是靠改变视图的外观实现动画效果;
Animator 简介 : Animator 也是一种动画, 可以由用户执行开始, 中断执行, 还可以设置动画执行监听器;
AnimatorSet 简介 :
-- 功能 : 按照特定顺序执行一个 Animator 动画集合, 动画可以一起执行, 先后执行, 延迟执行;
-- 添加动画 : 有两种方式向 AnimatorSet 中添加动画, 调用 playTogether() 或者 playSequentially() 可以一次性向其中添加一个 动画集合, 调用 AnimatorSet.Builder 中得 play() 方法, 可以一个一个地向其中添加动画;
3. 坐标计算时机
坐标计算 : 计算坐标时需要获取组件的宽 和 高, 下面的代码中可以获取宽高, 获取到宽高后, 其坐标自然就计算好了;
-- 获取屏幕宽高代码 : 在其中的 onGlobalLayout 方法中可以获取其宽高;
/* * 获取对话框的宽 高 * 不是真的获取对话框的宽高, 是在对话框被构建绘制到 布局中时 * 利用这个时机去设置对话框位置 */ ViewTreeObserver viewTreeObserver = dialogView.getViewTreeObserver(); viewTreeObserver .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 当View可以获取宽高的时候,设置view的位置 relocation(location); } });
4. 屏幕填充设置
设置是否填充屏幕 :
/** * 设置是否填充屏幕,如果不填充就适应布局内容的宽度,显示内容的位置会尽量随着三角形的位置居中 */ public EasyDialog setMatchParent(boolean matchParent) { ViewGroup.LayoutParams layoutParams = llContent.getLayoutParams(); layoutParams.width = matchParent ? ViewGroup.LayoutParams.MATCH_PARENT : ViewGroup.LayoutParams.WRAP_CONTENT; llContent.setLayoutParams(layoutParams); return this; }
-- 填充屏幕样式 : 可以看到 填充全屏, 左右只留下了 margin;
-- 不填充屏幕样式 : 不会横向充满屏幕;
二. EasyDialog 主要源码
1. EasyDialog 包装类
package cn.org.octopus.easydialog; import java.util.ArrayList; import java.util.List; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.RotateDrawable; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Toast; public class EasyDialog { /** * 上下文对象 */ private Context context; /** * 内容在三角形上面 */ public static final int GRAVITY_TOP = 0; /** * 内容在三角形下面 */ public static final int GRAVITY_BOTTOM = 1; /** * 对话框本身 */ private Dialog dialog; /** * 坐标 */ private int[] location; /** * 提醒框位置 */ private int gravity; /** * 外面传递进来的View */ private View contentView; /** * 三角形 */ private ImageView ivTriangle; /** * 用来放外面传递进来的View */ private LinearLayout llContent; /** * 触摸外面,是否关闭对话框 */ private boolean touchOutsideDismiss; /** * 提示框所在的容器 */ private RelativeLayout rlOutsideBackground; public EasyDialog(Context context) { initDialog(context); } /** * 初始化 * @param context */ private void initDialog(final Context context) { this.context = context; /* * 说明传入的对象是一个 Activity * 获取 Activity 的布局加载器 */ LayoutInflater layoutInflater = ((Activity) context) .getLayoutInflater(); //要显示的对话框布局 View dialogView = layoutInflater.inflate(R.layout.layout_dialog, null); /* * 获取对话框的宽 高 * 不是真的获取对话框的宽高, 是在对话框被构建绘制到 布局中时 * 利用这个时机去设置对话框位置 */ ViewTreeObserver viewTreeObserver = dialogView.getViewTreeObserver(); viewTreeObserver .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 当View可以获取宽高的时候,设置view的位置 relocation(location); } }); //初始化对话框所在的容器 rlOutsideBackground = (RelativeLayout) dialogView .findViewById(R.id.rlOutsideBackground); //为容器设置点击事件, 一旦点击, 就让对话框消失 rlOutsideBackground.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //关闭对话框前提 标志位true, 对话框不为 null if (touchOutsideDismiss && dialog != null) { onDialogDismiss(); } return false; } }); //对话框上部 或者 下部的 小三角形 ivTriangle = (ImageView) dialogView.findViewById(R.id.ivTriangle); //对话框的长条 llContent = (LinearLayout) dialogView.findViewById(R.id.llContent); //创建对话框 dialog = new Dialog( context, isFullScreen() ? android.R.style.Theme_Translucent_NoTitleBar_Fullscreen : android.R.style.Theme_Translucent_NoTitleBar); //设置对话框布局 dialog.setContentView(dialogView); //对话框显示动画 animatorSetForDialogShow = new AnimatorSet(); //对话框消失动画 animatorSetForDialogDismiss = new AnimatorSet(); objectAnimatorsForDialogShow = new ArrayList<>(); objectAnimatorsForDialogDismiss = new ArrayList<>(); //初始化默认值 initData(); } /** * 初始化默认值 */ private void initData() { this.setLocation(new int[] { 0, 0 }) //设置默认位置 .setGravity(GRAVITY_BOTTOM) //设置三角形位置 (上 或者 下) .setTouchOutsideDismiss(true) //设置是否可以点击对话框消失 .setOutsideColor(Color.TRANSPARENT) //设置对话框外部背景颜色 .setBackgroundColor(Color.BLUE) //设置对话框背景 .setMatchParent(true) //设置是否填充全屏 .setMarginLeftAndRight(24, 24); //设置左右margin } /** * 设置提示框中要显示的内容 */ public EasyDialog setLayout(View layout) { if (layout != null) { this.contentView = layout; } return this; } /** * 设置提示框中要显示的内容的布局Id */ public EasyDialog setLayoutResourceId(int layoutResourceId) { View view = ((Activity) context).getLayoutInflater().inflate( layoutResourceId, null); setLayout(view); return this; } /** * 设置三角形所在的位置 * * @param location * 传入 x y 坐标 * @return */ public EasyDialog setLocation(int[] location) { this.location = location; return this; } /** * 设置三角形位置 * -- x 坐标 : x坐标值为attachedView所在屏幕位置的中心 * -- y 坐标 : y坐标值依据当前的gravity,如果gravity是top,则为控件上方的y值,如果是bottom,则为控件的下方的y值 * * @param attachedView * 在哪个View显示提示信息 */ public EasyDialog setLocationByAttachedView(View attachedView) { if (attachedView != null) { //为成员变量赋值 this.attachedView = attachedView; //该数组存储三角形位置数据 int[] attachedViewLocation = new int[2]; // 获取 attachedView 的位置, 左上角位置 attachedView.getLocationOnScreen(attachedViewLocation); //计算 x 坐标, 即 attachedView 的中间位置 attachedViewLocation[0] = attachedViewLocation[0] + attachedView.getWidth() / 2; //计算 y 坐标 switch (gravity) { case GRAVITY_BOTTOM: //如果三角形在下, 即三角形位置是 attachedView 的下方 attachedViewLocation[1] = attachedViewLocation[1] + attachedView.getHeight(); break; case GRAVITY_TOP: //如果三角形在上, 即三角形位置是 attachedView 的上方, 即默认值 break; } //设置三角形位置 setLocation(attachedViewLocation); } return this; } /** * 对话框所依附的View * */ private View attachedView = null; /** * 设置显示的内容在上方还是下方,如果设置错误,默认是在下方 */ public EasyDialog setGravity(int gravity) { //如果设置的位置值 既不是上 也不是下, 默认为下 if (gravity != GRAVITY_BOTTOM && gravity != GRAVITY_TOP) { gravity = GRAVITY_BOTTOM; } //设置到成员变量中 this.gravity = gravity; //设置三角形的图片, switch (this.gravity) { case GRAVITY_BOTTOM: ivTriangle.setBackgroundResource(R.drawable.triangle_bottom); break; case GRAVITY_TOP: ivTriangle.setBackgroundResource(R.drawable.triangle_top); break; } //对话框 主题长条的 View llContent.setBackgroundResource(R.drawable.round_corner_bg); // 如果用户调用setGravity()之前就调用过setLocationByAttachedView,需要再调用一次setLocationByAttachedView if (attachedView != null) { this.setLocationByAttachedView(attachedView); } //设置对话框颜色 this.setBackgroundColor(backgroundColor); return this; } /** * 设置是否填充屏幕,如果不填充就适应布局内容的宽度,显示内容的位置会尽量随着三角形的位置居中 */ public EasyDialog setMatchParent(boolean matchParent) { ViewGroup.LayoutParams layoutParams = llContent.getLayoutParams(); layoutParams.width = matchParent ? ViewGroup.LayoutParams.MATCH_PARENT : ViewGroup.LayoutParams.WRAP_CONTENT; llContent.setLayoutParams(layoutParams); return this; } /** * 距离屏幕左右的边距 * 设置对话框所在的整个容器的布局 */ public EasyDialog setMarginLeftAndRight(int left, int right) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) llContent .getLayoutParams(); layoutParams.setMargins(left, 0, right, 0); llContent.setLayoutParams(layoutParams); return this; } /** * 设置触摸对话框外面,对话框是否消失 */ public EasyDialog setTouchOutsideDismiss(boolean touchOutsideDismiss) { this.touchOutsideDismiss = touchOutsideDismiss; return this; } /** * 设置提醒框外部区域的颜色 */ public EasyDialog setOutsideColor(int color) { rlOutsideBackground.setBackgroundColor(color); return this; } private int backgroundColor; /** * 设置对话框的颜色 * <p/> * 三角形的图片是layer-list里面嵌套一个RotateDrawable,在设置颜色的时候需要特别处理 * http://stackoverflow. * com/questions/24492000/set-color-of-triangle-on-run-time * http://stackoverflow * .com/questions/16636412/change-shape-solid-color-at-runtime * -inside-drawable-xml-used-as-background */ public EasyDialog setBackgroundColor(int color) { backgroundColor = color; LayerDrawable drawableTriangle = (LayerDrawable) ivTriangle .getBackground(); GradientDrawable shapeTriangle = (GradientDrawable) (((RotateDrawable) drawableTriangle .findDrawableByLayerId(R.id.shape_id)).getDrawable()); if (shapeTriangle != null) { shapeTriangle.setColor(color); } else { Toast.makeText(context, "shape is null", Toast.LENGTH_SHORT).show(); } GradientDrawable drawableRound = (GradientDrawable) llContent .getBackground(); if (drawableRound != null) { drawableRound.setColor(color); } return this; } /** * 显示提示框 * * 这个对话框 整个填充全屏, 显示后, 执行里面的 小对话框 (小三角 和 提示框内容) */ public EasyDialog show() { if (dialog != null) { if (contentView == null) { throw new RuntimeException( "您是否未调用setLayout()或者setLayoutResourceId()方法来设置要显示的内容呢?"); } //设置对话框显示的内容 llContent.addView(contentView); //显示整个对话框 dialog.show(); //显示小对话框的动画 onDialogShowing(); } return this; } /** * 显示对话框的View的parent,如果想自己写动画,可以获取这个实例来写动画 * * */ public View getTipViewInstance() { return rlOutsideBackground.findViewById(R.id.rlParentForAnimate); } /** 横向 */ public static final int DIRECTION_X = 0; /** 纵向 */ public static final int DIRECTION_Y = 1; /** * 水平动画 * * @param direction * 动画的方向 * @param duration * 动画执行的时间长度 * @param values * 动画移动的位置 * */ public EasyDialog setAnimationTranslationShow(int direction, int duration, float... values) { return setAnimationTranslation(true, direction, duration, values); } /** * 水平动画 * * @param direction * 动画的方向 * @param duration * 动画执行的时间长度 * @param values * 动画移动的位置 * */ public EasyDialog setAnimationTranslationDismiss(int direction, int duration, float... values) { return setAnimationTranslation(false, direction, duration, values); } private EasyDialog setAnimationTranslation(boolean isShow, int direction, int duration, float... values) { if (direction != DIRECTION_X && direction != DIRECTION_Y) { direction = DIRECTION_X; } String propertyName = ""; switch (direction) { case DIRECTION_X: propertyName = "translationX"; break; case DIRECTION_Y: propertyName = "translationY"; break; } ObjectAnimator animator = ObjectAnimator.ofFloat( rlOutsideBackground.findViewById(R.id.rlParentForAnimate), propertyName, values).setDuration(duration); if (isShow) { objectAnimatorsForDialogShow.add(animator); } else { objectAnimatorsForDialogDismiss.add(animator); } return this; } /** * 对话框出现时候的渐变动画 * * @param duration * 动画执行的时间长度 * @param values * 动画移动的位置 * */ public EasyDialog setAnimationAlphaShow(int duration, float... values) { return setAnimationAlpha(true, duration, values); } /** * 对话框消失时候的渐变动画 * * @param duration * 动画执行的时间长度 * @param values * 动画移动的位置 * */ public EasyDialog setAnimationAlphaDismiss(int duration, float... values) { return setAnimationAlpha(false, duration, values); } private EasyDialog setAnimationAlpha(boolean isShow, int duration, float... values) { ObjectAnimator animator = ObjectAnimator.ofFloat( rlOutsideBackground.findViewById(R.id.rlParentForAnimate), "alpha", values).setDuration(duration); if (isShow) { objectAnimatorsForDialogShow.add(animator); } else { objectAnimatorsForDialogDismiss.add(animator); } return this; } private AnimatorSet animatorSetForDialogShow; private AnimatorSet animatorSetForDialogDismiss; private List<Animator> objectAnimatorsForDialogShow; private List<Animator> objectAnimatorsForDialogDismiss; /** * 对话框显示的动画 */ private void onDialogShowing() { if (animatorSetForDialogShow != null && objectAnimatorsForDialogShow != null && objectAnimatorsForDialogShow.size() > 0) { animatorSetForDialogShow.playTogether(objectAnimatorsForDialogShow); animatorSetForDialogShow.start(); } } /** * 对话框消失的动画 */ private void onDialogDismiss() { if (animatorSetForDialogDismiss.isRunning()) { return; } if (animatorSetForDialogDismiss != null && objectAnimatorsForDialogDismiss != null && objectAnimatorsForDialogDismiss.size() > 0) { animatorSetForDialogDismiss .playTogether(objectAnimatorsForDialogDismiss); animatorSetForDialogDismiss.start(); animatorSetForDialogDismiss .addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { dialog.dismiss(); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } else { dialog.dismiss(); } } /** * 关闭提示框 */ public void dismiss() { if (dialog != null && dialog.isShowing()) { onDialogDismiss(); } } /** * 根据x,y,重新设置控件的位置 * * 因为setX setY为0的时候,都是在状态栏以下的,所以app不是全屏的话,需要扣掉状态栏的高度 */ private void relocation(int[] location) { ivTriangle.setX(location[0] - ivTriangle.getWidth() / 2); ivTriangle.setY(location[1] - ivTriangle.getHeight() / 2 - (isFullScreen() ? 0.0f : getStatusBarHeight()));// 因为三角形是通过XML绘制出来的,可以到activity_tip_overlay.xml中把三角形的那个ImageView背景设置一下,就知道什么情况了。所以需要减掉一半的高度 switch (gravity) { case GRAVITY_BOTTOM: llContent.setY(location[1] - ivTriangle.getHeight() / 2 - (isFullScreen() ? 0.0f : getStatusBarHeight()) + ivTriangle.getHeight()); break; case GRAVITY_TOP: llContent.setY(location[1] - llContent.getHeight() - (isFullScreen() ? 0.0f : getStatusBarHeight()) - ivTriangle.getHeight() / 2); break; } // 显示内容的区域往三角形靠拢 int triangleCenterX = (int) (ivTriangle.getX() + ivTriangle.getWidth() / 2);// 三角形的中心点 int contentWidth = llContent.getWidth(); int rightMargin = getScreenWidth() - triangleCenterX;// 三角形中心距离屏幕右边的距离 int leftMargin = getScreenWidth() - rightMargin;// 三角形中心距离屏幕左边的距离 RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) llContent .getLayoutParams(); int availableLeftMargin = leftMargin - layoutParams.leftMargin;// 左边可用的距离 int availableRightMargin = rightMargin - layoutParams.rightMargin;// 右边可用的距离 int x = 0; if (contentWidth / 2 <= availableLeftMargin && contentWidth / 2 <= availableRightMargin)// 左右两边有足够的距离 { x = triangleCenterX - contentWidth / 2; } else { if (availableLeftMargin <= availableRightMargin)// 判断三角形在屏幕中心的左边 { x = layoutParams.leftMargin; } else// 三角形在屏幕中心的右边 { x = getScreenWidth() - (contentWidth + layoutParams.rightMargin); } } llContent.setX(x); } /** * 获取屏幕的宽度 * */ private int getScreenWidth() { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); return metrics.widthPixels; } /** * 获取状态栏的高度 */ private int getStatusBarHeight() { int result = 0; int resourceId = context.getResources().getIdentifier( "status_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result; } /** * 判断下当前要显示对话框的Activity是否是全屏 */ public boolean isFullScreen() { int flg = ((Activity) context).getWindow().getAttributes().flags; boolean flag = false; if ((flg & 1024) == 1024) { flag = true; } return flag; } /** * 设置是否可以按返回按钮取消 * */ public EasyDialog setCancelable(boolean cancelable) { dialog.setCancelable(cancelable); return this; } }
2. EasyDialog 调用
package cn.org.octopus.easydialog; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.Toast; public class MainActivity extends ActionBarActivity implements View.OnClickListener { private RelativeLayout rlBackground; private Button btnTopLeft; private Button btnTopRight; private Button btnMiddleTop; private Button btnMiddleBottom; private Button btnBottomLeft; private Button btnBottomRight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iniComponent(); } private void iniComponent() { rlBackground = (RelativeLayout)findViewById(R.id.rlBackground); btnTopLeft = (Button) findViewById(R.id.btnTopLeft); btnTopRight = (Button) findViewById(R.id.btnTopRight); btnMiddleTop = (Button) findViewById(R.id.btnMiddleTop); btnMiddleBottom = (Button) findViewById(R.id.btnMiddleBottom); btnBottomLeft = (Button) findViewById(R.id.btnBottomLeft); btnBottomRight = (Button) findViewById(R.id.btnBottomRight); btnTopLeft.setOnClickListener(this); btnTopRight.setOnClickListener(this); btnMiddleTop.setOnClickListener(this); btnMiddleBottom.setOnClickListener(this); btnBottomLeft.setOnClickListener(this); btnBottomRight.setOnClickListener(this); rlBackground.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int[] location = new int[2]; location[0] = (int)event.getX(); location[1] = (int)event.getY(); location[1] = location[1] + getActionBarHeight() + getStatusBarHeight(); Toast.makeText(MainActivity.this, "x:" + location[0] + " y:" + location[1], Toast.LENGTH_SHORT).show(); new EasyDialog(MainActivity.this) .setLayoutResourceId(R.layout.layout_tip_content_horizontal) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_black)) .setLocation(location) .setGravity(EasyDialog.GRAVITY_TOP) .setTouchOutsideDismiss(true) .setMatchParent(false) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_gray)) .show(); return false; } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnTopLeft: View view = this.getLayoutInflater().inflate(R.layout.layout_tip_content_horizontal, null); new EasyDialog(MainActivity.this) .setLayout(view) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_black)) .setLocationByAttachedView(btnTopLeft) .setGravity(EasyDialog.GRAVITY_BOTTOM) .setAnimationTranslationShow(EasyDialog.DIRECTION_X, 1000, -600, 100, -50, 50, 0) .setAnimationAlphaShow(1000, 0.3f, 1.0f) .setAnimationTranslationDismiss(EasyDialog.DIRECTION_X, 500, -50, 800) .setAnimationAlphaDismiss(500, 1.0f, 0.0f) .setTouchOutsideDismiss(true) .setMatchParent(true) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_trans)) .show(); break; case R.id.btnTopRight: new EasyDialog(MainActivity.this) .setLayoutResourceId(R.layout.layout_tip_image_text) .setGravity(EasyDialog.GRAVITY_BOTTOM) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_black)) .setLocationByAttachedView(btnTopRight) .setAnimationTranslationShow(EasyDialog.DIRECTION_X, 350, 400, 0) .setAnimationTranslationDismiss(EasyDialog.DIRECTION_X, 350, 0, 400) .setTouchOutsideDismiss(true) .setMatchParent(false) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_trans)) .show(); break; case R.id.btnMiddleTop: new EasyDialog(MainActivity.this) .setLayoutResourceId(R.layout.layout_tip_content_horizontal) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_blue)) .setLocationByAttachedView(btnMiddleTop) .setAnimationTranslationShow(EasyDialog.DIRECTION_Y, 1000, -800, 100, -50, 50, 0) .setAnimationTranslationDismiss(EasyDialog.DIRECTION_Y, 500, 0, -800) .setGravity(EasyDialog.GRAVITY_TOP) .setTouchOutsideDismiss(true) .setMatchParent(false) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_pink)) .show(); break; case R.id.btnMiddleBottom: new EasyDialog(MainActivity.this) .setLayoutResourceId(R.layout.layout_tip_content_horizontal) .setGravity(EasyDialog.GRAVITY_BOTTOM) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_brown)) .setLocationByAttachedView(btnMiddleBottom) .setAnimationTranslationShow(EasyDialog.DIRECTION_Y, 1000, 800, -100, -50, 50, 0) .setAnimationTranslationDismiss(EasyDialog.DIRECTION_Y, 500, 0, 800) .setAnimationAlphaShow(1000, 0.3f, 1.0f) .setTouchOutsideDismiss(true) .setMatchParent(true) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_gray)) .show(); break; case R.id.btnBottomLeft: new EasyDialog(MainActivity.this) .setLayoutResourceId(R.layout.layout_tip_text) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_pink)) .setLocationByAttachedView(btnBottomLeft) .setGravity(EasyDialog.GRAVITY_TOP) .setAnimationAlphaShow(600, 0.0f, 1.0f) .setAnimationAlphaDismiss(600, 1.0f, 0.0f) .setTouchOutsideDismiss(true) .setMatchParent(false) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_trans)) .show(); break; case R.id.btnBottomRight: new EasyDialog(MainActivity.this) .setLayoutResourceId(R.layout.layout_tip_image_text) .setBackgroundColor(MainActivity.this.getResources().getColor(R.color.background_color_yellow)) .setLocationByAttachedView(btnBottomRight) .setGravity(EasyDialog.GRAVITY_TOP) .setAnimationTranslationShow(EasyDialog.DIRECTION_X, 300, 400, 0) .setAnimationTranslationShow(EasyDialog.DIRECTION_Y, 300, 400, 0) .setAnimationTranslationDismiss(EasyDialog.DIRECTION_X, 300, 0, 400) .setAnimationTranslationDismiss(EasyDialog.DIRECTION_Y, 300, 0, 400) .setTouchOutsideDismiss(true) .setMatchParent(false) .setMarginLeftAndRight(24, 24) .setOutsideColor(MainActivity.this.getResources().getColor(R.color.outside_color_trans)) .show(); break; } } private int getStatusBarHeight() { int result = 0; int resourceId = this.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = this.getResources().getDimensionPixelSize(resourceId); } return result; } private int getActionBarHeight() { return this.getSupportActionBar().getHeight(); } }
【Android应用开发】EasyDialog 源码解析的更多相关文章
- Git8.3k星,十万字Android主流开源框架源码解析,必须盘
为什么读源码 很多人一定和我一样的感受:源码在工作中有用吗?用处大吗?很长一段时间内我也有这样的疑问,认为哪些有事没事扯源码的人就是在装,只是为了提高他们的逼格而已. 那为什么我还要读源码呢?一刚开始 ...
- httprunner开发实践&源码解析
上次作业讲解 排错 控制台查看报错信息 打开代理工具,调试脚本 注释掉其他接口,先跑一个接口 pip uninstall httprunner 修复断言100为int型问题 修复两次登陆问题 报告 p ...
- iOS开发SDWebImage源码解析之SDWebImageManager的注解
最近看了两篇博客,写得很不错,关于SDWebImage源码解析之SDWebImageManager的注解: 1.http://www.jianshu.com/p/6ae6f99b6c4c 2.http ...
- Android构建工具--AAPT2源码解析(一)
一.什么是AAPT2 在Android开发过程中,我们通过Gradle命令,启动一个构建任务,最终会生成构建产物"APK"文件.常规APK的构建流程如下: (引用自Google官方 ...
- 【Android】IntentService & HandlerThread源码解析
一.前言 在学习Service的时候,我们一定会知道IntentService:官方文档不止一次强调,Service本身是运行在主线程中的(详见:[Android]Service),而主线程中是不适合 ...
- Android Handler消息机制源码解析
好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础.下面我们分析一下Handler的源码实现. Handler消息机制有4个 ...
- nginx开发_ngx_http_script源码解析
功能简介 nginx中有很多配置项支持以变量的形式存在,在运行时根据实时值进行处理.例如如下配置: location / { sub_filter '<a href="http://1 ...
- nginx开发_ngx_palloc源码解析
功能简介 ngx_pool_t是nginx开发中最经常使用到的内存容器.对动态内存的封装,由框架进行创建与释放,模块开发过程中仅需要进行内存申请,不需要关注何时释放.常见的pool对象有: 1. ng ...
- iOS开发——GPUImage源码解析
一.基本概念 GPUImage:一个开源的.基于openGL的图片或视频的处理框架,其本身内置了多达120多种常见的滤镜效果,并且支持照相机和摄像机的实时滤镜,并且能够自定义图像滤镜.同时也很方便在原 ...
随机推荐
- bzoj1597[Usaco2008 Mar]土地购买 斜率优化dp
1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5524 Solved: 2074[Submit] ...
- sql server 表分区
背景: 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆分为多个小文件,还可以把这些小文件放在不同的 ...
- SQL之排序
1.按多个列排序 经常需要按不止一个列进行数据排序.例如,如果要显示雇员名单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序).如果多个雇员有相同的姓,这样做很有用. 要按多个列排序,简 ...
- 用IO创建并格式化分区
转载:http://raylinn.iteye.com/blog/570274 BOOL Result; // used to read bad DeviceIoControl calls DWORD ...
- js操作符+和()
ECMA-262 描述了一组用于操作数据值的操作符,包括一元操作符.算数操作符逻辑操作符.关系操作符.赋值操作符.字符串操作符.对象操作符等.ECMAScript 操作符的与众不同之处在于,它们能够适 ...
- 如何上传本地项目到gitHub解决方案
最近有人有人问到我怎么将新创建的本地代码上传到github上,这里简单的记录一下,我喜欢使用命令行,这里全用命令行来实现,不了解Git命令的可以去了解下. 1. 建立本地仓库,cd到你想要上传文件的 ...
- numpy.squeeze()是干啥的
例子: a = 3 print np.squeeze(a) # 输出3 a = [3] print np.squeeze(a) # 输出3 a = [[3]] print np.squeeze(a) ...
- 31. Next Permutation(中等,搞清楚啥是 next permutation)
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- Python安装与环境变量的配置
python下载: Python安装包下载地址:http://www.python.org/ 根据实际的操作系统,安装合适的安装版本. Python安装: 本文以python 2.7.8(64位)为例 ...
- R语言do.call 函数用法详解
虽然R语言有类型很丰富的数据结构,但是很多时候数据结构比较复杂,那么基本就会用到list这种结构的数据类型.但是list对象很难以文本的形式导出,因此需要一个函数能快速将复杂的list结构扁平化成da ...