安卓自定义EditText控件,在短信或邮件群发界面,添加联系人的效果

来源:互联网 发布:php项目技术文档 编辑:程序博客网 时间:2024/06/01 10:17

安卓自定义EditText控件,在短信或邮件群发界面,添加联系人的效果。

最近在做一个邮件客户端,在写邮件界面需要添加联系人功能,要实现图中给的那种效果。

这种效果在手机短信群发添加联系人也有,读源码累觉不爱了,网上也没找到合适的资料了,于是就自己动手整了整,这里把代码贴出来,大家一起交流学习,有bug欢迎指出。。

思路很简单,大致就是自定义控件中的组合思想,用代码更改布局内容。

自定义类CustomEditText继承一个LinearLayout,设置线性方向为竖直方向,默认情况是该线性布局中有一个子View,是一个水平的LinearLayout,这里面包含一个EditText,

对EditText设置焦点改变监听,在失去焦点的时候,就将原本输入在输入框中的文字以逗号分隔转换为若干个TextView,放到EditText前面,水平排列。每次排列完成后需计算横向剩余空间,以便于后续添加的文字出现在下一行。删除文字原理基本一样,点击软键盘删除按钮就可以删除输入好的文字。。

好了,思路大概这样,下面贴代码:

package com.example.customedittext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Editable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;


public class CustomEditText extends LinearLayout {


private LinearLayout ll_contact_container;
private EditText et_input_contact;
private int screenWidth;
private int tv_width;
private OnFocusChangeListener ofcl;


@SuppressLint("NewApi")
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOrientation(LinearLayout.VERTICAL);
ll_contact_container = (LinearLayout) View.inflate(context,
R.layout.custom_edittext, null);
et_input_contact = (EditText) ll_contact_container
.findViewById(R.id.et_input_contact);
getScreenSize();
}


private void getScreenSize() {
DisplayMetrics metric = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay()
.getMetrics(metric);
screenWidth = metric.widthPixels; 
}


public CustomEditText(Context context) {
super(context);
}


@Override
protected void onFinishInflate() {
super.onFinishInflate();


addView(ll_contact_container);
et_input_contact.setOnFocusChangeListener(new OnFocusChangeListener() {


@Override
public void onFocusChange(View v, boolean hasFocus) {
ofcl.onFocusChange((LinearLayout)(v.getParent().getParent()), hasFocus);
if (!hasFocus) {
String contacts = et_input_contact.getText().toString();
String[] arrContact = contacts.split(",");
LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_VERTICAL;
LayoutParams params1 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_VERTICAL;
for(int i= 0; i<arrContact.length;i++){
String str = arrContact[i];
if(str.trim().length() == 0)
continue;
tv_width = (int) getTextWidth(str);

TextView tv = new TextView(getContext());
tv.setGravity(Gravity.CENTER);
tv.setBackgroundResource(R.drawable.mm_title_btn_pressed);
tv.setText(str.trim());
//空间不够,下一行再继续布局
if (et_input_contact.getWidth() <= screenWidth/5 + tv_width) {
((LinearLayout) et_input_contact.getParent())
.removeView(et_input_contact);
LinearLayout ll = new LinearLayout(getContext());
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.addView(tv, params);
ll.addView(et_input_contact);
addView(ll, params1);
} else {
((LinearLayout) et_input_contact.getParent()).addView(tv,((LinearLayout) et_input_contact.getParent()).getChildCount()-1, params);
}
}
et_input_contact.setText("");


}
}
});
et_input_contact.setOnKeyListener(new OnKeyListener() {

private LinearLayout parent;


@SuppressLint("NewApi")
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {

if(keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN){
if(et_input_contact.getText().toString().isEmpty()){
int childCount = getChildCount();
parent = (LinearLayout) getChildAt(childCount-1);
if(parent.getChildCount()<=1){
if(childCount == 1){
return false;
}else {
parent.removeView(et_input_contact);
removeView(parent);
parent = (LinearLayout) getChildAt(childCount-2);
parent.addView(et_input_contact);
}
}
parent.removeViewAt(parent.getChildCount()-2);
parent.setFocusable(true);
}else 
return false;
}
return false;
}
});
}
/**
* 计算文本的宽度,便于布局
* @param str
* @return
*/
public static float getTextWidth(String str){
Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
mTextPaint.setColor(Color.WHITE);  
float textWidth = mTextPaint.measureText(str);
return textWidth;
}

public void setOnFocusChangeListener(OnFocusChangeListener ofcl){
this.ofcl = ofcl;
}
public Editable getText(){
return et_input_contact.getText();
}

public void setText(CharSequence text){
et_input_contact.setText(text);
et_input_contact.setSelection(text.length());
}

/**
* 获取所有输入进去的文本,中间用逗号隔开
* @return
*/
public String getAllText(){
StringBuffer sb = new StringBuffer();
for (int i = 0; i < getChildCount(); i++) {
LinearLayout parent = (LinearLayout) getChildAt(i);
for (int j = 0; j < parent.getChildCount(); j++) {
View v = parent.getChildAt(j);
if(v instanceof TextView){
TextView et = (TextView) v;
sb.append(et.getText().toString()+",");
}
}
}
String str = sb.toString().substring(0,sb.length()-1);
return str;
}
}


xml布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_contact_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <EditText
        android:id="@+id/et_input_contact"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" />

</LinearLayout>

里面用到了一个背景图片,见附件

这种方式当添加数目过多会导致显示错乱的问题,下面一种方式避免该问题,但对于不同的分辨率可能需要自适配相应位置的大小;

贴代码:

package com.example.mymail.view;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;


public class CustomEditText2 extends EditText {

private Context context;
private int height;
private int times;
private boolean isAllChange;


public CustomEditText2(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public CustomEditText2(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setLineSpacing(2, 1);
}


public CustomEditText2(Context context) {
super(context);
}

@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if(!focused){
changeState();
}else{
if(isAllChange){
append(",");
isAllChange = false;
}
}
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(times == 0){
height = getHeight();
height = height<100?100:height;//这个还是根据具体的屏幕密度自行适配
Log.i("NNN", height+"高度");
}
times++;
}


public void changeState() {
String text = getText().toString().trim();
if(!TextUtils.isEmpty(text)){
String[] arrText = text.split(",");
setText("");
for (int i = 0; i < arrText.length; i++) {
if(TextUtils.isEmpty(arrText[i]))
continue;
Drawable drawable = getDrawable(arrText[i]);  
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  
SpannableString spannable = new SpannableString(arrText[i]);  
ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);  
spannable.setSpan(span, 0,arrText[i].length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);    
append(spannable);
if(i != arrText.length-1)
append(",");
}
isAllChange = true;
}
}

public Drawable getDrawable(String str){

Drawable drawable = null;
Config config = Config.ARGB_8888;
int textWidth = getTextWidth(str);
Bitmap textBitmap = Bitmap.createBitmap(3*textWidth, height,config );
Canvas canvas = new Canvas(textBitmap);
Paint paint = new Paint();
RectF rect = new RectF(0, 0, 3*textWidth, height);
paint.setColor(Color.GRAY);
canvas.drawRoundRect(rect , 20, 20, paint);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setTextSize(62);
canvas.drawText(str, textWidth/4,28+height/2, paint);

canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
drawable = new BitmapDrawable(textBitmap);
return drawable;
}
public int getTextWidth(String str){
Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
mTextPaint.setColor(Color.WHITE);  
float textWidth = mTextPaint.measureText(str);
return sp2px(context, textWidth);
}


public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}




1 0