wake-up-neo.com

Floating Label Spinner?

Nachdem ich die TextInputLayout der Android Design Support Library verwendet habe, um ein Floating-Label über einer EditText -Komponente zu platzieren, fragte ich mich, ob es eine Möglichkeit gibt, ein Floating-Label der Spinner -Komponente hinzuzufügen (nicht unbedingt Verwenden der Design Library).

Damit meine ich so etwas wie eine TextView , die über der Spinner platziert ist (offensichtlich keine Animationen wie die TextInputLayout), aber ich möchte, dass Textgröße, Schriftart und Farbe mit der des Floating-Labels der TextInputLayout übereinstimmen.

Zum Beispiel würde es ungefähr so ​​aussehen (siehe die Beschriftungen über der Spinners):

 enter image description here

Wie bereits erwähnt, besteht mein Hauptziel darin, über der Variablen Spinner eine Beschriftung zu haben, genau wie in der Variable TextInputLayout. Textgröße, Schriftart, Farbe und Abstände zwischen der Beschriftung und der Komponente wären also gleich.

Auf der Google Design-Seite zu schwebenden Beschriftungstextfeldern gibt es ein Diagramm, das die Abmessungen der Beschriftung relativ zur Komponente zeigt, jedoch keine Angabe der Farbe oder Größe des Beschriftungstextes:

 enter image description here

Zusammenfassend frage ich:
- Wenn es eine spezielle Komponente gibt, um zu erreichen, was ich frage, oder eine benutzerdefinierte Ansicht, die ich verwenden kann, was wäre sie und wie kann ich sie verwenden?.
- Wenn nicht, wie groß ist die Größe, Farbe und Schriftart des Floating-Labels, so dass ich eine TextView über meiner Spinner mit den im obigen Bild angezeigten Layoutabmessungen platzieren kann.


EDIT:

Aus den Google Design-Richtlinien für Textfelder ergibt sich Folgendes für Floating-Labels:

Hinweis und Eingabeschriftart: Roboto Regular 16sp
Etikettenschrift: Roboto Regular 12sp
Fliesenhöhe: 72dp
Textabdeckung oben und unten: 16dp
Textfeldtrennerfüllung: 8dp 

sowie die oben gezeigten Bilder. 

Die Floating-Label-Schrift lautet also: Roboto Regular 12sp. Sie können daher eine TextView verwenden, um das Label Spinner anzuzeigen, da mir keine benutzerdefinierten Views oder spezielle Komponenten bekannt sind, die Sie verwenden könnten.

Allerdings sieht es nach dem Ausprobieren nicht ganz so gut aus wie das im Bild gezeigte Beispiel. Eine benutzerdefinierte Ansicht ist vielleicht besser für diese, da sie schöner aussehen könnte, aber die Lösung oben ist nur eine Möglichkeit, etwas zu erreichen, das dem entspricht, was ich ursprünglich wollte.

74

Ich möchte, dass die Textgröße, die Schriftart und die Farbe von derjenigen der TextInputLayout-Gleitmarke entsprechen.

Dies ist ohne externe Bibliotheken problemlos möglich. Nachdem ich versucht hatte, die TextInputLayout zu hacken und sogar meine eigene benutzerdefinierte Ansicht zu erstellen, wurde mir klar, dass die Verwendung einer einfachen TextView viel weniger Code erfordert und wahrscheinlich effizienter ist.

Der Textstil kann aus der Bibliothek AppCompat kopiert werden.

Der Style

Aus den Richtlinien für Materialdesign erhalten wir folgende Informationen:

  • das Etikett sollte einen unteren Rand von 8dp haben
  • die Beschriftung sollte vertikal zum Eingabetext ausgerichtet sein

Folgendes wird in den Richtlinien nicht über das Material EditText erwähnt:

  • es hat eine linke Auffüllung von 4dp
  • sein Label hat eigentlich keinen Abstand von 16dp darüber, dies bleibt dem Interface-Designer überlassen: Dies ist sinnvoll, denn wenn Sie es unter einer anderen EditText platzieren, benötigen Sie nur einen zusätzlichen 8dp-Platz

Darüber hinaus enthält die Design Support Library diesen Stil für die Beschriftung eines fokussierten Elements:

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

Inaktive Elemente verwenden einfach TextAppearance.AppCompat.Caption.

Implementierung

Fügen Sie Ihrer dimens.xml-Datei Folgendes hinzu:

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

Dann füge dies zu styles.xml hinzu:

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

Wenn das Etikett immer die hervorgehobene (Akzent-) Farbe haben soll, ersetzen Sie TextAppearance.AppCompat.Caption durch TextAppearance.Design.Hint aus der Google Design Support Library. Dies wird jedoch wahrscheinlich ein bisschen komisch aussehen, wenn Sie auf demselben Bildschirm auch EditText-Ansichten beschriftet haben.

Schließlich können Sie eine TextView über der Spinner (oder einem anderen Element) mit dem angewendeten Stil platzieren:

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

Ergebnis

Der folgende Screenshot zeigt ein einfaches Beispiel mit zwei normalen TextInputLayout-Ansichten, gefolgt von einem Label und einer Spinner. Ich habe den zusätzlichen 8dp-Abstand nicht angewendet, um sie weiter voneinander zu trennen, aber dies zeigt Ihnen, dass Größe, Schriftart und Farbe wiedergegeben werden.

Die Elemente in der Variablen Spinner haben eine andere Auffüllung, ich ziehe es jedoch vor, die vertikale Ausrichtung mit allen anderen Beschriftungen beizubehalten, um ein einheitlicheres Aussehen zu erzielen.

 enter image description here

36

Ich habe eine Gist von mir gemacht, um das gleiche Problem zu lösen, das Sie haben.

Hör zu:

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

Jetzt brauche ich keine Spinner. Sie haben immer noch Floating-Label-Effekt mit enthaltenen Animationen. 

33

Ich habe dies erreicht, indem ich ein AutoCompleteTextView verwendet habe, die Tastatur deaktiviert habe und die Optionen bei Berührung angezeigt habe.

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

Ich habe eine zusammengesetzte View-Komponente erstellt, die eine Beschriftung über der Spinner anzeigt. Der Text für das Label kann über XML oder in Java festgelegt werden.

Die Komponente hat die Hauptmerkmale einer Spinner (nicht alle davon) und ähnelt der TextInputLayout-Komponente.

Ich habe es eine LabelledSpinner genannt und ist als Teil meiner UsefulViews Android-Bibliothek auf GitHub unter der Apache 2.0-Lizenz verfügbar.

Um es zu verwenden, fügen Sie die Bibliotheksabhängigkeit in Ihre build.gradle-Datei ein:

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

Beispiele für seine Verwendung finden Sie im GitHub-Repository (sowohl eine Beispielanwendung als auch ein Verwendungshandbuch).

11

Ich habe eine alternative Lösung, die das Verhalten von TextInputLayout und ein benutzerdefiniertes DialogFragment (AlertDialog) verwendet, um ein Dialogfenster für ein Dialogfenster zu emulieren.

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>

Benutzerdefiniertes Spinner über DialogFragment erstellen (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();
}

}

Aktivität.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");
}

Ergebnis

Wenn Sie auf das Textfeld „TextInputLayout“ im Spinner-Stil klicken, wird ein Benachrichtigungsdialogfeld mit Ihrer Auswahlliste ausgelöst. Wenn Sie eine Auswahl ausgewählt haben, wird der EditText mit Ihrer Auswahl gefüllt, und die Beschriftung wird wie gewünscht verschoben.

5
Kenny Li

Ich habe die Lösung von Rodrigo geändert, um einen Adapter zu verwenden, d. H. Eher wie ein Standard-Spinner https://Gist.github.com/smithaaron/d2acd57937d7a4201a79

5
aaronmarino

Hier ist mein Trick,

das Gute ist, dass alles so funktioniert, wie Sie wollen, 

das Schlimme ist jedoch, dass die Layout-Hierarchie zunimmt, und Sie müssen mit der Funktionalität im Code umgehen, und es ist eine hässliche Lösung:

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

und überschreiben Sie den Adapter für den Spinner, um die ausgewählten Werte transparent zu machen

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

wenn Sie im Drehfeld ausgewählt haben, rufen Sie einfach den ausgewählten Text auf und setzen Sie ihn auf EditText. Dies hat dieselbe Wirkung wie bei der 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) {

        }
    });

wenn Sie Fragen haben, fragen Sie mich

3

Hier ist eine Bibliothek, die ich für den Floating-Label-Spinner verwende rey5137 Material Library

Zur späteren Bezugnahme finden Sie hier eine Liste einiger großartiger Bibliotheken . UI-BibliothekenCore Libraries

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

Sie können dies erreichen: enter image description here

Mit neuen Materialbibliotheksstilen wie folgt:

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

weitere Informationen: https://material.io/develop/Android/components/menu/

0