自定义固定头文字的多行编辑框控件的实现分析

原创 2016年08月30日 13:38:48

自定义固定头文字的多行编辑框控件的实现分析

写这个自定义控件的缘由:公司新的UI界面实现需要实现一个可以固定头文字,并且可以代码去配置这个头文字,用户不能去修改和删除,在网上查阅了相关资料,貌似没有人去做过相关的自定义控件,于是自己花几个小时写了一遍,其中也想过多种方案,踩过许多坑。


首先,按照国际惯例,要实现自己的EditText当然得继承EditText控件于是乎我开始创建一个自定义的EditText,也开始了第一步入坑:

/**
 * 主要功能: 左边有固定文字EditText
 * Created by wz on 2016/8/5
 * 修订历史:
 */
public class FixedEditText extends EditText {
    private String fixedText;
    private View.OnClickListener mListener;

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);

    }

    @Override
    public void setGravity(int gravity) {
        super.setGravity(gravity);

    }

    @Override
    public int getCompoundPaddingLeft() {
        return 20;
    }

    public FixedEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setFixedText(String text) {
        fixedText = text;
        int left = (int) getPaint().measureText(fixedText)+ getPaddingLeft();
        setPadding(left, 0, 0, 100);
        invalidate();
    }

    public void setDrawableClk(View.OnClickListener listener) {
        mListener = listener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint=new Paint();
        if (!TextUtils.isEmpty(fixedText)) {
            canvas.drawText(fixedText, 0,  getTextSize(), getPaint());
            this.setSelection(fixedText.length());
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (mListener != null && getCompoundDrawables()[2] != null) {

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    int i = getMeasuredWidth() - getCompoundDrawables()[2].getIntrinsicWidth();
                    int h=getMeasuredHeight() - getCompoundDrawables()[2].getIntrinsicHeight();
                    if (event.getX() > i||event.getY()>h) {
                        mListener.onClick(this);
                        return true;
                    }
                    break;
                case MotionEvent.ACTION_UP:

                    break;
                default:
                    break;
            }

        }

        return super.onTouchEvent(event);
    }
}

这段代码当我敲完,我以为可以完美的去装逼了,但是当我在准备运行时候,我忽然想到了,我需要的是多行文本,而且多行文本左对齐,运行来看,不能多行,设置完属性,发现多行特别并不是左对齐后面的活动文本左对齐了(UI要求的是第二行开始下面的活动文本都得与第一行的固定文本对齐),然后这样的Code当然是不能实现的。然后无脑的我马上想到了第二种解决办法,既然继承EditText得不到我想要的结果,而且显示不出我想要的效果,于是转换了一下思路,所谓固定值,也就是不能让用户删除,对吧?然而我们能够监听用户对键盘的操作,所以当我们判定到用户是否正在删除固定文字,如果是就拦截操作,这里面会涉及到光标的操作,和用户点击的操作,处理好这两个的关系,就会很简单的实现所谓的固定多行文本框啦。
下面贴上类代码供参考


/**
 * 主要功能:
 * Created by wz on 2016/8/5
 * 修订历史:
 */
public class FixEditView extends EditText {
    private Context context;
    private String fixText;
    private boolean isDelete = false;//是否是可删除
    private boolean isFix = false;//表示是否需要显示固定文字
    private ColorStateList defColor;//默认的字体颜色
    private int fixColor=0;

    public String getFixText() {
        return fixText;
    }
    public void setFixTextColor(int color){
        this.fixColor=color;
    }
    public void setFixText(String fixText) {
        this.fixText = fixText;
        if(fixColor!=0){
            this.setTextColor(fixColor);
        }
        this.setText(fixText);
        if (fixText.length() > 0) {
            isFix = true;
        }
        //初始化光标位置
        this.setSelection(fixText.length());
    }

    public FixEditView(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public FixEditView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public void init() {
        defColor=this.getTextColors();
        this.addTextChangedListener(textWatcher);
        this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
        this.setLongClickable(false);
    }

    TextWatcher textWatcher = new TextWatcher() {
        private CharSequence temp;

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            temp = charSequence;
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            Random random=new Random();
            //产生100000-999999的随机数
            int randNum=random.nextInt(100000)%(999999-100000+1) + 100000;
            //监听用户的输入状态
            if (temp.length() == fixText.length() || temp.length() < fixText.length()) {
                isDelete = false;
            } else {
                //产生随机颜色代码,只为装13,辣眼睛
                int color=Color.parseColor("#"+randNum);
                FixEditView.this.setTextColor(color);
                isDelete = true;
            }
        }
    };

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        //限制光标的位置,使得最初光标总是从固定文本之后开始的
        if (isFix) {
            selStart = selStart < fixText.length() ? fixText.length() : selStart;
            selEnd = selStart;
            this.setSelection(selStart, selEnd);
        }
        super.onSelectionChanged(selStart, selEnd);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == 67) {//删除键
            //当标记为不能删除的时候拦截操作
            if (!isDelete) {
                return !isDelete;
            }
        }
        return super.dispatchKeyEvent(event);
    }
}

xml布局文件代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:background="@color/bg_page"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="250px"
        android:layout_marginTop="14px"
        android:background="@color/white"
        android:orientation="horizontal"
        android:visibility="visible">

        <TextView
            android:layout_width="170px"
            android:layout_height="wrap_content"
            android:layout_marginTop="30px"
            android:gravity="center"
            android:singleLine="true"
            android:text="工作要求"
            android:textColor="@color/text_gray_normal"
            android:textSize="28px" />

        <View
            android:layout_width="1px"
            android:layout_height="206px"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10px"
            android:background="@color/line_main" />

        <com.example.lenovo.diyedittext.FixEditView
            android:id="@+id/fev_work_info"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40px"
            android:layout_marginTop="30px"
            android:layout_weight="1"
            android:background="@color/transparent"
            android:gravity="top"
            android:hint="请输入相关内容,岗位要求,要求20-1500字。"
            android:maxHeight="220px"
            android:maxLength="1500"
            android:minHeight="220px"
            android:padding="5dp"
            android:textColor="@color/text_gray_normal"
            android:textSize="28px" />
    </LinearLayout>
</LinearLayout>

Activity中如何使用:

/**
 * 主要功能:
 * Created by wz on 2016/8/5
 * 修订历史:
 */
public class MainActivity extends Activity {

    FixEditView fev_work_info;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maple);
        fev_work_info= (FixEditView) findViewById(R.id.fev_work_info);
        fev_work_info.setFixTextColor(Color.parseColor("#30C27B"));
        fev_work_info.setFixText("这是固定文字。");
        fev_work_info.setGravity(Gravity.LEFT);
    }
}

感受:不要总是用别人造的轮子,新手主要是用现成的轮子,普通的主要是改造成自己的轮子,高手都是造轮子,所以一步步来,能自己写出来的东西尽量自己写,相信总有一天会蜕变成那个造轮子的嘛。
内容大概就是这样,如果有什么不对的地方,欢迎指正,相互学习很有必要。

源码地址附上:http://download.csdn.net/detail/u011862733/9616817

版权声明:本文为博主原创文章,未经博主允许不得转载。

大小不固定,多行文字的垂直居中

单行文字 可能很多人都知道如何让单行文字垂直居中显示,就是使用line-height,将line-height值与外部标签盒子的高度值设置成一致就可以了。例如如下css代码:height:3em; l...
  • xm1037782843
  • xm1037782843
  • 2016年09月27日 19:53
  • 1106

android固定头部和侧边表格实现

哈哈,感觉下CSDN的新版本编辑器,至少看起来还挺不错的,之前的编辑器插入代码很不方便,发布后会出现源代码,还估计是一个bug.言归正传,这次要记录的是android怎么实现表格头、侧边固定滑动,并且...
  • aj1031689
  • aj1031689
  • 2015年07月13日 19:08
  • 1315

大小不固定,多行文字的垂直居

(1)、垂直居中-父元素高度确定的单行文本 设置父元素的height和line-height高度一致 注: height是指该元素的高度,line-height是指行间距。 line-heig...
  • zxx2011082427
  • zxx2011082427
  • 2017年05月05日 16:05
  • 174

关于iOS tableview自定义区头

很多人自定义区头时继承与UIView,本身没有问题,但在ViewController调用时就要下功夫了。其实区头继承与UITableViewHeaderFooterView才是最实用的。毕竟还要重用滴...
  • zhaojiao123456
  • zhaojiao123456
  • 2017年07月13日 17:11
  • 743

JS实现的表头列头固定页面功能示例

本文实例讲述了JS实现的表头列头固定页面功能。分享给大家供大家参考,具体如下: 这里的示例演示了一个table页面,并固定表头或者列头,以达到excel冻结列的效果,主要使用的js的scrollTo...
  • JoneYoung_ts
  • JoneYoung_ts
  • 2017年03月22日 15:51
  • 260

Flume<自定义Source和拦截器实现抓取异常多行日志>

假设现在有一个日志文件test.log,文件中的内容如下: 现在的需求是需要将日志通过Flume收集上来,在HDFS进行分区,比如 2016-07-08/INFO 2016-07-08/DEBU...
  • Gpwner
  • Gpwner
  • 2017年05月06日 18:20
  • 2118

netty4 实现自定义协议开发

netty4实现自定义协议开发本示例使用的是最新netty4.1.8 参考excmples (securechat) 消息格式定义 编码器 解码器 示例指令 源码 本示例协议头部使用12个字节来定义...
  • edwardqiang
  • edwardqiang
  • 2017年02月25日 00:13
  • 396

.wav文件头分析

这篇文章是网络上流行的比较广泛的针对WAVE头分析的文章, 整体写的简单明了非常好,但是 18H 2 int 采样率(每秒样本数),表示每个通道的播放速...
  • xieyanyi1
  • xieyanyi1
  • 2015年09月04日 11:11
  • 1486

css3——大小不固定的图片、多行文字的水平垂直居中

http://www.zhangxinxu.com/wordpress/2009/08/%E5%A4%A7%E5%B0%8F%E4%B8%8D%E5%9B%BA%E5%AE%9A%E7%9A%84%E...
  • yang295242361
  • yang295242361
  • 2017年11月03日 15:06
  • 163

大小不固定的图片和多行文字的垂直水平居中

原文转载自:http://www.zhangxinxu.com/study/200908/img-text-vertical-align.html 一、大小不固定,多行文字的垂直居中 ① 单行...
  • greenqingqingws
  • greenqingqingws
  • 2013年12月24日 11:22
  • 545
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义固定头文字的多行编辑框控件的实现分析
举报原因:
原因补充:

(最多只允许输入30个字)