После использования библиотеки поддержки дизайна Android TextInputLayout
для размещения плавающей метки над EditText
компонентом мне стало интересно, есть ли способ добавить плавающую метку к Spinner
компоненту (не обязательно с использованием библиотеки дизайна).
Под этим я подразумеваю что-то вроде TextView
размещенного над Spinner
(очевидно, без анимации, подобной TextInputLayout
), но я хочу, чтобы размер, шрифт и цвет текста соответствовали TextInputLayout
плавающей метке .
Например, это будет выглядеть примерно так (см. Метки над буквами Spinner
s):
Как я упоминал ранее, моя основная цель - иметь метку над Spinner
, так же, как и в TextInputLayout
- чтобы размер текста, шрифт, цвет и расстояния между меткой и компонентом были такими же.
На странице Google Design, посвященной текстовым полям с плавающей меткой , есть диаграмма, показывающая размеры метки относительно компонента, но не указывается цвет или размер текста метки:
Итак, чтобы подвести итог, я спрашиваю:
- Если есть специальный компонент для достижения того, о чем я прошу, или настраиваемое представление, которое я могу использовать, что это будет и как я могу его использовать.
- Если нет, то каков размер, цвет и шрифт текста плавающей метки, чтобы я мог разместить TextView
над ним Spinner
с размерами макета, показанными на изображении выше.
РЕДАКТИРОВАТЬ:
Из руководящих принципов Google дизайна для текстовых полей , он имеет следующий для плавающих меток:
Подсказка и шрифт ввода: Roboto Regular 16sp
Шрифт ярлыка: Roboto Regular 12sp
Высота плитки: 72dp Отступ
сверху и снизу
текста : 16dp Отступ разделителя текстового поля: 8dp
а также изображения, показанные выше.
Итак, шрифт плавающей метки: Roboto Regular 12sp . Поэтому вы можете использовать a TextView
для отображения Spinner
метки, так как я не знаю каких-либо пользовательских View
s или специальных компонентов, которые вы могли бы использовать.
Однако после опробования он выглядит не так хорошо, как пример, показанный на изображении. Настраиваемое представление может быть лучше для этого , так как это может выглядеть лучше, но решение выше , является лишь одним из способов достижения чего - то близко к тому , что я изначально хотел.
источник
<item name="android:textColor">?android:textColorHint</item>
в свой стиль тот же цвет текста в настраиваемой метке, который используется в TextInputLayout в несфокусированном состоянии.SpinnerLabel
аInputLabel
не использовать его только для прядильщиков.Я добился этого, используя AutoCompleteTextView, отключив клавиатуру и показав параметры на ощупь.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.locations)); AutoCompleteTextView mTextView = (AutoCompleteTextView) findViewById(R.id.location); mTextView.setAdapter(adapter); mTextView.setKeyListener(null); mTextView.setOnTouchListener(new View.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event){ ((AutoCompleteTextView) v).showDropDown(); return false; } });
источник
TextInputLayout
, гарантируя, что у вас будет точный правильный внешний вид.R.layout.support_simple_spinner_dropdown_item
вместоandroid.R.layout.simple_spinner_item
mTextView.setText(...)
, вы не получите все значения от адаптера в раскрывающемсяadapter.getFilter().filter(null);
У меня есть смысл решить ту же проблему, что и у вас.
Проверьте это:
https://gist.github.com/rodrigohenriques/77398a81b5d01ac71c3b
Теперь мне не нужны блесны. У вас по-прежнему будет эффект плавающей метки с включенной анимацией.
источник
setInputType(InputType.TYPE_NULL);
кonDraw(canvas)
методу, чтобы отключить любой ввод в текст редактирования. В противном случае, например, длинные щелчки вызовут контекстное меню и позволят пользователю вставить текст.EditText
илиAppCompatEditText
, пожалуйста!Я создал составной
View
компонент, над которым отображается меткаSpinner
. Текст для метки можно задать с помощью XML или Java.Компонент имеет ключевые особенности
Spinner
( не все из них), а также внешне похож наTextInputLayout
компонент.Я назвал его a
LabelledSpinner
, и он доступен как часть моей библиотеки Android UsefulViews на GitHub под лицензией Apache 2.0 .Чтобы использовать его, добавьте в
build.gradle
файл зависимость библиотеки :compile 'com.satsuware.lib:usefulviews:+'
Примеры его использования доступны в репозитории GitHub (как образец приложения, так и руководство по использованию).
источник
Spinner
, которая похожа на то, как есть маленькие метки надEditText
компонентами, завернутые внутрьTextInputLayout
. Как вы себе это представляли?Я изменил решение Родриго, чтобы использовать адаптер, то есть больше похоже на стандартный Spinner https://gist.github.com/smithaaron/d2acd57937d7a4201a79
источник
У меня есть альтернативное решение, которое использует поведение TextInputLayout и настраиваемый DialogFragment (AlertDialog) для имитации всплывающего диалогового окна счетчика.
layout.xml:
<android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/your_et" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/your_label" android:maxLines="1" android:inputType="textNoSuggestions" android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:focusable="false" style="@style/Base.Widget.AppCompat.Spinner.Underlined"/> </android.support.design.widget.TextInputLayout>
Создание настраиваемого счетчика через DialogFragment (AlertDialog)
SpinnerFragment.java:
public class SpinnerFragment extends DialogFragment { private static final String TITLEID = "titleId"; private static final String LISTID = "listId"; private static final String EDITTEXTID = "editTextId"; public static SpinnerFragment newInstance(int titleId, int listId, int editTextId) { Bundle bundle = new Bundle(); bundle.putInt(TITLEID, titleId); bundle.putInt(LISTID, listId); bundle.putInt(EDITTEXTID, editTextId); SpinnerFragment spinnerFragment = new SpinnerFragment(); spinnerFragment.setArguments(bundle); return spinnerFragment; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final int titleId = getArguments().getInt(TITLEID); final int listId = getArguments().getInt(LISTID); final int editTextId = getArguments().getInt(EDITTEXTID); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); try { final String[] items = getResources().getStringArray(listId); builder.setTitle(titleId) .setItems(listId, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int pos) { EditText et = (EditText) getActivity().findViewById(editTextId); String selectedText = items[pos]; if (!TextUtils.isEmpty(selectedText)) { et.setText(selectedText); } else { et.getText().clear(); } } }); } catch (NullPointerException e) { Log.e(getClass().toString(), "Failed to select option in " + getActivity().toString() + " as there are no references for passed in resource Ids in Bundle", e); Toast.makeText(getActivity(), getString(R.string.error_failed_to_select), Toast.LENGTH_LONG).show(); } return builder.create(); }
}
Activity.java:
private void addCustomSpinner() { EditText yourEt = (EditText) findViewById(R.id.your_et); yourEt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showCustomSpinnerDialog(view); } }); } private void showCustomSpinnerDialog(View v) { int titleId = R.string.your_label; int listId = R.array.spinner_selections; int editTextId = R.id.your_et; SpinnerFragment spinnerFragment = SpinnerFragment.newInstance(titleId, listId, editTextId); spinnerFragment.show(getFragmentManager(), "customSpinner"); }
Результат
Когда вы нажимаете на счетчик в стиле TextInputLayout, он запускает диалоговое окно с предупреждением, содержащее ваш список выбора. Как только выбор будет выбран, EditText будет заполнен вашим выбором, и метка будет плавать так, как вы хотите.
источник
android:focusable="false"
делает ли это представление недоступным для тех, кто использует клавиатуру или голос для взаимодействия с приложением?android:focusable="false"
пользователь не может ввести ввод, которого нет в выделенном списке. К сожалению, у меня нет физического телефона Android, чтобы проверить его поведение и сообщить вам об этом.Вы можете добиться этого:
С новыми стилями библиотеки материалов, подобными этому:
<com.google.android.material.textfield.TextInputLayout android:id="@+id/fullNameLay" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" android:layout_width="wrap_content" android:layout_height="wrap_content"> <androidx.appcompat.widget.AppCompatAutoCompleteTextView android:id="@+id/fullNameEt" android:layout_width="match_parent" android:layout_height="wrap_content"/> </com.google.android.material.textfield.TextInputLayout>
для получения дополнительной информации: https://material.io/develop/android/components/menu/
источник
Вот моя уловка,
хорошо то, что все будет работать так, как вы хотите,
но плохо то, что это увеличивает иерархию макета, и вам приходится обрабатывать функциональность в коде, и это уродливое решение:
<RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.TextInputLayout android:id="@+id/til" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/edt" android:layout_width="match_parent" android:layout_height="@dimen/edt_height" android:hint="@string/create_gcc_visa_txt_step" /> </android.support.design.widget.TextInputLayout> <Spinner android:id="@+id/spn" style="@style/MyAppTheme.Base.Spinner" android:layout_height="@dimen/edt_height" android:layout_alignBottom="@id/til" /> </RelativeLayout>
и переопределить адаптер для счетчика, чтобы сделать выбранные значения прозрачными
public class MySpinnerAdapter extends SimpleAdapter { Context mContext; public MySpinnerAdapter(Context context, List<String> data, int resource, String[] from, int[] to) { super(context, data, resource, from, to); mContext = context; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = super.getView(position, convertView, parent); TextView tv = (TextView) convertView.findViewById(android.R.id.text1); tv.setTextColor(ContextCompat.getColor(mContext, R.color.transparent)); return convertView; } }
и после выбора в счетчике просто возьмите выделенный текст и установите для него EditText, и он будет иметь тот же эффект с анимацией
yourSpinnerView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<String> adapterView, View view, int i, long l) { //get your selected text from adapter or from where you want String selectedText = adapterView.getItemAtPosition(i)); if (i != 0) { edt.setText(selectedText); } else { // if in case your spinner have first empty text, // then when spinner selected, just empty EditText. edt.setText(""); } } @Override public void onNothingSelected(AdapterView<?> adapterView) { } });
если у вас есть вопросы Задайте мне
источник
Вот библиотека, которую я использую для счетчика плавающих этикеток rey5137 Material Library.
Также, на будущее, вот список некоторых замечательных библиотек. Библиотеки пользовательского интерфейса Основные библиотеки
источник
SpinnerCustom.java
package com.pozitron.tfkb.customviews; import android.content.Context; import android.content.res.TypedArray; import android.support.annotation.Nullable; import android.text.SpannableString; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import com.pozitron.commons.customviews.TextViewFont; import com.pozitron.tfkb.R; import butterknife.BindView; import butterknife.ButterKnife; /** * Created by so12607 on 31/01/2018. */ public class SpinnerCustom extends LinearLayout { @BindView(R.id.layoutSpinnerCustomLabel) TextViewFont layoutSpinnerCustomLabel; @BindView(R.id.layoutSpinnerCustomSpinner) TextViewFont layoutSpinnerCustomSpinner; @BindView(R.id.layoutSpinner) LinearLayout layoutSpinner; private View v; public SpinnerCustom(Context context) { this(context, null); } public SpinnerCustom(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public SpinnerCustom(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); v = LayoutInflater.from(context).inflate(R.layout.layout_spinner_custom, this, true); ButterKnife.bind(this); if (!isInEditMode()) { TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SpinnerCustom, 0, 0); final String label = array.getString(R.styleable.SpinnerCustom_label); final boolean enable = array.getBoolean(R.styleable.SpinnerCustom_enabled, true); layoutSpinnerCustomLabel.setText(label); layoutSpinnerCustomLabel.setEnabled(enable); layoutSpinnerCustomSpinner.setEnabled(enable); layoutSpinner.setEnabled(enable); layoutSpinner.setClickable(enable); v.setEnabled(enable); v.setClickable(enable); array.recycle(); } } public void setText(String text) { layoutSpinnerCustomSpinner.setText(text); } public void setText(SpannableString text) { layoutSpinnerCustomSpinner.setText(text); } public void setText(CharSequence text) { layoutSpinnerCustomSpinner.setText(text); } public void setLabel(String text) { layoutSpinnerCustomLabel.setText(text); } public void setError(SpannableString text) { layoutSpinnerCustomSpinner.setError(text); } public void setEnabled(boolean enable) { layoutSpinnerCustomLabel.setEnabled(enable); layoutSpinnerCustomSpinner.setEnabled(enable); layoutSpinner.setEnabled(!enable); layoutSpinner.setClickable(!enable); } }
layout_spinner_custom.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/layoutSpinner" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <com.pozitron.commons.customviews.TextViewFont android:id="@+id/layoutSpinnerCustomLabel" style="@style/TextLabel" tools:text="label" /> <com.pozitron.commons.customviews.TextViewFont android:id="@+id/layoutSpinnerCustomSpinner" style="@style/SpinnerText" android:clickable="false" /> </LinearLayout>
style.xml
<style name="TextLabel" parent="android:Widget.TextView"> <item name="font">@integer/font_GTEestiDisplay_Regular</item> <item name="android:layout_width">match_parent</item> <item name="android:textSize">14sp</item> <item name="android:layout_height">wrap_content</item> <item name="android:gravity">bottom</item> <item name="android:textColor">@color/greyLabel</item> </style> <style name="SpinnerText" parent="EditText"> <item name="font">@integer/font_GTEestiDisplay_Medium</item> <item name="android:gravity">bottom</item> <item name="android:textSize">17sp</item> <item name="android:minHeight">35dp</item> <item name="android:focusable">false</item> <item name="android:background">@drawable/spinner_selector</item> <item name="android:text">@string/select</item> <item name="android:textColor">@color/selector_spinner_text</item> </style>
источник