android自定义TextView

Android控件中的TextView控件只有一个输入框,但是为了用于的操作方便我们应该实现一些功能:

1. 可以直接将内容删除的功能按钮

2. 可以记录用户以前输入的数据,同时能够将数据通过下拉显示,点击的时候实现输入

先上图:

下拉的图片没有做,所以和删除的图片使用同一个了,同志们可以直接在xml文件中更换就行了

分析:

肯定要使用自定义view来实现的,我们知道自定义view大概可以分为三类:自绘控件,组合控件,继承控件,我们这里是要进行增强的textView的功能,所以我这里使用的

是组合控件的方式来进行实现

既然使用组合控件,那么我们就来看看到底要使用什么控件来组合呢:

1.  其中一个必须是textView了

2. 下拉的那两个按钮是什么,当然是imageView了

3. 还有一个下拉列表,。。。。那就使用popwindow了

思路:

1. 如何实现直接删除用户的输入

使用addTextChangedListener监听textView内容的变化的时间根据内容的变化进行确定是否显示删除按钮,同时绑定删除按钮的点击事件

2.如何实现下拉显示用户输入过的数据,以及选中的时候实现输入

我们通过下拉按钮的点击进行确定popwindow窗口的显示,在popwindow的界面有一个listview,在这个listview的adpater中进行绑定条目的点击事件

那么我们在adapter中绑定的事件,如何控制整个控件的功能输入呢,这里就是用handler了,在创建adapter的时候将handler传递过去,

然后当点击事件发生的时候我们使用handler进行send消息就行了,当然我们在send消息的时候将当前点击的数据传递过来就行了

上代码:

1. 控件主体代码

/**
 * 自定义的控件,自带删除的按钮,下拉按钮
 * @author zcs
 * */
public class EditTextClearSelect extends FrameLayout {

	private EditText editText;  //显示的editText输入框
    private ImageButton clearImageButton;  //显示的用于进行删除editText中内容的按钮
    private ImageButton selectImageButton;  //显示的用于下拉editText中内容的按钮

    //PopupWindow对象  ,用于已下拉形式显示数据
    private PopupWindow selectPopupWindow= null;
    //自定义Adapter
    private ECS_OptionsAdapter optionsAdapter = null;
    //下拉框选项数据源
    private ArrayList<String> datas = new ArrayList<String>();
    //下拉框依附组件
    private LinearLayout parent;
    //展示所有下拉选项的ListView
    private ListView listView = null;
    //用来处理选中或者删除下拉项消息
    private Handler handler;  

	public EditTextClearSelect(Context context) {
		super(context);
	}
	//用于对自定义的控件进行初始化
	public EditTextClearSelect(Context context, AttributeSet attrs){
		super(context, attrs);
		//调用初始化自定义控件的方法
		init(context,attrs);
	}

	/**
     * 初始化下拉功能使用的组件
     */
    private void initWedget(Context context){
        //初始化Handler,用来处理消息
        handler = new Handler(){
        	public void handleMessage(Message msg) {
        		//当adapter中传递过来消息以后根据选中的id,将对应的值填写到EditText组件中
        		Bundle data = msg.getData();
                //选中下拉项,下拉框消失
                int selIndex = data.getInt("selIndex");
                editText.setText(datas.get(selIndex));
                dismiss();
        	}
        };

        //如果没有数据,则下拉菜单不显示
        if( !(datas.size() > 0) ){
        	selectImageButton.setVisibility(View.GONE);
        }

        //设置点击下拉箭头图片事件,点击弹出PopupWindow浮动下拉框
        selectImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	 //获取下拉框依附的组件宽度,然后重新设置popWindow的宽度
            	selectPopupWindow.setWidth(parent.getWidth());
                //显示PopupWindow窗口
                popupWindwShowing();
            }
        });  

        //初始化PopupWindow
        initPopuWindow(context);
    }  

    /**
     * 初始化PopupWindow
     */
    private void initPopuWindow(Context context){   

        //PopupWindow浮动下拉框布局
        View loginwindow = LayoutInflater.from(context).inflate(R.layout.wecs_options, null);
        listView = (ListView) loginwindow.findViewById(R.id.list);   

        //设置自定义Adapter
        optionsAdapter = new ECS_OptionsAdapter(context,handler,datas);
        listView.setAdapter(optionsAdapter);   

        selectPopupWindow = new PopupWindow(loginwindow, 0,LayoutParams.WRAP_CONTENT, true);
        selectPopupWindow.setOutsideTouchable(true);
        //实现当点击屏幕其他地方的时候将当前的pop关闭
        selectPopupWindow.setBackgroundDrawable(new BitmapDrawable());
    }  

    /**
     * 显示PopupWindow窗口
     * @param popupwindow
     */
    public void popupWindwShowing() {
       //将pop窗口在自定义控件的底部显示
       selectPopupWindow.showAsDropDown(parent);
    }   

    /**
     * PopupWindow消失
     */
    public void dismiss(){
        selectPopupWindow.dismiss();
    }  

	 /**
     * 初始化,包括增加删除按钮,下拉按钮
     */
    public void init(Context context,AttributeSet attrs){
    	//获取自定义控件的界面,相当于当前的自定义View就使用的View
        View view = LayoutInflater.from(context).inflate(R.layout.weight_edit_clear_select, this, true);

        parent =  (LinearLayout) view.findViewById(R.id.parent);  //当前的自定义控件
        editText = (EditText) view.findViewById(R.id.et);  //输入框
        clearImageButton = (ImageButton) view.findViewById(R.id.clear_ib); //删除按钮
        selectImageButton = (ImageButton) view.findViewById(R.id.select_id); //下拉按钮

        //当点击删除按钮的会后将输入框数据清空
        clearImageButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                editText.setText("");
            }
        });
        //根据输入框中的内容,决定是否显示删除按钮
        editText.addTextChangedListener(new TextWatcher(){
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.length() > 0) {
                	//输入框有内容,显示按钮
                	editText.setSelection(s.length());
                    clearImageButton.setVisibility(View.VISIBLE);
                } else {
                    clearImageButton.setVisibility(View.GONE);
                }
            }
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
            }
            @Override
            public void afterTextChanged(Editable s) {
            }

        });

        //初始化pop组件,设置下拉按钮的功能
        initWedget(context);  

        //将属性值设置到控件中
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.EditTextClearSelect);
        //输入框的默认的显示文本
        CharSequence text = a.getText(R.styleable.EditTextClearSelect_textECS);
        CharSequence hint = a.getText(R.styleable.EditTextClearSelect_hintECS);
        CharSequence parent_width  = a.getText(R.styleable.EditTextClearSelect_layout_width);

        if (text!=null&&!"".equals(text.toString().trim())) {
            editText.setText(text);
            //设置光标位置
            editText.setSelection(text.length());
            this.clearImageButton.setVisibility(View.VISIBLE);
        }
        if (hint!=null&&!"".equals(hint.toString().trim())) {
            editText.setHint(hint);
        }
        if(parent_width!=null && !"".equals(parent_width.toString().trim()) ){
        	//设置当前控件的宽度,为屏幕的百度比有参数进行设置
        	LayoutParams parent_lp = (LayoutParams) parent.getLayoutParams();
        	parent_lp.width = (int) (AppUtil.getScreenDispaly(context)[0] * ( (Double)(Double.parseDouble(parent_width.toString()) / 100) ));
        	Log.i("控件宽度", parent_lp.width+"");
        	parent.setLayoutParams(parent_lp);
        }
        a.recycle();
    }

    /**
     * 获得输入的值
     * @return
     */
    public String getText(){
        return this.editText.getText().toString();
    }

    /**
     * 设置值
     * @param text
     */
    public void setText(String text){
        this.editText.setText(text);
    }

    /**
     * 设置默认值
     * @param hint
     */
    public void setHint(String hint){
        this.editText.setHint(hint);
    }

    /**
     * 获得输入框控件
     * @return
     */
    public EditText getEditText(){
        return this.editText;
    }

    /**
     * 获得消除按钮
     * @return
     */
    public ImageButton getClearImageButton(){
        return this.clearImageButton;
    }

    //设置下拉列表中的选项值
    public void setOptionsValue(ArrayList<String> inDatas){
    	datas.clear();
    	if( (inDatas ==null) || !(inDatas.size() > 0) ){
    		selectImageButton.setVisibility(View.GONE);
    	}else{
    		selectImageButton.setVisibility(View.VISIBLE);
    		datas.addAll(inDatas);
    	}
    	optionsAdapter.notifyDataSetChanged();
    }

2. popwindow里面listview的适配器

public class ECS_OptionsAdapter extends BaseAdapter {

	  	private ArrayList<String> list = new ArrayList<String>();
	    private Context context = null;
	    //传递过来的hanler,用于进行通知操作(这里是通知自定义的view要继续修改editText中的数据)
	    private Handler handler;

	    public ECS_OptionsAdapter(Context context,Handler handler,ArrayList<String> list){
	        this.context = context;
	        this.handler = handler;
	        this.list = list;
	    }  

	    @Override
	    public int getCount() {
	        return list.size();
	    }  

	    @Override
	    public Object getItem(int position) {
	        return list.get(position);
	    }  

	    @Override
	    public long getItemId(int position) {
	        return position;
	    }  

	    @Override
	    public View getView(final int position, View convertView, ViewGroup parent) {  

	    	ViewHolder holder = null;
	        if (convertView == null) {
	            holder = new ViewHolder();
	            //下拉项布局
	            convertView = LayoutInflater.from(context).inflate(R.layout.wecs_option_item, null);
	            holder.textView = (TextView) convertView.findViewById(R.id.item_text);
	            convertView.setTag(holder);
	        } else {
	            holder = (ViewHolder) convertView.getTag();
	        }
	        holder.textView.setText(list.get(position));
	        //为下拉框选项文字部分设置事件,最终效果是点击将其文字填充到文本框
	        holder.textView.setOnClickListener(new View.OnClickListener() {
	            @Override
	            public void onClick(View v) {
	            	//当点击的时候进行发送消息,通知组件进行修改数据
	                Message msg = new Message();
	                //设置要传递的数据
	                Bundle data = new Bundle();
	                //设置选中索引
	                data.putInt("selIndex", position);
	                msg.setData(data);
	                //发出消息
	                handler.sendMessage(msg);
	            }
	        });
	        return convertView;
	    }  

	}  

	class ViewHolder {
	    TextView textView;
	}   

3. 使用

	private EditTextClearSelect etcs;

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

	//初始化
	private void init(){
		String selectDatas = "admin,login,user";
		etcs = (EditTextClearSelect) findViewById(R.id.username_edit);
		//为控件设置下拉的数据
		etcs.setOptionsValue( new ArrayList<String>(Arrays.asList(selectDatas.split(","))) );

	}

ok搞定

源码下载

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

时间: 07-17

android自定义TextView的相关文章

Android 自定义TextView实现文本内容自动调整字体大小以适应TextView的大小

最近做通讯录小屏机 联系人姓名显示--长度超过边界字体变小 /**   * 自定义TextView,文本内容自动调整字体大小以适应TextView的大小   * @author yzp   */   public class AutoFitTextView extends TextView {       private Paint mTextPaint;       private float mTextSize;          public AutoFitTextView(Context

Android开发学习笔记-自定义TextView属性模版

如果项目中有很多个控件使用的是同一种样式,则为了方便,可以将样式设置到系统中去,这样使用的时候会方便很多. 下面是自定义样式模版的方法. 1.在style.xml文件中添加自己要设置的样式内容 <resources> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devic

Android自定义视图(一):带下划线的TextView

package com.francis.underlinetextviewtest; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import an

Android学习笔记---自定义TextView实现阴影效果

直接上代码 SGTextView.java 1 package com.example.tv.view; 2 3 import android.content.Context; 4 import android.graphics.Canvas; 5 import android.graphics.Color; 6 import android.graphics.LinearGradient; 7 import android.graphics.Paint; 8 import android.gr

Android自定义“图片+文字”控件四种实现方法之 二--------个人最推荐的一种

http://blog.csdn.net/yanzi1225627/article/details/8633872 第二种方法也要新建一个图片+文字的xml布局文件,然后写一个类继承自LinearLayout.在主程序里实例化并设置相应参数.这种方式也是我最推荐的一种. 第一部分:myimgbtn_layout.xml [html] view plaincopyprint? <?xml version="1.0" encoding="utf-8"?> &

Android 自定义ProgressDialog示例实现

闲来无事,总结了两个自定义的ProgressDialog,大家可以参考下,根据自己需要进行选择修改: 实现效果: 示例1: 示例2: 代码如下: MainActivity:只是两个Button点击事件 package com.customwaitdialog; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import

Android自定义可循环的滚动选择器CycleWheelView 替代TimePicker/NumberPicker/WheelView

最近碰到个项目要使用到滚动选择器,原生的NumberPicker可定制性太差,不大符合UI要求. 网上开源的WheelView是用ScrollView写的,不能循环滚动,而且当数据量很大时要加载的Item太多,性能非常低. 然后,还是自己写一个比较靠谱,用的是ListView实现的.写完自己体验了一下,性能不错,再大的数据也不怕了. 感觉不错,重新封装了一下,提供了一些接口可以直接按照自己的需求定制,调用方法在MainActivity中. 不多说了,直接上代码: CycleWheelView.j

Android 自定义Gallery浏览图片

之前写的<Android ImageSwitcher和Gallery的使用>一文中提到我在教室一下午为实现那个效果找各种资料.期间在网上找了一个个人觉得比较不错的效果,现在贴图上来: 其实这个效果使用的知识点就是图像的获取.创建.缩放.旋转.Matrix类.Canvas类等,另外就是自定义的Gallery控件. 相信大家都期待马上上代码了吧,嘻嘻.(注释比较多,相信大家都能看懂.) main.xml: <?xml version="1.0" encoding=&quo

自定义TextView实现微信动态的全文和收起功能

本示例实现微信朋友圈发布动态后呈现的全文和收起功能. 1,自定义TextView的布局文件——my_text_view.xml 1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 自定义TextView,实现自动的添加全文和收起功能 --> 3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi