界面效果:

android实现聊天室技术 android聊天功能开发_控件

注意:

1.文本框默认文字是“tel:10086”,当你点击文字时,文字会秘文显示(即。。。。。这样),再次点击,会显示原文,实际就调用了一个Text对象的


setTransformationMethod(PasswordTransformationMethod.getInstance());


将文字以秘文显示。

2.<requestFocus />: 标签用于指定屏幕内的焦点View,例如下面我在<EditText>   <requestFocus />  </EditText>放了EditText

则界面一开始焦点就会位于EditText控件处

小知识点:

容器控件:(如LinearLayout、FrameLayout等),

也可以使用非容器控件:(如:EditText、TextView等)。对于非容器控件,只能在非容器控件标签中放<requestFocus />标签,表示将当前控件设为焦点

代码如下:

main_activity.xml

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

        <EditText
            android:id="@+id/editText1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/textView1"
            android:singleLine="true"
            android:maxLength="12"
            android:hint="请输入用户名">

            <requestFocus />
        </EditText>

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="125dp"
            android:onClick="onBtnSend"
            android:text="发送消息" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginTop="27dp"
            android:text="Tel:10086" />

</RelativeLayout>

 mainActivity类:

public class MainActivity extends Activity {
//文本编辑控件
	private EditText mETMessage;
//文本显示控件
	private TextView mTVMessage;
	
	// 定义一个标记变量,表示明文还是密文显示
	private boolean mHideMessage = false;

	// onCreate是重写的父类Activity的方法
	// 当画面对象Activity创建的时候,该方法会被系统回调
	// 该方法通常用于画面的初始化操作
	// 应用Layout布局文件,获得布局中的控件 对象 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// 回调父类的onCreate方法
		super.onCreate(savedInstanceState);
		// 设置显示内容(布局文件引用 )
		// R.java是由开发环境 自动创建的一个资源管理文件(我们不修改它的内容)
		// 当我们需要访问到res目录下的资源的时候,在代码中可以通过R.xxx.常量方法来引用 
		// 该int类型对应一个具体的资源,我们称他为资源ID
		setContentView(R.layout.myrelative_layout);
		
		// 获得画面中布局上的EdtiText对象
		// findViewByID,通过指定的资源ID来找到对应的控件对象 
		mETMessage = (EditText) findViewById(R.id.editText1);
		mTVMessage = (TextView) findViewById(R.id.textView1);
		
		// 为TextView添加点击事件监听器
		// 一旦用户点击了该控件时,OS会调用监听器对象里的方法
		// 在监听器方法添加上处理逻辑
		mTVMessage.setOnClickListener(new OnClickListener() {
			// 用户点击TextView时,onClick方法会被调用 
			@Override
			public void onClick(View v) {
				System.out.println("mTVMessage is clicked");
				// 当第一次点击时,将内容密文显示
				if(!mHideMessage){
					// 密文显示
					mTVMessage.setTransformationMethod(PasswordTransformationMethod.getInstance());
					mHideMessage = true;
				}else{
					// 当第二次点击时,将内容明文显示
					mTVMessage.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
					mHideMessage = false;
				}
				
			}
		});
	}
	
	// Ctrl + shift + o, 自动导入包的操作
//点击发送消息,就会执行函数,获取输入框的内容,并显示到文本框
	public void onBtnSend(View view){
		System.out.println("Hello im clicked");
		
		// 首先要获得EditText的内容
		String msg = mETMessage.getText().toString();
		
		// 将该内容显示到TextView上
		mTVMessage.setText(msg);
	}
}

 

 

 

第二课:添加表情图片:(android图文混排)

效果:

android实现聊天室技术 android聊天功能开发_Text_02

布局文件activity_main .xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

    <GridView
        android:id="@+id/gridView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="4">
       <!--行数不限,列数为4列-->
</GridView>

</LinearLayout>

下面定义图片在上,文字在下的布局item_girdview.xml:

效果是这样:

android实现聊天室技术 android聊天功能开发_android_03

代码说明:

android:adjustViewBounds
是否保持宽高比。需要与maxWidth、MaxHeight一起使用,否则单独使用没有效果。
设置View的最大高度,单独使用无效。


android:layout_gravity="center_horizontal" 图片居中


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

    <ImageView
        android:id="@+id/item_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:adjustViewBounds="true"
        android:maxWidth="72dp"
        android:maxHeight="72dp"
        android:src="@drawable/ic_launcher_background" />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:text="TextView" />

</LinearLayout>

MainActivity代码:

里面的图片可以自己找,放在drawable下即可

注意


initDataList(){}函数中不能这样写:


dataList = new ArrayList<HashMap<String,Object>>();
		HashMap<String, Object> item = new HashMap<String, Object>();

		item.put("image", R.drawable.emo001);
		item.put("text", "<emo001>");

		item.put("image", R.drawable.emo002);
		item.put("text", "<emo002>");
        。。。。。。。。。。。
        
       item.put("image", R.drawable.emo012);
		item.put("text", "<emo012>");

         dataList.add(item);

结果会这样:

android实现聊天室技术 android聊天功能开发_android实现聊天室技术_04

 

因为new HashMap()只执行了一次,相当于只new了一个hash对象,,只添加了一个hash对象,


ArrayList<HashMap<String, Object>> dataList;


dataList数组里只有一个hash对象,故只又一个显示,我们需要new多次hash,生成多个hash对象,下面代码中,虽然item对象名相同,但是hash类new出来的却不同

 

还有一点:SpannableString

SpannableString其实和String一样,都是一种字符串类型。不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示。比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉,总之,SpannableString、SpannableStringBuilder与String一样,可以认为是String的升级版

【【

2.setSpan()
void setSpan (Object what, int start, int end, int flags)

object what :对应的各种Span,后面会提到;

int start:开始应用指定Span的位置,索引从0开始

int end:结束应用指定Span的位置,不包含

int flags


Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括(在标志位【start,end)前后添加文字,新添加的文字不会有任何设置的属性)

Spannable.SPAN_EXCLUSIVE_INCLUSIVE :前面不包括,后面包括。(在标志位【start,end)前添加文字,新添加的文字不会有任何设置的属性,后边的添加的文字会带有设置的what属性)】】

关系的图像为  imgSpan,该对象用来插入到EditText控件中去,结合SpannableString将图片转为文本插入到EditTextView中

 

 

public class MainActivity extends Activity implements OnClickListener {
	private Button mBtn;
	private TextView mTextView;
	private EditText mETInput;
	private GridView mGridView;

	private ArrayList<HashMap<String, Object>> dataList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mBtn = (Button) findViewById(R.id.button1);
		mBtn.setOnClickListener(this);


		mTextView = (TextView) findViewById(R.id.textView1);
		mETInput = (EditText) findViewById(R.id.editText1);


		// 为mImgBtn设置一个点击事件的监听器
		// 一旦用户点击了该按钮,则设置的监听器上的监听对象会调用对应处理代码
		// OnClickListener:接口
		// 1. Java中的匿名内部类来创建一个对象
		// 2. 我们也可以定义一个类来实现该接口,然后再创建自定义类的监听对象
		// 3. 让MainActivity对象来监听该按钮,让MainActivity实现OnClickListener
		// 4. xml文件中配置监听方法
/*		mImgBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 点击操作实现代码
				System.out.println("匿名内部类实现点击事件处理");
			}
		});*/
/*		MyListener listener = new MyListener();
		mImgBtn.setOnClickListener(listener);*/
		//mImgBtn.setOnClickListener(this);

		// 通过该方法初始化GridView数据源
		initDataList();

		mGridView = (GridView) findViewById(R.id.gridView1);
		// 通过该方法来设置其适配器
		// 适配器用来将原始数据转化成GridView可用的数据,然后显示出来
		// SimpleAdapter:
		SimpleAdapter adapter = new SimpleAdapter(
				// 指定当前适配器的上下文
				this,
				// 指定数据源
				dataList,
				// 指定每一项的布局
				R.layout.item_gridview,
				//
				new String[]{"image", "text"},
	           //int数组里面是imageView和TextView控件
				new int[]{R.id.item_image, R.id.item_text});
		mGridView.setAdapter(adapter);

		// 为GridView添加了项点击监听器
		mGridView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
									long arg3) {
				System.out.println("您点击了第" + arg2 + "项");
				String text = (String) dataList.get(arg2).get("text");
				System.out.println(text);

				int resID = (Integer) dataList.get(arg2).get("image");
				// 该对象用来插入到EditText控件中去
				ImageSpan imgSpan = new ImageSpan(MainActivity.this, resID);
				SpannableString spanString = new SpannableString(text);
				// 设置Spannable关联关系
				// 参数1:关系的图像
				// 参数2:从SpannString中哪个字符开始关系
				// 参数3:关系到SpannString中哪个字符
				// 参数4:关系的类型(只关系指定的范围)
				spanString.setSpan(imgSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				// 将带有图像的Spanned对象追加到输入框中
				mETInput.append(spanString);
			}
		});

	}

	private void initDataList(){
		dataList = new ArrayList<HashMap<String,Object>>();
		HashMap<String, Object> item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo001);
		item.put("text", "<emo001>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo002);
		item.put("text", "<emo002>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo003);
		item.put("text", "<emo003>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo004);
		item.put("text", "<emo004>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo005);
		item.put("text", "<emo005>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo006);
		item.put("text", "<emo006>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo007);
		item.put("text", "<emo007>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo008);
		item.put("text", "<emo008>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo009);
		item.put("text", "<emo009>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo010);
		item.put("text", "<emo010>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo011);
		item.put("text", "<emo011>");
		dataList.add(item);
		item = new HashMap<String, Object>();
		item.put("image", R.drawable.emo012);
		item.put("text", "<emo012>");
		dataList.add(item);
	}

	/**
	 * 按钮的点击事件监听内部类
	 */
/*	private class MyListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			System.out.println("内部类实现点击事件处理");
		}
	}*/
/*	public void onPlaybtnClicked(View v){
		System.out.println("play button is clicked");
	}*/

	@Override
	public void onClick(View v) {
		System.out.println("让MainActivity来监听点击事件处理");
		mTextView.setText(mETInput.getText());
		System.out.println("输入信息为:" + mETInput.getText().toString());
		mETInput.setText("");
	}
}