Android 控件之--发送邮件时的,收件人列表,可以自动匹配,可以删除,可以添加的。

本文介绍如何在Android应用中创建一个动态的收件人列表,该列表支持自动匹配、删除和添加联系人。通过点击,收件人项会变为高亮并显示删除图标。删除联系人时,后续联系人会自动前移。文章通过代码示例展示了具体的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先不管,截几个图:添加了2个Item  ,后面那个是自动匹配联想。



根据每个Item的宽度,动态计算,一行到底放多少个Item.不够放,就换行(其实不是文本编辑器里的那种换行,是新建一个LinearLayout.嘿嘿)



每个Item的初始状态是 没有那个叉叉的, 当click一下它,它就变成黄色背景,并且那个白色的叉叉出现了。



click那个叉叉,就把它删除了,而且后面的那些要自动往前排(其实这里,目前的一种方式是很粗糙的方式,直接removeAll,然后再一个个的add进去)





废话少说,直接帖代码:如下------------》

  1。先看主界面布局文件:

          

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

    <com.test.demo.MyScrollView
        android:id="@+id/mScrollView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_white"/>

</LinearLayout>

  单个Item的布局文件:
    
<?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"
    android:orientation="horizontal"
    android:background="@color/color_light"
    android:gravity="center">

    <TextView
         android:id="@+id/itemTv"
         android:layout_width="wrap_content"
    		 android:layout_height="wrap_content">
    </TextView>

    <ImageView
        android:id="@+id/delete_iv"
        android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:background="@drawable/email_delete">
    </ImageView>

</LinearLayout>

3.color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
	<drawable name="darkgray">#808080FF</drawable>
    <drawable name="white">#FFFFFFFF</drawable>
	<drawable name="black">#000000</drawable>
    <drawable name="silver">#00ffffff</drawable> 
    <drawable name="text_yellow">#FFFF71</drawable>
    
    <color name="blue">#7F0000FF</color> 
    <color name="transparent">#00000000</color>
    
     <!-- Colors -->
    <color name="color_black">#000000</color>
    <color name="color_white">#FFFFFF</color>
    <color name="color_violet">#9900FF</color>
      <color name="color_orange">#fd810a</color>
        
    <color name="color_gray">#736F6E</color>
    <color name="color_dark">#161C27</color>
    <color name="color_light">#4D6288</color>
       <color name="color_middle">#F17EAB</color>
  
       
</resources>




 2.再看Activity:

           
package com.test.demo;


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class EditTextDemoActivity extends Activity {

	private MyScrollView mSrollView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        	findViews();
    }

    private void findViews(){

    		mSrollView = (MyScrollView)findViewById(R.id.mScrollView);

    		mSrollView.setItemLayout(R.layout.email_item);

    		String[] userNameList = new String[]{"Jacky","Jacky2","Jacky3",
    				"Jacky4","Jacky5","Jacky6","Jacky7","Jacky8"};
    		mSrollView.initAutoCompleteTextView(userNameList);
    }


}

3.核心类--------->

   

package com.test.demo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

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

public class MyScrollView extends ScrollView implements OnItemClickListener{

	private Context mContext;
	private LayoutInflater mInflater;

	private LinearLayout mainLayout;					//ScrollView下的主LinearLayout
	private LinearLayout lastLinearLayout;			//记录最后一个LinearLayout
	private List<LinearLayout> subLayoutList = new ArrayList<LinearLayout>();  //LinearLayout数组(mainLayout除外)

	private AutoCompleteTextView autoCompleteTv;		//自动匹配输入框
	private int autoCompleteTvWidth = 30;

	private int lineLayoutIndex = -1;				    //主LinaerLayout下的子LinearLayout总数:也就是总行数
	private int lineWidth;

	private int itemLayoutResourceId;				//每行的LinearLayout的布局文件id
    private int currLineWidth = 0;
    private boolean haveNewLine = true;

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

	public MyScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public MyScrollView(Context context) {
		super(context);
		init(context);
	}

	/**
	 * 初始化ScrollView下的主LinearLayout,第一个LinearLayout,和AutoCompleteTextView
	 * @param context
	 */
	private void init(Context context){
		mContext = context;
		mInflater = LayoutInflater.from(context);

		mainLayout  = new LinearLayout(mContext);
		mainLayout.setOrientation(LinearLayout.VERTICAL);
		mainLayout.setLayoutParams( new LinearLayout.LayoutParams(
						LinearLayout.LayoutParams.FILL_PARENT,
						LinearLayout.LayoutParams.WRAP_CONTENT
				));

		this.addView(mainLayout);

		//创建第一个horizontal 的 LinaerLayout
		LinearLayout firstLayout = newSubLinearLayout();
		subLayoutList.add(firstLayout);
		lastLinearLayout = firstLayout;
		lastLinearLayout.setBackgroundColor(mContext.getResources().getColor(R.color.color_gray));

		//将AutoCompleteTextView加入到第一个LinearLayout
		autoCompleteTv = new AutoCompleteTextView(mContext);
		autoCompleteTv.setOnItemClickListener(this);
		autoCompleteTv.setWidth(autoCompleteTvWidth);
		firstLayout.addView(autoCompleteTv);

		//将创建的第一个linearLayout 加入到mainLayout中
		mainLayout.addView(firstLayout);
	}

	/**
	 * 新建一行:新建一个LinearLayout
	 * @return
	 */
	private LinearLayout newSubLinearLayout(){
		LinearLayout layout = new LinearLayout(mContext);
		LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.FILL_PARENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);
		layout.setOrientation(LinearLayout.HORIZONTAL);
		layout.setLayoutParams(lp1);
		layout.setGravity(Gravity.CENTER_VERTICAL);

		lineLayoutIndex++;
		return layout;
	}

	public void setHeight(int height){

	}

	/**
	 * 设置Item布局资源id
	 * @param resourceId
	 */
	public void setItemLayout(int resourceId){
		this.itemLayoutResourceId = resourceId;
	}


	/**
	 * 初始化AutoCompleteTextView的数据源
	 * @param data
	 */
	public void initAutoCompleteTextView(String[] data){
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,
				android.R.layout.simple_dropdown_item_1line, data);
		autoCompleteTv.setAdapter(adapter);
	}

	/**
	 *
	 * 重新添加所有的Item
	 *
	 * @param itemList
	 */
	private void reAddAllItem(List<View> itemList){
		LinearLayout firstLayout = newSubLinearLayout();
		subLayoutList.add(firstLayout);
		lastLinearLayout = firstLayout;
		mainLayout.addView(firstLayout);
		currLineWidth = 0;
		for(View item:itemList){
			int childCount = lastLinearLayout.getChildCount();
			int itemWidth = item.getWidth();
			if(childCount==0){
		    		lastLinearLayout.addView(item, 0);
		    		item.setTag(lastLinearLayout);
		    		currLineWidth += itemWidth+10;
	        }else{
		        	if(lineWidth-currLineWidth<itemWidth+10){  //如果当前行不足以显示该Item,要做换行处理
		    	    	    lastLinearLayout = newSubLinearLayout();
		    	    		lastLinearLayout.addView(item);
		    	    		item.setTag(lastLinearLayout);

		    	    		mainLayout.addView(lastLinearLayout);
		    	    		subLayoutList.add(lastLinearLayout);

		    	    		currLineWidth = itemWidth+10;
		    	    		haveNewLine = true;
		    	    }else{

		    	    		lastLinearLayout.addView(item, childCount);
		    	    		item.setTag(lastLinearLayout);
		    	    		currLineWidth += itemWidth+10;
		    	    		haveNewLine = false;
		    	    }
	        }
		}

		//最后添加autocompleteTextView
		lastLinearLayout.addView(autoCompleteTv);
	}

	/**
	 * 添加一个Item:自动去判断是在当前lastLinearLayout中添加,还是要再new 一个LinearLayout
	 * @param value
	 */
	int currLayoutIndex = 0;
	private void addItem(String value){
		lineWidth  = lastLinearLayout.getWidth();
		final LinearLayout item = (LinearLayout)mInflater.inflate(itemLayoutResourceId,null);

		final ImageView deleteIv = (ImageView)item.findViewById(R.id.delete_iv);
		deleteIv.setVisibility(View.GONE);
		deleteIv.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				LinearLayout layout = (LinearLayout)item.getTag();
				layout.removeView(item);
				List<View> itemList =new ArrayList<View>();
				int mainLayoutChildCount = mainLayout.getChildCount();
				for(int i = 0 ;i< mainLayoutChildCount;i++){
					LinearLayout linearLayout = (LinearLayout)mainLayout.getChildAt(i);
					int count = linearLayout.getChildCount();
					for(int j =0;j<count;j++){
						View itemLayout = (View)linearLayout.getChildAt(j);
						if(!(itemLayout instanceof AutoCompleteTextView)){
							itemList.add(itemLayout);
						}
					}
					linearLayout.removeAllViews();
				}
				mainLayout.removeAllViews();
				subLayoutList.clear();
				reAddAllItem(itemList);
			}
		});


	    item.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				if(deleteIv.getVisibility() == View.GONE){
					deleteIv.setVisibility(View.VISIBLE);
					item.setBackgroundColor(mContext.getResources().getColor(R.color.color_orange));
				}else{
					deleteIv.setVisibility(View.GONE);
					item.setBackgroundColor(mContext.getResources().getColor(R.color.color_light));
				}
			}
		});


		TextView itemTv = (TextView)item.findViewById(R.id.itemTv);
		int itemWidth = (int) LableCloudUtlis.getFontWidth(value, (int)itemTv.getTextSize(), mContext)+30;

	    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(itemWidth,
	    		LinearLayout.LayoutParams.WRAP_CONTENT);
	    params.setMargins(10, 10, 10, 10);

	    item.setLayoutParams(params);
	    itemTv.setText(value);

	    Log.i("test","autoCompleteTv.width="+autoCompleteTv.getWidth());
	    int childCount = lastLinearLayout.getChildCount();
	    if(childCount==1){
	    		lastLinearLayout.addView(item, 0);
	    		currLineWidth += itemWidth+10;
	    }else{
	    	    if(lineWidth-currLineWidth<itemWidth+10){  //如果当前行不足以显示该Item,要做换行处理
	    	        lastLinearLayout.removeView(autoCompleteTv);
	    	    	    lastLinearLayout = newSubLinearLayout();
	    	    		lastLinearLayout.addView(item);
	    	    		lastLinearLayout.addView(autoCompleteTv);
	    	    		mainLayout.addView(lastLinearLayout);
	    	    		subLayoutList.add(lastLinearLayout);
	    	    		currLineWidth = itemWidth+10;
	    	    		haveNewLine = true;
	    	    }else{
	    	    		lastLinearLayout.addView(item, childCount-1);
	    	    		currLineWidth += itemWidth+10;
	    	    		haveNewLine = false;
	    	    }
	    }

	    lastLinearLayout.setTag(lineLayoutIndex);
	    item.setTag(lastLinearLayout);


	    //如果目前该行剩余的宽度不足以显示autoCompleteTextView就要做换行处理
	    if( !haveNewLine && lineWidth-currLineWidth<autoCompleteTv.getWidth()-100){
	    	    //将autoCompleteTextView从lastLinearLayout中remove掉
	    		lastLinearLayout.removeView(autoCompleteTv);
	    		//新建一个LinearLayout,将autoCompleteTextView添加到此LinaerLayout
	    		lastLinearLayout = newSubLinearLayout();
	    		lastLinearLayout.addView(autoCompleteTv);
	    		mainLayout.addView(lastLinearLayout);

	    		subLayoutList.add(lastLinearLayout);
	    		currLineWidth = 0;
	    }
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		//选中后,往当前lastLinearLayout中添加一个Item
		String value = autoCompleteTv.getText().toString();
		addItem(value);
		autoCompleteTv.setText("");
	}

}

4. ok搞定!


5.说明: 之所以实现这个东西,是因为目前项目里要提供一个这样的功能:就是发消息给某些人,要一边输入一边发输入的前2个字符到服务器,然后用自动匹配,将服务器返回的东西显示出来,让用户选择。 而且,要能删除,删除呢,不管删哪个,删完后还要重排。不过,这个还要优化,集成到项目中去,还要改点东西,但是基本上搞定了。


那张叉叉图片也附上:

































评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值