Po użyciu biblioteki obsługi projektów systemu Android w TextInputLayout
celu umieszczenia pływającej etykiety nad EditText
komponentem, zastanawiałem się, czy istnieje sposób na dodanie pływającej etykiety do Spinner
komponentu (niekoniecznie przy użyciu biblioteki projektu).
Rozumiem przez to coś w rodzaju a TextView
umieszczonego powyżej Spinner
(oczywiście bez animacji takich jak TextInputLayout
), ale chcę, aby rozmiar tekstu, czcionka i kolor były zgodne z TextInputLayout
pływającą etykietą .
Na przykład wyglądałoby to mniej więcej tak (zobacz etykiety nad Spinner
znakami):
Jak wspomniałem wcześniej, moim głównym celem jest umieszczenie etykiety powyżej Spinner
, tak jak w TextInputLayout
- aby rozmiar tekstu, czcionka, kolor i odległości między etykietą a komponentem były takie same.
Na stronie Google Design dotyczącej pływających pól tekstowych etykiet znajduje się diagram przedstawiający wymiary etykiety w stosunku do komponentu, ale nie ma wskazania koloru ani rozmiaru tekstu etykiety:
Podsumowując, pytam:
- Jeśli istnieje specjalny komponent do osiągnięcia tego, o co proszę, lub niestandardowy widok, którego mogę użyć, co by to było i jak mogę go użyć.
- Jeśli nie, jaki jest rozmiar, kolor i czcionka pływającego tekstu etykiety, abym mógł umieścić go TextView
nad moim Spinner
z wymiarami układu pokazanymi na powyższym obrazku.
EDYTOWAĆ:
Ze wskazówek Google dotyczących projektowania pól tekstowych wynika, że dla etykiet pływających są następujące:
Wskazówka i czcionka: Roboto Regular 16 sp
Czcionka etykiety: Roboto Regular 12 sp
Wysokość kafelka: 72 dp Wypełnienie
tekstu na górze i na dole: 16 dp Dopełnienie
pola tekstowego : 8 dp
jak również na zdjęciach pokazanych powyżej.
Tak więc czcionka pływającej etykiety to: Roboto Regular 12sp . Możesz zatem użyć a TextView
do wyświetlenia Spinner
etykiety, ponieważ nie znam żadnych niestandardowych View
ani specjalnych komponentów, których mógłbyś użyć.
Jednak po wypróbowaniu nie wygląda tak dobrze, jak przykład pokazany na obrazku. Niestandardowy widok może być lepiej dla tego , jak mógłby wyglądać ładniej, ale rozwiązanie jest tylko jednym ze sposobów osiągnięcia czegoś blisko tego, co pierwotnie chciał.
źródło
<item name="android:textColor">?android:textColorHint</item>
swój styl, aby uzyskać ten sam kolor tekstu w etykiecie niestandardowej, jaki jest używany w TextInputLayout w stanie niezogniskowanym.SpinnerLabel
zamiastInputLabel
, aby używać ich tylko dla spinnerów.Osiągnąłem to, używając AutoCompleteTextView, wyłączając klawiaturę i pokazując opcje dotykowe.
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; } });
źródło
TextInputLayout
, zapewniając w ten sposób dokładny poprawny wygląd.R.layout.support_simple_spinner_dropdown_item
zamiastandroid.R.layout.simple_spinner_item
mTextView.setText(...)
, nie otrzymasz wszystkich wartości z adaptera w menu rozwijanym ... Wywołanieadapter.getFilter().filter(null);
pokazuje ponownie wszystkie sugestieMam sedno rozwiązania tego samego problemu, co ty.
Sprawdź to:
https://gist.github.com/rodrigohenriques/77398a81b5d01ac71c3b
Teraz nie potrzebuję błystek. Nadal będziesz mieć efekt pływającej etykiety z dołączonymi animacjami.
źródło
setInputType(InputType.TYPE_NULL);
doonDraw(canvas)
metody, aby wyłączyć wszelkie dane wejściowe do pliku edittext. W przeciwnym razie, np. Długie kliknięcia, wywołają menu kontekstowe i pozwolą użytkownikowi wkleić tekst.EditText
lubAppCompatEditText
, proszę!Utworzyłem
View
komponent złożony , który wyświetla etykietę powyżejSpinner
. Tekst etykiety można ustawić za pomocą XML lub Java.Komponent ma kluczowe cechy
Spinner
( nie wszystkie ), a także wygląda podobnie doTextInputLayout
komponentu.I nazwali go do
LabelledSpinner
, i jest dostępny jako część mojego UsefulViews biblioteki Androida na GitHub pod Apache 2.0 License .Aby z niego skorzystać, dodaj zależność biblioteki w swoim
build.gradle
pliku:compile 'com.satsuware.lib:usefulviews:+'
Przykłady jego użycia są dostępne w repozytorium GitHub (zarówno przykładowa aplikacja, jak i przewodnik użytkowania).
źródło
Spinner
, która jest podobna do małych etykiet umieszczonych nadEditText
komponentamiTextInputLayout
. Jak sobie to wyobrażałeś?Zmodyfikowałem rozwiązanie Rodrigo tak, aby używał adaptera, czyli bardziej przypominającego standardowy Spinner https://gist.github.com/smithaaron/d2acd57937d7a4201a79
źródło
Mam alternatywne rozwiązanie, które wykorzystuje zachowanie TextInputLayout i niestandardowy DialogFragment (AlertDialog) do emulacji wyskakującego okna dialogowego pokrętła.
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>
Utwórz niestandardowy spinner za pomocą 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"); }
Wynik
Kliknięcie elementu TextInputLayout w stylu pokrętła spowoduje wyświetlenie okna dialogowego z ostrzeżeniem zawierającego listę wyborów. Po wybraniu zaznaczenia EditText zostanie wypełniony zaznaczeniem, a etykieta będzie pływać tak, jak chcesz.
źródło
android:focusable="false"
ten widok nie jest niedostępny dla osób używających klawiatury lub głosu do interakcji z aplikacją?android:focusable="false"
jest to, że użytkownik nie może wpisać wejścia, którego nie ma wśród zaznaczenia. Niestety, nie mam fizycznego telefonu z Androidem, aby przetestować zachowania i poinformować Cię o tym.Możesz to osiągnąć:
Dzięki nowym stylom biblioteki materiałów, takim jak ten:
<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>
więcej informacji: https://material.io/develop/android/components/menu/
źródło
Oto moja sztuczka
dobre jest to, że wszystko będzie działać tak, jak chcesz,
ale złe jest to, że zwiększa hierarchię układu i musisz obsługiwać funkcjonalność w kodzie, a to jest brzydkie rozwiązanie:
<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>
i nadpisać adapter dla pokrętła, aby wybrane wartości stały się przezroczyste
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; } }
a po wybraniu w przędzarce po prostu pobierz zaznaczony tekst i ustaw go na EditText i będzie to miało ten sam efekt z animacją
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) { } });
jeśli masz jakieś pytanie, zapytaj mnie
źródło
Oto biblioteka, której używam dla pływającej przędzarki etykiet rey5137 Material Library
Poniżej znajduje się lista kilku wspaniałych bibliotek, do wykorzystania w przyszłości. Biblioteki UI Podstawowe biblioteki
źródło
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>
źródło