码迷,mamicode.com
首页 > 其他好文 > 详细

一个类似MIUI中原生短信编辑功能

时间:2016-04-22 12:06:41      阅读:360      评论:0      收藏:0      [点我收藏+]

标签:

首先描述下需求:

1、新增短信时,进来收件人是为空,显示一行文字(提醒)

2、从通讯录选择联系人后,回到短信编辑界面,收件栏显示一行,内容为“收件人:XXX、XXX、XXX、XXX.....”

3、当点击收件栏时,收件栏内容变化,变成可删除,最多显示四行,多余四行有上下滑动轮,不足四行,是几行显示几行

4、填写短信内容,即时计算短信条算,并有文本提示

下面是实现后效果图

技术分享

技术分享

技术分享

技术分享

下面终于到了代码实现块了,主要写一些主要用到的类,其他不太重要的就忽略写,读者自行补全。

首先是短信收件人是一个自定义的流布局,这个流布局不是本人写的,只是在上面加了些修改来满足自己的业务需求。

TagFlowLayout类

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.zhaonongzi.wnshhseller.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 自定义tag 页面的整体页面
 * 
 * 实现绑定数据,事件处理
 * @author admin
 *
 */
public class TagFlowLayout extends FlowLayout implements
		TagAdapter.OnDataChangedListener {
	
	private TagAdapter mTagAdapter;
	
	private boolean mAutoSelectEffect = true;
	private int mSelectedMax = -1;// -1为不限制数量
	private static final String TAG = "TagFlowLayout";
	private MotionEvent mMotionEvent;

	private Set<Integer> mSelectedView = new HashSet<Integer>();

	public TagFlowLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		TypedArray ta = context.obtainStyledAttributes(attrs,
				R.styleable.TagFlowLayout);
		mAutoSelectEffect = ta.getBoolean(R.styleable.TagFlowLayout_auto_select_effect, true);
		mSelectedMax = ta.getInt(R.styleable.TagFlowLayout_max_select, -1);
		ta.recycle();

		if (mAutoSelectEffect) {
			setClickable(true);
		}
	}

	public TagFlowLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public TagFlowLayout(Context context) {
		this(context, null);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int cCount = getChildCount();

		for (int i = 0; i < cCount; i++) {
			TagView tagView = (TagView) getChildAt(i);
			if (tagView.getVisibility() == View.GONE)
				continue;
			if (tagView.getTagView().getVisibility() == View.GONE) {
				tagView.setVisibility(View.GONE);
			}
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	public interface OnSelectListener {
		void onSelected(Set<Integer> selectPosSet);
	}

	private OnSelectListener mOnSelectListener;

	public void setOnSelectListener(OnSelectListener onSelectListener) {
		mOnSelectListener = onSelectListener;
		if (mOnSelectListener != null)
			setClickable(true);
	}

	public interface OnTagClickListener {
		boolean onTagClick(View view, int position, FlowLayout parent);
	}

	private OnTagClickListener mOnTagClickListener;

	public void setOnTagClickListener(OnTagClickListener onTagClickListener) {
		mOnTagClickListener = onTagClickListener;
		if (onTagClickListener != null)
			setClickable(true);
	}

	public void setAdapter(TagAdapter adapter) {
		// if (mTagAdapter == adapter)
		// return;
		mTagAdapter = adapter;
		mTagAdapter.setOnDataChangedListener(this);
		changeAdapter();

	}

	private void changeAdapter() {
		removeAllViews();
		TagAdapter adapter = mTagAdapter;
		TagView tagViewContainer = null;
		HashSet preCheckedList = mTagAdapter.getPreCheckedList();
		for (int i = 0; i < adapter.getCount(); i++) {
			View tagView = adapter.getView(this, i, adapter.getItem(i));

			tagViewContainer = new TagView(getContext());
			// ViewGroup.MarginLayoutParams clp = (ViewGroup.MarginLayoutParams)
			// tagView.getLayoutParams();
			// ViewGroup.MarginLayoutParams lp = new
			// ViewGroup.MarginLayoutParams(clp);
			// lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
			// lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
			// lp.topMargin = clp.topMargin;
			// lp.bottomMargin = clp.bottomMargin;
			// lp.leftMargin = clp.leftMargin;
			// lp.rightMargin = clp.rightMargin;
			tagView.setDuplicateParentStateEnabled(true);
			tagViewContainer.setLayoutParams(tagView.getLayoutParams());
			tagViewContainer.addView(tagView);
			addView(tagViewContainer);

			if (preCheckedList.contains(i)) {
				tagViewContainer.setChecked(true);
			}
		}
		mSelectedView.addAll(preCheckedList);

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_UP) {
			mMotionEvent = MotionEvent.obtain(event);
		}
		return super.onTouchEvent(event);
	}

	@Override
	public boolean performClick() {
		if (mMotionEvent == null)
			return super.performClick();

		int x = (int) mMotionEvent.getX();
		int y = (int) mMotionEvent.getY();
		mMotionEvent = null;

		TagView child = findChild(x, y);
		int pos = findPosByView(child);
		if (child != null) {
			doSelect(child, pos);
			if (mOnTagClickListener != null) {
				return mOnTagClickListener.onTagClick(child.getTagView(), pos,
						this);
			}
		}
		return super.performClick();
	}

	public void setMaxSelectCount(int count) {
		if (mSelectedView.size() > count) {
			Log.w(TAG, "you has already select more than " + count
					+ " views , so it will be clear .");
			mSelectedView.clear();
		}
		mSelectedMax = count;
	}

	public Set<Integer> getSelectedList() {
		return new HashSet<Integer>(mSelectedView);
	}

	private void doSelect(TagView child, int position) {
		if (mAutoSelectEffect) {
			if (!child.isChecked()) {
				// 处理max_select=1的情况
				if (mSelectedMax == 1 && mSelectedView.size() == 1) {
					Iterator<Integer> iterator = mSelectedView.iterator();
					Integer preIndex = iterator.next();
					TagView pre = (TagView) getChildAt(preIndex);
					pre.setChecked(false);
					child.setChecked(true);
					mSelectedView.remove(preIndex);
					mSelectedView.add(position);
				} else {
					if (mSelectedMax > 0
							&& mSelectedView.size() >= mSelectedMax)
						return;
					child.setChecked(true);
					mSelectedView.add(position);
				}
			} else {
				child.setChecked(false);
				mSelectedView.remove(position);
			}
			if (mOnSelectListener != null) {
				mOnSelectListener
						.onSelected(new HashSet<Integer>(mSelectedView));
			}
		}
	}

	private static final String KEY_CHOOSE_POS = "key_choose_pos";
	private static final String KEY_DEFAULT = "key_default";

	@Override
	protected Parcelable onSaveInstanceState() {
		Bundle bundle = new Bundle();
		bundle.putParcelable(KEY_DEFAULT, super.onSaveInstanceState());

		String selectPos = "";
		if (mSelectedView.size() > 0) {
			for (int key : mSelectedView) {
				selectPos += key + "|";
			}
			selectPos = selectPos.substring(0, selectPos.length() - 1);
		}
		bundle.putString(KEY_CHOOSE_POS, selectPos);
		return bundle;
	}

	@Override
	protected void onRestoreInstanceState(Parcelable state) {
		if (state instanceof Bundle) {
			Bundle bundle = (Bundle) state;
			String mSelectPos = bundle.getString(KEY_CHOOSE_POS);
			if (!TextUtils.isEmpty(mSelectPos)) {
				String[] split = mSelectPos.split("\\|");
				for (String pos : split) {
					int index = Integer.parseInt(pos);
					mSelectedView.add(index);

					TagView tagView = (TagView) getChildAt(index);
					tagView.setChecked(true);
				}

			}
			super.onRestoreInstanceState(bundle.getParcelable(KEY_DEFAULT));
			return;
		}
		super.onRestoreInstanceState(state);
	}

	private int findPosByView(View child) {
		final int cCount = getChildCount();
		for (int i = 0; i < cCount; i++) {
			View v = getChildAt(i);
			if (v == child)
				return i;
		}
		return -1;
	}

	private TagView findChild(int x, int y) {
		final int cCount = getChildCount();
		for (int i = 0; i < cCount; i++) {
			TagView v = (TagView) getChildAt(i);
			if (v.getVisibility() == View.GONE)
				continue;
			Rect outRect = new Rect();
			v.getHitRect(outRect);
			if (outRect.contains(x, y)) {
				return v;
			}
		}
		return null;
	}

	@Override
	public void onChanged() {
		changeAdapter();
	}

}
FlowLayout类

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import com.zhaonongzi.wnshhseller.activity.customer.AddMessageActivity;
import com.zhaonongzi.wnshhseller.utils.GlobalMemoryCache;

/**
 * Tag 页面布局基类 主要实现测量子view,绘制view
 * 
 * @author admin
 *
 */
public class FlowLayout extends ViewGroup {

	protected List<List<View>> mAllViews = new ArrayList<List<View>>();
	protected List<Integer> mLineHeight = new ArrayList<Integer>();
	private int lines, counts, lastItem;// 限制显示多少行
	private boolean isShow;// 是否需要在最后显示省略号
	private LastListerInterface lastListerInterface = null;
	private int ihegth;

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

	public FlowLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public FlowLayout(Context context) {
		this(context, null);
	}

	public void setLines(int line) {
		this.lines = line;
	}

	public int getLastItem() {
		Log.e("lastItem", lastItem + "");
		return lastItem;
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
		int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
		int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
		int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

		// wrap_content
		int width = 0;
		int height = 0;

		int lineWidth = 0;
		int lineHeight = 0;
		int childHeight1 = 0;
		int cCount = getChildCount();

		for (int i = 0; i < cCount; i++) {
			View child = getChildAt(i);
			if (child.getVisibility() == View.GONE) {
				if (i == cCount - 1) {
					width = Math.max(lineWidth, width);
					height += lineHeight;
				}
				continue;
			}
			measureChild(child, widthMeasureSpec, heightMeasureSpec);
			MarginLayoutParams lp = (MarginLayoutParams) child
					.getLayoutParams();

			int childWidth = child.getMeasuredWidth() + lp.leftMargin
					+ lp.rightMargin;
			int childHeight = child.getMeasuredHeight() + lp.topMargin
					+ lp.bottomMargin;
			childHeight1 = childHeight;
			if (lineWidth + childWidth > sizeWidth - getPaddingLeft()
					- getPaddingRight()) {
				width = Math.max(width, lineWidth);
				lineWidth = childWidth;
				height += lineHeight;
				lineHeight = childHeight;
			} else {
				lineWidth += childWidth;
				lineHeight = Math.max(lineHeight, childHeight);
			}
			if (i == cCount - 1) {
				width = Math.max(lineWidth, width);
				height += lineHeight;

			}
			if (lastItem == 0 && height == (3 * childHeight)) {
				lastItem = i - 1;
				if (lastItem > 0 && null != lastListerInterface) {
					lastListerInterface.getLastItem(lastItem);
				}
			}

			// Log.e("lastItem", lastItem + "");
		}
		height = (height <= (lines * childHeight1)) ? height
				: (lines * childHeight1);
		ihegth = height;
		AddMessageActivity.iheight = childHeight1;

		setMeasuredDimension(
				//
				modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width
						+ getPaddingLeft() + getPaddingRight(),
				modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height
						+ getPaddingTop() + getPaddingBottom()//
		);

	}

	public int getHeigth() {
		return ihegth;
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		mAllViews.clear();
		mLineHeight.clear();

		int width = getWidth();

		int lineWidth = 0;
		int lineHeight = 0;

		List<View> lineViews = new ArrayList<View>();

		int cCount = getChildCount();

		for (int i = 0; i < cCount; i++) {
			View child = getChildAt(i);
			if (child.getVisibility() == View.GONE)
				continue;
			MarginLayoutParams lp = (MarginLayoutParams) child
					.getLayoutParams();

			int childWidth = child.getMeasuredWidth();
			int childHeight = child.getMeasuredHeight();

			if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width
					- getPaddingLeft() - getPaddingRight()) {
				if (mAllViews.size() < lines) {
					mLineHeight.add(lineHeight);
					mAllViews.add(lineViews);

					lineWidth = 0;
					lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
					lineViews = new ArrayList<View>();
				}
			}
			lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
			lineHeight = Math.max(lineHeight, childHeight + lp.topMargin
					+ lp.bottomMargin);
			lineViews.add(child);

		}
		mLineHeight.add(lineHeight);
		mAllViews.add(lineViews);

		int left = getPaddingLeft();
		int top = getPaddingTop();

		int lineNum = mAllViews.size();
		AddMessageActivity.ilines = lineNum;
		if (lines > 0) {
			lineNum = lineNum > lines ? lines : lineNum;
		}
		for (int i = 0; i < lineNum; i++) {
			lineViews = mAllViews.get(i);
			lineHeight = mLineHeight.get(i);

			for (int j = 0; j < lineViews.size(); j++) {
				View child = lineViews.get(j);
				if (child.getVisibility() == View.GONE) {
					continue;
				}

				MarginLayoutParams lp = (MarginLayoutParams) child
						.getLayoutParams();

				int lc = left + lp.leftMargin;
				int tc = top + lp.topMargin;
				int rc = lc + child.getMeasuredWidth();
				int bc = tc + child.getMeasuredHeight();

				child.layout(lc, tc, rc, bc);

				left += child.getMeasuredWidth() + lp.leftMargin
						+ lp.rightMargin;
			}
			left = getPaddingLeft();
			top += lineHeight;
		}
		if ((boolean) GlobalMemoryCache.getInstance().get("addMessage")) {
			AddMessageActivity.tfl_add_message_labellay
					.setVisibility(View.GONE);
			AddMessageActivity.scr_add_message_labellay
					.setVisibility(View.GONE);
		}
	}

	@Override
	public LayoutParams generateLayoutParams(AttributeSet attrs) {
		return new MarginLayoutParams(getContext(), attrs);
	}

	@Override
	protected LayoutParams generateDefaultLayoutParams() {
		return new MarginLayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
	}

	@Override
	protected LayoutParams generateLayoutParams(LayoutParams p) {
		return new MarginLayoutParams(p);
	}

	public interface LastListerInterface {
		public void getLastItem(int lastItem);
	}

	public void setLastListener(LastListerInterface lastListerInterface) {
		this.lastListerInterface = lastListerInterface;
	}
}

TagAdapter类

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

import android.view.View;

/**
 * tag 布局适配器
 * @author admin
 *
 * @param <T>
 */
public abstract class TagAdapter<T>
{
    private List<T> mTagDatas;
    private OnDataChangedListener mOnDataChangedListener;
    private HashSet<Integer> mCheckedPosList = new HashSet<Integer>();

    public TagAdapter(List<T> datas)
    {
        mTagDatas = datas;
    }

    public TagAdapter(T[] datas)
    {
        mTagDatas = new ArrayList<T>(Arrays.asList(datas));
    }

	static interface OnDataChangedListener
    {
        void onChanged();
    }

    void setOnDataChangedListener(OnDataChangedListener listener)
    {
        mOnDataChangedListener = listener;
    }

    public void setSelectedList(int... pos)
    {
        for (int i = 0; i < pos.length; i++)
            mCheckedPosList.add(pos[i]);
        notifyDataChanged();
    }

    HashSet<Integer> getPreCheckedList()
    {
        return mCheckedPosList;
    }


    public int getCount()
    {
        return mTagDatas == null ? 0 : mTagDatas.size();
    }

    public void notifyDataChanged()
    {
        mOnDataChangedListener.onChanged();
    }

    public T getItem(int position)
    {
        return mTagDatas.get(position);
    }

    public abstract View getView(FlowLayout parent, int position, T t);

}
TagView类

import android.content.Context;
import android.view.View;
import android.widget.Checkable;
import android.widget.FrameLayout;

/**
 * 单个Tag 的自定义布局
 * 
 * @author admin
 *
 */
public class TagView extends FrameLayout implements Checkable
{
    private boolean isChecked;
    private static final int[] CHECK_STATE = new int[]{android.R.attr.state_checked};

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

    public View getTagView()
    {
        return getChildAt(0);
    }

    @Override
    public int[] onCreateDrawableState(int extraSpace)
    {
        int[] states = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked())
        {
            mergeDrawableStates(states, CHECK_STATE);
        }
        return states;
    }


    /**
     * Change the checked state of the view
     *
     * @param checked The new checked state
     */
    @Override
    public void setChecked(boolean checked)
    {
        if (this.isChecked != checked)
        {
            this.isChecked = checked;
            refreshDrawableState();
        }
    }

    /**
     * @return The current checked state of the view
     */
    @Override
    public boolean isChecked()
    {
        return isChecked;
    }

    /**
     * Change the checked state of the view to the inverse of its current state
     */
    @Override
    public void toggle()
    {
        setChecked(!isChecked);
    }


}


上面是用到TagFlowLayout这个自定义控件需要的类。

下面给出短信编辑的布局xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tag="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f5f5f5"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >

    <com.zhaonongzi.wnshhseller.view.TopBar
        android:id="@+id/message_mass_top"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|top" />

    <LinearLayout
        android:id="@+id/linear_edit_message_add_receiver"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/message_mass_top"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/txt_add_message_customer_declare"
            android:layout_width="wrap_content"
            android:layout_height="45dp"
            android:gravity="center"
            android:paddingLeft="15dp"
            android:text="收信人"
            android:textColor="@color/black"
            android:visibility="gone" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1" >

            <TextView
                android:id="@+id/txt_add_message_add_customer_btn"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:gravity="left|center"
                android:paddingLeft="15dp"
                android:singleLine="true"
                android:text="点击添加收信客户"
                android:textColor="@color/gray" />

            <ScrollView
                android:id="@+id/scr_add_message_labellay"
                android:layout_width="fill_parent"
                android:layout_height="90dp"
                android:visibility="gone" >

                <com.zhaonongzi.wnshhseller.view.flowlayout.TagFlowLayout
                    android:id="@+id/tfl_add_message_labellay"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/ac_include"
                    android:layout_marginTop="4dp"
                    android:layout_weight="1"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"
                    android:visibility="gone"
                    tag:max_select="-1" />
            </ScrollView>
        </FrameLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="10dp"
            android:paddingRight="15dp" 
            android:layout_gravity="center"
            android:paddingTop="5dp"
            android:paddingBottom="5dp">

            <ImageView
                android:id="@+id/img_add_message_add_customer"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_gravity="center"
                android:src="@drawable/username" />

            <TextView
                android:id="@+id/txt_add_message_customer_counts"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:textColor="@color/black"
                android:text="0" />
        </LinearLayout>
    </LinearLayout>

    <View
        android:id="@+id/line_1"
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:layout_below="@+id/linear_edit_message_add_receiver"
        android:layout_marginBottom="2dp"
        android:layout_marginTop="2dp"
        android:background="#A0A0A0" />

    <EditText
        android:id="@+id/edittext_add_message_add_content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/line_1"
        android:background="@drawable/select_white_bg"
        android:minHeight="80dp"
        android:padding="15dp"
        android:maxLength="650"
        android:scrollbars="vertical"
        android:maxHeight="200dp"
        android:textColor="@color/black" />

    <TextView
        android:id="@+id/txt_add_message_add_content_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/edittext_add_message_add_content"
        android:layout_toLeftOf="@+id/txt_add_message_add_content_word"
        android:paddingTop="10dp"
        android:text="0"
        android:textColor="@color/orange_title" />

    <TextView
        android:id="@+id/txt_add_message_add_content_word"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/edittext_add_message_add_content"
        android:paddingRight="15dp"
        android:paddingTop="10dp"
        android:text=""
        android:textColor="@color/gray" />

</RelativeLayout>
实例化一个收件人adapter

adapter = new TagAdapter<String>(meBean.getReceiver()) {
					final LayoutInflater mInflater = LayoutInflater
							.from(AddMessageActivity.this);

					@SuppressLint("NewApi")
					@Override
					public View getView(FlowLayout parent, final int position,
							final String s) {
						final TextView tv = (TextView) mInflater.inflate(
								R.layout.item_label_tv_medium,
								tfl_add_message_labellay, false);
						SpannableStringBuilder sp1 = new SpannableStringBuilder(
								s);// 姓名
						SpannableStringBuilder sp2 = new SpannableStringBuilder(
								"x");// 删除
						sp1.setSpan(
								new ForegroundColorSpan(Color
										.rgb(102, 102, 102)), 0, s.length(),
								Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
						sp2.setSpan(
								new ForegroundColorSpan(Color.rgb(255, 0, 0)),
								0, "X".length(),
								Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

						SpannableStringBuilder sp = new SpannableStringBuilder();//
						sp.append(sp1).append(sp2);

						if (position == 0) {
							tv.setText(s);
							tv.setTextColor(android.graphics.Color
									.parseColor("#666666"));
						} else {
							tv.setText(sp);
							tv.setTextSize(16);
							tv.setBackgroundResource(R.drawable.selector_contacts_gray_btn);
						}
						tv.setOnClickListener(new View.OnClickListener() {

							@Override
							public void onClick(View v) {
								// 跳页面带值
								if (position != 0) {
									meBean.getReceiver().remove(position);
									handler.sendEmptyMessage(1);
								}
							}
						});
						return tv;
					}
				};

计算短信条数方法:

/**
	 * 计算短信内容条算
	 * 
	 * @param wordNum
	 * @return
	 */
	public int getSMSCounts(int wordNum) {
		int counts;
		if (wordNum <= 63)
			counts = 1;
		else if (wordNum <= 127)
			counts = 2;
		else {
			counts = (wordNum - 127) % 67 == 0 ? ((wordNum - 127) / 67 + 2)
					: ((wordNum + 7) / 67 + 1);
		}
		return counts;
	}

监听编辑文本框来提示短信条数和字数:

edittext_edit_message_add_content
				.addTextChangedListener(new TextWatcher() {

					@Override
					public void onTextChanged(CharSequence s, int start,
							int before, int count) {
						// TODO Auto-generated method stub

					}

					@Override
					public void beforeTextChanged(CharSequence s, int start,
							int count, int after) {

					}

					@Override
					public void afterTextChanged(Editable s) {
						if (getSMSCounts(edittext_edit_message_add_content
								.getText().toString().trim().length()) == 1) {
							int c = 63 - edittext_edit_message_add_content
									.getText().toString().trim().length();
							txt_add_message_add_content_num.setText(c + "");
							txt_add_message_add_content_word.setText("");
						} else if (getSMSCounts(edittext_edit_message_add_content
								.getText().toString().trim().length()) == 2) {
							int c = 127 - edittext_edit_message_add_content
									.getText().toString().trim().length();
							txt_add_message_add_content_num.setText(c + "");
							txt_add_message_add_content_word.setText("(2)");
						} else if (getSMSCounts(edittext_edit_message_add_content
								.getText().toString().trim().length()) > 2) {
							int c = getSMSCounts(edittext_edit_message_add_content
									.getText().toString().trim().length())
									* 67
									- 7
									- edittext_edit_message_add_content
											.getText().toString().trim()
											.length();
							txt_add_message_add_content_num.setText(c + "");
							txt_add_message_add_content_word
									.setText("("
											+ getSMSCounts(edittext_edit_message_add_content
													.getText().toString()
													.trim().length()) + ")");
						}
					}
				});


接收删除后的handler处理:

private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) {
				tfl_add_message_labellay.onChanged();
				txt_add_message_customer_counts.setText((meBean.getReceiver()
						.size() - 1) + "");
			}
		};
	};

上面已经把关键的代码都贴出来了,其实最重要的 地方是按流布局去显示收件人,原生的是没有限制显示行数,也没有处理多行后的滑动轮,头疼的地方是去计算显示高度并动态设置scrollview的高地。坑都已经踩过了,但是这个代码的效率不是很高,有待继续完善,或者有什么好的建议也可以给我提。




一个类似MIUI中原生短信编辑功能

标签:

原文地址:http://blog.csdn.net/zhuod/article/details/51217333

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!