Почему MenuItemCompat.getActionProvider возвращает значение null?
Я попытался использовать 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>
здесь мой код для создания кнопки действия с общим ресурсом:
@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);
}
Мой вопрос:
- MenuItemCompat.getActionProvider(shareItem) всегда возвращает null для меня, почему это?
- Когда я прокомментирую эти строки, кнопка совместного доступа появляется на панели, но ничего не делает, щелкая, как ее исправить (если вопрос 1 не может быть разрешен)
btw, я проверил коды MenuItemCompat.getActionProvider, похоже, что этот метод проверяет, реализует ли пункт меню интерфейс SupportMenuItem и возвращает сбой, если это не так. Как я могу справиться с этим?
Ответы
Ответ 1
В моем случае это неправильное пространство имен в 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"/>
Обратите внимание на app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
: он должен иметь
- правильный пакет (
android.widget android.support.v7.widget)
- правильное пространство имен (приложение
android).
Несчастливо, компилятор компилирует его без ошибок, только Android Studio делает уведомление с подчеркиванием.
Ответ 2
Вот это единственное решение, которое работает, чтобы сделать ShareActionProvider не null... я использую вместо этого 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);
}
}
и... 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>
и другие вещи, которые можно проверить:
активность должна расширять ActionBarActivity:
MyActivity extends ActionBarActivity
проверить и использовать этот импорт:
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;
В AndroidManifest.xml поместите эту строку в атрибуты тега активности:
android:theme="@style/Theme.AppCompat.Light"
Если вы не знаете, как импортировать библиотеки совместимости v7 и v4, см. ниже: http://developer.android.com/tools/support-library/setup.html
Ответ 3
Если кто-то хочет сохранить progaurd
и все еще использовать код:
ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);
Просто добавьте в proguard
:
-keep class android.support.v7.widget.ShareActionProvider { *; }
Ответ 4
Убедитесь, что ваш класс расширяет AppCompatActivity, а не только Activity.
Примечание. Отредактировано с учетом обновленной библиотеки совместимых приложений.
Ответ 5
После некоторого чтения, который включает, вероятно, некоторые из ваших ответов, наконец, это разрешено:
-
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>
-
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;
-
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" >
-
build.gradle
4.1. В моем случае, чтобы остаться в безопасной стороне, я превратил ProGuard в Debug.
debug {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
4,2. Убедитесь, что у вас есть следующий раздел компиляции в зависимостях
`compile 'com.android.support:appcompat-v7:20.0.+'`
Ответ 6
У меня была такая же проблема с nullPointer в моем приложении. Как заявил @josh527, я забыл определить собственное пространство имен xml для моего приложения. Я знаю, что это не твоя проблема, но некоторые люди могут дойти до твоего поста, подобного мне, и не вижу этого, поэтому я просто хотел его заметить;)
Ответ 7
У меня был такой же тип ошибки. MenuItemCompat.getActionProvider возвращает null.
Моя проблема была в ProGuard. Повернув ProGuard, я решил это для меня.
Ответ 8
Попробуйте добавить в блок действий
import android.support.v4.view.MenuItemCompat;
У меня была та же проблема, и это было решение.
Ответ 9
переменная:
Android.Support.V7.Widget.ShareActionProvider shareActionProvider;
this.MenuInflater.Inflate(Resource.Menu.share_action_provider, menu);
var shareItem = menu.FindItem(Resource.Id.menu_item_share_action_provider_action_bar);
MenuItemCompat.SetShowAsAction (shareItem, MenuItemCompat.ShowAsActionIfRoom);
var actionprov = new Android.Support.V7.Widget.ShareActionProvider (this);
MenuItemCompat.SetActionProvider (shareItem, actionprov);
var test = MenuItemCompat.GetActionProvider (shareItem);
shareActionProvider = test.JavaCast<Android.Support.V7.Widget.ShareActionProvider>();
var intent = new Intent(Intent.ActionSend);
intent.SetType("text/plain");
intent.PutExtra(Intent.ExtraText, "ActionBarCompat is Awesome! Support Lib v7 #Xamarin");
shareActionProvider.SetShareIntent (intent);
return base.OnCreateOptionsMenu(menu);
это сошло с меня... я просто создал свой собственный shareactionprovider! и я сам его установил, а потом заработал... и, может быть, какой-то код даже этого не нужен.. но его много кастинга И УБЕДИТЕСЬ, что вы используете правильные все время, если вы просто наберете "ShareActionProvider", вы фактически используя V4..! вместо V7
Ответ 10
Вы должны изменить объявление и определение функции onCreateOptionsMenu. вы изменили объявление функции с базового класса. это означает, что метод не переопределяется.
Попробуйте следующее:
@Override
public boolean onCreateOptionsMenu (Menu menu) {
inflater.inflate(R.menu.share, menu);// declare a local layout inflater
MenuItem shareItem = menu.findItem(R.id.action_share);
ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);
mShareActionProvider.setShareIntent(getDefaultIntent());
// super.onCreateOptionsMenu(menu, inflater); <--- Remove this line or put in the first line because base class constructor should be called in the first line of the method.
return super.onCreateOptionsMenu(menu);//<-- Add this line to set the menu after adding menu items
}
Ответ 11
Ни одно из решений здесь не решило мою проблему с ShareActionProvider, не приводя/не возвращая null. В итоге я заменил ShareActionProvider на Intent.SEND_ACTION, чтобы делиться изображениями в моем приложении, как показано в учебнике по Android для разработчиков: https://developer.android.com/training/sharing/send
Хотя Google упоминает в этом руководстве, что: Note: The best way to add a share action item to an ActionBar is to use ShareActionProvider, which became available in API level 14. ShareActionProvider is discussed in the lesson about Adding an Easy Share Action.
Я нашел гораздо проще реализовать только Intention.SEND_ACTION. Не уверен, есть ли другие причины для реализации ShareActionProvider...
Ответ 12
Для Android Pie класс провайдера действий снова изменился:
app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider"
Ответ 13
Есть еще одна потенциальная проблема. Если ваш MenuItem всегда присутствует в ActionBar, используйте следующий код:
menuItem?.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
Полученный пункт меню не будет работать (он будет виден, но не включен). Есть два варианта: либо изменить тип ShowAsAction, либо вызвать setShareIntent непосредственно в функции onCreateOptionsMenu():
[email protected](java.lang.Runnable {
actionProvider.setShareIntent(shareIntent)
})