基本功能
1. 自定义标题栏。(标题栏不做任何功能)
2. 有左右发送按钮。(这个只能自己和自己聊天哦,所以有左右发送按钮)
(1)点击左边按钮发送按钮,在ListView的左侧显示。
(2)点击右边按钮发送按钮,在ListView的右侧显示。
3.有表情发送按钮。
(1)当点击表情发送按钮时, 弹出表情框,点击想要发送的表情将其添加输入框中。
(2)当在此点击表情按钮时,表情框收回。
(3)当表情框处在显示状态时, 点击输入框时,表情框收回。
聊天界面的制作(一)——基本布局的实现
聊天界面的制作(二)——发送消息后ListView左右布局显示
源码下载链接
表情列表发送功能
1. 在总布局中添加一个GridView控件,用于显示表情列表。控件中设置一个android:visibility="gone"
让其不显示且不占用空间。当点击表情按钮时才显示,也就是将其值在设置为”visible”;当在次点击时,不显示表情框,也就是又将其值设置为”gone”。
<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"tools:context=".MainActivity"><include
android:id="@+id/title_bar"layout="@layout/title_bar"android:layout_width="fill_parent"android:layout_height="wrap_content" /><ListView
android:id="@+id/listview"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/chatting_background"android:listSelector="@android:color/transparent"></ListView><LinearLayout
android:id="@+id/linearlayout"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/grey"android:gravity="bottom"android:orientation="horizontal"><ImageButton
android:id="@+id/imagebutton_expression"android:layout_width="40dp"android:layout_height="40dp"android:layout_margin="10dp"android:focusable="true"android:background="@drawable/imagebutton_expression" /><Button
android:id="@+id/button_left"android:layout_width="wrap_content"android:layout_height="40dp"android:layout_margin="5dp"android:background="@drawable/button_send_background"android:padding="5dp"android:text="发送"android:textColor="@color/white" /><EditText
android:id="@+id/edittext_input"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="5dp"android:layout_weight="1"android:background="@drawable/edittext_background"android:padding="7dp"android:layout_gravity="center"/><Button
android:id="@+id/button_right"android:layout_width="wrap_content"android:layout_height="40dp"android:layout_margin="5dp"android:background="@drawable/button_send_background"android:padding="5dp"android:text="发送"android:textColor="@color/white" /></LinearLayout><GridView
android:id="@+id/gridview"android:layout_width="match_parent"android:layout_height="wrap_content"android:numColumns="7"android:visibility="visible"android:background="@color/grey"></GridView></LinearLayout>
2. 首先定义一个布局,用于在GridView中的Item中显示每一个表情。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><ImageView
android:id="@+id/imageview_expression"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:src="@mipmap/dra" /></LinearLayout>
定义ExpressionAdapter将表情数据添加到布局中。
public class ExpressionAdapter extends BaseAdapter {//表情数据private int[] mExpression = {R.mipmap.dra,R.mipmap.drb,R.mipmap.drc,R.mipmap.drd,R.mipmap.dre,R.mipmap.drf,R.mipmap.drg,R.mipmap.drh,R.mipmap.dri,R.mipmap.drj,R.mipmap.drk,R.mipmap.drl,R.mipmap.drm,R.mipmap.drn,R.mipmap.dro,R.mipmap.drp,R.mipmap.drq,R.mipmap.drr,R.mipmap.drs,R.mipmap.drt,R.mipmap.dru,R.mipmap.drv,R.mipmap.drw,R.mipmap.drx,R.mipmap.dry,R.mipmap.drz,R.mipmap.dra};private LayoutInflater mInflater;public ExpressionAdapter(LayoutInflater mInflater) {this.mInflater = mInflater;}@Overridepublic int getCount() {return mExpression.length;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup viewGroup) {ViewHolder viewHolder = null;if(convertView == null){convertView = mInflater.inflate(R.layout.item_expression, null);viewHolder = new ViewHolder();viewHolder.imageview = (ImageView) convertView.findViewById(R.id.imageview_expression);convertView.setTag(viewHolder);}else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.imageview.setImageResource(mExpression[position]);return convertView;}class ViewHolder{ImageView imageview;}
}
3. 定义一个富文本,富文本中需要创建ImageGetter对象。然后通过Spanned对象ImageGetter对象返回的id来获得图片。
public class MainActivity extends Activity implements View.OnClickListener {private Button mButtonLeft;//左边发送按钮private Button mButtonRight;//右边发送按钮private EditText mEditTextInput;//输入框private ListView mListView;//显示消息的ListViewprivate GridView mGridView;//显示表情的GridViewprivate ImageButton mImageButtonExpression;//弹出和收回表情框的按钮private Spanned mSpanned;//富文本private Html.ImageGetter mImageGetter;//获得富文本图片private List<ChatMessage> mData;//消息数据private MessageAdapter mMessageAdapter;//消息适配器private ExpressionAdapter mExpressionAdapter;//表情适配器private InputMethodManager mInputMethodManager;//用于控制手机键盘的显示有否的对象(此处)//表情数据名称private String[] mExpression = {"dra", "drb", "drc", "drd", "dre", "drf","drg", "drh", "dri", "drg", "drk", "drl","drm", "drn", "dro", "drp", "drq", "drr","drs", "drt", "dru", "drv", "drw", "drx","dry", "drz", "dra"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mButtonLeft = (Button) findViewById(R.id.button_left);mButtonRight = (Button) findViewById(R.id.button_right);mEditTextInput = (EditText) findViewById(R.id.edittext_input);mImageButtonExpression = (ImageButton) findViewById(R.id.imagebutton_expression);mListView = (ListView) findViewById(R.id.listview);mGridView = (GridView) findViewById(R.id.gridview);mButtonLeft.setOnClickListener(this);mButtonRight.setOnClickListener(this);mImageButtonExpression.setOnClickListener(this);mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);//消息数据初始化mData = new ArrayList<ChatMessage>();//通过反射获得图片的idmImageGetter = new Html.ImageGetter() {@Overridepublic Drawable getDrawable(String s) {Drawable drawable = null;int id = R.mipmap.dra;if (s != null) {Class clazz = R.mipmap.class;try {Field field = clazz.getDeclaredField(s);id = field.getInt(s);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}drawable = getResources().getDrawable(id);drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());return drawable;}};mExpressionAdapter = new ExpressionAdapter(getLayoutInflater());mGridView.setAdapter(mExpressionAdapter);//点击表情,将表情添加到输入框中。mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {//通过mImageGetter获得id获得表情图片,然后将其添加到输入框中。mSpanned = Html.fromHtml("<img src='" + mExpression[position] + "'/>", mImageGetter, null);mEditTextInput.getText().insert(mEditTextInput.getSelectionStart(), mSpanned);}});//点击输入框收回表情框mEditTextInput.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (mGridView.getVisibility() == View.VISIBLE) {mGridView.setVisibility(View.GONE);}}});}@Overridepublic void onClick(View view) {mMessageAdapter = new MessageAdapter(getLayoutInflater(), mData, mImageGetter);switch (view.getId()) {case R.id.imagebutton_expression://添加表情的按钮if (mGridView.getVisibility() == View.VISIBLE) {mGridView.setVisibility(View.GONE);} else {mGridView.setVisibility(View.VISIBLE);mInputMethodManager.hideSoftInputFromWindow(mEditTextInput.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);}break;case R.id.button_left://左边的发送按钮showListViewLeft();break;case R.id.button_right://右边的发送按钮showListViewRight();break;default:break;}}/*发送左边消息*/private void showListViewRight() {ChatMessage dataRight = new ChatMessage();dataRight.setTextViewTime(System.currentTimeMillis());dataRight.setTextViewHonour("营长");dataRight.setTextviewName("虫虫");/*判断发送的消息是否为空,如果为空则弹出提示不允许发送*/if (filterHtml(Html.toHtml(mEditTextInput.getText())).equals("")) {Toast.makeText(getApplicationContext(), "发送的消息不能为空!", Toast.LENGTH_SHORT).show();return;}dataRight.setTextViewInput(filterHtml(Html.toHtml(mEditTextInput.getText())));dataRight.setType(MessageAdapter.SEND_RIGHT);mMessageAdapter.notifyDataSetChanged();mData.add(dataRight);mListView.setAdapter(mMessageAdapter);mListView.setSelection(mData.size() - 1);mEditTextInput.setText("");}/*发送右边消息*/private void showListViewLeft() {ChatMessage dataLeft = new ChatMessage();dataLeft.setTextViewTime(System.currentTimeMillis());dataLeft.setTextViewHonour("营长");dataLeft.setTextviewName("虫虫");/*判断发送的消息是否为空,如果为空则弹出提示不允许发送*/if (filterHtml(Html.toHtml(mEditTextInput.getText())).equals("")) {Toast.makeText(getApplicationContext(), "发送的消息不能为空!", Toast.LENGTH_SHORT).show();return;}//将解析的数据添加到输入框中。dataLeft.setTextViewInput(filterHtml(Html.toHtml(mEditTextInput.getText())));dataLeft.setType(MessageAdapter.SEND_LEFT);mMessageAdapter.notifyDataSetChanged();mData.add(dataLeft);mListView.setAdapter(mMessageAdapter);mListView.setSelection(mData.size() - 1);mEditTextInput.setText("");}public String filterHtml(String str) {str = str.replaceAll("<(?!br|img)[^>]+>", "").trim();return str;}
}
弹出收回表情框功能演示:
发送表情,在文本任意处插入表情功能演示:
聊天界面在点击表情按钮时会收回手机输入法键盘,在模拟器中无法演示,在此说明下。