Что касается вашего публикуемую кода, это выход:
Как вы можете видеть, есть два левых поля: контейнер виджетов и значок увеличения. Вот почему у вас пустое пространство больше, чем другое окно с заголовком. И пункты меню вытесняются за пределы панели инструментов, которая, я думаю, является по умолчанию SearchView ActionView
, когда это не CollapseActionView
, так что он заполняет родителя.
От источника SearchView
виджета и его компоновки abc_search_view.xml, я попытался удалить дополнительные поля и не нажимать другие элементы за пределами панели инструментов.
Но после многих манипуляций, я думаю, вы должны использовать собственный виджет и/или собственный макет. Или играть с setIconifiedByDefault(true)
, который удаляет значок увеличения и его дополнительный запас и использовать setMaxWidth(MAX_SIZE)
, где MAX_SIZE
динамически вычисляется Integer.MAX_VALUE - (SIZE_OF_A_MENU_ITEM * NB_OF_MENU_ITEMS)
... Но для этого требуется много работы. Таким образом, использование пользовательского макета может быть решением.
Однако, есть возможный способ сохранить виджет appcompat, некоторые небольшие обходные пути. Во-первых, чтобы избежать ударов других предметов, вы можете использовать CollapseActionView
.
<item
...
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView"/>
и сохранить ваши требования, вы должны расширить его при инициализации:
final SearchView searchView =
(SearchView) MenuItemCompat.getActionView(item);
MenuItemCompat.expandActionView(item);
Имейте в виду, что вы должны использовать setOnActionExpandListener()
для того, чтобы закрыть окно, если вы этого не сделаете хотите свернуть элемент. Это предложение даст вам этот результат:
Все еще дополнительные поля, не так ли? Поэтому вам нужно получить контейнер и значок увеличения их идентификаторами (которые вы можете найти в abc_search_view.xml
... но давайте сэкономим время: они R.id.search_edit_frame
и R.id.search_mag_icon
).Вы можете удалить их полей с помощью этого метода:
private void changeSearchViewElements(View view) {
if (view == null)
return;
if (view.getId() == R.id.search_edit_frame
|| view.getId() == R.id.search_mag_icon) {
LinearLayout.LayoutParams p =
(LinearLayout.LayoutParams) view.getLayoutParams();
p.leftMargin = 0; // set no left margin
view.setLayoutParams(p);
}
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
changeSearchViewElements(viewGroup.getChildAt(i));
}
}
}
Называя его в теме:
final SearchView searchView =
(SearchView) MenuItemCompat.getActionView(item);
...
searchView.post(new Runnable() {
@Override
public void run() {
changeSearchViewElements(searchView);
}
});
Вот результат:
Наконец, чтобы получить линию под полем есть возможное обходное решение, использующее 9-патч для рисования и его установку в качестве фона. Вы можете легко найти инструкции в Google. Таким образом, условие будет:
private void changeSearchViewElements(View view) {
...
if (view.getId() == R.id.search_edit_frame
|| view.getId() == R.id.search_mag_icon) {
LinearLayout.LayoutParams p =
(LinearLayout.LayoutParams) view.getLayoutParams();
p.leftMargin = 0; // set no left margin
view.setLayoutParams(p);
} else if (view.getId() == R.id.search_src_text) {
AutoCompleteTextView searchEdit = (AutoCompleteTextView) view;
searchEdit.setBackgroundResource(R.drawable.rect_underline_white);
}
...
}
С замечанием OP в поле ниже, поле Подчеркивание также может быть сделано со следующим утверждением:
searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text)
.setBackgroundResource(R.drawable.abc_textfield_search_default_mtrl_alpha);
После этих обходных путей, как я уже сказал, это может быть проще использовать пользовательский макет. Но если вы хотите сохранить виджет SearchView по умолчанию, это может помочь.
Вот почему я всегда создаю приложение linearlayout для установки панели инструментов вместо сборки на панели инструментов –