programacion not item first developer android android-layout android-spinner material-design android-textinputlayout

not - spinner android developer



Etiqueta flotante Spinner? (10)

Después de usar TextInputLayout la Biblioteca de soporte de diseño de Android para colocar una etiqueta flotante sobre un componente EditText , me preguntaba si hay una manera de agregar una etiqueta flotante al componente Spinner (no necesariamente usando la Biblioteca de diseño).

Con esto, quiero decir algo así como un TextView colocado encima del Spinner (obviamente no hay animaciones como TextInputLayout ), pero quiero que el tamaño, la fuente y el color del texto coincidan con los de la etiqueta flotante de TextInputLayout .

Por ejemplo, se vería así (ver las etiquetas arriba del Spinner ):

Como mencioné antes, mi objetivo principal es tener una etiqueta sobre el Spinner , al igual que en TextInputLayout , por lo que el tamaño, la fuente, el color y las distancias del texto entre la etiqueta y el componente serían los mismos.

En la página de Google Design sobre campos de texto de etiqueta flotante , hay un diagrama que muestra las dimensiones de la etiqueta en relación con el componente, pero no hay indicación del color o tamaño del texto de la etiqueta:

Entonces, para resumir, estoy preguntando:
- Si hay un componente especial para lograr lo que estoy pidiendo o una vista personalizada que puedo usar, qué sería y cómo puedo usarlo.
- Si no, ¿cuál es el tamaño, el color y la fuente del texto de la etiqueta flotante, para que pueda colocar un TextView sobre mi Spinner con las dimensiones de diseño que se muestran en la imagen de arriba.

EDITAR:

De las pautas de diseño de Google para campos de texto , tiene lo siguiente para etiquetas flotantes:

Sugerencia y fuente de entrada: Roboto Regular 16sp
Fuente de la etiqueta: Roboto Regular 12sp
Altura del azulejo: 72dp
Texto relleno superior e inferior: 16dp
Relleno divisor de campo de texto: 8dp

así como las imágenes que se muestran arriba.

Entonces la fuente de etiqueta flotante es: Roboto Regular 12sp . Por lo tanto, puede usar un TextView para mostrar la etiqueta del Spinner , ya que no conozco ninguna View personalizada o componentes especiales que pueda usar.

Sin embargo , después de probarlo, no se ve tan bien como el ejemplo que se muestra en la imagen. Una vista personalizada puede ser mejor para esto , ya que podría verse mejor, pero la solución anterior es solo una forma de lograr algo cercano a lo que originalmente quería.


Quiero que el tamaño, la fuente y el color del texto coincidan con los de la etiqueta flotante TextInputLayout .

Esto se puede lograr fácilmente sin bibliotecas externas. Después de intentar hackear TextInputLayout e incluso hacer mi propia vista personalizada, me di cuenta de que usar un TextView simple requiere mucho menos código y probablemente sea más eficiente.

El estilo de texto se puede copiar desde la biblioteca AppCompat .

El estilo

De las pautas de diseño de materiales obtenemos la siguiente información:

  • la etiqueta debe tener un margen inferior de 8dp
  • la etiqueta debe estar alineada verticalmente con el texto de entrada

EditText es lo que las pautas no mencionan sobre el Material EditText :

  • tiene un relleno izquierdo de 4dp
  • su etiqueta en realidad no tiene ningún espacio de 16dp encima, esto se deja al diseñador de la interfaz: esto tiene sentido porque si lo coloca debajo de otro EditText , solo necesitará 8dp adicionales de espacio

Además, la Biblioteca de soporte de diseño contiene este estilo para la etiqueta de un elemento enfocado:

<style name="TextAppearance.Design.Hint" parent="TextAppearance.AppCompat.Caption"> <item name="android:textColor">?attr/colorControlActivated</item> </style>

Los elementos inactivos simplemente usan TextAppearance.AppCompat.Caption .

Implementación

Agregue lo siguiente a su archivo dimens.xml :

<dimen name="input_label_vertical_spacing">8dp</dimen> <dimen name="input_label_horizontal_spacing">4dp</dimen>

Luego agregue esto a styles.xml :

<style name="InputLabel" parent="TextAppearance.AppCompat.Caption"> <item name="android:paddingBottom">@dimen/input_label_vertical_spacing</item> <item name="android:paddingLeft">@dimen/input_label_horizontal_spacing</item> <item name="android:paddingRight">@dimen/input_label_horizontal_spacing</item> </style>

Si desea que la etiqueta siempre tenga el color resaltado (acento), reemplace TextAppearance.AppCompat.Caption con TextAppearance.Design.Hint de la Biblioteca de soporte de diseño de Google. Sin embargo, esto probablemente se verá un poco extraño si también ha etiquetado EditText vistas EditText en la misma pantalla.

Finalmente, puede colocar un TextView sobre su Spinner (o cualquier otro elemento) con el estilo aplicado:

<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/category" style="@style/InputLabel" />

Resultado

La siguiente captura de pantalla muestra un ejemplo simple con dos vistas normales TextInputLayout seguidas de una etiqueta y un Spinner . No 8dp espacio adicional de 8dp para separarlos más, pero esto muestra que el tamaño, la fuente y el color se reflejan.

Los elementos dentro del Spinner tienen un relleno diferente, sin embargo, prefiero mantener la alineación vertical con todas las otras etiquetas para obtener un aspecto más uniforme.


Aquí está mi truco

Lo bueno es que todo funcionará como tú quieres,

pero lo malo es que está aumentando la jerarquía de diseño, y tiene que manejar la funcionalidad en el código, y es una solución fea:

<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>

y anular el adaptador para spinner, para hacer que los valores seleccionados sean transparentes

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; } }

y después de seleccionar en la ruleta, solo obtenga el texto seleccionado y configúrelo en EditText y tendrá el mismo efecto con la animación

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) { } });

si tienes alguna pregunta pregúntame



He creado un componente de View compuesto que muestra una etiqueta sobre el Spinner . El texto para la etiqueta se puede establecer usando XML o en Java.

El componente tiene las características clave de un Spinner ( no todas ) y tiene un aspecto similar al componente TextInputLayout .

Lo he llamado LabelledSpinner , y está disponible como parte de mi biblioteca de Android UsefulViews en GitHub bajo la Licencia Apache 2.0 .

Para usarlo, agregue la dependencia de la biblioteca en su archivo build.gradle :

compile ''com.satsuware.lib:usefulviews:+''

Hay ejemplos de su uso disponibles en el repositorio de GitHub (una aplicación de muestra y una guía de uso).


Lo logré usando AutoCompleteTextView, deshabilitando el teclado y mostrando las opciones al tacto.

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; } });



Puedes lograr esto:

Con nuevos estilos de biblioteca de materiales como este:

<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>

Para más información: https://material.io/develop/android/components/menu/


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>



Tengo una solución alternativa que utiliza el comportamiento de TextInputLayout y un DialogFragment (AlertDialog) personalizado para emular una ventana emergente de diálogo de flecha.

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>

Crear Spinner personalizado a través de 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"); }

Resultado

Cuando haces clic en el spinner con el estilo TextInputLayout, se activará un cuadro de diálogo de alerta que contiene tu lista de selecciones. Una vez que se elige una selección, EditText se completará con su selección y la etiqueta flotará como desee.