为什么MenuItemCompat.getActionProvider返回null?

hag*_*ago 24 java android

我试图在我的应用程序的操作栏上使用android.support.v7.widget.ShareActionProvider.所以我按照android文档的例子,但遇到了一些问题.
这是我的菜单xml:

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

    <item
        android:id="@+id/action_share"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_share"
        android:title="@string/action_share"
        myapp:showAsAction="ifRoom"
        myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider" />

</menu>
Run Code Online (Sandbox Code Playgroud)

这是我创建共享操作按钮的代码:

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.share, menu);
    MenuItem shareItem = menu.findItem(R.id.action_share);
    ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);
    mShareActionProvider.setShareIntent(getDefaultIntent());
    super.onCreateOptionsMenu(menu, inflater);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. MenuItemCompat.getActionProvider(shareItem)总是为我返回null,为什么?
  2. 当我评论这些行时,分享按钮出现在栏上,但在点击时什么都不做,如何修复它(如果问题1无法解决)?

顺便说一句,我检查了MenuItemCompat.getActionProvider的代码,看起来这个方法会检查菜单项是否实现了SupportMenuItem接口,如果不是则返回失败.我怎么处理它?

rad*_*tao 19

在我的情况下,它是错误的命名空间menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
  <item android:id="@+id/menu_item_share"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
Run Code Online (Sandbox Code Playgroud)

注意app:actionProviderClass="android.support.v7.widget.ShareActionProvider":应该有

  • 正确的(android.widget android.support.v7.widget)
  • 正确的命名空间(android app).

不幸的是,编译器编译它没有错误,只有Android Studio通过下划线进行通知.


Raz*_*uar 17

这是唯一可以使ShareActionProvider不为空的解决方案...我使用set ActionProvider代替...请参阅下面的代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.messages_activity_menu, menu);
    MenuItem menuItem = menu.findItem(R.id.menu_item_share);
    shareActionProvider = new ShareActionProvider(this);
    MenuItemCompat.setActionProvider(menuItem, shareActionProvider);

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if(item.getItemId() == R.id.menu_item_share){
        onShareAction();
    }

    return super.onOptionsItemSelected(item);
}

private void onShareAction(){
    // Create the share Intent
    String playStoreLink = "https://play.google.com/store/apps/details?id=" + getPackageName();
    String yourShareText = getResources().getString(R.string.share_text) + playStoreLink;
    Intent shareIntent = ShareCompat.IntentBuilder.from(this).setType("text/plain").setText(yourShareText).getIntent();
    // Set the share Intent
    if (shareActionProvider != null) {
        shareActionProvider.setShareIntent(shareIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)

和XML ...

 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
     <item
    android:id="@+id/menu_item_share"
    android:icon="@drawable/ic_action_share"
    android:showAsAction="ifRoom|withText"
    android:title="@string/menu_item_share" />
 </menu>
Run Code Online (Sandbox Code Playgroud)

和其他可以检查的事情:

活动必须扩展ActionBarActivity:

MyActivity extends ActionBarActivity
Run Code Online (Sandbox Code Playgroud)

检查并使用此导入:

import android.support.v4.app.ShareCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.OnNavigationListener;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
Run Code Online (Sandbox Code Playgroud)

在AndroidManifest.xml中,将此行放在activity的标记属性中:

android:theme="@style/Theme.AppCompat.Light"
Run Code Online (Sandbox Code Playgroud)

如果您不知道如何导入v7和v4兼容性库,请参阅:http://developer.android.com/tools/support-library/setup.html

  • `"这是唯一能使ShareActionProvider不为空的解决方案".嗯,这不是真的.看到我的回答. (3认同)

ysh*_*hak 16

如果有人想继续progaurd使用并仍然使用代码:

ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);
Run Code Online (Sandbox Code Playgroud)

只需要添加到proguard:

-keep class android.support.v7.widget.ShareActionProvider { *; }
Run Code Online (Sandbox Code Playgroud)

  • 效果很好,这应该是公认的答案 (2认同)

Sky*_*ile 12

确保您的类扩展AppCompatActivity而不仅仅是Activity.

注意:已编辑以反映更新的应用程序compat库.


小智 11

经过一些阅读,其中可能包括你们的一些回复,最后这个问题得到了解决:

  1. Share_Menu.xml.确保您有自定义命名空间,actionProvider类来自该自定义命名空间以及正确的值:android.support.v7.widget.ShareActionProvider

    <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myapp="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_share" android:title="@string/action_detail_share" myapp:showAsAction="always" myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"></item> </menu>

  2. Detail_Activity.java
    2.1.从ActionBarActivity继承而不是Activity
    2.2.添加正确的导入

    import android.support.v4.app.Fragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.ShareActionProvider;

  3. AndroidManifest.xml 添加android:theme =" @ style/Theme.AppCompat.Light "

    <activity android:name=".detail_activity" android:label="@string/title_activity_detail_activity" android:theme="@style/Theme.AppCompat.Light" android:parentActivityName=".main_activity" >

  4. Build.gradle
    4.1.在我的情况下,为了保持安全,我在调试中转向ProGuard.

    debug { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }

4.2.确保依赖项中包含以下编译部分

`compile 'com.android.support:appcompat-v7:20.0.+'` 
Run Code Online (Sandbox Code Playgroud)