浮动标签微调?

在使用Androiddevise支持库的TextInputLayout在一个EditText组件上面放置一个浮动标签之后,我想知道是否有一种方法为Spinner组件添加浮动标签(不一定使用devise库)。

通过这个,我的意思是类似于放置在Spinner上方的TextView (显然没有像TextInputLayout这样的animation),但是我希望文本大小,字体和颜色与TextInputLayout的浮动标签相匹配

例如,它看起来像这样(参见Spinner上面的标签):

在这里输入图像说明

正如我之前提到的,我的主要目标是在Spinner上面添加一个标签,就像在TextInputLayout – 标签和组件之间的文本大小,字体,颜色和距离都是相同的。

在有关浮动标签文本字段的Googledevise页面上 ,有一个图表显示标签相对于组件的尺寸,但没有标签文字颜色或尺寸的指示:

在这里输入图像说明

所以,总结一下,我在问:
– 如果有一个特殊的组件来实现我所要求的或者我可以使用的一个自定义的视图,那么会是什么,以及如何使用它。
– 如果不是,浮动标签的文字大小,颜色和字体是什么,这样我就可以在上面的图片中显示布局尺寸,在我的Spinner TextView上方放置一个TextView


编辑:

从Google文本字段的devise准则中 ,它具有以下浮动标签:

提示和input字体:Roboto Regular 16sp
标签字体:Roboto Regular 12sp
瓷砖高度:72dp
文本顶部和底部填充:16dp
文本字段分隔符填充:8dp

以及上面显示的图像。

所以浮动标签字体是: Roboto Regular 12sp 。 因此,您可以使用TextView来显示Spinner标签,因为我不知道可以使用的任何自定义View或特殊组件。

然而 ,试用后,它看起来不像图像中显示的例子。 自定义视图可能会更好 ,因为它可能看起来更好,但上面的解决scheme只是一种实现接近我原来想要的东西的方式。

我有自己的想法来解决你所面临的同样的问题。

一探究竟:

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

现在我不需要纺纱工。 包含animation的浮动标签效果仍然存在。

我希望文本大小,字体和颜色与TextInputLayout的浮动标签相匹配

这可以轻松实现,无需任何外部库。 在尝试破解TextInputLayout并创build自己的自定义视图之后,我意识到使用简单的TextView需要的代码less得多,而且效率可能更高。

文本样式可以AppCompat库中复制

样式

从材料devise指南中,我们得到以下信息:

  • 标签的底边应该是8dp
  • 标签应该与input文本垂直alignment

以下是指南没有提到Material EditText

  • 它有一个4dp的左边填充
  • 它的标签实际上没有16dp以上的任何间距,这留给了界面devise师:这是有道理的,因为如果你把它放在另一个EditText ,你只需要额外的8dp的空间

此外,devise支持库包含这种风格的焦点元素的标签:

 <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使用Googledevise支持库中的TextAppearance.Design.HintreplaceTextAppearance.AppCompat.Caption 。 但是,如果您也在同一屏幕上标记了EditText视图,这可能会显得有点怪异。

最后,你可以在你的Spinner (或任何其他元素)上方应用样式的TextView

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

结果

以下屏幕截图显示了一个简单的示例,其中包含两个普通的TextInputLayout视图,后面跟着一个标签和一个Spinner 。 我没有使用额外的8dp间距来进一步分离它们,但是这显示了大小,字体和颜色被反映出来。

Spinner的元素有不同的填充,但是我更喜欢与其他所有标签保持垂直alignment,以获得更均匀的外观。

在这里输入图像说明

我创build了一个复合View组件,在Spinner上方显示一个标签。 标签的文本可以使用XML或Java设置。

该组件具有Spinner不是全部 )的关键特性,以及类似于TextInputLayout组件。

我已经将它命名为LabelledSpinner ,它可以作为我的UsefulViews Android库在GitHub下的Apache 2.0许可证的一部分 。

要使用它,请在build.gradle文件中添加库依赖build.gradle

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

它的用法的例子可以在GitHub仓库(示例应用程序和使用指南)中find。

我通过使用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; } }); 

我修改了Rodrigo的解决scheme,使用一个适配器,即更像一个标准的Spinner https://gist.github.com/smithaaron/d2acd57937d7a4201a79

我有一个替代解决scheme,它使用TextInputLayout的行为和一个自定义的DialogFragment(AlertDialog)来模拟一个微调对话框popup窗口。

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> 

通过DialogFragment创build自定义微调(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"); } 

结果

当你点击微调框样式的TextInputLayout时,它会触发一个包含你的select列表的警告对话框。 一旦select了select,EditText将被填充您的select,标签将浮动像你想要的。

这是我的伎俩,

好事是一切都会像你想要的那样工作,

但不好的是它增加了布局层次,而且你必须在代码中处理function,这是一个丑陋的解决scheme:

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

并在微调器中select后,获取选定的文本,并将其设置为EditText,它将具有与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) { } }); 

如果你有任何问题问我

这是一个我用于浮动标签微调rey5137材料库的库

另外,为了将来的参考,这里是一些伟大的图书馆列表。 用户界面库 核心库