web-dev-qa-db-fra.com

Étiquette flottante Spinner?

Après avoir utilisé la variable TextInputLayout de la bibliothèque de conception Android pour placer une étiquette flottante au-dessus d’un composant EditText , je me demandais s’il existait un moyen d’ajouter une étiquette flottante au composant Spinner (pas nécessairement en utilisant la bibliothèque de conception).

Par cela, je veux dire quelque chose comme un TextView placé au-dessus de Spinner (évidemment pas d’animations comme le TextInputLayout), mais je veux que la taille du texte , la police et la couleur correspondent à celles de l’étiquette flottante de TextInputLayout.

Par exemple, cela ressemblerait à quelque chose comme ceci (voir les étiquettes au dessus de la Spinners):

 enter image description here

Comme je l’ai déjà mentionné, mon objectif principal est d’avoir une étiquette au-dessus de Spinner, comme dans TextInputLayout - afin que la taille du texte, la police, la couleur et les distances entre l’étiquette et le composant soient identiques.

Dans la page Google Design sur les champs de texte d'étiquette flottants , il existe un diagramme indiquant les dimensions de l'étiquette par rapport au composant, mais aucune indication de la couleur ou de la taille du texte de l'étiquette:

 enter image description here

Donc, pour résumer, je demande:
- S'il y a un composant spécial pour réaliser ce que je demande ou une vue personnalisée que je peux utiliser, de quoi s'agit-il et comment puis-je l'utiliser.
- Si non, quelle est la taille, la couleur et la police du texte de l'étiquette flottante, de sorte que je puisse placer une TextView au-dessus de ma Spinner avec les dimensions de la mise en page indiquées dans l'image ci-dessus.


MODIFIER:

Le Consignes de conception de Google relatives aux champs de texte , présente les caractéristiques suivantes pour les étiquettes flottantes:

Astuce et police de saisie: Roboto Regular 16sp
Label police: Roboto Regular 12sp
Hauteur de la tuile: 72dp
Rembourrage en haut et en bas du texte: 16dp
Rembourrage du séparateur de champ de texte: 8dp 

ainsi que les images montrées ci-dessus. 

La police de l'étiquette flottante est donc: Roboto Regular 12sp. Vous pouvez donc utiliser une variable TextView pour afficher l’étiquette Spinner, étant donné que je ne connais aucune Views personnalisée ni aucun composant spécial que vous pourriez utiliser.

Cependant, après l'avoir essayé, il n'a pas l'air aussi bon que l'exemple montré dans l'image. Une vue custom peut être meilleure pour cela, car cela pourrait sembler plus joli, mais la solution ci-dessus n'est qu'un moyen de réaliser quelque chose de proche de ce que je voulais à l'origine.

74

Je veux que la taille, la police et la taille du texte correspondent à celles de l'étiquette flottante de la TextInputLayout.

Ceci peut être réalisé facilement sans aucune bibliothèque externe. Après avoir essayé de pirater la TextInputLayout et même de créer ma propre vue personnalisée, je me suis rendu compte que l'utilisation d'une simple TextView prenait beaucoup moins de code et était probablement plus efficace.

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

Le style

Les directives de conception des matériaux fournissent les informations suivantes:

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

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

  • il a un remplissage gauche de 4dp
  • son étiquette n'a en fait aucun espacement de 16dp au-dessus, cela revient au concepteur d'interface: c'est logique, car si vous la placez sous une autre EditText, vous n'aurez besoin que d'un 8dp d'espace supplémentaire.

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

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

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

La mise en oeuvre

Ajoutez les éléments suivants à votre fichier dimens.xml:

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

Ajoutez ensuite ceci à 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 vous souhaitez que l'étiquette ait toujours la couleur mise en surbrillance (accent), remplacez TextAppearance.AppCompat.Caption par TextAppearance.Design.Hint dans la bibliothèque de support technique de Google Design. Cependant, cela semblera probablement un peu étrange si vous avez également étiqueté les vues EditText sur le même écran.

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

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

Résultat

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

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

 enter image description here

36
Andrea Lazzarotto

J'ai un Gist fait par moi-même pour résoudre le même problème que vous avez.

Vérifiez-le:

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

Maintenant, je n'ai plus besoin de fileuses. Vous aurez toujours un effet d'étiquette flottante avec des animations incluses. 

33
Rodrigo Henriques

J'ai atteint cet objectif en utilisant une AutoCompleteTextView, en désactivant le clavier et en affichant les options au toucher.

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;
    }
});
24
Sidney Veiga

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

Le composant présente les caractéristiques principales d'une Spinner (pas toutes d'entre elles) ainsi qu'un aspect similaire au composant TextInputLayout.

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

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

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

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

11

J'ai une solution alternative qui utilise le comportement de TextInputLayout et un DialogFragment personnalisé (AlertDialog) pour émuler une popup de dialogue de rotation.

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>

Créer une spinner personnalisée via 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();
}

}

Activité.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");
}

Résultat

Lorsque vous cliquez sur le style spinner TextInputLayout, une boîte de dialogue d'alerte contenant votre liste de sélections s'ouvrira. Une fois la sélection choisie, le texte EditText sera renseigné avec votre sélection et l’étiquette flottera comme vous le souhaitez.

5
Kenny Li

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

5
aaronmarino

Voici mon tour

les bonnes choses sont que tout fonctionnera comme vous le souhaitez, 

mais le problème, c'est que cela augmente la hiérarchie des dispositions et que vous devez gérer les fonctionnalités dans le code. C'est une solution laide:

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

et remplacez l'adaptateur pour spinner, pour rendre transparentes les valeurs sélectionnées

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

et après avoir sélectionné Spinner, récupérez simplement le texte sélectionné et réglez-le sur EditText. Il aura le même effet avec l'animation.

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 tu as une question demande moi

3
Damir Mailybayev

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

Aussi, pour référence future, voici une liste de quelques bonnes bibliothèques . Bibliothèques UIBibliothèques principales

1
Brandon Tripp

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>
0
Samet öztoprak

Vous pouvez y parvenir: enter image description here

Avec les nouveaux styles de bibliothèque de matériaux comme ceci:

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

pour plus d'informations: https://material.io/develop/Android/components/menu/

0
Amin Keshavarzian