Étiquette flottante Spinner?

Après avoir utilisé TextInputLayout la bibliothèque d’aide à la conception Android pour placer une étiquette flottante au-dessus d’un composant EditText , je me demandais s’il était possible d’append une étiquette flottante au composant Spinner (n’utilisant pas nécessairement la bibliothèque de conception).

Par cela, je veux dire quelque chose comme un TextView placé au-dessus du Spinner (évidemment aucune animation comme le TextInputLayout ), mais je veux que la taille du texte, la police et la couleur correspondent à celles du libellé flottant de TextInputLayout .

Par exemple, cela ressemblerait à ceci (voir les étiquettes au-dessus du Spinner s):

entrer la description de l'image ici

Comme je l’ai mentionné précédemment, mon objective principal est d’avoir une étiquette au-dessus du Spinner , tout comme dans TextInputLayout – afin que la taille du texte, la police, la couleur et les distances entre l’étiquette et le composant soient les mêmes.

Sur la page de conception de Google sur les champs de texte à libellé flottant , il y a un diagramme montrant les dimensions de l’étiquette par rapport au composant, mais il n’y a aucune indication de la couleur ou de la taille du texte de l’étiquette:

entrer la description de l'image ici

Donc, pour résumer, je demande:
– S’il existe un composant spécial pour réaliser ce que je vous demande ou une vue personnalisée, je peux l’utiliser, comment l’utiliser et comment l’utiliser.
– Si ce n’est pas le cas, quelle est la taille, la couleur et la police du texte de l’étiquette flottante, afin de pouvoir placer un TextView au-dessus de mon Spinner avec les dimensions de la mise en page indiquées dans l’image ci-dessus.


MODIFIER:

Dans les directives de conception de Google pour les champs de texte , les étiquettes flottantes sont les suivantes:

Astuce et police de saisie: Roboto Regular 16sp
Police de libellé: Roboto Regular 12sp
Hauteur de tuile: 72dp
Garniture supérieure et inférieure de texte: 16dp
Séparateur de champs de texte: 8dp

ainsi que les images ci-dessus.

La police de libellé flottant est donc: Roboto Regular 12sp . Vous pouvez donc utiliser un TextView pour afficher l’étiquette de Spinner car je ne connais aucun composant de View ou composant spécial que vous pourriez utiliser.

Cependant , après l’avoir essayé, il ne semble pas aussi bon que l’exemple montré dans l’image. Une vue personnalisée peut être meilleure pour cela , car elle peut sembler plus belle, mais la solution ci-dessus n’est qu’une façon d’atteindre un résultat proche de ce que je souhaitais.

J’ai moi-même une idée pour résoudre le même problème que vous.

Vérifiez-le:

https://gist.github.com/rodrigohenriques/77398a81b5d01ac71c3b

Maintenant je n’ai pas besoin de spinners. Vous aurez toujours un effet de libellé flottant avec les animations incluses.

Je souhaite que la taille du texte, la police et la couleur correspondent à celles de l’étiquette flottante de TextInputLayout .

Cela peut être réalisé facilement sans aucune bibliothèque externe. Après avoir essayé de pirater TextInputLayout et même de créer ma propre vue personnalisée, j’ai réalisé que l’utilisation d’un simple TextView nécessite beaucoup moins de code et est probablement plus efficace.

Le style de texte peut être copié à partir de la bibliothèque AppCompat .

Le style

À partir des directives sur la conception des matériaux, nous obtenons les informations suivantes:

  • l’étiquette devrait avoir une marge inférieure de 8dp
  • l’étiquette doit être alignée verticalement avec le texte saisi

Voici ce que les lignes direcsortingces ne mentionnent pas à propos de Material EditText :

  • il a un rembourrage gauche de 4dp
  • son libellé n’a pas d’espace de 16dp au dessus, c’est au concepteur de l’interface: cela a du sens car si vous le placez sous un autre EditText , vous n’aurez besoin que de 8dp d’espace supplémentaire

De plus, la bibliothèque d’aide à la conception contient ce style pour l’étiquette d’un élément ciblé:

  

Les éléments inactifs utilisent simplement TextAppearance.AppCompat.Caption .

la mise en oeuvre

Ajoutez ce qui suit à votre fichier dimens.xml :

 8dp 4dp 

Ajoutez ensuite ceci à styles.xml :

  

Si vous souhaitez que l’étiquette ait toujours la couleur en surbrillance (accentuée), remplacez TextAppearance.AppCompat.Caption par TextAppearance.Design.Hint dans la bibliothèque du support de conception de Google. Cependant, cela semblera probablement un peu bizarre si vous avez également étiqueté les vues EditText sur le même écran.

Enfin, vous pouvez mettre un TextView au-dessus de votre Spinner (ou de tout autre élément) avec le style appliqué:

  

Résultat

La capture d’écran suivante montre un exemple simple avec deux vues TextInputLayout normales suivies d’une étiquette et d’un Spinner . Je n’ai pas appliqué l’espacement supplémentaire de 8dp pour les séparer, mais cela montre que la taille, la police et la couleur sont reflétées.

Les éléments à l’intérieur du Spinner ont un rembourrage différent, mais je préfère garder l’alignement vertical avec toutes les autres étiquettes pour obtenir un aspect plus uniforme.

entrer la description de l'image ici

J’ai réussi ceci en utilisant un AutoCompleteTextView, en désactivant le clavier et en affichant les options au toucher.

 ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, getResources().getSsortingngArray(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; } }); 

J’ai créé un composant View composé qui affiche une étiquette au-dessus du Spinner . Le texte de l’étiquette peut être défini en XML ou en Java.

Le composant possède les fonctionnalités clés d’un Spinner ( pas toutes ) et ressemble au composant TextInputLayout .

Je l’ai nommé LabelledSpinner , et il est disponible dans la bibliothèque Android UsefulViews sur GitHub sous la licence Apache 2.0 .

Pour l’utiliser, ajoutez la dépendance de la bibliothèque dans votre fichier build.gradle :

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

Des exemples de son utilisation sont disponibles dans le référentiel GitHub (à la fois un exemple d’application et un guide d’utilisation).

J’ai modifié la solution de Rodrigo pour utiliser un adaptateur, c’est-à-dire plus comme un Spinner standard https://gist.github.com/smithaaron/d2acd57937d7a4201a79

J’ai une solution alternative qui utilise le comportement de TextInputLayout et un DialogFragment personnalisé (AlertDialog) pour émuler une boîte de dialog de dialog spinner.

layout.xml:

    

Créer un spinner personnalisé via DialogFragment (AlertDialog)

SpinnerFragment.java:

 public class SpinnerFragment extends DialogFragment { private static final Ssortingng TITLEID = "titleId"; private static final Ssortingng LISTID = "listId"; private static final Ssortingng 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 Ssortingng[] items = getResources().getSsortingngArray(listId); builder.setTitle(titleId) .setItems(listId, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int pos) { EditText et = (EditText) getActivity().findViewById(editTextId); Ssortingng selectedText = items[pos]; if (!TextUtils.isEmpty(selectedText)) { et.setText(selectedText); } else { et.getText().clear(); } } }); } catch (NullPointerException e) { Log.e(getClass().toSsortingng(), "Failed to select option in " + getActivity().toSsortingng() + " as there are no references for passed in resource Ids in Bundle", e); Toast.makeText(getActivity(), getSsortingng(R.ssortingng.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.ssortingng.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"); } 

Résultat

Lorsque vous cliquez sur le composant TextInputLayout de style spinner, il déclenche une boîte de dialog contenant votre liste de sélections. Une fois la sélection choisie, le EditText sera rempli avec votre sélection et l’étiquette flottera comme vous le souhaitez.

Voici mon tour,

les bonnes choses sont que tout fonctionnera comme vous voulez,

mais le mauvais est que cela augmente la hiérarchie de mise en page, et vous devez gérer les fonctionnalités dans le code, et c’est une solution moche:

        

et remplacer l’adaptateur pour spinner, pour rendre les valeurs sélectionnées transparentes

 public class MySpinnerAdapter extends SimpleAdapter { Context mContext; public MySpinnerAdapter(Context context, List data, int resource, Ssortingng[] 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; } } 

et après avoir sélectionné dans spinner, obtenez simplement le texte sélectionné et définissez-le sur EditText et cela aura le même effet avec l’animation

 yourSpinnerView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, int i, long l) { //get your selected text from adapter or from where you want Ssortingng 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 vous avez des questions Demandez moi

Voici une bibliothèque que j’utilise pour la bibliothèque de matériaux de l’ étiquette flottante rey5137

Aussi, pour référence future, voici une liste de quelques grandes bibliothèques. Bibliothèques de base

SpinnerCustom.java

 package com.pozitron.tfkb.customviews; import android.content.Context; import android.content.res.TypedArray; import android.support.annotation.Nullable; import android.text.SpannableSsortingng; import android.util.AtsortingbuteSet; 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 AtsortingbuteSet attrs) { this(context, attrs, 0); } public SpinnerCustom(Context context, @Nullable AtsortingbuteSet 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.obtainStyledAtsortingbutes(attrs, R.styleable.SpinnerCustom, 0, 0); final Ssortingng label = array.getSsortingng(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(Ssortingng text) { layoutSpinnerCustomSpinner.setText(text); } public void setText(SpannableSsortingng text) { layoutSpinnerCustomSpinner.setText(text); } public void setText(CharSequence text) { layoutSpinnerCustomSpinner.setText(text); } public void setLabel(Ssortingng text) { layoutSpinnerCustomLabel.setText(text); } public void setError(SpannableSsortingng 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"?>     

style.xml