• 自定义控件添加自定义属性问题


      先提一下需求,用一个自定义EditText实现禁止输入表情。谈一下自定义控件中自定义属性的定义和使用方式。

      第一步当然是自定义类EditTextNoEmoji继承EditText,同时重写三个构造方法。这里需要注意的是,三个构造方法中必须分别实现父类对应的构造方法,就是三个super();而不能出现调用当前类的不同参数的另一个构造方法的形式,就是不能出现this()。否则的话,这个控件在实际使用时是获得不到焦点的,似乎是由于EditText继承TextView的原因,具体原因待查。

      谈谈这三个构造方法的区别,一参的构造EditTextNoEmoji(Context context),是在使用的java文件中动态生成时调用,两参的构造EditTextNoEmoji(Context context, AttributeSet attrs),是在使用的xml文件中静态生成时调用,三参的构造基本不会使用,暂且不讨论。而两参构造中的第二个参数attrs,正是我们要自定义的属性,所以在该方法中调用setAttrs(context, attrs)设置xml文件中使用到的自定义属性。

     1   public EditTextNoEmoji(Context context) {
     2         super(context);
     3     }
     4 
     5     public EditTextNoEmoji(Context context, AttributeSet attrs) {
     6         super(context, attrs);
     7         setAttrs(context, attrs);
     8     }
     9 
    10     public EditTextNoEmoji(Context context, AttributeSet attrs, int defStyle) {
    11         super(context, attrs, defStyle);
    12         setAttrs(context, attrs);
    13     }

      第二步需要声明自定义属性控制是否禁止输入表情,同时为了方便该控件在使用时的xml布局中配置该属性,要先在res/values/styles.xml中自定义属性名称。自定义属性的styleable名称必须是和自定义控件的类名保持一致的,在这个样式下可以添加任意的自定义属性,如下代码,添加了一个boolean类型的属性,名称为canInputEmoji。另外可以添加的属性类型包括 color,boolean,dimension,enum,flag,float,fraction,integer,reference,string等十种。这里定义的属性如下所示。

     1 <declare-styleable name="EditTextNoEmoji"> 2 <attr name="canInputEmoji" format="boolean"/> 3 </declare-styleable> 

      接下来要回到刚刚的EditTextNoEmoji类中继续写setAttrs(Context context, AttributeSet attrs)里边的内容了,接着看代码。

    1      //自定义属性,控制是否输入表情
    2     private boolean canInputEmoji;
    3 
    4     private void setAttrs(Context context, AttributeSet attrs){
    5         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.EditTextNoEmoji);
    6         canInputEmoji=typedArray.getBoolean(R.attr.canInputEmoji, false);
    7     }

      上文提到如果在java文件中动态使用该控件,就是调用一参的构造,那上文的方式就不好使了,所以需要提供对该属性的封装,

    1     public boolean canInputEmoji() {
    2         return canInputEmoji;
    3     }
    4 
    5     public void setCanInputEmoji(boolean canInputEmoji) {
    6         this.canInputEmoji = canInputEmoji;
    7     }

      最后重写EditText的onTextChanged()方法即可,同时自定义属性在该方法中判断,代码如下。

     1     @Override
     2     protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
     3         super.onTextChanged(text, start, lengthBefore, lengthAfter);
     4         if(canInputEmoji()){
     5             int index = getSelectionStart() - 1;
     6             if (index > 0) {
     7                 if (isEmojiChar(text.charAt(index))) {
     8                     Editable edit = getText();
     9                     edit.delete(text.length() - 2, text.length());
    10                 }
    11             }
    12         }
    13     }

      下面贴上判断字符是否为表情字符的方法。

    1    /**
    2      * 判断字符是否是表情符号
    3      * @param inputChar
    4      * @return
    5      */
    6     private boolean isEmojiChar(char inputChar) {
    7         return !((inputChar == 0x0) || (inputChar == 0x9) || (inputChar == 0xA) || (inputChar == 0xD) || ((inputChar >= 0x20) && inputChar <= 0xD7FF)) || ((inputChar >= 0xE000) && (inputChar <= 0xFFFD)) || ((inputChar >= 0x10000) && (inputChar <= 0x10FFFF));
    8     }
  • 相关阅读:
    wpf 不规则窗体
    wpf treeview使用expanded事件出错的问题
    获取文件图标
    C#操作快捷方式总结
    mysql 更改存储引擎,更改自增列计数值,更改默认字符集
    zend framework集成smarty
    文本文件数据导入mysql注意事项
    MYSQL 外键
    uchome 日志发布函数blog_post()
    mysql order by null
  • 原文地址:https://www.cnblogs.com/BobGo/p/5954769.html
Copyright © 2020-2023  润新知