获取 TapTargetView 的 MenuItem 视图参考
Get MenuItem's View reference for TapTargetView
我正在尝试将 TapTargetView 用于菜单项,但我看不到它。
我的代码:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);
new TapTargetSequence(this)
.targets(
TapTarget.forView(menu.findItem(R.id.add).getActionView(), "Gonna"))
.listener(new TapTargetSequence.Listener() {
// This listener will tell us when interesting(tm) events happen in regards
// to the sequence
@Override
public void onSequenceFinish() {
// Yay
}
@Override
public void onSequenceStep(TapTarget lastTarget, boolean targetClicked) {
}
@Override
public void onSequenceCanceled(TapTarget lastTarget) {
// Boo
}
});
return true;
}
错误:
java.lang.IllegalArgumentException: Given null view to target
我该如何解决这个问题?
我试过将 android:actionViewClass
添加到 xml 文件,但没有成功。
您可以利用View#findViewsWithText()
API来获取MenuItem
的观点的参考。
菜单如下xml
:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="ifRoom"/>
</menu>
并假设正在显示 MenuItem
,则:
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final View decorView = getWindow().getDecorView();
decorView.post(() -> {
ArrayList<View> list = new ArrayList<>();
decorView.findViewsWithText(list, getString(R.string.action_settings), View.FIND_VIEWS_WITH_TEXT);
// `itemView` is the actual view you should use to create your `TapTargetView`
View itemView = list.get(0);
});
}
使用[=h11=]代替TapTarget.forView
像这样更改代码...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);
new TapTargetSequence(this)
.targets(
TapTarget.forToolbarMenuItem(toolbar,R.id.add, "Gonna"))
.listener(new TapTargetSequence.Listener() {
// This listener will tell us when interesting(tm) events happen in regards
// to the sequence
@Override
public void onSequenceFinish() {
// Yay
}
@Override
public void onSequenceStep(TapTarget lastTarget, boolean targetClicked) {
}
@Override
public void onSequenceCanceled(TapTarget lastTarget) {
// Boo
}
});
return true;
}
另一种方法是在菜单项中使用 "app:actionLayout="@layout/some_layout"
,some_layout 可以将该项目作为其中的视图。然后,在您的 activity 中,您可以使用:
MenuItem menuItem = menu.findItem(R.id.menu_item); // get the menu item
ImageView menuView = menuItem.getActionView().findViewById(R.id.some_icon);
您可以使用此 menuView 来设置点击目标
TapTargetView.showFor(activity, getTapTarget(menuView, title, message),
new TapTargetView.Listener()
{
@Override
public void onTargetClick(TapTargetView view)
{
super.onTargetClick(view);
view.dismiss(true);
}
@Override
public void onOuterCircleClick(TapTargetView view)
{
super.onOuterCircleClick(view);
view.dismiss(true);
}
});
经过反复的搜索和测试,终于找到了可行的解决方案!
只需在 onCreateOptionsMenu()
中获取对您的菜单项的引用。启动一个处理程序,以便在您获取 id 引用之前正确地膨胀视图。否则你将得到 空视图错误
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
new Handler().post(new Runnable() {
@Override
public void run() {
final View view = findViewById(R.id.askHelp);
TapTargetView.showFor(BasicInformation.this, // `this` is an Activity
TapTarget.forView(view, "You can tap here to get Chat Support")
// All options below are optional
.outerCircleColor(R.color.colorAccent) // Specify a color for the outer circle
.outerCircleAlpha(0.96f) // Specify the alpha amount for the outer circle
.targetCircleColor(R.color.white) // Specify a color for the target circle
.titleTextSize(30) // Specify the size (in sp) of the title text
.titleTextColor(R.color.white) // Specify the color of the title text
.textColor(R.color.white) // Specify a color for both the title and description text
.textTypeface(Typeface.SANS_SERIF) // Specify a typeface for the text
.dimColor(R.color.black) // If set, will dim behind the view with 30% opacity of the given color
.drawShadow(true) // Whether to draw a drop shadow or not
.cancelable(true) // Whether tapping outside the outer circle dismisses the view
.tintTarget(true) // Whether to tint the target view's color
.transparentTarget(false) // Specify whether the target is transparent (displays the content underneath)
.targetRadius(60), // Specify the target radius (in dp)
new TapTargetView.Listener() { // The listener can listen for regular clicks, long clicks or cancels
@Override
public void onTargetClick(TapTargetView view) {
super.onTargetClick(view); // This call is optional
//doSomething();
}
});
}
});
return true;
}
我正在尝试将 TapTargetView 用于菜单项,但我看不到它。
我的代码:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);
new TapTargetSequence(this)
.targets(
TapTarget.forView(menu.findItem(R.id.add).getActionView(), "Gonna"))
.listener(new TapTargetSequence.Listener() {
// This listener will tell us when interesting(tm) events happen in regards
// to the sequence
@Override
public void onSequenceFinish() {
// Yay
}
@Override
public void onSequenceStep(TapTarget lastTarget, boolean targetClicked) {
}
@Override
public void onSequenceCanceled(TapTarget lastTarget) {
// Boo
}
});
return true;
}
错误:
java.lang.IllegalArgumentException: Given null view to target
我该如何解决这个问题?
我试过将 android:actionViewClass
添加到 xml 文件,但没有成功。
您可以利用View#findViewsWithText()
API来获取MenuItem
的观点的参考。
菜单如下xml
:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="ifRoom"/>
</menu>
并假设正在显示 MenuItem
,则:
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final View decorView = getWindow().getDecorView();
decorView.post(() -> {
ArrayList<View> list = new ArrayList<>();
decorView.findViewsWithText(list, getString(R.string.action_settings), View.FIND_VIEWS_WITH_TEXT);
// `itemView` is the actual view you should use to create your `TapTargetView`
View itemView = list.get(0);
});
}
使用[=h11=]代替TapTarget.forView
像这样更改代码...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);
new TapTargetSequence(this)
.targets(
TapTarget.forToolbarMenuItem(toolbar,R.id.add, "Gonna"))
.listener(new TapTargetSequence.Listener() {
// This listener will tell us when interesting(tm) events happen in regards
// to the sequence
@Override
public void onSequenceFinish() {
// Yay
}
@Override
public void onSequenceStep(TapTarget lastTarget, boolean targetClicked) {
}
@Override
public void onSequenceCanceled(TapTarget lastTarget) {
// Boo
}
});
return true;
}
另一种方法是在菜单项中使用 "app:actionLayout="@layout/some_layout"
,some_layout 可以将该项目作为其中的视图。然后,在您的 activity 中,您可以使用:
MenuItem menuItem = menu.findItem(R.id.menu_item); // get the menu item
ImageView menuView = menuItem.getActionView().findViewById(R.id.some_icon);
您可以使用此 menuView 来设置点击目标
TapTargetView.showFor(activity, getTapTarget(menuView, title, message),
new TapTargetView.Listener()
{
@Override
public void onTargetClick(TapTargetView view)
{
super.onTargetClick(view);
view.dismiss(true);
}
@Override
public void onOuterCircleClick(TapTargetView view)
{
super.onOuterCircleClick(view);
view.dismiss(true);
}
});
经过反复的搜索和测试,终于找到了可行的解决方案!
只需在 onCreateOptionsMenu()
中获取对您的菜单项的引用。启动一个处理程序,以便在您获取 id 引用之前正确地膨胀视图。否则你将得到 空视图错误
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
new Handler().post(new Runnable() {
@Override
public void run() {
final View view = findViewById(R.id.askHelp);
TapTargetView.showFor(BasicInformation.this, // `this` is an Activity
TapTarget.forView(view, "You can tap here to get Chat Support")
// All options below are optional
.outerCircleColor(R.color.colorAccent) // Specify a color for the outer circle
.outerCircleAlpha(0.96f) // Specify the alpha amount for the outer circle
.targetCircleColor(R.color.white) // Specify a color for the target circle
.titleTextSize(30) // Specify the size (in sp) of the title text
.titleTextColor(R.color.white) // Specify the color of the title text
.textColor(R.color.white) // Specify a color for both the title and description text
.textTypeface(Typeface.SANS_SERIF) // Specify a typeface for the text
.dimColor(R.color.black) // If set, will dim behind the view with 30% opacity of the given color
.drawShadow(true) // Whether to draw a drop shadow or not
.cancelable(true) // Whether tapping outside the outer circle dismisses the view
.tintTarget(true) // Whether to tint the target view's color
.transparentTarget(false) // Specify whether the target is transparent (displays the content underneath)
.targetRadius(60), // Specify the target radius (in dp)
new TapTargetView.Listener() { // The listener can listen for regular clicks, long clicks or cancels
@Override
public void onTargetClick(TapTargetView view) {
super.onTargetClick(view); // This call is optional
//doSomething();
}
});
}
});
return true;
}