Android-自定义控件之IP输入框

本文介绍了一种在Android应用中自定义IP地址输入框的方法,包括定义布局文件、实现自动跳转及合法性验证等功能。

  之前在写一个手机与电脑通信的程序,需要在手机端输入IP地址,Android上没有专门IP输入框,所以自己自定义了一个IP地址输入框。

1 定义该控件的布局文件

  这里使用的是merge标签,主要是在主布局里面放该布局文件时,系统会自动省略merge节点并且直接添加merge节点里面的小控件,这样可以减少布局中多余的层级。当然,你也可以不用merge,使用RelativeLayout等布局,相当于布局里面嵌套小布局,这样完全可以。
  这里的布局文件一共4个EditText,每个EditText中间一个.

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <EditText
        android:id="@+id/edit1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@null"
        android:inputType="number"
        android:maxLength="3"
        android:text=""/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/point"/>

    <EditText
        android:id="@+id/edit2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@null"
        android:inputType="number"
        android:maxLength="3"
        android:text=""/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/point"/>

    <EditText
        android:id="@+id/edit3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@null"
        android:inputType="number"
        android:maxLength="3"
        android:text=""/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/point"/>

    <EditText
        android:id="@+id/edit4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@null"
        android:inputType="number"
        android:maxLength="3"
        android:text=""/>
</merge>

2 自定义控件属性

  这里自定义View需要继承ViewGroup子类,此处继承的是LinearLayout控件分为4个输入框,定义为:
1. 每个输入框在1-255之间
2. 当前一个输入框满足输入条件则自动将输入焦点转移到下一个输入框
3. 当一个输入框删除里面数字则自动返回前一个输入框
代码如下,附注释:

public class IPEditText extends LinearLayout {
    //控件
    private EditText Edit1;
    private EditText Edit2;
    private EditText Edit3;
    private EditText Edit4;
    //文本
    private String text;
    private String text1;
    private String text2;
    private String text3;
    private String text4;

    public IPEditText(final Context context, AttributeSet attrs) {
        super(context, attrs);
        //初始化界面
        View view =     LayoutInflater.from(context).inflate(R.layout.iptext, this);
        //绑定
        Edit1=(EditText)findViewById(R.id.edit1);
        Edit2=(EditText)findViewById(R.id.edit2);
        Edit3=(EditText)findViewById(R.id.edit3);
        Edit4=(EditText)findViewById(R.id.edit4);
        //初始化函数
        init(context);
    }

    private void init(final Context context) {
        /**
         * 监听文本,得到ip段,自动进入下一个输入框
         */
        Edit1.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) {
                text1 = s.toString().trim();
                if (s.length() > 2 ) {
                    if (Integer.parseInt(text1) > 255) {
                        Toast.makeText(context, "请输入合法的ip地址",Toast.LENGTH_LONG).show();
                    }else{
                        Edit2.setFocusable(true);
                        Edit2.requestFocus();
                    }
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        Edit2.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) {
                text2 = s.toString().trim();
                if (s.length()> 2) {
                    if (Integer.parseInt(text2) > 255) {
                        Toast.makeText(context, "请输入合法的ip地址",Toast.LENGTH_LONG).show();
                    }else{
                        Edit3.setFocusable(true);
                        Edit3.requestFocus();
                    }
                }
                /**
                 * 输入框为空,删除按键则返回上一个文本框
                 */
                /*
                if (start == 0 && s.length() == 0) {
                    Edit1.setFocusable(true);
                    Edit1.requestFocus();
                }
                */
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        Edit3.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) {
                text3 = s.toString().trim();
                if (s.length()> 2 ) {

                    if (Integer.parseInt(text3) > 255) {
                        Toast.makeText(context, "请输入合法的ip地址",Toast.LENGTH_LONG).show();
                    }else{
                        Edit4.setFocusable(true);
                        Edit4.requestFocus();
                    }
                }
                /**
                 * 当用户需要删除时,此时的EditText为空时,上一个EditText获得焦点
                 */
                /*
                if (start == 0 && s.length() == 0) {
                    Edit2.setFocusable(true);
                    Edit2.requestFocus();
                }
                */
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        Edit4.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) {
                text4 = s.toString().trim();
                if (s.length() > 2 ) {

                    if (Integer.parseInt(text4) > 255) {
                        Toast.makeText(context, "请输入合法的ip地址",Toast.LENGTH_LONG).show();
                    }
                }
                /**
                 * 当用户需要删除时,此时的EditText为空时,上一个EditText获得焦点
                 */
                /*
                if (start == 0 && s.length() == 0) {
                    Edit3.setFocusable(true);
                    Edit3.requestFocus();
                }
                */
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        /**
         *  监听控件,空值时del键返回上一输入框
         */
        Edit2.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(text2==null||text2.isEmpty()){
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        Edit1.setFocusable(true);
                        Edit1.requestFocus();
                    }
                }
                return false;
            }
        });
        Edit3.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(text3==null||text3.isEmpty()){
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        Edit2.setFocusable(true);
                        Edit2.requestFocus();
                    }
                }
                return false;
            }
        });
        Edit4.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(text4==null||text4.isEmpty()){
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        Edit3.setFocusable(true);
                        Edit3.requestFocus();
                    }
                }
                return false;
            }
        });
    }

    /**
     *
     * 成员函数,返回整个ip地址
     */
    public String getText(){
        if (TextUtils.isEmpty(text1) || TextUtils.isEmpty(text2)
                || TextUtils.isEmpty(text3) || TextUtils.isEmpty(text4)) {
            text=null;
        }else {
            text= text1 + "." + text2 + "." + text3 + "." + text4;
        }
        return text;
    }

}

3 把它当做正常的控件一样使用

3.1 主布局文件里插入该布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 需要插入的自定义控件-->
    <com.example.zqj.pptcontrol.view.IPEditText
        android:id="@+id/iptext"
        android:layout_height="wrap_content"
        android:layout_width="340dp"
        android:layout_alignParentLeft="true"
        />
    <Button
        android:id="@+id/button"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_marginTop="42dp"
        android:text="连接"
        android:layout_below="@+id/iptext"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
</RelativeLayout>

3.2 正常使用该控件

IPEditText edittext = (IPEditText) findViewById(R.id.iptext);

//得到该IP地址
String Ip = edittext.getText().toString();
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值