在Android中编程触发操作栏菜单项

4

我有一个带有菜单项的操作栏。当我点击刷新图标时,会显示进度条的方法。

我想在此活动加载时执行此操作。因此,我尝试通过编程方式调用刷新图标项单击程序:

onOptionsItemSelected(menu.findItem(R.id.action_Refresh)); 

我在创建菜单后调用了上述内容。
但是,当我加载数据时,它会出现空指针异常。如果我点击刷新按钮,它就可以正常工作,但如果我以编程方式调用它,就会出现错误。
以下是我的代码:
 @Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    this.optionsMenu = menu;
    getMenuInflater().inflate(R.menu.main, menu);

    onOptionsItemSelected(menu.findItem(R.id.action_Refresh));

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    switch (item.getItemId()) 
    {
    case R.id.action_about:
        aboutapp();
        return true;

    case R.id.action_Refresh:
        Log.e("REfressh","Clicked");
        Mapsthree.refreshValue = 0;
        timer = new Timer();
        timerMethod();
        setRefreshActionButtonState(true);
        displayView(1);
        return true;

    default:
        return super.onOptionsItemSelected(item);
    }
}

private void timerMethod()
{
    timer.scheduleAtFixedRate(new TimerTask() 
    {
        @Override
        public void run() 
        {
            updateProgressBar();
        }

    }, 0, 800);
}

private void updateProgressBar() 
{
    runOnUiThread(new Runnable() 
    {
        public void run() 
        {
            if (Maps.refreshValue == 1)
            {
                setRefreshActionButtonState(false);
                timer.purge();
                timer.cancel();
            }
        }
    });
}

public void setRefreshActionButtonState(final boolean refreshing) 
{
    if (optionsMenu != null) 
    {
        final MenuItem refreshItem = optionsMenu.findItem(R.id.action_Refresh);
        if (refreshItem != null) 
        {
            if (refreshing) 
            {
                refreshItem.setActionView(R.layout.actionbar_indeterminate_progress);
            } 
            else 
            {
                refreshItem.setActionView(null);
            }
        }
    }
}

有没有可能以编程方式调用菜单项?如果可以,怎么做呢?

谢谢!


将您执行的刷新操作的代码封装在一个新方法中,然后为操作项调用它,在活动中需要调用它的任何地方也可以调用它。 - fasteque
4个回答

6

可以直接使用findViewById(R.id.action_Refresh).callOnClick();

或者

findViewById(R.id.action_Refresh).performClick();


将其更改为performClick()即可。简单易行。 - Pedro Oliveira
我正在尝试在onCreateOptionsMenu中使用此代码,在创建菜单后,我只是调用:findViewById(R.id.action_Refresh).performClick()。 - TheDevMan
“创建菜单后”?那是错误的。菜单仅在返回 true 后创建。在此之前根本没有菜单。因此会出现 NPE。 - Pedro Oliveira
首先,删除你在onOptionsItemSelected中的所有内容,然后尝试你的初始解决方案。我敢打赌,如果你把它删除并只放置一个toast,它就会被调用。NPE错误的原因可能是你在那里调用了某些函数,这些函数会以某种方式干扰视图。这个视图还没有被创建。 - Pedro Oliveira
我删除了所有内容,只加了像你建议的那样的日志,但仍然不起作用。 - TheDevMan
显示剩余4条评论

2

为什么要在onCreateOptionsMenu中调用它?

根据需求,您可以在onCreateonResume方法中编写加载代码:

@Override
protected void onCreate(Bundle arg0) {

    super.onCreate(arg0);

    //whatever you are doing

    //now code for refresh

    Log.e("REfressh","First time");
    Mapsthree.refreshValue = 0;
    timer = new Timer();
    timerMethod();
    setRefreshActionButtonState(true);
    displayView(1);
}

我不能这样做,只有在单击时才将刷新图标更改为进度条。 - TheDevMan
所以,你希望它在第一次加载时也改为进度条? - Pramod Ravikant
没错 - 因为我正在从云上加载一些东西,需要些时间。 - TheDevMan
使用了您的逻辑并进行了一些更改。运行良好!非常感谢! - TheDevMan

2
你可以尝试这样做:
在此处获取你的Activity中Menu类opMenu的引用:
Menu opMenu;
@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    opMenu= menu;
    getMenuInflater().inflate(R.menu.main, menu);

    onOptionsItemSelected(opMenu.findItem(R.id.action_Refresh));

    return super.onCreateOptionsMenu(menu);;
}  

使用opMenu.findItem()来触发点击。

@TheDevMan 只需将您的代码替换为我的并检查,您使用了 menu.findItem(),我得到了正确的结果。 - Piyush Kukadiya
我用了一个方法,它起作用了,但我正在使用微处理器逻辑。这个方法完美地工作。谢谢!因为你的逻辑给了一个+1,谢谢! - TheDevMan

0
// check is assignable to menu item implementation
if(menuItem !=null 
    && MenuItemImpl.class.isAssignableFrom(menuItem.getClass())){
  // if so cast 
  MenuItemImpl impl = (MenuItemImpl)menuItem;
  // invoke listener 
  impl.invoke();
}

这意味着实现相等;

public boolean invoke() {
    if (mClickListener != null && mClickListener.onMenuItemClick(this)) {
        return true;
    }

    if (mIntent != null) {
        mContext.startActivity(mIntent);
        return true;
    }
    return false;
}

你总是可以使用反射 :)


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