Blame | Last modification | View Log | RSS feed
/*** Copyright 2010-present Facebook.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.facebook.widget;import android.app.Activity;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewTreeObserver;import android.view.Window;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.PopupWindow;import android.widget.TextView;import com.facebook.android.R;import java.lang.ref.WeakReference;public class ToolTipPopup {public static enum Style {/*** The tool tip will be shown with a blue style; including a blue background and blue* arrows.*/BLUE,/*** The tool tip will be shown with a black style; including a black background and black* arrows.*/BLACK}/*** The default time that the tool tip will be displayed*/public static final long DEFAULT_POPUP_DISPLAY_TIME = 6000;private final String mText;private final WeakReference<View> mAnchorViewRef;private final Context mContext;private PopupContentView mPopupContent;private PopupWindow mPopupWindow;private Style mStyle = Style.BLUE;private long mNuxDisplayTime = DEFAULT_POPUP_DISPLAY_TIME;private final ViewTreeObserver.OnScrollChangedListener mScrollListener =new ViewTreeObserver.OnScrollChangedListener() {@Overridepublic void onScrollChanged() {if (mAnchorViewRef.get() != null &&mPopupWindow != null &&mPopupWindow.isShowing()) {if (mPopupWindow.isAboveAnchor()) {mPopupContent.showBottomArrow();} else {mPopupContent.showTopArrow();}}}};/*** Create a new ToolTipPopup* @param text The text to be displayed in the tool tip* @param anchor The view to anchor this tool tip to.*/public ToolTipPopup(String text, View anchor) {mText = text;mAnchorViewRef = new WeakReference<View>(anchor);mContext = anchor.getContext();}/*** Sets the {@link Style} of this tool tip.* @param mStyle*/public void setStyle(Style mStyle) {this.mStyle = mStyle;}/*** Display this tool tip to the user*/public void show() {if (mAnchorViewRef.get() != null) {mPopupContent = new PopupContentView(mContext);TextView body = (TextView) mPopupContent.findViewById(R.id.com_facebook_tooltip_bubble_view_text_body);body.setText(mText);if (mStyle == Style.BLUE) {mPopupContent.bodyFrame.setBackgroundResource(R.drawable.com_facebook_tooltip_blue_background);mPopupContent.bottomArrow.setImageResource(R.drawable.com_facebook_tooltip_blue_bottomnub);mPopupContent.topArrow.setImageResource(R.drawable.com_facebook_tooltip_blue_topnub);mPopupContent.xOut.setImageResource(R.drawable.com_facebook_tooltip_blue_xout);} else {mPopupContent.bodyFrame.setBackgroundResource(R.drawable.com_facebook_tooltip_black_background);mPopupContent.bottomArrow.setImageResource(R.drawable.com_facebook_tooltip_black_bottomnub);mPopupContent.topArrow.setImageResource(R.drawable.com_facebook_tooltip_black_topnub);mPopupContent.xOut.setImageResource(R.drawable.com_facebook_tooltip_black_xout);}final Window window = ((Activity) mContext).getWindow();final View decorView = window.getDecorView();final int decorWidth = decorView.getWidth();final int decorHeight = decorView.getHeight();registerObserver();mPopupContent.onMeasure(View.MeasureSpec.makeMeasureSpec(decorWidth, View.MeasureSpec.AT_MOST),View.MeasureSpec.makeMeasureSpec(decorHeight, View.MeasureSpec.AT_MOST));mPopupWindow = new PopupWindow(mPopupContent,mPopupContent.getMeasuredWidth(),mPopupContent.getMeasuredHeight());mPopupWindow.showAsDropDown(mAnchorViewRef.get());updateArrows();if (mNuxDisplayTime > 0) {mPopupContent.postDelayed(new Runnable() {@Overridepublic void run() {dismiss();}}, mNuxDisplayTime);}mPopupWindow.setTouchable(true);mPopupContent.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {dismiss();}});}}/*** Set the time (in milliseconds) the tool tip will be displayed. Any number less than or equal* to 0 will cause the tool tip to be displayed indefinitely* @param displayTime The amount of time (in milliseconds) to display the tool tip*/public void setNuxDisplayTime(long displayTime) {this.mNuxDisplayTime = displayTime;}private void updateArrows() {if (mPopupWindow != null && mPopupWindow.isShowing()) {if (mPopupWindow.isAboveAnchor()) {mPopupContent.showBottomArrow();} else {mPopupContent.showTopArrow();}}}/*** Dismiss the tool tip*/public void dismiss() {unregisterObserver();if (mPopupWindow != null) {mPopupWindow.dismiss();}}private void registerObserver() {unregisterObserver();if (mAnchorViewRef.get() != null) {mAnchorViewRef.get().getViewTreeObserver().addOnScrollChangedListener(mScrollListener);}}private void unregisterObserver() {if (mAnchorViewRef.get() != null) {mAnchorViewRef.get().getViewTreeObserver().removeOnScrollChangedListener(mScrollListener);}}private class PopupContentView extends FrameLayout {private ImageView topArrow;private ImageView bottomArrow;private View bodyFrame;private ImageView xOut;public PopupContentView(Context context) {super(context);init();}private void init() {LayoutInflater inflater = LayoutInflater.from(getContext());inflater.inflate(R.layout.com_facebook_tooltip_bubble, this);topArrow = (ImageView) findViewById(R.id.com_facebook_tooltip_bubble_view_top_pointer);bottomArrow = (ImageView) findViewById(R.id.com_facebook_tooltip_bubble_view_bottom_pointer);bodyFrame = findViewById(R.id.com_facebook_body_frame);xOut = (ImageView) findViewById(R.id.com_facebook_button_xout);}public void showTopArrow() {topArrow.setVisibility(View.VISIBLE);bottomArrow.setVisibility(View.INVISIBLE);}public void showBottomArrow() {topArrow.setVisibility(View.INVISIBLE);bottomArrow.setVisibility(View.VISIBLE);}// Expose so popup content can be sized@Overridepublic void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}}}