无法单击自定义操作视图

Posted

技术标签:

【中文标题】无法单击自定义操作视图【英文标题】:Custom Action View can't be clicked 【发布时间】:2011-07-23 16:47:30 【问题描述】:

我正在尝试将自定义 ActionView 添加到我的 ActionBar

我正在尝试添加通用刷新按钮。 (ImageButtonProgressBarFrameLayout 内)但如果我使用 ActionView,则永远不会调用 onOptionsItemSelected()

代码如下:

在我的Activity:

@Override
public boolean onCreateOptionsMenu(Menu menu) 
    MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.messages_actionbar, menu);
mRefreshView = (RefreshView) menu.findItem(R.id.messages_refresh).getActionView();

return super.onCreateOptionsMenu(menu);

messages_actionbar的来源:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/messages_refresh"
        android:title="title"
        android:icon="@drawable/icon"
        android:showAsAction="always"
        android:actionViewClass="com.blabla.RefreshView"/>
</menu>

RefreshView的代码:

public class RefreshView extends FrameLayout 

    private ImageView mButton;
    private ProgressBar mProgressBar;
    private boolean mLoading;

    public RefreshView(Context context) 
        super(context, null);
        initView(context);
    

    public RefreshView(Context context, AttributeSet attrs) 
        super(context, attrs, 0);
        initView(context);
    

    public RefreshView(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
        initView(context);
    

    private void initView(Context context) 
        LayoutInflater inflator = LayoutInflater.from(context);
        View v = inflator.inflate(R.layout.actionbar_refresh, this);
        mProgressBar = (ProgressBar) v.findViewById(R.id.action_refresh_progress);
        mButton = (ImageView) v.findViewById(R.id.action_refresh_button);
    

    public void setLoading(boolean loading) 
        if (loading != mLoading) 
            mProgressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
            mButton.setVisibility(loading ? View.GONE : View.VISIBLE);
            mLoading = loading;
        
    

actionbar_refresh的源代码:

<?xml version="1.0" encoding="utf-8" ?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

    <ImageView
        android:id="@+id/action_refresh_button"
        android:layout_
        android:layout_
        android:scaleType="center"
        android:background="@drawable/icon" />

    <ProgressBar
        android:id="@+id/action_refresh_progress"
        android:layout_
        android:layout_
        android:layout_gravity="center"
        android:visibility="gone"
        android:indeterminate="true" />
</FrameLayout>

另一方面,如果我在RefreshView 类中将clickListener 设置为ImageView,它就会被调用。

有人已经这样做了吗?

【问题讨论】:

“我正在尝试添加通用刷新按钮。(ImageButton,FrameLayout 内的 ProgressBar)但如果我使用 ActionView,则永远不会调用 onOptionsItemSelected()。” - 是什么让你认为它应该被调用?它不再是一个菜单选项——它是你的自定义View——所以我不希望onOptionsItemSelected()被调用。 @CommonsWare:为什么不呢?该视图是现有菜单项的ActionViewmenu.findItem(R.id.messages_refresh).getActionView(); 返回正确的视图。如果您说的是正确的,Gmail 应用程序是如何做到的?你认为他们设置了clickListener 并且自定义视图会以某种方式通知Activity 这是我的猜测。想一想:假设我有一个 17 个按钮的动作视图。他们都会触发onOptionsItemSelected()吗?如果是这样,您将如何区分它们? 【参考方案1】:

onOptionsItemSelected() 仅在操作项位于溢出菜单中时才应调用,您也应处理该菜单。 (您将其强制“始终”显示在操作栏上,因此不会调用 onOptionsItemSelected())。

onCreateOptionsMenu() 充气后,您必须为菜单项设置OnMenuItemClickListener

【讨论】:

我参与上面的后面。我做了一些额外的测试。 onOptionsItemSelected() 不会为操作视图调用,仅用于操作项(在操作栏或溢出菜单中)。这解释了你所看到的。但是当动作视图被放置在溢出菜单中时,会为其调用 onOptionsItemSelected(),如果定义了则调用 onMenuItemClick()。【参考方案2】:

我最终使用了来自 http://code.google.com/p/styled-action-bar/ 的 src 代码。

【讨论】:

这可行,但是我以与您设置它的方式非常相似的方式实现了这一点,因为我需要对实际视图进行更多控制。您应该刚刚在视图上实现了 onClickListener,然后为要实现的基本活动或片段实现了回调。同样,如果您只需要一个简单的刷新微调器,我会建议您使用的方法,我只想说它可以与您的原始代码一起工作,只需稍作改动。 我已经从您的blog post 进行了调整,现在我已经上传到Github【参考方案3】:

我找到了一个可行的解决方案,我想与您分享。它基于 (@Macarse) 的第一种方法,但有一些重要的变化。

重要提示:相应地调整 initView 方法

    为 ImageView 设置一个 onClickListener (mButton)

    loading 设置为 true 并通知 Activity (MyActivity) 关于点击

    private void initView(final Context context) 
        final LayoutInflater inflator = LayoutInflater.from(context);
    
        final View actionView = inflator.inflate(
                R.layout.action_refresh_progress, this);
        mProgressBar = (ProgressBar) actionView
                .findViewById(R.id.action_refresh_progress);
    
        mButton = (ImageView) actionView
                .findViewById(R.id.action_refresh_button);
    
        mButton.setOnClickListener(new OnClickListener() 
    
            @Override
            public void onClick(final View view) 
                setLoading(true);
                ((MyActivity) context).handleRefreshButtonClick();
            
        );
    
    

    React根据 Activity 中的点击 (MyActivity)

    public void handleRefreshButtonClick() 
        // Start refreshing...
    
    

我希望我的方法可以为您节省一些时间来寻找可行的解决方案!

【讨论】:

以上是关于无法单击自定义操作视图的主要内容,如果未能解决你的问题,请参考以下文章

无法单击 UWP 自定义标题栏按钮

单击 UITabBarController 时的自定义操作

Django admin:如何在单击自定义按钮时调用操作?

为啥我的自定义表格单元格中的标签在单击行之前无法显示

是否无法在 UITableViewCell 上的删除操作(滑动按钮)中使用自定义视图?

ViewController 操作后,Swift UIView 自定义视图不会更新