安卓ActionBar自定义操作视图工具提示

6
我有一个使用SupportActionBar的应用程序。我正在为操作使用自定义视图。
问题是,默认操作在长按时显示工具提示,但我的自定义操作没有显示。
这里是默认操作(可以看到有工具提示): Action item with tool-tip 这是我的自定义操作(没有工具提示): enter image description here 这两个的XML:
    <menu
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:custom="http://schemas.android.com/apk/res-auto">

        <item
            android:visible="false"
            android:title="Clear history"
            android:id="@+id/action_clear_history"
            custom:showAsAction="always"
            android:icon="@drawable/ic_action_trash" />
        <item
            android:title="Open chat"
            android:id="@+id/action_chat"
            custom:showAsAction="always"
            custom:actionLayout="@layout/ab_chat" />
    </menu>

有人可以帮忙吗?


你有答案了吗?@Arthur - Pratik Butani
我会尽快更新,一旦我有时间检查这个问题 ;) 你知道的,优先级 :D - Arthur
看我的回答,它很容易实现并且在我的端上运行。 - Lokesh
6个回答

9

我认为没有任何“官方”的API调用来实现这个功能。我相信像其他答案建议的那样,在您的自定义视图中添加View.OnClickListener,是最好的选择。

不过,您可以更好地计算工具提示toast的位置。我建议您从ActionMenuItemView类(来自支持库源代码)中简单复制和粘贴相关片段,因为它处理了一些特殊情况:

@Override
public boolean onLongClick(View v) {
    if (hasText()) {
        // Don't show the cheat sheet for items that already show text.
        return false;
    }

    final int[] screenPos = new int[2];
    final Rect displayFrame = new Rect();
    getLocationOnScreen(screenPos);
    getWindowVisibleDisplayFrame(displayFrame);

    final Context context = getContext();
    final int width = getWidth();
    final int height = getHeight();
    final int midy = screenPos[1] + height / 2;
    int referenceX = screenPos[0] + width / 2;
    if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR) {
        final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
        referenceX = screenWidth - referenceX; // mirror
    }
    Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT);
    if (midy < displayFrame.height()) {
        // Show along the top; follow action buttons
        cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, referenceX, height);
    } else {
        // Show along the bottom center
        cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
    }
    cheatSheet.show();
    return true;
}

你可以在<android-sdk>\sources\android-21\android\support\v7\internal\view\menu路径下找到它。


7

使用android.support.v7.widget.TooltipCompat是一种易用而完美的方法:

TooltipCompat.setTooltipText(view, "...");

仅适用于API 8及以上版本 - liminal
这应该是被接受的答案。同时也适用于androidx.appcompat.widget.TooltipCompat,在api 26及以上,我们可以简单地使用view.setTooltip("....")。 - Klitos G.

0

由于您正在使用自定义布局来设置按钮,因此以下代码应该可以正常工作:

view.setOnLongClickListener(new OnLongClickListener() {
    public boolean onLongClick(View view) {
        Toast toast = Toast.makeText(v.getContext(), "Open chat", Toast.LENGTH_SHORT);
        toast.show();
        return true;
    }
}

只需将此设置为操作栏中按钮的长按监听器即可。


0
尝试将值withText添加到showAsAction功能中。就像这样
android:showAsAction="ifRoom|always|withText"

0

使用Menu上的findItem方法获取您的视图,并在您的视图上设置OnLongClickListener

在您的Menuxml文件中进行一项更改,即添加行android:actionViewClass="android.widget.ImageButton"(您可以更改该View):

<item
     android:title="Open chat"
     android:id="@+id/action_chat"
     custom:showAsAction="always"
     android:actionViewClass="android.widget.ImageButton"
     custom:actionLayout="@layout/ab_chat" />

在获取父级View时,您可能会在此处遇到错误,我认为它应该是自定义布局的主视图。您可以先使用它,然后再使用actionViewClass

现在进入onCreateOptionMenu()以进行长按事件:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub
        getSupportMenuInflater().inflate(R.menu.menu_xml, menu);
        /*
        As per your defined view in XML of MENU
        */ 
        ImageButton view = (ImageButton) menu.findItem(R.id.action_chat).getActionView();
        view.setOnLongClickListener(new OnLongClickListener() {

            @Override
            public boolean onLongClick(View arg0) {
                // TODO Auto-generated method stub
                Display display = getWindowManager().getDefaultDisplay();
                Point size = new Point();
                display.getSize(size);
                int width = size.x;
                Toast toast = Toast.makeText(context, "Open Chat", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.TOP, width - 200, 50); //your width and height
                toast.show();
                return false;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

在顶部使用Gravity显示 Toast

您可以查看:演示 Toast


看起来有点不太对劲。而且我为什么需要 android:actionViewClass - Arthur
因为它将帮助您获取任何View来控制您的onLongPress点击事件。 - Pratik Butani
实际上,您不需要androidLactionViewClass来访问它。 MenuItem item_chat = menu.findItem(R.id.action_chat);可以在没有它的情况下工作。然后我只需在操作视图本身上放置一个onLongPress侦听器View item_chat_action_view = MenuItemCompat.getActionView(item_chat); - Arthur
我会再等一段时间,看看是否有更正式的答案,因为那个工具提示不仅仅是在固定坐标处放置吐司(在显示工具提示时,项目的确切位置+振动)。也许有一个API调用可以实现这一点。如果没有更好的答案,我会接受你的答案。 - Arthur
没问题,但你可以使用带有选择器的图像可绘制对象来实现振动效果。 - Pratik Butani

0
创建一个自定义布局并将其设置在操作栏上,希望这对您有所帮助。
View view     = getLayoutInflater().inflate(R.layout.actionbar_demo,null);
    btn   = (ImageView) view.findViewById(R.id.btn_action);
    btn.setOnLongClickListener(new OnLongClickListener()
    {

        @Override
        public boolean onLongClick(View v) {

            return true;
        }
    });



  getActionBar() . setCustomView(view);

你也可以像这样实现

   ActionBar actionBar = getSupportActionBar();
            actionBar.setCustomView(R.layoutcustom_action_bar);
            actionBar.setDisplayShowCustomEnabled(true);
            mLogo = (ImageView) actionBar.getCustomView().findViewById(
                    R.id.logo);
            mLogo.setOnLongClickListener(new OnLongClickListener()
              {

                  @Override
                  public boolean onLongClick(View v) {

                     return true;
                   }
              });

嗨!但这与工具提示有什么关系? - Arthur
我的周末已经开始了,如果可能的话,我会在星期一回复,并附上工具提示。这个答案也是我们问题的解决方案。请尝试这个。 - Lokesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接