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>

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

    下载地址:点击


  • 相关阅读:
    Benelux Algorithm Programming Contest 2016 Preliminary K. Translators’ Dinner(思路)
    Benelux Algorithm Programming Contest 2016 Preliminary Target Practice
    Benelux Algorithm Programming Contest 2016 Preliminary I. Rock Band
    Benelux Algorithm Programming Contest 2016 Preliminary A. Block Game
    ICPC Northeastern European Regional Contest 2019 Apprentice Learning Trajectory
    ICPC Northeastern European Regional Contest 2019 Key Storage
    2018 ACM ICPC Asia Regional
    2018 ACM ICPC Asia Regional
    Mybatis入库出现异常后,如何捕捉异常
    优雅停止 SpringBoot 服务,拒绝 kill -9 暴力停止
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6869710.html
Copyright © 2011-2022 走看看