مثال TextInputLayout لـ Android

في هذا البرنامج التعليمي، سنتطلع بعمق على الميزات التي يوفرها Android TextInputLayout لنا. Android TextInputLayout هو عنصر تصميم يأتي مع مكتبة دعم تصميم المواد.

Android TextInputLayout

يوسع Android TexInputLayout LinearLayout. الاستخدام الأساسي لـ TextInputLayout هو العمل كغلاف لـ EditText (أو أحد أحفادها) وتمكين تحريك تلميحات العنوان. قاعدة عامة: يجب أن يكون TextInputLayout يحتوي على TextInputEditText بدلاً من الـ EditText العادي. لماذا؟ TextInputEditText هو فئة فرعية من EditText ومصممة للاستخدام كطفل لـ TextInputLayout. علاوة على ذلك، ستظهر تحذيرًا إذا تم استخدام EditText بدلاً من ذلك : تمت إضافة EditText وليس TextInputEditText. يرجى التبديل إلى استخدام تلك الفئة بدلاً من ذلك. TextInputLayout يقدم الكثير أكثر من عرض تسميات تلميح عائمة.

ميزات Android TextInputLayout

بعض الميزات التي سنغطيها في هذا البرنامج التعليمي هي:

  1. تمكين/تعطيل تسميات العناوين العائمة
  2. تمكين/تعطيل تحريك تسميات العناوين العائمة
  3. عرض رسائل الخطأ
  4. عرض عداد الأحرف
  5. التنبيه للمستخدم عند تجاوز عدد الأحرف الخاصة به
  6. تخصيص مظهر النص لتلميح عائم، وعلامة الخطأ، وعداد الأحرف
  7. زر تبديل رؤية كلمة المرور

سنتناول كل من هذه الميزات ونقوم بتنفيذها في مشروع Android Studio.

مثال على هيكل مشروع Android TextInputLayout

هذا هو تطبيق نشاط واحد. سنقوم بفعل كل شيء داخل تخطيط، نشاط، وملفات styles.xml و colors.xml. أولاً، قم بإضافة التبعية لمكتبة دعم التصميم داخل ملف build.gradle كما هو موضح أدناه.

compile 'com.android.support:design:25.3.1'

تمكين/تعطيل تلميحات الطفو

تم تمكين تلميحات الطفو بشكل افتراضي في TextInputLayout. لتعطيلها، نحتاج إلى إضافة السمة التالية داخل العلامة: app:hintEnabled="false". الشيفرة البرمجية XML أدناه هي من تخطيط activity_main.xml وتحتوي على ثلاث حقول EditText.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            android:hint="TextInputEditText" />


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Enabled Default" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:hintEnabled="false">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Disabled" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

تم تعطيل تلميح العنصر EditText الثالث العائم. دعنا نرى الناتج الذي يعطيه الكود أعلاه:

تمكين/تعطيل تحريك تلميح العنصر العائم

على غرار الميزة السابقة، يتم تمكين تحريك تلميح العنصر العائم افتراضيًا. لتعطيله، نحتاج إلى إضافة السمة التالية داخل علامة TextInputLayout. app:hintAnimationEnabled="false" الشيفرة البرمجية XML أدناه هي من تخطيط activity_main.xml وتحتوي على حقول EditText لأي من الحالتين.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Enabled Default" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:hintAnimationEnabled="false">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Hint Animation Disabled" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

يظهر الناتج من الكود أعلاه أدناه. يجدر بالذكر أن العنصر EditText الثاني لا يقوم بتحريك تلميحه العائم عند التركيز.

تنسيق نص التلميح TextAppearance

لاستخدام ألوان وأحجام نص مخصصة للتلميحات، يتم استخدام السمة التالية: app:hintTextAppearance="@style/HintText" يتم كتابة نمط HintText داخل ملف styles.xml كما هو موضح أدناه.

<style name="HintText" parent="TextAppearance.Design.Hint">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/colorPrimary</item>
    </style>

الكود XML التالي هو من تخطيط activity_main.xml ويحتوي على حقول إدخال النص سواء مع أو بدون استخدام hintTextAppearance.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Enabled" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Custom Hint TextAppearance" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

يتم عرض نتيجة الكود أعلاه كما هو مبين أدناه.

عداد الأحرف

عداد الأحرف هو ميزة تستخدمها العديد من التطبيقات. (تذكر حد الأحرف في Twitter؟). قم بتعيين app:counterEnabled إلى true و app:counterMaxLength بأقصى عدد من الأحرف التي ترغب فيها في TextInputLayout. يتم عرض عداد الأحرف بشكل افتراضي أسفل حقل إدخال النص (أسفل اليمين) وأثناء كتابة هذا البرنامج التعليمي، لا يوجد طريقة لتغيير الموضع حتى الآن. تنسيق عداد الأحرف مشابه لتنسيق نص التلميح. app:counterTextAppearance هي السمة المستخدمة في هذا الوقت. قمنا بإضافة النمط التالي داخل ملف styles.xml في مشروعنا.

<style name="CounterText" parent="TextAppearance.Design.Counter">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_pink</item>
    </style>

الكود XML التالي هو من تخطيط activity_main.xml ويحتوي على حقول إدخال النص مع عداد أحرف افتراضي وآخر مخصص.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Character Counter Limit 10" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Character Counter Custom TextAppearance" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

إليك الناتج من الكود أعلاه. دعنا نلاحظ الناتج أعلاه بعناية.

  • يتغير لون النص الموجود في حقل EditText الأول، ولون التلميح ولون المؤشر عند تجاوز عدد الأحرف.
  • يقوم حقل EditText الثاني بنفس الأمر، ولكنه أيضًا يغير لون النص المخصص للعداد وحجم النص المخصص عند تجاوز الحد.

لتحديد النمط الذي نحتاجه عند تجاوز عداد الأحرف لحدوده، نحتاج إلى استخدام سمة counterFlow التي سنراها في الخطوة التالية.

تجاوز عداد الأحرف

كما رأينا في الأعلى عند تجاوز عدد الأحرف الحد المحدد، يستخدم النص الموجود في العداد السمات المحددة في counterFlow. إذا لم تكن السمات موجودة، فسيستمر في استخدام السمات الافتراضية كما رأينا في الناتج أعلاه. نحتاج إلى استخدام المعلمة التالية app:counterOverflowTextAppearance النمط الخاص بـ CounterOverflow موجود داخل styles.xml:

 <style name="CounterOverFlow" parent="TextAppearance.Design.Counter.Overflow">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_orange</item>
    </style>

أضف قطعة الكود التالية إلى تخطيط activity_main.xml السابق:

<android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="CounterOverflow CustomTextAppearance" />

        </android.support.design.widget.TextInputLayout>

لنقم بتشغيل التطبيق مرة أخرى.

تسمية الخطأ

إعداد app:errorEnabled على true يتيح لنا عرض نص خطأ في حالة معينة تحت حقل EditText الخاص بنا. لتنسيق نص الخطأ، سنستخدم السمة app:errorTextAppearance ونضيف الكود التالي داخل ملف styles.xml.

<style name="ErrorText" parent="TextAppearance.Design.Error">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_black</item>
    </style>

الكود الـ XML أدناه هو من تخطيط activity_main.xml ويحتوي على حقول EditText لتسمية خطأ افتراضية وخصصة.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/errorInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:errorEnabled="true"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/errorEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Default Error Label" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:id="@+id/customErrorInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:errorEnabled="true"
            app:errorTextAppearance="@style/ErrorText"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/customErrorEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Custom Error Label" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

لعرض نص الخطأ، سيتعين علينا استدعاء الطريقة setError(String) على مثيل من TextInputLayout في فئة MainActivity.java كما هو موضح أدناه.

package com.journaldev.featuresoftextinputlayout;

import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;

public class MainActivity extends AppCompatActivity {


    TextInputLayout errorInputLayout, customErrorInputLayout;
    TextInputEditText errorEditText, customErrorEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        errorEditText = (TextInputEditText) findViewById(R.id.errorEditText);
        errorInputLayout = (TextInputLayout) findViewById(R.id.errorInputLayout);

        customErrorEditText = (TextInputEditText) findViewById(R.id.customErrorEditText);
        customErrorInputLayout = (TextInputLayout) findViewById(R.id.customErrorInputLayout);

        errorEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

                if (s.length() > errorInputLayout.getCounterMaxLength())
                    errorInputLayout.setError("Max character length is " + errorInputLayout.getCounterMaxLength());
                else
                    errorInputLayout.setError(null);

            }
        });

        customErrorEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

                if (s.length() > customErrorInputLayout.getCounterMaxLength())
                    customErrorInputLayout.setError("Max character length is " + customErrorInputLayout.getCounterMaxLength());
                else
                    customErrorInputLayout.setError(null);

            }
        });


    }
}

في الكود أعلاه، نقوم بإضافة TextChangedListener (الذي ينفذ TextWatcher) على كل حالة من TextInputEditText. نقوم بعرض تسمية الخطأ عندما يتجاوز عدد الأحرف الحالي الحد الأقصى للعداد. لمسح تسمية الخطأ، نقوم بتعيين القيمة داخل setError() كـ null. الناتج الذي يعطينا الكود أعلاه هو: ملاحظة: مؤشر حقل النص يستخدم نفس لون تسمية الخطأ. يتجاوز اللون الذي يتم تعيينه بواسطة counterOverflow لذلك يكون له أعلى أولوية.

عرض تبديل كلمة المرور

ضبط app:passwordToggleEnabled إلى true يتيح لك إظهار/إخفاء كلمة المرور. لتغيير لون الأيقونة، استخدم app:passwordToggleTint. الكود الـ xml أدناه هو من تخطيط activity_main.xml ويحتوي على حقول EditText لتبديل رؤية كلمة المرور (أيقونة افتراضية ومع تظليل)

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText"
            app:passwordToggleEnabled="true">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password Visibility Toggle"
                android:inputType="textPassword" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText"
            app:passwordToggleEnabled="true"
            app:passwordToggleTint="@color/my_orange">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password Visibility Toggle Tint"
                android:inputType="textPassword" />

        </android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>

الناتج الذي يظهره الشيفرة أعلاه هو: ملحوظة: يمكننا استخدام رموزنا المخصصة الخاصة بالرؤية لتبديل كلمة المرور باستخدام app:passwordToggleDrawable. وبهذا ننهي هذا البرنامج التعليمي. لقد قمنا بتغطية جميع الميزات الرئيسية الموجودة في TextInputLayout. يمكنك تنزيل مشروع مثال Android TextInputLayout من الرابط أدناه. يتضمن كل قطعة من الشيفرة أعلاه.

تنزيل مشروع Android TextInputLayout

المرجع: مستندات Android الرسمية

Source:
https://www.digitalocean.com/community/tutorials/android-textinputlayout-example