android 4.0, текст на панели действий НИКОГДА не отображается
Я пытаюсь использовать новые api из google, в частности панель действий.
Когда assembly была установлена на api 10, если бы я нажал кнопку меню, у меня появились приятные варианты меню, каждый с изображением и значком. При использовании api 14, независимо от того, что я пытаюсь, он всегда помещает значок в панель действий без текста. Я пробовал все, что мог придумать. Я дал ему свойство «с текстом», изменил текст на один символ (в случае, если это был номер), но ничего.
Я видел это раньше, даже в руководстве разработчика в android.developer, но я не могу найти ответ о том, КАК заставить его появиться.
- Получение DrawerLayout для перемещения по ActionBar
- Изменение фонового рисунка виджета searchview
- Иконка «Нет приложений» на ActionBar
- Как показать значки в меню переполнения в ActionBar
- Ящик Android Navigation над вкладками
- Панель действий Android, например, твиттер
- Не показано приложение с AppCompat
- «Идентификатор ресурса не найден для атрибута« showAsAction »в пакете« андроид »»
- Как добавить меню опций панели действий в Android Fragments
- getActionView () моего MenuItem возвращает null
- Как установить пользовательский цвет / стиль ActionBar?
- Панель состояния Android и панель действий
- Android Lollipop, AppCompat ActionBar пользовательский вид не занимает всю ширину экрана
Я подозреваю, что разработчики Android сознательно решили никогда не отображать текст и значок одного элемента меню на узкой панели действий. Но если вы действительно этого хотите, вы можете использовать android: actionLayout в вашем файле menu.xml. Документация Android ActionBar имеет несколько лучшее объяснение.
Затем создайте свой макет action_button_foo.xml
:
и используйте селектор для его фона bg_btn_action_bar.xml
, поэтому он меняет цвет при нажатии на него:
Теперь вам нужно сделать свой клик по клику. В вашей деятельности мне нравится делать это, чтобы я мог обрабатывать щелчок в onOptionsItemSelected
вместе со всеми моими другими нестандартными элементами.
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_menu, menu); final MenuItem item = menu.findItem(R.id.menu_foo); item.getActionView().setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onOptionsItemSelected(item); } }); return super.onCreateOptionsMenu(menu); }
Это, безусловно, то же самое, что я наблюдал на моем Nexus S, работающем 4.0.4. В моем приложении используется панель действий с несколькими вкладками, которые реализованы как fragmentы. Мои различные fragmentы корректируют параметры меню, отображаемые на панели действий, пока их вкладка видна.
Это похоже на ошибку в ICS, поскольку она выполняется последовательно следующим образом, как на моем Nexus S, так и в эмуляторе (как HVGA, так и WVGA800):
- В портретном режиме в верхней строке панели действий отображается моя кнопка «вверх / вниз», во второй строке отображаются вкладки, а любые действия отображаются только в виде значков (без текста) в правой части верхней строки.
- Но если при повороте в ландшафт, панель действий сворачивается в одну строку, а вкладки перемещаются вверх по верхней панели в виде прядильного (раскрывающегося списка) рядом с моей кнопкой вверх. Но, в частности, текст появляется рядом с моими значками действий.
Я заметил некоторые другие сбои со счетчиком, который заставлял меня поверить, что этот маленький уголок ICS немного грязный / глючный. Если я скажу приложению разбить панель действий на узких дисплеях (добавив в манифест android:uiOptions="splitActionBarWhenNarrow"
, ICS всегда подталкивает эти элементы к нижней панели, хотя в верхней части еще много места. И даже с дополнительным баром, он все еще не отображает текст, просто значок.
На моем Xoom, работающем 4.0.4, вкладки и элементы действия всегда появляются так, как вы ожидали, что они появятся, потому что есть много места.
Обход проблемы: если вы действительно хотите текст на панели действий в портретном режиме, вам нужно отказаться от значка. Удалите значок из вашего пункта меню, и появится текст. Это не совсем то, что нам нужно.
Я разместил здесь отчет об ошибке: https://code.google.com/p/android/issues/detail?id=30180 .
Если вы хотите, чтобы ваше меню параметров отображалось в панели действий с помощью Honeycomb, я сделал следующее:
В вашей деятельности переопределите эту функцию:
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.actionbar_universe, menu); return true; }
где R.menu.actionbar_universe определяет ваш пункт меню следующим образом:
Обратите внимание на showAsAction = “always | withText” и укажите android: title.
Если у вас есть это и его не работает, скопируйте | вставьте свой ресурс меню здесь.
EDIT: Это отвечает на неправильный вопрос, но это оригинальный текст.
Я использую этот бит кода, чтобы установить заголовок панели действий, и нарисуйте его красным цветом с логотипом своих компаний. Он хорошо работает в версии 3.0.
public ActionBar setActionBarStyle(String title) { ActionBar actionBar = setActionBarStyle(); actionBar.setTitle(title); return actionBar; } public ActionBar setActionBarStyle() { ActionBar actionBar = getActionBar(); ShapeDrawable actionBackground = new ShapeDrawable(); actionBackground.getPaint().setColor(Color.RED); actionBackground.setBounds(0, 0, 5, 5); actionBar.setBackgroundDrawable(actionBackground); actionBar.setDisplayUseLogoEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); return actionBar; }
Свойство «withText» работает с большинством планшетов, но простой способ получить значки и текст на более мелких устройствах – это добавить текст рядом со значком в виде одного изображения (PNG-файл). Таким образом, как текст, так и значок будут отображаться как один значок, и все это будет отображаться.
Вы можете использовать оригинальный значок для планшетов, используя свойство withText.
-
Вы должны создать дополнительную папку меню в каталоге res под названием «menu-w600dp».
-
Файл optionsmenu.xml в этой папке применим только к ширине экрана, превышающей 600dp (те, которые без проблем отображают значки и текст).
Исправлена ошибка: « Если ваше приложение использует раздел« Библиотека поддержки »в разделе« Указание действий в XML » .
… для совместимости в версиях с Android 2.1 атрибут showAsAction недоступен из пространства имен
android:
Вместо этого этот атрибут предоставляется библиотекой поддержки, и вы должны определить собственное пространство имен XML и использовать это пространство имен в качестве префикса атрибута. (Пользовательское пространство имен XML должно основываться на имени вашего приложения, но это может быть любое имя, которое вы хотите, и доступно только в пределах области файла, в котором вы его объявляете.) Например:
Если ни одно из этих других действий не будет работать на вас, это может произойти.
Я пробовал много вариантов, и я придумал простой «трюк» без какой-либо странной строки кода, без изображений. И первое решение с пользовательским действиемLayout просто не работало для меня с совместимостью API уровня 10.
Если вы хотите отобразить значок текста И на небольшой панели действий, значит, вы знаете, что у вас есть пространство, не так ли? Таким образом, вы можете использовать 2 пункта меню:
- Сначала с иконкой ТОЛЬКО (игнорируйте предупреждение, если вы установите табло заголовка, вы увидите его дважды)
- Во-вторых, только текст
И при необходимости выберите текстовое действие в «ifRoom», чтобы, если вам нужно место, текст исчезнет. Это займет еще больше места на панели действий, но для меня это был хороший компромисс. Я получаю следующий код:
-
-
( EDIT, где «pelmel» – ваше имя приложения END EDIT )
И тогда ваш обработчик выбора должен поймать оба идентификатора:
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_save: case R.id.menu_save_text: // Your code here return true; } }
Вот еще один вариант, основанный примерно на dgmltn. Преимущества:
- Больше контроля – например, я поменял текст и изображение в своем макете.
- Легче использовать – требуется только две дополнительные линии в ваших действиях / fragmentах.
- Требуется только два дополнительных файла.
- Возможно, немного правильнее, но это еще немного взломать IMO.
Я предположил, что вы используете ActionBarSherlock в этом примере. Сначала создайте макет вида, который вы хотите. Это основано на ActionBarSherlock. Все, что я изменил, заключалось в замене изображения / просмотра, уменьшении общего поля / отступов до 0, чтобы они были ближе и разрешали все стили ABS.
Затем создайте соответствующий class View
. Возможно, вы захотите скопировать CapitalizingButton
если вас беспокоит использование внутренних вещей. О, также я никогда не фиксировал материал минимальной ширины. Не думайте, что это действительно важно.
package com.example.views; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageButton; import android.widget.LinearLayout; import com.actionbarsherlock.R; import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockListActivity; import com.actionbarsherlock.app.SherlockListFragment; import com.actionbarsherlock.internal.widget.CapitalizingButton; import com.actionbarsherlock.view.MenuItem; @SuppressLint({ "NewApi" }) public class ActionMenuTextItemView extends LinearLayout implements OnClickListener { private ImageButton mImageButton; private CapitalizingButton mTextButton; private Object mTarget; private MenuItem mItem; // Set up all the data. Object must be a sherlock activity or fragment with an onMenuItemSelected(). public void initialise(MenuItem item, Object target) { mItem = item; mTarget = target; setIcon(mItem.getIcon()); setTitle(mItem.getTitle()); } public ActionMenuTextItemView(Context context, AttributeSet attrs) { super(context, attrs); } public ActionMenuTextItemView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void onFinishInflate() { super.onFinishInflate(); mImageButton = (ImageButton) findViewById(R.id.abs__imageButton); mTextButton = (CapitalizingButton) findViewById(R.id.abs__textButton); mImageButton.setOnClickListener(this); mTextButton.setOnClickListener(this); setOnClickListener(this); } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); mImageButton.setEnabled(enabled); mTextButton.setEnabled(enabled); } public void setIcon(Drawable icon) { mImageButton.setImageDrawable(icon); if (icon != null) mImageButton.setVisibility(VISIBLE); else mImageButton.setVisibility(GONE); } public void setTitle(CharSequence title) { mTextButton.setTextCompat(title); setContentDescription(title); } @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { onPopulateAccessibilityEvent(event); return true; } @Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) super.onPopulateAccessibilityEvent(event); final CharSequence cdesc = getContentDescription(); if (!TextUtils.isEmpty(cdesc)) event.getText().add(cdesc); } @Override public boolean dispatchHoverEvent(MotionEvent event) { // Don't allow children to hover; we want this to be treated as a single component. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) return onHoverEvent(event); return false; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int minWidth = 0; final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int specSize = MeasureSpec.getSize(widthMeasureSpec); final int oldMeasuredWidth = getMeasuredWidth(); final int targetWidth = widthMode == MeasureSpec.AT_MOST ? Math.min(specSize, minWidth) : minWidth; if (widthMode != MeasureSpec.EXACTLY && minWidth > 0 && oldMeasuredWidth < targetWidth) { // Remeasure at exactly the minimum width. super.onMeasure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), heightMeasureSpec); } } @Override public void onClick(View v) { if (mTarget == null) return; else if (mTarget instanceof SherlockActivity) ((SherlockActivity)mTarget).onOptionsItemSelected(mItem); else if (mTarget instanceof SherlockFragmentActivity) ((SherlockFragmentActivity)mTarget).onOptionsItemSelected(mItem); else if (mTarget instanceof SherlockListActivity) ((SherlockListActivity)mTarget).onOptionsItemSelected(mItem); else if (mTarget instanceof SherlockListFragment) ((SherlockListFragment)mTarget).onOptionsItemSelected(mItem); else if (mTarget instanceof SherlockFragment) ((SherlockFragment)mTarget).onOptionsItemSelected(mItem); else throw new IllegalArgumentException("Target must be a sherlock activity or fragment."); } }
Хорошо, теперь вы готовы его использовать. В пунктах меню, которые вы хотите иметь текст, вы делаете то же самое, что и dgmltn:
// Or whatever you called it.
И, наконец, просто добавьте этот код в свою активность / fragment:
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getSupportMenuInflater().inflate(R.menu.activity_main, menu); // The magic lines. MenuItem it = menu.findItem(R.id.menu_foo); ((ActionMenuTextItemView)it.getActionView()).initialise(it, this);
Вот и все!