这个,今天终于做出来了。
首先需要一个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>