Невидимые значки элементов ActionMode в Theme.Sherlock.Light.DarkActionBar

При использовании Theme.Sherlock.Light.DarkActionBar (или Theme.Holo.Light.DarkActionBar, не имеет значения) ActionMode (или "контекстный ActionBar" ), который появляется, например, при выборе текста, по умолчанию имеет стиль, аналогичный стандарту темная тема, то есть синяя с яркими значками действия.

Однако, когда вы пытаетесь выбрать текст в диалоговом окне (который светлый в этой теме, в отличие от черного ActionBar), вместо него появляется ActionMode, созданный в виде темы Light (белый фон). Проблема в том, что ее иконки действия не темны, как должны быть, но свет, что делает их эффективно невидимыми.

enter image description here

Кажется, что фон был взят из легкой темы (из-за светлого диалога), но иконы были взяты из темной темы. Это ошибка в теме Light.DarkActionBar? Могу ли я что-то сделать?

Ответы

Ответ 1

Я боролся с той же проблемой, что и последние два дня. Наконец я придумал обходной путь!

Я использую DialogFragment с объектом AlertDialog. В методе onCreateDialog() все, что нам нужно сделать, это получить контекст родительской активности и снова установить ее тему на Theme.Light.

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    //get the parent activity context and set it theme again.
    Context ctx = getActivity();
    ctx.setTheme(android.R.style.Theme_Holo_Light);
    AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
    LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.your_dialog_layout, null, false);
    builder.setView(view);

    //your other code for the dialog
    //

    return builder.create();

Теперь значки в Контекстуальном ActionBar EditText имеют нужный цвет.

Ответ 2

Принуждение setTheme в текущем контексте не является хорошей идеей, так как оно искажает тему. Чтобы решить эту проблему, вы можете использовать ContextThemeWrapper.

Context themedContext = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light);
final AlertDialog dialog = new AlertDialog.Builder(themedContext)

Ответ 3

У меня была такая же проблема. Я использую пользовательскую тему, унаследованную от Theme.AppCompat.Light. В моей теме я переопределил элемент actionModeTheme своим элементом стиля. Но я столкнулся с проблемой, как с вашей проблемой. Чтобы решить эту проблему, просто переопределите элемент android:alertDialogTheme в своей настраиваемой теме.

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
        ...
        <item name="android:alertDialogTheme">@style/AppBaseTheme</item>
        ...
</style>

<style name="AlertDialogTheme">
        ...
        <item name="android:actionModeStyle">@style/ActionModeStyle</item>
        ...
</style>
<style name="ActionModeStyle" parent="Widget.AppCompat.Base.ActionMode">
            ...
            <item name="android:background">@color/gray</item>
            ...
</style>

Обратите внимание: он работает с уровня api 11.

Ответ 4

Проблема:

Тема приложения наследуется от android: Theme.Light, и для AlertDialog нет выделенной темы, так что элементы ActionMode как-то невидимы.


Решение:

1. Создайте выделенную тему для AlertDialog;

<style name="AppTheme" parent="android:Theme.Light">
</style>
<style name="AlertDialogTheme" parent="AppTheme">
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowCloseOnTouchOutside">true</item>
    <item name="android:windowActionModeOverlay">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
    <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
    <item name="android:maxLines">1</item>
    <item name="android:scrollHorizontally">true</item>
    <item name="android:textColor">@android:color/holo_blue_light</item>
</style>

Примечание: самая важная строка, которая делает магию <item name="android:textColor">@android:color/holo_blue_light</item>

2. Используйте специальную тему при создании AlertDialog.

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);

Пожалуйста, посмотрите на скриншот, который отображается до и после применения темы.

screenshot

Ответ 5

Добавьте это к теме:

    <item name="android:actionModeCutDrawable">@drawable/ic_menu_cut_holo_light</item>
    <item name="android:actionModeCopyDrawable">@drawable/ic_menu_copy_holo_light</item>
    <item name="android:actionModePasteDrawable">@drawable/ic_menu_paste_holo_light</item>
    <item name="android:actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_light</item>

И затем добавьте необходимые ресурсы для вашего проекта, которые можно найти здесь: https://github.com/android/platform_frameworks_base/tree/master/core/res/res

Ответ 6

Я пробовал вышеупомянутые решения, единственный, который работал у меня (у меня есть приложение, ориентированное на API 7, с AppCompat 21.0.3), чтобы установить стиль диалога в R.style.Theme_AppCompat. Да, глупый диалог теперь черный. Эта проблема также присутствует в AppCompat 22.

    final Context themedContext = new ContextThemeWrapper(activity, R.style.Theme_AppCompat);
    builder = new AlertDialog.Builder(themedContext);
    contents = ((LayoutInflater) themedContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.tag_editor, null);
    builder.setView(contents);

Ответ 7

У меня была та же проблема с приложением, которое я поддерживаю Решение было очень простым - мне просто пришлось сменить compileSdkVersion и targetSdkVersion на последние

Ответ 8

Решение состоит в том, чтобы использовать контекст ActionBar для создания AlertDialog:

Context themedContext = getActivity().getActionBar().getThemedContext();

Или используя ActionBarSherlock/ActionBarCompat:

Context themedContext = getActivity().getSupportActionBar().getThemedContext();

Затем создайте AlertDialog, используя этот тематический контекст:

AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);