获取MenuItem的TapTargetView视图参考

时间:2017-06-13 06:38:53

标签: android android-layout android-view menuitem android-menu

我正在尝试使用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:给定目标的空视图

如何解决此问题? 我尝试将android:actionViewClass添加到xml文件中,但没有运气。

4 个答案:

答案 0 :(得分:2)

经过反复的搜索和测试,终于想出了一个有效的解决方案!

只需在onCreateOptionsMenu()内获取对菜单项的引用即可。启动处理程序,以便在获取id引用之前正确地扩展视图。否则,您将收到 null视图错误

@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;
}

答案 1 :(得分:1)

您可以使用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);
  });
}

答案 2 :(得分:1)

使用TapTarget.forToolbarMenuItem

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

答案 3 :(得分:0)

另一种方法是在菜单项中使用"app:actionLayout="@layout/some_layout",some_layout可以将项目作为其中的视图。然后,在您的活动中,您可以使用:

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