Android仿系统短信多选联系人编辑控件

这个,今天终于做出来了。

首先需要一个FlowLayout布局,是从github找到的一个老外写的java类,国内很多博客上找到的FlowLayout布局不能用,类的继承有问题,不知道是啥原因。这里提供一个地址:https://github.com/ApmeM/android-flowlayout

其次是自己实现了一个帧布局将显示与操作的控件分别互换,主要控制FlowLayout的view与EditText的事件。

这个例子主要实现了编辑框的功能,其他如字段匹配,搜索之类的可以另行添加。


(2013/2/5 补一张实现好的UI图片)

废话少说,上代码:

EditContactActivity

package com.example.animationtest;

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

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.animationtest.view.FlowLayout;

public class EditContactActivity extends Activity {
	/** @category 上下文对象 */
	Context context = this;
	/** @category 编辑框 */
	EditText edit;
	/** @category 模拟增加按钮 */
	Button add;
	/** @category 流布局 */
	FlowLayout fl;
	TextView tips;
	RelativeLayout editPanel;
	LinearLayout tipsPanel;
	List<EditBean> data;
	int count = 0;
	boolean delMode = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_editcontact);
		data = new ArrayList<EditContactActivity.EditBean>();

		init();

		tips.setText("请输入号码或选择联系人");

		editPanel.setVisibility(View.GONE);
		tipsPanel.setVisibility(View.VISIBLE);

		tipsPanel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				editPanel.setVisibility(View.VISIBLE);
				tipsPanel.setVisibility(View.GONE);
				edit.requestFocus();
			}
		});

		edit.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				// TODO Auto-generated method stub
				if (!hasFocus) {
					String content = edit.getText().toString();
					if (!"".equals(content)) {
						add(content);
						edit.setText("");
					}

					editPanel.setVisibility(View.GONE);
					tipsPanel.setVisibility(View.VISIBLE);

					loadTips();
				}
			}
		});

		edit.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) {
				// TODO Auto-generated method stub
				delMode = false;
				int flSize = fl.getChildCount();
				if (flSize > 1) {
					View v = fl.getChildAt(flSize - 2);
					v.setBackgroundColor(Color.TRANSPARENT);
				}
			}

			@Override
			public void afterTextChanged(android.text.Editable s) {
				// TODO Auto-generated method stub

			}
		});
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO 截获按键
		switch (keyCode) {
		case KeyEvent.KEYCODE_DEL:
			delete();
			break;
		}
		return super.onKeyDown(keyCode, event);

	}

	private void init() {
		editPanel = (RelativeLayout) findViewById(R.id.editPanel);
		tipsPanel = (LinearLayout) findViewById(R.id.editTipsPanel);
		tips = (TextView) findViewById(R.id.editTips);

		add = (Button) findViewById(R.id.btn_add);
		edit = (EditText) findViewById(R.id.contact);

		int width = context.getResources().getDisplayMetrics().widthPixels;
		edit.setWidth(width);

		final float scale = context.getResources().getDisplayMetrics().density;
		int height = (int) (48 * scale + 0.5f);
		edit.setHeight(height);

		fl = (FlowLayout) findViewById(R.id.area);

		add.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				add("Element:" + count);
				loadTips();
			}
		});
	}

	/** @category 加载人员提示 */
	public void loadTips() {
		String tipsContent = "";
		for (EditBean b : data) {
			tipsContent += b.getName() + ",";
		}
		if (tipsContent.length() > 1) {
			tipsContent = tipsContent.substring(0, tipsContent.length() - 1);

			tips.setText(tipsContent + "(共" + count + "人)");
		} else {
			tips.setText("请输入号码或选择联系人");
		}
	}

	/** @category 增加一个元素 */
	public void add(String title) {
		int n = fl.getChildCount();
		System.out.println("now have element:" + n);
		Editable ea = new Editable(context);
		ea.title.setText(title);
		ea.v.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				delete(v);
			}
		});

		data.add(new EditBean(title, "000", ea.v));
		fl.addView(ea.v, n - 1);
		count++;
	}

	/** @category 删除一个元素 */
	public void delete(View v) {
		EditBean removeItem = null;
		for (EditBean b : data) {
			if (v.equals(b.getView())) {
				removeItem = b;
			}
		}

		// TODO List在遍历时不能删除Item,只有拿到for之外删除了
		if (removeItem != null) {
			data.remove(removeItem);
		}

		System.out.println("del element:" + v.toString());
		count--;
		fl.removeView(v);
	}

	/** @category 删除最后一个元素 */
	public void delete() {
		System.out.println("Now Press Key is Delete.");
		String content = edit.getText().toString();
		System.out.println("Now content is:" + content);
		System.out.println("Now content lenght is:" + content.length());
		int flSize = fl.getChildCount();
		if (flSize > 1 && "".equals(content)) {
			if (delMode) {
				delMode = false;
				System.out.println("Now delete the last item.");
				fl.removeViewAt(flSize - 2);

				count--;
				if (data.size() > 0)
					data.remove(data.size() - 1);
			} else {
				View v = fl.getChildAt(flSize - 2);
				v.setBackgroundColor(Color.parseColor("#ff0000"));
				delMode = true;
			}
		}
	}

	/** @category 元素界面容器 */
	class Editable {
		Context context;
		public View v;
		public TextView title, delete;

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

		private void init() {
			v = LayoutInflater.from(context).inflate(R.layout.item_editable,
					null);
			title = (TextView) v.findViewById(R.id.title);
			delete = (TextView) v.findViewById(R.id.delete);
		}
	}

	/** @category 元素数据Bean */
	class EditBean {

		public EditBean(String name, String cell, View view) {
			setName(name);
			setCell(cell);
			setView(view);
		}

		private String name;
		private View view;

		public View getView() {
			return view;
		}

		public void setView(View view) {
			this.view = view;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getCell() {
			return cell;
		}

		public void setCell(String cell) {
			this.cell = cell;
		}

		private String cell;
	}
}

布局文件:

activity_editcontact.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <LinearLayout
                android:id="@+id/editTipsPanel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/input_box_full"
                android:padding="5dp" >

                <TextView
                    android:id="@+id/editTips"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:ellipsize="middle"
                    android:gravity="center_vertical|left"
                    android:singleLine="true"
                    android:textColor="@android:color/black" />
            </LinearLayout>

            <RelativeLayout
                android:id="@+id/editPanel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/input_box_full" >

                <com.example.animationtest.view.FlowLayout
                    xmlns:f="http://schemas.android.com/apk/res/com.example.animationtest"
                    xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/area"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="5.0dp"
                    android:orientation="vertical"
                    f:horizontalSpacing="6dip"
                    f:verticalSpacing="6dip" >

                    <EditText
                        android:id="@+id/contact"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@null"
                        android:inputType="none"
                        android:text=""
                        android:textColor="#000000" />
                </com.example.animationtest.view.FlowLayout>
            </RelativeLayout>
        </FrameLayout>

        <Button
            android:id="@+id/btn_add"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10.0dp"
            android:background="@android:color/darker_gray"
            android:padding="5.0dp"
            android:text="增加人员"
            android:textColor="@android:color/white"
            android:textSize="22sp" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="@drawable/input_box_full"
            android:hint="在这里输入短信内容"
            android:inputType="none" />
    </LinearLayout>

</ScrollView>

编辑项布局文件:

item_editable.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3.0dp"
        android:background="#000000" >

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1234"
            android:textColor="#ffffff" />

        <TextView
            android:id="@+id/delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5.0dp"
            android:layout_toRightOf="@id/title"
            android:gravity="center"
            android:text="X"
            android:textColor="#00ffff" />
    </RelativeLayout>

</LinearLayout>

资源文件:

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="FlowLayout">
        <attr name="horizontalSpacing" format="dimension" />
        <attr name="verticalSpacing" format="dimension" />
        <attr name="orientation" format="enum">
            <enum name="horizontal" value="0" />
            <enum name="vertical" value="1" />
        </attr>
        <attr name="debugDraw" format="boolean" />
    </declare-styleable>
    <declare-styleable name="FlowLayout_LayoutParams">
        <attr name="layout_newLine" format="boolean" />
        <attr name="layout_horizontalSpacing" format="dimension" />
        <attr name="layout_verticalSpacing" format="dimension" />
    </declare-styleable>

</resources>

转载于:https://my.oschina.net/ldaga/blog/105092

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值