获取 Toolbar 的导航图标视图参考

Posted

技术标签:

【中文标题】获取 Toolbar 的导航图标视图参考【英文标题】:Get Toolbar's navigation icon view reference 【发布时间】:2015-07-07 12:21:22 【问题描述】:

我想在我的Toolbar 中突出显示抽屉图标(正在编写教程)。为此,我需要它的位置。如何获得对抽屉导航图标(汉堡)视图的引用?

【问题讨论】:

((ViewGroup)yourtoolbar).get(0); 可能是 01 但我确定它为零,顺便说一句,这是你想要的吗?它会返回一个View,而View 是你的抽屉图标,可能是一个imageButton “突出显示”抽屉图标是什么意思? 您确定需要突出显示视图吗?例如,您可以获得用于图标的drawable。 @Elltz 为什么需要将工具栏投射到 ViewGroup?工具栏扩展了 ViewGroup,所以它不是,或者我错过了什么?这就是您的意思吗:View drawerIcon = toolbar.getChildAt(0); 它没有返回正确的视图(它返回的视图是我工具栏中间的图像)。 @JaredBurrows 这并不重要,但是如果您有兴趣,我开发了一个教程模块,它以视图作为参数并通过使屏幕变暗来突出显示它,同时使目标视图周围的圆圈可见。我希望突出显示工具栏中的导航图标。 【参考方案1】:

您可以利用视图的内容描述,然后使用findViewWithText()方法获取视图引用

 public static View getToolbarNavigationIcon(Toolbar toolbar)
        //check if contentDescription previously was set
        boolean hadContentDescription = !TextUtils.isEmpty(toolbar.getNavigationContentDescription());
        String contentDescription = hadContentDescription ? toolbar.getNavigationContentDescription() : "navigationIcon";
        toolbar.setNavigationContentDescription(contentDescription);
        ArrayList<View> potentialViews = new ArrayList<View>();
        //find the view based on it's content description, set programatically or with android:contentDescription
        toolbar.findViewsWithText(potentialViews,contentDescription, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
        //Nav icon is always instantiated at this point because calling setNavigationContentDescription ensures its existence 
        View navIcon = null;
        if(potentialViews.size() > 0)
            navIcon = potentialViews.get(0); //navigation icon is ImageButton
        
         //Clear content description if not previously present
        if(!hadContentDescription)
            toolbar.setNavigationContentDescription(null);
        return navIcon;
     

More

Kotlin 扩展属性:

val Toolbar.navigationIconView: View?
        get() 
            //check if contentDescription previously was set
            val hadContentDescription = !TextUtils.isEmpty(navigationContentDescription)
            val contentDescription = if (hadContentDescription) navigationContentDescription else "navigationIcon"
            navigationContentDescription = contentDescription
            val potentialViews = arrayListOf<View>()
            //find the view based on it's content description, set programatically or with android:contentDescription
            findViewsWithText(potentialViews, contentDescription, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION)
            //Clear content description if not previously present
            if (!hadContentDescription) 
                navigationContentDescription = null
            
            //Nav icon is always instantiated at this point because calling setNavigationContentDescription ensures its existence
            return potentialViews.firstOrNull()
        

【讨论】:

有趣,但我们为什么要这样做。为什么没有类似toolbar.getNavigationIconView() hadContentDescriptionisEmpty 时是true,此外“拼写错误”效果很好:) @snachmsm 你说得对,我已经编辑了答案并修复了错误。【参考方案2】:

在调试模式下查看工具栏的子视图后,我看到抽屉图标可以在那里找到,作为 ImageButton。 (感谢 Elltz)

我使用带有 2 个子项(LinearLayout 和 ImageView)的自定义 xml 布局的工具栏,所以我的工具栏最后有 4 个子项,位置如下:

[0] LinearLayout(from custom xml)
[1] ImageView(from custom xml)
[2] ImageButton(drawer icon)
[3] ActionMenuView(menu icon)

知道了这一点,我现在可以使用:

View drawerIcon = toolbar.getChildAt(2);

获取对抽屉菜单图标的引用。在我的例子中,位置是 2。这个位置应该等于自定义工具栏布局中子视图的数量。

如果有人找到更好的解决方案,请告诉我。

【讨论】:

【参考方案3】:

如果你只想获取代表工具栏导航图标的Drawable,你可以这样做:

Drawable d = mToolbar.getNavigationIcon();

您可以通过以下方法获得对用于工具栏导航图标的 ImageButton 的引用:

public ImageButton getToolbarNavigationButton() 
    int size = mToolbar.getChildCount();
    for (int i = 0; i < size; i++) 
        View child = mToolbar.getChildAt(i);
        if (child instanceof ImageButton) 
            ImageButton btn = (ImageButton) child;
            if (btn.getDrawable() == mToolbar.getNavigationIcon()) 
                return btn;
            
        
    
    return null;

【讨论】:

【参考方案4】:

即兴@Nikola Despotoski's回答

public static View getNavigationIconView(Toolbar toolbar)  

    String previousContentDescription = (String) toolbar.getNavigationContentDescription();
    // Check if contentDescription previously was set
    boolean hadContentDescription = !TextUtils.isEmpty(previousContentDescription);
    String contentDescription = hadContentDescription ? 
            previousContentDescription : "navigationIcon";
    toolbar.setNavigationContentDescription(contentDescription);

    ArrayList<View> potentialViews = new ArrayList<>();
    // Find the view based on it's content description, set programmatically or with
    // android:contentDescription
    toolbar.findViewsWithText(potentialViews, contentDescription,
            View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);

    // Nav icon is always instantiated at this point because calling
    // setNavigationContentDescription ensures its existence
    View navIcon = null;
    if (potentialViews.size() > 0) 
        navIcon = potentialViews.get(0); //navigation icon is ImageButton
    

    // Clear content description if not previously present
    if (!hadContentDescription)
        toolbar.setNavigationContentDescription(previousContentDescription);

    return navIcon;

【讨论】:

以上是关于获取 Toolbar 的导航图标视图参考的主要内容,如果未能解决你的问题,请参考以下文章

jQuery实现返回顶部按钮功能

怎样调整toolbar中setNavigationIcon的图标大小

toolbar右边怎么添加新的功能按钮

python toolbar怎么改变图标大小

自定义ToolBar

Toolbar-标题栏的使用