Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 輕量級的友好的交互對話框庫,EasyDialog,實現已詳細標注

android 輕量級的友好的交互對話框庫,EasyDialog,實現已詳細標注

編輯:關於Android編程

 

Git上看到的一個蠻清爽的一個Dialog介紹給大家。
實現效果
這裡寫圖片描述
個人感覺做的還是滿Q彈的
如何使用?

 compile 'com.github.michaelye.easydialog:easydialog:1.0'

其實也就是一個類和幾個layout文件,建議直接copy進你的項目還更方便點。

項目結構:

這裡寫圖片描述
因為標注的很清晰,直接就貼代碼看,不做什麼解釋了,如有什麼不理解可以留言可以回答你的問題

核心類EasyDialog

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);
    }

    private void initDialog(final Context context)
    {
        this.context = context;
        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)
            {
                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<>();
        ini();
    }

    /**
     * 初始化默認值
     */
    private void ini()
    {
        this.setLocation(new int[]{0, 0})
                .setGravity(GRAVITY_BOTTOM)
                .setTouchOutsideDismiss(true)
                .setOutsideColor(Color.TRANSPARENT)
                .setBackgroundColor(Color.BLUE)
                .setMatchParent(true)
                .setMarginLeftAndRight(24, 24);
    }

    /**
     * 設置提示框中要顯示的內容
     */
    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;
    }

    /**
     * 設置三角形所在的位置
     */
    public EasyDialog setLocation(int[] location)
    {
        this.location = location;
        return this;
    }

    /**
     * 設置三角形所在的位置
     * location.x坐標值為attachedView所在屏幕位置的中心
     * location.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.getLocationOnScreen(attachedViewLocation); attachedViewLocation[0] = attachedViewLocation[0] + attachedView.getWidth() / 2; switch (gravity) { case GRAVITY_BOTTOM: attachedViewLocation[1] = attachedViewLocation[1] + attachedView.getHeight(); break; case GRAVITY_TOP: 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; } llContent.setBackgroundResource(R.drawable.round_corner_bg); if(attachedView != null)//如果用戶調用setGravity()之前就調用過setLocationByAttachedView,需要再調用一次setLocationByAttachedView { 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; /** * 設置對話框的顏色 *

* 三角形的圖片是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 objectAnimatorsForDialogShow; private List objectAnimatorsForDialogDismiss; private void onDialogShowing() { if(animatorSetForDialogShow != null && objectAnimatorsForDialogShow != null && objectAnimatorsForDialogShow.size() > 0) { animatorSetForDialogShow.playTogether(objectAnimatorsForDialogShow); animatorSetForDialogShow.start(); } //TODO 縮放的動畫效果不好,不能從控件所在的位置開始縮放 // ObjectAnimator.ofFloat(rlOutsideBackground.findViewById(R.id.rlParentForAnimate), scaleX, 0.3f, 1.0f).setDuration(500).start(); // ObjectAnimator.ofFloat(rlOutsideBackground.findViewById(R.id.rlParentForAnimate), scaleY, 0.3f, 1.0f).setDuration(500).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; } }

MainActivity

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();
    }
}

布局文件:



    

具體的東西可以直接看源碼,直接可以RUN並沒有什麼 問題
 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved