6

首次运行时(或在某些重大更新后),某些 Google 应用程序或核心 Android 系统本身有时会显示一个透明的叠加层,并带有简短的工具提示如何使用新功能。一个例子可能是下面的图像。

Android 框架中是否有一些 API 用于创建这些 API,或者它们都是定制的?在后一种情况下如何实现它?最后但并非最不重要的一点是,这些工具提示是否有某种官方/技术名称,人们可以通过它来引用它们(在谷歌搜索有关该主题的一些信息时可能很有用)?谢谢。

编辑

我已经获得了一个更准确地说明我的意思的截图。除了“指向手”图形外,此工具提示的时钟应用程序图标周围还有一个突出显示的圆圈。这不仅仅是点击后消失的半透明覆盖:此时可以单击甚至长按时钟图标,但在工具栏消失之前无法访问其他图标(圆圈外)。所有这些行为是专门为此目的定制的,还是存在一些内置设施?

在此处输入图像描述

4

3 回答 3

3

它只是一个半透明的对话框。

在 res 文件夹中的 theme.xml 中插入以下代码

 <style name="Theme.TranparentDialog" parent="@android:style/Theme.NoTitleBar">
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:colorForeground">@color/transparent</item>
        <item name="android:windowIsFloating">false</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:windowBackground">@color/transparent</item>
    </style>

在屏幕上创建对话框以获得半透明效果/

Dialog dialog= new Dialog(context,  R.style.Theme_TutorialDialog);

对话框.show();

于 2013-08-22T18:20:52.340 回答
2

我认为这是使用ShowcaseView Library。请参阅此相关问题

于 2014-08-29T05:34:24.333 回答
0

如果在上述对话框中用作背景,则此视图可用于在屏幕上绘制透明矩形。

public class WindowView extends View {
private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;

private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;

private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;
Context mContext;

int mHeight, mWidth, mTop, mRight, mLeft, mBottom;
Rect mLeftRect, mRightRect, mTopRect, mBottomRect;

Rect mRect;
Paint mPaint;
View mAnchorView;
Paint mTempPaint1;

public WindowView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public WindowView(Context context) {
    this(context, null);
}

public WindowView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mContext = context;
    initVariables();
}

boolean mReset = false;

GestureDetector mGestureDetector;
GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener;

private View getView() {
    return this;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (mSimpleOnGestureListener == null) {
        mSimpleOnGestureListener = new SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                if (mListener != null && e.getX() >= mRect.left
                        && e.getX() <= mRect.right && e.getY() >= mRect.top
                        && e.getY() <= mRect.bottom)
                    mListener.onClick(getView());
                return true;
            }
        };
    }
    if (mGestureDetector == null) {
        mGestureDetector = new GestureDetector(mContext,
                mSimpleOnGestureListener);
    }
    mGestureDetector.onTouchEvent(event);
    return true;
}

private void initVariables() {
    mPaint = new Paint();
    mPaint.setStyle(Style.FILL);
    mPaint.setColor(mContext.getResources().getColor(
            R.color.tut_transcluscent_bg));
    mRect = new Rect();

    mTempPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
    mTempPaint1.setAlpha(64);
    mTempPaint1.setColorFilter(new PorterDuffColorFilter(Color.WHITE,
            Mode.SRC_IN));
}

OnClickListener mListener;

public void setTransparentBackGroundColor(int color) {
    mPaint.setColor(color);
    invalidate();
}

@Override
public void setOnClickListener(OnClickListener l) {
    mListener = l;
}

public View getAnchorView() {
    return mAnchorView;
}

float[] mPaddings;
Rect mAnchorRect;;

public void setAnchorView(View mView, Rect rect, float[] paddings) {
    mAnchorRect = rect;
    if (mAnchorRect == null)
        mAnchorView = mView;
    else
        mAnchorView = null;
    mPaddings = paddings;
    requestLayout();
    invalidate();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (mAnchorView != null || mAnchorRect != null)
        initView();
    mReset = true;
}

boolean mFlagInvalid = false;
Handler mAnrHandler;

public void setHandler(Handler handler) {
    mAnrHandler = handler;
}

private int getStatusBarHeight() {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
            .getDefaultDisplay().getMetrics(displayMetrics);

    int statusBarHeight;

    switch (displayMetrics.densityDpi) {
    case DisplayMetrics.DENSITY_HIGH:
        statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_MEDIUM:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_LOW:
        statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
        break;
    default:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
    }
    return statusBarHeight;
}

public void initView() {

    mFlagInvalid = false;
    int top = 0, left = 0;
    if (mAnchorView != null) {
        top = mAnchorView.getTop();
        left = mAnchorView.getLeft();
        View temp = mAnchorView;
        int cnt = 0;
        try {
            while (((View) temp.getParent()).getId() != android.R.id.content) {
                temp = (View) temp.getParent();
                int scrolledHeight = 0;
                if (temp instanceof ScrollView) {
                    scrolledHeight = ((ScrollView) temp).getScrollY();
                }
                top = top + temp.getTop() - scrolledHeight;
                left = left + temp.getLeft();
                cnt++;
                if (cnt > 100) {
                    if (mAnrHandler != null)
                        mAnrHandler.sendEmptyMessage(9);
                    mFlagInvalid = true;
                    break;
                }
            }
        } catch (Exception e) {
            mFlagInvalid = true;
            if (mAnrHandler != null)
                mAnrHandler.sendEmptyMessage(8);
            e.printStackTrace();
        }
        TypedValue tv = new TypedValue();
        if (getContext()
                .getTheme()
                .resolveAttribute(
                        VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB ? android.R.attr.actionBarSize
                                : R.attr.actionBarSize, tv, true)) {
            int actionBarHeight = TypedValue.complexToDimensionPixelSize(
                    tv.data, getResources().getDisplayMetrics());
            top = top + actionBarHeight;
        }

    } else if (mAnchorRect != null) {
    }

    if (mFlagInvalid)
        init(20, 20, 50, 50);
    else {
        if (mAnchorRect != null) {
            init(mAnchorRect.bottom, mAnchorRect.right, mAnchorRect.left,
                    mAnchorRect.top);
        } else
            init(mAnchorView.getHeight(), mAnchorView.getWidth(), left, top);
    }
}

public void init(int height, int width, int left, int top) {
    mWidth = width;
    mHeight = height;
    mTop = top;
    mBottom = top + height;
    mLeft = left;
    mRight = left + width;

    mLeft = (int) (mLeft + mPaddings[0] * mWidth);
    mTop = (int) (mTop + mPaddings[1] * mHeight);
    mRight = (int) (mRight - mPaddings[2] * mWidth);
    mBottom = (int) (mBottom - mPaddings[3] * mHeight);
    mRect = new Rect(mLeft, mTop, mRight, mBottom);

    invalidate();
}

public Rect getAnchorRect() {
    return mRect;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    initOnceOnDraw();
    canvas.drawRect(mLeftRect, mPaint);
    canvas.drawRect(mTopRect, mPaint);
    canvas.drawRect(mRightRect, mPaint);
    canvas.drawRect(mBottomRect, mPaint);
    canvas.drawRect(mRect, mTempPaint1);
}

private void initOnceOnDraw() {
    if (mReset) {
        mReset = false;
        mTopRect = new Rect(0, 0, getWidth(), mRect.top);
        mLeftRect = new Rect(0, mRect.top, mRect.left, mRect.bottom);
        mRightRect = new Rect(mRect.right, mRect.top, getWidth(),
                mRect.bottom);
        mBottomRect = new Rect(0, mRect.bottom, getWidth(), getHeight());
    }
}}

setAnchorView() 方法给出了必须在其上绘制叠加层的视图。

    mWindowView = (WindowView) mTutorialView
                            .findViewById(R.id.windowview_tutorial);
                        mWindowView.setTransparentBackGroundColor(backgroundColor);

                    mWindowView.setAnchorView(view, null, padding);

希望这可以帮助

于 2013-08-30T19:54:43.563 回答