web-dev-qa-db-ja.com

Material ComponentsライブラリからAndroidの入力フィールドにチップを追加する方法は?

Android-P googleで、マテリアルチップを含む新しいマテリアルコンポーネントライブラリを追加するのを見ました:

Androidのマテリアルコンポーネント

Material.ioチップの使用

GitHubのマテリアルコンポーネント

そこで、マテリアルインプットチップをプロジェクトに追加することにしましたが、残念ながらそれを作成する方法を見つけることができませんでした。 Gmailチップのようなものを作成したいのですが、最初は画像がありません。

Appcompatライブラリを使用しているため、Android.support.design.chip.ChipおよびAndroid.support.design.chip.ChipGroup。しかし、結果は入力フィールドのない単なるチップでした。また、スタンドアロンのChipDrawableを作成してからEditTextに追加しようとしました

Editable text = editText.getText();

text.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

しかし、私はチップなしで空のEditTextを得ました。では、この材料コンポーネントライブラリを使用して、Gmailのようなチップ入力を作成するにはどうすればよいですか?たぶん誰かが経験があるか、私がこれを作成する方法を見ることができるチュートリアルを知っていますか?

前もって感謝します!

10
IDmikael

回答

Androidにチップを追加するためのデフォルトの入力フィールドはありません。入力チップについて言及しましたが、入力チップのレイアウトやビューグループが見つかりませんでした。だから私はChipdrawableメソッドを使ってチップをedittextに追加します。ここでは AppCompatEdittext を使用しています。テキスト入力をリッスンする任意のビューに変更できます。 参照

ステップ1

チップxmlリソースを追加します。 chip.xml

res-> xml-> chip.xml

<?xml version="1.0" encoding="utf-8"?>
<chip xmlns:Android="http://schemas.Android.com/apk/res/Android"
 xmlns:app="http://schemas.Android.com/apk/res-auto"
 Android:textAppearance="@style/ChipTextApperance"
 app:chipBackgroundColor="@color/colorAccent"
 app:chipIcon="@drawable/ic_call_white_24dp"
 app:closeIconEnabled="true"  <!--property for close icon if no need set to false. -->
 app:closeIconTint="@Android:color/white" />

次に、style.xmlにtextappearanceスタイルを追加します(textStyleを変更する場合)

<style name="ChipTextApperance" parent="TextAppearance.MaterialComponents.Chip">
    <item name="Android:textColor">@Android:color/white</item>
</style>

ステップ2

ここにビューを追加するには、AppCompatEdittextを使用します

  <Android.support.v7.widget.AppCompatEditText
    Android:id="@+id/phone"
    Android:layout_width="0dp"
    Android:layout_height="wrap_content"
    Android:layout_marginEnd="8dp"
    Android:layout_marginLeft="8dp"
    Android:layout_marginRight="8dp"
    Android:layout_marginStart="8dp"
    Android:layout_marginTop="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tvt_Contact" />

ステップ3
このコードをビューに追加して、目的の動作を取得します。

 private int SpannedLength = 0,chipLength = 4;

 AppCompatEditText Phone = findViewById(R.id.phone);

 Phone.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            if (charSequence.length() == SpannedLength - chipLength)
            {
                SpannedLength = charSequence.length();
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {

            if(editable.length() - SpannedLength == chipLength) {
                ChipDrawable chip = ChipDrawable.createFromResource(getContext(), R.xml.chip);
                chip.setChipText(editable.subSequence(SpannedLength,editable.length()));
                chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight());
                ImageSpan span = new ImageSpan(chip);
                editable.setSpan(span, SpannedLength, editable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                SpannedLength = editable.length();
            }

        }
    });

edittextに新しいチップを追加する必要がある場合、必要に応じてchipLengthを変更します。

[〜#〜] output [〜#〜]

enter image description here

[〜#〜]編集済み[〜#〜]

スパン Here でテキストを中央に揃える方法の詳細を確認できます。

ここで、ソリューションから修正するコードをいくつか追加しました。

public class VerticalImageSpan extends ImageSpan {

public VerticalImageSpan(Drawable drawable) {
    super(drawable);
}

@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end,
                   Paint.FontMetricsInt fontMetricsInt) {
    Drawable drawable = getDrawable();
    Rect rect = drawable.getBounds();
    if (fontMetricsInt != null) {
        Paint.FontMetricsInt fmPaint = Paint.getFontMetricsInt();
        int fontHeight = fmPaint.descent - fmPaint.ascent;
        int drHeight = rect.bottom - rect.top;
        int centerY = fmPaint.ascent + fontHeight / 2;

        fontMetricsInt.ascent = centerY - drHeight / 2;
        fontMetricsInt.top = fontMetricsInt.ascent;
        fontMetricsInt.bottom = centerY + drHeight / 2;
        fontMetricsInt.descent = fontMetricsInt.bottom;
    }
    return rect.right;
}

@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end,
                 float x, int top, int y, int bottom, @NonNull Paint paint) {

    Drawable drawable = getDrawable();
    canvas.save();
    Paint.FontMetricsInt fmPaint = Paint.getFontMetricsInt();
    int fontHeight = fmPaint.descent - fmPaint.ascent;
    int centerY = y + fmPaint.descent - fontHeight / 2;
    int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;
    canvas.translate(x, transY);
    drawable.draw(canvas);
    canvas.restore();
}

}

以下のようにimagespanクラスを変更します

VerticalImageSpan span = new VerticalImageSpan(chip);
16

これを行うには、スタイルを追加せずに素材チップデザイン自体を使用します。

AndroidXのアプリgradleに追加する

実装 'com.google.Android.material:material:1.0.0-beta01'

AndroidXより前の場合はこれを使用します

実装 'com.Android.support:design:28.0.0'

enter image description here

フラグメント

class EntryChipDemoFragment : Fragment() {
    private lateinit var mView: View

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        mView = inflater.inflate(R.layout.fragment_entry_chip_demo, container, false)

        mView.etValue.setOnEditorActionListener(TextView.OnEditorActionListener { v, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                val txtVal = v.text
                if(!txtVal.isNullOrEmpty()) {
                    addChipToGroup(txtVal.toString(), mView.chipGroup2)
                    mView.etValue.setText("")
                }

                return@OnEditorActionListener true
            }
            false
        })

        return mView
    }


    private fun addChipToGroup(txt: String, chipGroup: ChipGroup) {
        val chip = Chip(context)
        chip.text = txt
//        chip.chipIcon = ContextCompat.getDrawable(requireContext(), baseline_person_black_18)
        chip.isCloseIconEnabled = true
        chip.setChipIconTintResource(R.color.chipIconTint)

        // necessary to get single selection working
        chip.isClickable = false
        chip.isCheckable = false
        chipGroup.addView(chip as View)
        chip.setOnCloseIconClickListener { chipGroup.removeView(chip as View) }
        printChipsValue(chipGroup)
    }

    private fun printChipsValue(chipGroup: ChipGroup) {
        for (i in 0 until chipGroup.childCount) {
            val chipObj = chipGroup.getChildAt(i) as Chip
            Log.d("Chips text :: " , chipObj.text.toString())

        }
    }

    companion object {
        @JvmStatic
        fun newInstance() = EntryChipDemoFragment()
    }
}

XMLファイル:

<HorizontalScrollView
    Android:id="@+id/chipGroup2HorizontalView"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_marginStart="8dp"
    Android:layout_marginTop="16dp"
    Android:scrollbars="none"
    app:layout_constraintVertical_bias="0.62">

    <LinearLayout
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:gravity="center_vertical"
        Android:orientation="horizontal">

        <androidx.appcompat.widget.AppCompatTextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Skills: " />

        <com.google.Android.material.chip.ChipGroup
            Android:id="@+id/chipGroup2"
            Android:layout_width="wrap_content"
            Android:layout_height="match_parent"
            Android:duplicateParentState="false">

        </com.google.Android.material.chip.ChipGroup>

        <com.google.Android.material.textfield.TextInputLayout
            Android:id="@+id/textInputLayout"
            Android:layout_width="wrap_content"
            Android:layout_height="43dp"
            Android:layout_marginStart="8dp"
            Android:layout_marginEnd="8dp"
            Android:layout_marginBottom="5dp"
            Android:minWidth="32dp"
            Android:visibility="visible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/chipGroup2HorizontalView"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_min="32dp">

            <androidx.appcompat.widget.AppCompatEditText
                Android:id="@+id/etValue"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:background="@Android:color/transparent"
                Android:imeOptions="actionDone"
                Android:maxLines="1"
                Android:singleLine="true" />

        </com.google.Android.material.textfield.TextInputLayout>

    </LinearLayout>


</HorizontalScrollView>

詳細については、 ここをクリック

1
Naveen Kumar M

マテリアルチップ "com.google.Android.material.chip.Chip"および "implementation 'com.google.Android.material:material:1.0.0'"をbuild.gradleに追加して使用できます。

Filter style = "@ style/Widget.MaterialComponents.Chip.Filter"

Choice Chips style = "@ style/Widget.MaterialComponents.Chip.Choice"

エントリ入力:style = "@ style/Widget.MaterialComponents.Chip.Entry"

0
Arul Pandian