2013-08-22 18 views
5

Quando si esegue per la prima volta (o dopo un aggiornamento importante), alcune applicazioni Google o il sistema Android principale a volte visualizzano una sovrapposizione trasparente con un breve suggerimento su come utilizzare le nuove funzionalità. Un esempio potrebbe essere l'immagine qui sotto.Descrizione comandi overlay display alla prima esecuzione

C'è qualche API nel framework Android per la creazione di questi o è tutto personalizzato? Come si potrebbe implementarlo nel secondo caso? E, ultimo, ma non meno importante, questi tooltip hanno una sorta di nome ufficiale/tecnico con cui si può fare riferimento a loro (potrebbe essere utile quando si cerca su Google qualche informazione sull'argomento)? Grazie.

Modifica

ho acquisito uno screenshot che illustra con maggiore precisione cosa intendo. Oltre alla grafica "mano che punta", questa descrizione mostra un cerchio di evidenziazione attorno all'icona dell'app Orologio. Questo non è semplicemente un overlay traslucido che scompare dopo il clic: l'icona Orologio può essere cliccata o anche premuta a lungo in questo momento, ma altre icone (al di fuori del cerchio) non sono accessibili fino a quando il toolip non scompare. Tutto questo comportamento è stato creato su misura appositamente per questo scopo, oppure esiste una funzione integrata?

enter image description here

+1

Stavo proprio per fare questa domanda da solo, sebbene stavo cercando l'effetto "balloon-tooltip". Hai trovato un modo per farlo? Preferirei non rendere il mio layout più complesso per una funzionalità che verrà utilizzata una volta ... – Basic

risposta

3

E 'solo un dialogo trasparente.

inserire il codice qui sotto in themes.xml nella cartella res

<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> 

creare la finestra sopra lo schermo per ottenere un effetto traslucido/

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

dialog.show();

+0

Grazie per la risposta. Tuttavia, ho fornito uno screenshot più preciso e ho aggiornato la mia domanda un po '. Dai un'occhiata per favore. – Natix

0

questa vista può essere utilizzata per disegnare un rettangolo trasparente sullo schermo se utilizzato come sfondo nella finestra di dialogo precedente.

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

Il metodo setAnchorView() dà la vista, che la sovrapposizione deve essere disegnato ..

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

        mWindowView.setAnchorView(view, null, padding); 

Spero che questo aiuti

Problemi correlati