zoukankan      html  css  js  c++  java
  • Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录

    经过一个星期的折腾,最终做完了这个Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录。这仅仅是一个单独聊天表情的输入,以及聊天的效果实现。由于我没有写server,所以没有两方聊天的效果。

    主要是聊天中表情的选择。发送。

    表情翻页带有不同的效果。

    我在主要代码中都写了凝视。以下看代码实现。附上本文源代码,代码较多。

    下载地址:点击

    一、先看实现的效果图


    二、调用接口以及设置MainActivity

    package com.example.activity;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Set;
    
    import com.org.adapter.FaceAdapter;
    import com.org.adapter.FacePageAdeapter;
    import com.org.adapter.MessageAdapter;
    import com.org.util.MyApplication;
    import com.org.util.SharePreferenceUtil;
    import com.org.view.CirclePageIndicator;
    import com.org.view.JazzyViewPager;
    import com.org.view.JazzyViewPager.TransitionEffect;
    import com.org.xlistview.MsgListView;
    import com.org.xlistview.MsgListView.IXListViewListener;
    import android.os.Bundle;
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.drawable.ColorDrawable;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.text.Editable;
    import android.text.Spannable;
    import android.text.SpannableString;
    import android.text.TextWatcher;
    import android.text.style.ImageSpan;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.KeyEvent;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.view.View.OnClickListener;
    import android.view.View.OnKeyListener;
    import android.view.View.OnTouchListener;
    import android.view.ViewGroup.LayoutParams;
    import android.view.inputmethod.InputMethodManager;
    import android.widget.AdapterView;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.GridView;
    import android.widget.ImageButton;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.AdapterView.OnItemClickListener;
    
    public class MainActivity extends Activity 
    implements 
    OnClickListener,
    OnTouchListener,
    IXListViewListener{
    
    	private Button sendBtn;
    	private ImageButton faceBtn;
    	private LinearLayout faceLinearLayout;
    	private EditText msgEt;
    	private InputMethodManager mInputMethodManager;
    	private MessageAdapter mMessageAdapter;
    	private JazzyViewPager faceViewPager;
    	private MsgListView mMsgListView;
    	private MyApplication mApplication;
    	private SharePreferenceUtil mSpUtil;
    	private WindowManager.LayoutParams mLayoutParams;
    	private List<String> mListFaceKeys;
    	private int currentPage = 0;
    	private boolean isFaceShow = false;
    	private static int MsgPagerNum;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.chat_main);
    		initData();
    		initUI();
    		initFacePage();
    	}
    	
    	private void initData() {
    		mApplication = MyApplication.getInstance();
    		//SharePreference存储类
    		mSpUtil = new SharePreferenceUtil(this, "message_save");
    		//初始化消息列表适配器
    		mMessageAdapter = new MessageAdapter(this, initMsgData());
    		
    		//载入表情的列表
    		Set<String> keySet = MyApplication.getInstance().getFaceMap().keySet();
    		mListFaceKeys = new ArrayList<String>();
    		mListFaceKeys.addAll(keySet);
    		MsgPagerNum = 0;
    	}
    	private void initUI() {
    		mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    		//获取窗体触摸操作
    		mLayoutParams = getWindow().getAttributes();
    		
    		mMsgListView = (MsgListView) findViewById(R.id.msg_listView);
    		// 触摸ListView隐藏表情和输入法
    		mMsgListView.setOnTouchListener(this);
    		mMsgListView.setPullLoadEnable(false);
    		mMsgListView.setXListViewListener(this);
    		mMsgListView.setAdapter(mMessageAdapter);
    		mMsgListView.setSelection(mMessageAdapter.getCount() - 1);
    		
    		sendBtn = (Button) findViewById(R.id.send_btn);
    		faceBtn = (ImageButton) findViewById(R.id.face_btn);
    		faceLinearLayout = (LinearLayout) findViewById(R.id.face_ll);
    		msgEt = (EditText) findViewById(R.id.msg_et);
    		faceLinearLayout = (LinearLayout) findViewById(R.id.face_ll);
    		faceViewPager = (JazzyViewPager) findViewById(R.id.face_pager);
    		
    		//标题栏控件
    		TextView mTitle = (TextView) findViewById(R.id.ivTitleName);
    		mTitle.setText("默默笙箫");
    		TextView mTitleLeftBtn = (TextView) findViewById(R.id.ivTitleBtnLeft);
    		mTitleLeftBtn.setVisibility(View.VISIBLE);
    		mTitleLeftBtn.setOnClickListener(this);
    		
    		//输入框的触摸监听的绑定
    		msgEt.setOnTouchListener(this);
    		msgEt.setOnKeyListener(new OnKeyListener() {
    
    			@Override
    			public boolean onKey(View v, int keyCode, KeyEvent event) {
    				if (keyCode == KeyEvent.KEYCODE_BACK) {
    					if (mLayoutParams.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
    							|| isFaceShow) {
    						faceLinearLayout.setVisibility(View.GONE);
    						isFaceShow = false;
    						// imm.showSoftInput(msgEt, 0);
    						return true;
    					}
    				}
    				return false;
    			}
    		});
    		
    		//输入框的实时输入长度的监听
    		msgEt.addTextChangedListener(new TextWatcher() {
    			@Override
    			public void onTextChanged(CharSequence s, int start, int before,
    					int count) {
    			}
    
    			@Override
    			public void beforeTextChanged(CharSequence s, int start, int count,
    					int after) {
    			}
    
    			@Override
    			public void afterTextChanged(Editable s) {
    				if (s.length() > 0) {
    					sendBtn.setEnabled(true);
    				} else {
    					sendBtn.setEnabled(false);
    				}
    			}
    		});
    		
    		faceBtn.setOnClickListener(this);
    		sendBtn.setOnClickListener(this);
    	}
    	
    	@Override
    	public boolean onTouch(View v, MotionEvent event) {
    		switch (v.getId()) {
    		case R.id.msg_listView:   //ListView触摸实现
    			mInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);
    			faceLinearLayout.setVisibility(View.GONE);
    			isFaceShow = false;
    			break;
    		case R.id.msg_et:    //输入框触摸实现
    			mInputMethodManager.showSoftInput(msgEt, 0);
    			faceLinearLayout.setVisibility(View.GONE);
    			isFaceShow = false;
    			break;
    
    		default:
    			break;
    		}
    		return false;
    	}
    	
    	//历史数据。在開始时显示
    	private List<MessageItem> initMsgData() {
    		List<MessageItem> msgList = new ArrayList<MessageItem>();// 消息对象数组
    		
    		MessageItem item = new MessageItem(MessageItem.MESSAGE_TYPE_TEXT,
    				mSpUtil.getNick(), System.currentTimeMillis(), "历史消息",
    				mSpUtil.getHeadIcon(), false, 0);
    		msgList.add(item);
    		return msgList;
    
    	}
    	
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.face_btn:  //弹出表情
    			if (!isFaceShow) {
    				mInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);
    				try {
    					Thread.sleep(80);// 解决此时会黑一下屏幕的问题
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				faceLinearLayout.setVisibility(View.VISIBLE);
    				isFaceShow = true;
    			} else {
    				faceLinearLayout.setVisibility(View.GONE);
    				isFaceShow = false;
    			}
    			break;
    		case R.id.send_btn:// 发送消息
    			String msg = msgEt.getText().toString();
    			MessageItem item = new MessageItem(MessageItem.MESSAGE_TYPE_TEXT,
    					mSpUtil.getNick(), System.currentTimeMillis(), msg,
    					mSpUtil.getHeadIcon(), false, 0);
    			mMessageAdapter.upDateMsg(item);
    			
    			mMsgListView.setSelection(mMessageAdapter.getCount() - 1);
    			msgEt.setText("");
    			break;
    		case R.id.ivTitleBtnLeft:
    			finish();
    			break;
    //		case R.id.ivTitleBtnRigh:
    //			break;
    		default:
    			break;
    		}
    		
    	}
    	
    	//载入表情。以及设置翻页效果
    	private void initFacePage() {
    		List<View> lv = new ArrayList<View>();
    		for (int i = 0; i < MyApplication.NUM_PAGE; ++i)
    			lv.add(getGridView(i));
    		FacePageAdeapter adapter = new FacePageAdeapter(lv, faceViewPager);
    		faceViewPager.setAdapter(adapter);
    		faceViewPager.setCurrentItem(currentPage);
    		faceViewPager.setTransitionEffect(mEffects[mSpUtil.getFaceEffect()]);
    		CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator);
    		indicator.setViewPager(faceViewPager);
    		adapter.notifyDataSetChanged();
    		faceLinearLayout.setVisibility(View.GONE);
    		indicator.setOnPageChangeListener(new OnPageChangeListener() {
    
    			@Override
    			public void onPageSelected(int arg0) {
    				currentPage = arg0;
    			}
    
    			@Override
    			public void onPageScrolled(int arg0, float arg1, int arg2) {
    				// do nothing
    			}
    
    			@Override
    			public void onPageScrollStateChanged(int arg0) {
    				// do nothing
    			}
    		});
    
    	}
    	
    	//表情表格控件放置。设置背景
    	private GridView getGridView(int i) {
    		GridView gv = new GridView(this);
    		gv.setNumColumns(7);      //一行显示7个表情
    		gv.setSelector(new ColorDrawable(Color.TRANSPARENT));// 屏蔽GridView默认点击效果
    		gv.setBackgroundColor(Color.TRANSPARENT);
    		gv.setCacheColorHint(Color.TRANSPARENT);
    		gv.setHorizontalSpacing(1);
    		gv.setVerticalSpacing(1);
    		gv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
    		gv.setGravity(Gravity.CENTER);
    		gv.setAdapter(new FaceAdapter(this, i));
    		gv.setOnTouchListener(forbidenScroll());    	// 防止乱pageview乱滚动
    		gv.setOnItemClickListener(new OnItemClickListener() {
    
    			@Override
    			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
    					long arg3) {
    				if (arg2 == MyApplication.NUM) {   // 删除表情键的位置
    					int selection = msgEt.getSelectionStart();
    					String text = msgEt.getText().toString();
    					if (selection > 0) {
    						String text2 = text.substring(selection - 1);
    						if ("]".equals(text2)) {
    							int start = text.lastIndexOf("[");
    							int end = selection;
    							msgEt.getText().delete(start, end);
    							return;
    						}
    						msgEt.getText().delete(selection - 1, selection);
    					}
    				} else {
    					int count = currentPage * MyApplication.NUM + arg2;
    					// 凝视的部分,在EditText中显示字符串
    					// String ori = msgEt.getText().toString();
    					// int index = msgEt.getSelectionStart();
    					// StringBuilder stringBuilder = new StringBuilder(ori);
    					// stringBuilder.insert(index, keys.get(count));
    					// msgEt.setText(stringBuilder.toString());
    					// msgEt.setSelection(index + keys.get(count).length());
    
    					// 以下这部分。在EditText中显示表情
    					Bitmap bitmap = BitmapFactory.decodeResource(
    							getResources(), (Integer) MyApplication
    									.getInstance().getFaceMap().values()
    									.toArray()[count]);
    					if (bitmap != null) {
    						int rawHeigh = bitmap.getHeight();
    						int rawWidth = bitmap.getHeight();
    						int newHeight = 40;
    						int newWidth = 40;
    						// 计算缩放因子
    						float heightScale = ((float) newHeight) / rawHeigh;
    						float widthScale = ((float) newWidth) / rawWidth;
    						// 新建立矩阵
    						Matrix matrix = new Matrix();
    						matrix.postScale(heightScale, widthScale);
    						// 设置图片的旋转角度
    						// matrix.postRotate(-30);
    						// 设置图片的倾斜
    						// matrix.postSkew(0.1f, 0.1f);
    						// 将图片大小压缩
    						// 压缩后图片的宽和高以及kB大小均会变化
    						Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0,
    								rawWidth, rawHeigh, matrix, true);
    						ImageSpan imageSpan = new ImageSpan(MainActivity.this,
    								newBitmap);
    						String emojiStr = mListFaceKeys.get(count);
    						SpannableString spannableString = new SpannableString(
    								emojiStr);
    						spannableString.setSpan(imageSpan,
    								emojiStr.indexOf('['),
    								emojiStr.indexOf(']') + 1,
    								Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    						msgEt.append(spannableString);
    					} else {
    						String ori = msgEt.getText().toString();
    						int index = msgEt.getSelectionStart();
    						StringBuilder stringBuilder = new StringBuilder(ori);
    						stringBuilder.insert(index, mListFaceKeys.get(count));
    						msgEt.setText(stringBuilder.toString());
    						msgEt.setSelection(index + mListFaceKeys.get(count).length());
    					}
    				}
    			}
    		});
    		return gv;
    	}	
    	
    	// 防止乱pageview乱滚动
    	private OnTouchListener forbidenScroll() {
    		return new OnTouchListener() {
    			public boolean onTouch(View v, MotionEvent event) {
    				if (event.getAction() == MotionEvent.ACTION_MOVE) {
    					return true;
    				}
    				return false;
    			}
    		};
    	}
    	
    	@Override
    	protected void onPause() {
    		// TODO Auto-generated method stub
    		mInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);
    		faceLinearLayout.setVisibility(View.GONE);
    		isFaceShow = false;
    		super.onPause();
    	}
    	
    	
    	//处理下拉刷新的效果
    	@Override
    	public void onRefresh() {
    		MsgPagerNum++;
    		List<MessageItem> msgList = initMsgData();
    		int position = mMessageAdapter.getCount();
    		mMessageAdapter.setMessageList(msgList);
    		mMsgListView.stopRefresh();
    		
    		mMsgListView.setSelection(mMessageAdapter.getCount() - position - 1);
    		Log.i("Show","MsgPagerNum = " + mMessageAdapter + ", adapter.getCount() = "
    				+ mMessageAdapter.getCount());
    		
    	}
    	@Override
    	public void onLoadMore() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	private TransitionEffect mEffects[] = { TransitionEffect.Standard,
    			TransitionEffect.Tablet, TransitionEffect.CubeIn,
    			TransitionEffect.CubeOut, TransitionEffect.FlipVertical,
    			TransitionEffect.FlipHorizontal, TransitionEffect.Stack,
    			TransitionEffect.ZoomIn, TransitionEffect.ZoomOut,
    			TransitionEffect.RotateUp, TransitionEffect.RotateDown,
    			TransitionEffect.Accordion, };// 表情翻页效果
    
    }
    
    二、基本的xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/root"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <include layout="@layout/common_title_bg" />
    
        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="0.0dip"
            android:layout_weight="1.0"
            android:background="@drawable/chat_bg_01" >
    
            <com.org.xlistview.MsgListView
                android:id="@+id/msg_listView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:divider="@null"
                android:listSelector="@android:color/transparent"
                android:transcriptMode="normal" />
        </FrameLayout>
    
        <LinearLayout
            android:id="@+id/inputBar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bottombar_bg"
            android:gravity="center_vertical" >
    
            <!-- <ImageButton
                android:id="@+id/more_btn"
                android:layout_width="42.0dip"
                android:layout_height="fill_parent"
                android:background="@android:color/transparent"
                android:paddingLeft="10.0dip"
                android:src="@drawable/pop_btn_selector" /> -->
    
            <ImageButton
                android:id="@+id/face_btn"
                android:layout_width="42.0dip"
                android:layout_height="fill_parent"
                android:background="@android:color/transparent"
                android:paddingLeft="5.0dip"
                android:paddingRight="5.0dip"
                android:src="@drawable/pop_btn_face_selector" />
    
            <EditText
                android:id="@+id/msg_et"
                android:layout_width="0.0dip"
                android:layout_height="40dip"
                android:layout_marginBottom="6.0dip"
                android:layout_marginTop="6.0dip"
                android:layout_weight="1.0"
                android:background="@drawable/chat_bottombar_input"
                android:inputType="textMultiLine"
                android:maxHeight="68.0dip"
                android:paddingBottom="4.0dip"
                android:paddingLeft="10.0dip"
                android:paddingRight="14.0dip"
                android:paddingTop="4.0dip"
                android:textSize="16.0sp" />
    
            <LinearLayout
                android:id="@+id/send_layout"
                android:layout_width="56.0dip"
                android:layout_height="fill_parent"
                android:layout_gravity="left|center"
                android:clickable="true"
                android:gravity="center_vertical" >
    
                <Button
                    android:id="@+id/send_btn"
                    android:layout_width="42.0dip"
                    android:layout_height="34.0dip"
                    android:layout_marginLeft="4.0dip"
                    android:background="@drawable/chat_bottombar_btn_selector"
                    android:enabled="false"
                    android:shadowColor="#ff568ab5"
                    android:shadowDx="0.0"
                    android:shadowDy="-1.0"
                    android:shadowRadius="0.2"
                    android:text="发送"
                    android:textColor="@color/send_btn_textcolor"
                    android:textSize="14.0sp" />
            </LinearLayout>
        </LinearLayout>
    
        <FrameLayout
            android:id="@+id/panelLayout"
            android:layout_width="fill_parent"
            android:layout_height="204.0dip"
            android:background="#ff34373c"
            android:visibility="gone" >
    
            <GridView
                android:id="@+id/panel"
                android:layout_width="fill_parent"
                android:layout_height="204.0dip"
                android:gravity="center"
                android:listSelector="#ff34373c"
                android:numColumns="4"
                android:paddingLeft="11.0dip"
                android:paddingRight="11.0dip"
                android:paddingTop="14.0dip"
                android:scrollbars="none"
                android:stretchMode="columnWidth"
                android:verticalSpacing="14.0dip" />
    
            <ImageView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/chat_plugin_shadow" />
        </FrameLayout>
    
        <LinearLayout
            android:id="@+id/face_ll"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="#fff0f0f0"
            android:orientation="vertical"
            android:paddingBottom="5dip"
            android:paddingTop="5dip"
            android:visibility="gone" >
    
            <com.org.view.JazzyViewPager
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/face_pager"
                app:style="cubeout"
                android:layout_width="fill_parent"
                android:layout_height="120.0dip"
                android:layout_marginLeft="5dip"
                android:layout_marginRight="5dip"
                android:background="#0000"
                android:flipInterval="30"
                android:persistentDrawingCache="animation" />
    
            <com.org.view.CirclePageIndicator
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/indicator"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="10dip" />
        </LinearLayout>
    
    </LinearLayout>

    还有很多适配器,其它实现效果的源代码就不具体贴了,须要细致研究,下载本文的源代码。

    下载地址:点击


  • 相关阅读:
    ubuntu apt 命令相关
    linux 常用命令
    sqli-labs 通关详解(sql注入知识点整理)
    运维手册2---查看机子的系统信息
    运维手册1---ssh命令:使用密钥文件进行登陆
    Java中的==和equals,常量池
    Java Persistence
    VSCode常用插件汇总
    VSCode常用插件之Auto Rename Tag使用
    ESLint 使用指南
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6869710.html
Copyright © 2011-2022 走看看