您的位置:首页 > 其它

ShowCase──操作引导的简单实现

2015-06-06 21:12 363 查看

前言

实现上还不完善,主要是思路的展示,为了抛砖引玉。

效果图



原理

自定义 Dialog 展示引导视图。设置 Dialog 的 BackgroundDrawable 为一个有一块透明的 Bitmap。这个 Bitmap 借由 Canvas 创建。中间透明则用到 Paint 的 XferMode。
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
。使用它可以镂空。

源码

[code]public class ShowCaseDialog extends Dialog {

    private Window dialogWindow;
    private Rect transparentRect;

    public ShowCaseDialog(Context context) {
        super(context);
        init();
    }

    public ShowCaseDialog(Context context, int theme) {
        super(context, theme);
        init();
    }

    protected ShowCaseDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
        init();
    }

    private void init() {
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        dialogWindow = getWindow();
        dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

        dialogWindow.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);

        WindowManager.LayoutParams params = dialogWindow.getAttributes();
        params.width = getWindowWidth();
        params.height = getWindowHeight();
        dialogWindow.setAttributes(params);

        LayoutInflater inflater = LayoutInflater.from(getContext());
        inflater.inflate(R.layout.dialog_show_case, (ViewGroup) getWindow().getDecorView(), true);
    }

    private int getWindowWidth() {
        return getContext().getResources().getDisplayMetrics().widthPixels;
    }

    public void setTransparentRect(Rect transparentRect) {
        this.transparentRect = transparentRect;
        dialogWindow.setBackgroundDrawable(getBgDrawable());
    }

    public Drawable getBgDrawable(){
        Activity activity = getOwnerActivity();
        Bitmap bgBitmap = Bitmap.createBitmap(getWindowWidth(), getWindowHeight(), Bitmap.Config.ARGB_8888);
        Canvas bgCanvas = new Canvas(bgBitmap);
        bgCanvas.drawColor(Color.parseColor("#cc000000"));
        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        bgCanvas.drawRect(transparentRect, paint);
        return  new BitmapDrawable(getContext().getResources(), bgBitmap);
    }

    public int getWindowHeight(){
        return getContext().getResources().getDisplayMetrics().heightPixels - Dimension.getStatusBarHeight(getContext());
    }
}


[code]public class TestShowCaseDialogActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_show_case_dialog);
        final Button button = (Button) findViewById(R.id.button);
        button.post(new Runnable() {
            @Override
            public void run() {
                ShowCaseDialog showCaseDialog = new ShowCaseDialog(TestShowCaseDialogActivity.this);
                int[] location = new int[2];
//                button.getLocationInWindow(location);
                button.getLocationOnScreen(location);
                int statusBarHeight = Dimension.getStatusBarHeight(getApplicationContext());
                Rect transparentRect = new Rect(location[0],
                        location[1] - statusBarHeight,
                        location[0] + button.getMeasuredWidth(),
                        location[1] + button.getMeasuredHeight() - statusBarHeight);
                showCaseDialog.setTransparentRect(transparentRect);
                showCaseDialog.show();
            }
        });
    }
}


遇到的问题

确定控件在非系统区域的位置

利用函数
getLocationOnScreen
,然后向下偏移 StatusBar 的高度。

Dialog 的布局 LayoutParamas 没有起效

不用
setContentView(int ResId)
,用
inflater.inflate(R.layout.dialog_show_case, (ViewGroup) getWindow().getDecorView(), true);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: