[英]How to add floating label on Spinner
在使用Android Design Support Library 的TextInputLayout
在EditText
組件上方放置浮動標簽后,我想知道是否有辦法將浮動標簽添加到Spinner
組件(不一定使用設計庫)。
在這里,我的意思是類似於放置在Spinner
上方的TextView
(顯然沒有像TextInputLayout
這樣的動畫),但我希望文本大小、字體和顏色與TextInputLayout
的浮動標簽相匹配。
例如,它看起來像這樣(參見Spinner
上方的標簽):
正如我之前提到的,我的主要目標是在Spinner
上方有一個標簽,就像在TextInputLayout
- 因此文本大小、字體、顏色以及標簽與組件之間的距離是相同的。
在關於浮動標簽文本字段的Google Design 頁面上,有一個圖表顯示了標簽相對於組件的尺寸,但沒有指示標簽文本顏色或大小:
所以,總而言之,我問:
- 如果有一個特殊的組件來實現我的要求或我可以使用的自定義視圖,它會是什么,我該如何使用它。
- 如果沒有,浮動標簽的文本大小、顏色和字體是多少,以便我可以在Spinner
上方放置一個TextView
,其布局尺寸如上圖所示。
從Google Design Guidelines for text fields 中,浮動標簽具有以下內容:
提示和輸入字體:Roboto Regular 16sp
標簽字體:Roboto Regular 12sp
平鋪高度:72dp
文字上下內邊距:16dp
文本字段分隔符填充:8dp
以及上面顯示的圖像。
所以浮動標簽字體是: Roboto Regular 12sp 。 因此,您可以使用TextView
來顯示Spinner
標簽,因為我不知道您可以使用任何自定義View
或特殊組件。
但是,經過試用后,它看起來並不像圖像中顯示的示例那么好。 自定義視圖可能對此更好,因為它看起來更好,但上面的解決方案只是實現接近我最初想要的東西的一種方法。
我希望文本大小、字體和顏色與
TextInputLayout
的浮動標簽相匹配。
這可以在沒有任何外部庫的情況下輕松實現。 在嘗試破解TextInputLayout
甚至制作我自己的自定義視圖后,我意識到使用簡單的TextView
需要的代碼少得多,而且效率可能更高。
文本樣式可以從AppCompat
庫中復制。
從 Material Design 指南中,我們獲得了以下信息:
8dp
以下是指南未提及 Material EditText
:
4dp
16dp
以上的間距,這是留給界面設計師的:這是有道理的,因為如果你把它放在另一個EditText
,你只需要額外的8dp
空間此外,設計支持庫包含用於焦點元素標簽的這種樣式:
<style name="TextAppearance.Design.Hint" parent="TextAppearance.AppCompat.Caption">
<item name="android:textColor">?attr/colorControlActivated</item>
</style>
非活動元素僅使用TextAppearance.AppCompat.Caption
。
將以下內容添加到您的dimens.xml
文件中:
<dimen name="input_label_vertical_spacing">8dp</dimen>
<dimen name="input_label_horizontal_spacing">4dp</dimen>
然后將其添加到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>
如果您希望標簽始終具有突出顯示(強調)顏色,請將TextAppearance.AppCompat.Caption
替換為 Google 設計支持庫中的TextAppearance.Design.Hint
。 但是,如果您還在同一屏幕上標記了EditText
視圖,這可能看起來EditText
。
最后,你可以在你的Spinner
(或任何其他元素)上方放置一個TextView
並應用樣式:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/category"
style="@style/InputLabel" />
以下屏幕截圖顯示了一個簡單示例,其中包含兩個普通的TextInputLayout
視圖,后跟一個 label 和一個Spinner
。 我沒有應用額外的8dp
間距來進一步分隔它們,但這表明大小、字體和顏色都得到了反映。
Spinner
內的元素具有不同的填充,但是我更喜歡與所有其他標簽保持垂直對齊以獲得更統一的外觀。
我通過使用 AutoCompleteTextView、禁用鍵盤並在觸摸時顯示選項來實現這一點。
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;
}
});
我有一個自己的要點來解決你遇到的同樣問題。
一探究竟:
https://gist.github.com/rodrigohenriques/77398a81b5d01ac71c3b
現在我不需要微調器。 您仍將具有包含動畫的浮動標簽效果。
我創建了一個復合View
組件,它在Spinner
上方顯示一個標簽。 標簽的文本可以使用 XML 或 Java 設置。
該組件具有Spinner
的主要功能(並非全部),並且看起來類似於TextInputLayout
組件。
我將它命名為LabelledSpinner
,它作為我的UsefulViews Android 庫的一部分在 GitHub 上根據Apache 2.0 許可證提供。
要使用它,請在build.gradle
文件中添加庫依賴build.gradle
:
compile 'com.satsuware.lib:usefulviews:+'
GitHub 存儲庫中提供了其使用示例(示例應用程序和使用指南)。
使用像這樣的新材料庫樣式:
<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>
更多信息: https : //material.io/develop/android/components/menu/
UPDATE:不可編輯的變化:禁止在用戶輸入*AutoCompleteTextView*
有通過設置菜單中的一個不可編輯的變化android:inputType="none"
的AutoCompleteTextView
。
我修改了 Rodrigo 的解決方案以使用適配器,即更像標准 Spinner https://gist.github.com/smithaaron/d2acd57937d7a4201a79
我有一個替代解決方案,它使用 TextInputLayout 的行為和自定義 DialogFragment (AlertDialog) 來模擬微調對話框彈出窗口。
布局.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>
通過 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();
}
}
活動.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");
}
結果
當您單擊微調樣式 TextInputLayout 時,它將觸發一個包含您的選擇列表的警報對話框。 選擇一個選項后,EditText 將填充您的選擇,並且標簽將按照您想要的方式浮動。
這是我的訣竅,
好處是一切都會如你所願,
但壞處是它增加了布局層次結構,您必須在代碼中處理功能,這是一個丑陋的解決方案:
<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>
並覆蓋微調器的適配器,使選定的值透明
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;
}
}
在微調器中選擇后,只需獲取選定的文本並將其設置為 EditText 它將與動畫具有相同的效果
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) {
}
});
如果你有任何問題問我
這是我用於浮動標簽微調器rey5137 材料庫的庫
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 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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.