/*
* Copyright 2013 Niek Haarman
* 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.nhaarman.supertooltips;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.nhaarman.supertooltips.exception.NoOverflowMenuRuntimeException;
import com.nhaarman.supertooltips.exception.NoTitleViewRuntimeException;
import com.nhaarman.supertooltips.exception.ViewNotFoundRuntimeException;
public class ToolTipRelativeLayout extends RelativeLayout {
public static final String ACTION_BAR_TITLE = "action_bar_title";
public static final String ID = "id";
public static final String ANDROID = "android";
public static final String ACTION_BAR = "action_bar";
public static final String ACTION_MENU_VIEW = "ActionMenuView";
public static final String OVERFLOW_MENU_BUTTON = "OverflowMenuButton";
public ToolTipRelativeLayout(final Context context) {
super(context);
}
public ToolTipRelativeLayout(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ToolTipRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
/**
* Shows a {@link ToolTipView} based on given {@link ToolTip} at the proper
* location relative to given {@link View}.
*
* @param toolTip
* the ToolTip to show.
* @param view
* the View to position the ToolTipView relative to.
*
* @return the ToolTipView that was created.
*/
public ToolTipView showToolTipForView(final ToolTip toolTip, final View view) {
final ToolTipView toolTipView = new ToolTipView(getContext());
toolTipView.setToolTip(toolTip, view);
addView(toolTipView);
return toolTipView;
}
/**
* **EXPERIMENTAL**</p> Shows a {@link ToolTipView} based on given
* {@link ToolTip} at the proper location relative to the {@link View} with
* given resource id.</p>NOTE: This method will throw a
* {@link ViewNotFoundRuntimeException} if the View is not found. You can
* choose to ignore this by catching the ViewNotFoundRuntimeException.
*
* @param activity
* the Activity which holds the ActionBar.
* @param toolTip
* the ToolTip to show.
* @param resId
* the resource id of the View to position the ToolTipView
* relative to.
* @return the ToolTipView that was created.
*/
public ToolTipView showToolTipForViewResId(final Activity activity, final ToolTip toolTip, final int resId) {
final ToolTipView toolTipView = new ToolTipView(getContext());
final View decorView = activity.getWindow().getDecorView();
final View view = decorView.findViewById(resId);
if (view == null) {
throw new ViewNotFoundRuntimeException();
}
toolTipView.setToolTip(toolTip, view);
addView(toolTipView);
return toolTipView;
}
/**
* **EXPERIMENTAL**</p> Shows a {@link ToolTipView} based on given
* {@link ToolTip} at the proper location relative to the {@link ActionBar}
* home {@link View}.
*
* @param activity
* the Activity which holds the ActionBar.
* @param toolTip
* the ToolTip to show.
* @return the ToolTipView that was created.
*/
@TargetApi(11)
public ToolTipView showToolTipForActionBarHome(final Activity activity, final ToolTip toolTip) {
final int homeResId = android.R.id.home;
return showToolTipForViewResId(activity, toolTip, homeResId);
}
/**
* **EXPERIMENTAL**</p>
*
* Shows a {@link ToolTipView} based on given {@link ToolTip} at the proper
* location relative to the {@link ActionBar} title {@link View}.</p>NOTE:
* This method will throw a {@link NoTitleViewRuntimeException} if the title
* View is not found. You can choose to ignore this by catching the
* NoTitleViewRuntimeException.</p>NOTE: This method uses an internal API to
* find the View. It MAY cause your application to crash in future Android
* versions.
*
* @param activity
* the Activity which holds the ActionBar.
* @param toolTip
* the ToolTip to show.
* @return the ToolTipView that was created.
*/
@TargetApi(11)
public ToolTipView showToolTipForActionBarTitle(final Activity activity, final ToolTip toolTip) {
final int titleResId = Resources.getSystem().getIdentifier(ACTION_BAR_TITLE, ID, ANDROID);
if (titleResId == 0) {
throw new NoTitleViewRuntimeException();
}
return showToolTipForViewResId(activity, toolTip, titleResId);
}
/**
* **EXPERIMENTAL**</p> Shows a {@link ToolTipView} based on given
* {@link ToolTip} at the proper location relative to the overflow menu
* button.</p>NOTE: This method will throw a
* {@link NoOverflowMenuRuntimeException} if the overflow menu is not found.
* This happens when there simply is no overflow menu button, or the menu
* isn't initialised yet. You can choose to ignore this by catching the
* NoOverflowMenuRuntimeException.</p>NOTE: This method uses an internal API
* to find the View. It MAY cause your application to crash in future
* Android versions.
*
* @param activity
* the Activity which holds the ActionBar.
* @param toolTip
* the ToolTip to show.
* @return the ToolTipView that was created.
*/
@TargetApi(11)
public ToolTipView showToolTipForActionBarOverflowMenu(final Activity activity, final ToolTip toolTip) {
return showToolTipForView(toolTip, findActionBarOverflowMenuView(activity));
}
@TargetApi(11)
private static View findActionBarOverflowMenuView(final Activity activity) {
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final int actionBarViewResId = Resources.getSystem().getIdentifier(ACTION_BAR, ID, ANDROID);
final ViewGroup actionBarView = (ViewGroup) decorView.findViewById(actionBarViewResId);
ViewGroup actionMenuView = null;
int actionBarViewChildCount = actionBarView.getChildCount();
for (int i = 0; i < actionBarViewChildCount; ++i) {
if (actionBarView.getChildAt(i).getClass().getSimpleName().equals(ACTION_MENU_VIEW)) {
actionMenuView = (ViewGroup) actionBarView.getChildAt(i);
}
}
if (actionMenuView == null) {
throw new NoOverflowMenuRuntimeException();
}
int actionMenuChildCount = actionMenuView.getChildCount();
View overflowMenuButton = null;
for (int i = 0; i < actionMenuChildCount; ++i) {
if (actionMenuView.getChildAt(i).getClass().getSimpleName().equals(OVERFLOW_MENU_BUTTON)) {
overflowMenuButton = actionMenuView.getChildAt(i);
}
}
if (overflowMenuButton == null) {
throw new NoOverflowMenuRuntimeException();
}
return overflowMenuButton;
}
}