Android Design Support Libraryの TextInputLayout
を使用して EditText
コンポーネントの上にフローティングラベルを配置した後、フローティングを追加する方法があるかどうか疑問に思いました Spinner
コンポーネントのラベル(必ずしもデザインライブラリを使用しているわけではありません)。
これにより、 TextView
のようなものがSpinner
の上に配置されます(明らかにTextInputLayout
のようなアニメーションはありません)が、テキストサイズ、フォント、色を一致させたいTextInputLayout
の浮動ラベルのラベル。
たとえば、次のようになります(Spinner
sの上のラベルを参照)。
前述したように、私の主な目的は、Spinner
と同様に、TextInputLayout
の上にラベルを付けることです。したがって、テキストサイズ、フォント、色、およびラベルとコンポーネント間の距離は同じになります。
フローティングラベルテキストフィールドに関するGoogleデザインページ には、コンポーネントに対するラベルの寸法を示す図がありますが、ラベルテキストの色やサイズは示されていません。
だから、要約するために、私は尋ねています:
-求めていることや、使用できるカスタムビューを実現するための特別なコンポーネントがある場合、それはどのようなもので、どのように使用できますか。
-そうでない場合、フローティングラベルのテキストサイズ、色、およびフォントは何ですか。そのため、上記の画像に示すレイアウトサイズでTextView
をSpinner
の上に配置できます。
テキストフィールドのGoogleデザインガイドライン から、フローティングラベルについては次のようになります。
ヒントと入力フォント:Roboto Regular 16sp
ラベルフォント:Roboto Regular 12sp
タイルの高さ:72dp
テキストの上下のパディング:16dp
テキストフィールド区切りパディング:8dp
上記の画像と同様に。
したがって、フローティングラベルのフォントは次のとおりです。Roboto Regular 12sp。したがって、使用できるカスタムTextView
sまたは特別なコンポーネントがわからないので、Spinner
を使用してView
ラベルを表示できます。
ただし、、試してみると、画像に示されている例ほど良く見えません。 カスタムビューは、見た目が良くなるため、これに適している可能性がありますが、上記のソリューションは、私が当初望んでいたものに近いものを達成するための1つの方法にすぎません。
テキストサイズ、フォント、色を
TextInputLayout
のフローティングラベルと一致させたい.
これは、外部ライブラリなしで簡単に実現できます。 TextInputLayout
をハックして、独自のカスタムビューを作成した後でも、単純なTextView
を使用するとコードがはるかに少なくなり、おそらくより効率的であることがわかりました。
テキストスタイルは、AppCompat
ライブラリからコピーできます。
材料設計ガイドラインから、次の情報を取得します。
8dp
の下マージンが必要です以下は、ガイドラインがマテリアル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>
ラベルを常に強調表示(アクセント)色にする場合は、Google Design Support LibraryのTextAppearance.AppCompat.Caption
をTextAppearance.Design.Hint
に置き換えます。ただし、同じ画面でEditText
ビューもラベル付けしている場合、これはおそらく少し奇妙に見えます。
最後に、スタイルを適用してTextView
(またはその他の要素)の上にSpinner
を配置できます。
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="@string/category"
style="@style/InputLabel" />
次のスクリーンショットは、2つの通常のTextInputLayout
ビューの後にラベルとSpinner
が続く単純な例を示しています。追加の8dp
間隔を適用してそれらをさらに分離しませんでしたが、サイズ、フォント、色が反映されていることがわかります。
Spinner
内の要素のパディングは異なりますが、より均一な外観にするために、他のすべてのラベルと垂直方向の配置を維持することを好みます。
あなたが持っているのと同じ問題を解決するために自分で作った要点があります。
見てみな:
https://Gist.github.com/rodrigohenriques/77398a81b5d01ac71c3b
今、私はスピナーを必要としません。アニメーションを含むフローティングラベルエフェクトは引き続き使用できます。
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;
}
});
View
の上にラベルを表示する複合Spinner
コンポーネントを作成しました。ラベルのテキストは、XMLまたはJavaを使用して設定できます。
このコンポーネントには、Spinner
の主要な機能(すべてではない)があり、TextInputLayout
コンポーネントに似ています。
LabelledSpinner
という名前を付けて、 UsefulViews の一部として使用できます Androidライブラリは、 Apache 2.0 License の下のGitHubにあります。
使用するには、build.gradle
ファイルにライブラリの依存関係を追加します。
compile 'com.satsuware.lib:usefulviews:+'
その使用例はGitHubリポジトリで入手できます(サンプルアプリと使用ガイドの両方)。
TextInputLayoutの動作とカスタムDialogFragment(AlertDialog)を使用してスピナーダイアログポップアップをエミュレートする代替ソリューションがあります。
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を介してカスタムスピナーを作成する(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スタイルのスピナーをクリックすると、選択リストを含むアラートダイアログがトリガーされます。選択範囲が選択されると、EditTextに選択範囲が入力され、ラベルは希望どおりに浮き上がります。
Rodrigoのソリューションを変更して、アダプターを使用しました。つまり、標準のスピナーのようなものです https://Gist.github.com/smithaaron/d2acd57937d7a4201a79
これが私のトリックです
良いことは、あなたが望むようにすべてが機能するということです
しかし、悪いのは、レイアウト階層が増加していることであり、コード内の機能を処理する必要があり、それはい解決策です。
<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 Material Library
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>
このような新しいマテリアルライブラリスタイルでは:
<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/