`
wuchengyi2015106
  • 浏览: 24364 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

聊天APP界面中的表情

阅读更多

聊天APP界面中的表情

 

介绍:

聊天APP界面中的表情,自定义EmojiconTextView,和EmojiconEditText和一个表情EmojiconsFragment实现。

 项目来源:http://www.itlanbao.com/code/20151211/10000/100689.html,喜欢的朋友可以下载完整源码参考参考。

 

效果截图:


其中表情页面用ViewPager实现多个页面的,其中自定义EmojisPagerAdapter并且提供两个方法:

@Override
	public void onEmojiconClicked(Emojicon emojicon) {
		EmojiconsFragment.input(editEmojicon, emojicon);
	}

	@Override
	public void onEmojiconBackspaceClicked(View v) {
		EmojiconsFragment.backspace(editEmojicon);
	}

 

一个输入内容的,一个返回软键盘。自定义EmojiconGridFragment实现gridview效果。
使用的时候很方便直接引入库就可以了。


主要代码如下:

 

public class MainActivity extends FragmentActivity implements
		EmojiconGridFragment.OnEmojiconClickedListener,
		EmojiconsFragment.OnEmojiconBackspaceClickedListener {

	EditText editEmojicon;
	TextView txtEmojicon;
 

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		editEmojicon = (EditText) findViewById(R.id.editEmojicon);
		txtEmojicon = (TextView) findViewById(R.id.txtEmojicon);
		editEmojicon.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				txtEmojicon.setText(s);
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {

			}

			@Override
			public void afterTextChanged(Editable s) {

			}
		});
	}

	@Override
	public void onEmojiconClicked(Emojicon emojicon) {
		EmojiconsFragment.input(editEmojicon, emojicon);
	}

	@Override
	public void onEmojiconBackspaceClicked(View v) {
		EmojiconsFragment.backspace(editEmojicon);
	}
  
}

 

其中EmojiconsFragment 类实现标签页面,部分代码如下:

package com.rockerhieu.emojicon;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.*;
import android.widget.EditText;
import com.rockerhieu.emojicon.emoji.*;

import java.util.Arrays;
import java.util.List;

/**
 * @author Hieu Rocker (rockerhieu@gmail.com).
 */
public class EmojiconsFragment extends Fragment implements ViewPager.OnPageChangeListener {
    private OnEmojiconBackspaceClickedListener mOnEmojiconBackspaceClickedListener;
    private int mEmojiTabLastSelectedIndex = -1;
    private View[] mEmojiTabs;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.emojicons, container, false);
        final ViewPager emojisPager = (ViewPager) view.findViewById(R.id.emojis_pager);
        emojisPager.setOnPageChangeListener(this);
        EmojisPagerAdapter emojisAdapter = new EmojisPagerAdapter(getFragmentManager(), Arrays.asList(
                EmojiconGridFragment.newInstance(People.DATA),
                EmojiconGridFragment.newInstance(Nature.DATA),
                EmojiconGridFragment.newInstance(Objects.DATA),
                EmojiconGridFragment.newInstance(Places.DATA),
                EmojiconGridFragment.newInstance(Symbols.DATA)
        ));
        emojisPager.setAdapter(emojisAdapter);

        mEmojiTabs = new View[5];
        mEmojiTabs[0] = view.findViewById(R.id.emojis_tab_0_people);
        mEmojiTabs[1] = view.findViewById(R.id.emojis_tab_1_nature);
        mEmojiTabs[2] = view.findViewById(R.id.emojis_tab_2_objects);
        mEmojiTabs[3] = view.findViewById(R.id.emojis_tab_3_cars);
        mEmojiTabs[4] = view.findViewById(R.id.emojis_tab_4_punctuation);
        for (int i = 0; i < mEmojiTabs.length; i++) {
            final int position = i;
            mEmojiTabs[i].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    emojisPager.setCurrentItem(position);
                }
            });
        }
        view.findViewById(R.id.emojis_backspace).setOnTouchListener(new RepeatListener(1000, 50, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnEmojiconBackspaceClickedListener != null) {
                    mOnEmojiconBackspaceClickedListener.onEmojiconBackspaceClicked(v);
                }
            }
        }));
        onPageSelected(0);
        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (getActivity() instanceof OnEmojiconBackspaceClickedListener) {
            mOnEmojiconBackspaceClickedListener = (OnEmojiconBackspaceClickedListener) getActivity();
        } else if(getParentFragment() instanceof  OnEmojiconBackspaceClickedListener) {
            mOnEmojiconBackspaceClickedListener = (OnEmojiconBackspaceClickedListener) getParentFragment();
        } else {
            throw new IllegalArgumentException(activity + " must implement interface " + OnEmojiconBackspaceClickedListener.class.getSimpleName());
        }
    }

    @Override
    public void onDetach() {
        mOnEmojiconBackspaceClickedListener = null;
        super.onDetach();
    }

    public static void input(EditText editText, Emojicon emojicon) {
        if (editText == null || emojicon == null) {
            return;
        }

        int start = editText.getSelectionStart();
        int end = editText.getSelectionEnd();
        if (start < 0) {
            editText.append(emojicon.getEmoji());
        } else {
            editText.getText().replace(Math.min(start, end), Math.max(start, end), emojicon.getEmoji(), 0, emojicon.getEmoji().length());
        }
    }

    public static void backspace(EditText editText) {
        KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
        editText.dispatchKeyEvent(event);
    }

    @Override
    public void onPageScrolled(int i, float v, int i2) {
    }

    @Override
    public void onPageSelected(int i) {
        if (mEmojiTabLastSelectedIndex == i) {
            return;
        }
        switch (i) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
                if (mEmojiTabLastSelectedIndex >= 0 && mEmojiTabLastSelectedIndex < mEmojiTabs.length) {
                    mEmojiTabs[mEmojiTabLastSelectedIndex].setSelected(false);
                }
                mEmojiTabs[i].setSelected(true);
                mEmojiTabLastSelectedIndex = i;
                break;
        }
    }

    @Override
    public void onPageScrollStateChanged(int i) {
    }

    private static class EmojisPagerAdapter extends FragmentStatePagerAdapter {
        private List<EmojiconGridFragment> fragments;

        public EmojisPagerAdapter(FragmentManager fm, List<EmojiconGridFragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }

        @Override
        public Fragment getItem(int i) {
            return fragments.get(i);
        }

        @Override
        public int getCount() {
            return fragments.size();
        }
    }

    /**
     * A class, that can be used as a TouchListener on any view (e.g. a Button).
     * It cyclically runs a clickListener, emulating keyboard-like behaviour. First
     * click is fired immediately, next before initialInterval, and subsequent before
     * normalInterval.
     * <p/>
     * <p>Interval is scheduled before the onClick completes, so it has to run fast.
     * If it runs slow, it does not generate skipped onClicks.
     */
    public static class RepeatListener implements View.OnTouchListener {

        private Handler handler = new Handler();

        private int initialInterval;
        private final int normalInterval;
        private final View.OnClickListener clickListener;

        private Runnable handlerRunnable = new Runnable() {
            @Override
            public void run() {
                if (downView == null) {
                    return;
                }
                handler.removeCallbacksAndMessages(downView);
                handler.postAtTime(this, downView, SystemClock.uptimeMillis() + normalInterval);
                clickListener.onClick(downView);
            }
        };

        private View downView;

        /**
         * @param initialInterval The interval before first click event
         * @param normalInterval  The interval before second and subsequent click
         *                        events
         * @param clickListener   The OnClickListener, that will be called
         *                        periodically
         */
        public RepeatListener(int initialInterval, int normalInterval, View.OnClickListener clickListener) {
            if (clickListener == null)
                throw new IllegalArgumentException("null runnable");
            if (initialInterval < 0 || normalInterval < 0)
                throw new IllegalArgumentException("negative interval");

            this.initialInterval = initialInterval;
            this.normalInterval = normalInterval;
            this.clickListener = clickListener;
        }

        public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downView = view;
                    handler.removeCallbacks(handlerRunnable);
                    handler.postAtTime(handlerRunnable, downView, SystemClock.uptimeMillis() + initialInterval);
                    clickListener.onClick(view);
                    return true;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_OUTSIDE:
                    handler.removeCallbacksAndMessages(downView);
                    downView = null;
                    return true;
            }
            return false;
        }
    }

    public interface OnEmojiconBackspaceClickedListener {
        void onEmojiconBackspaceClicked(View v);
    }
}

 

0
0
分享到:
评论

相关推荐

    聊天APP界面中的表情用ViewPager实现

    总结一下,实现聊天APP界面中的表情功能主要涉及以下步骤: 1. 使用ViewPager作为表情页面的容器。 2. 创建一个继承自`PagerAdapter`的适配器,负责加载表情页面。 3. 在适配器中使用`GridView`或`RecyclerView`...

    聊天APP界面中的表情,所有东西全部打成了lib包,直接关联就可以使用,简单到不行

    聊天APP界面中的表情,所有东西全部打成了lib包,直接关联就可以使用,简单到不行 [注:本内容来自网络,在此分享仅为帮助有需要的网友,如果侵犯了您的权利,麻烦联系我,我会第一时间删除,谢谢您。]

    apicloud开发app案例 生成QQ和微信的聊天界面.zip

    本教程以“apicloud开发app案例 生成QQ和微信的聊天界面.zip”为例,深入探讨如何利用APICloud实现类似微信和QQ的聊天界面,包括输入法、表情包、图片选择和发送等功能。 首先,我们来看项目中的核心文件结构。在...

    类似微信聊天界面底部菜单

    在IT行业中,设计一个类似微信聊天界面底部菜单是常见的需求,尤其在开发移动应用时。这个功能涉及到用户界面(UI)设计、交互设计以及前端开发技术。以下将详细阐述相关知识点: 1. 用户界面(UI)设计:微信聊天...

    智能聊天机器人app

    实现聊天功能时,app需要有一个用户界面,包含一个输入框让用户输入问题或消息,以及一个展示聊天记录的对话框。头像的设计则增加了互动的真实感,让用户感觉像是在和一个真实的人物对话。通常,开发者会为机器人...

    uniapp聊天实例,支持图片,语音,表情.zip

    《uniapp实现聊天功能详解——图片、语音与表情支持》 在移动应用开发领域,uniapp因其跨平台的特性及丰富的组件库,逐渐成为开发者们的首选工具之一。本实例将详细解析如何使用uniapp构建一个支持图片、语音和表情...

    环信聊天appDemo

    在这个“环信聊天appDemo”中,我们可以看到三个关键的模块:redpacketlibrary、easeui和ChatDemoUI3.0,它们分别代表了环信服务的不同方面。 1. **redpacketlibrary**: 这个模块通常与红包功能有关。在移动应用...

    uni-app聊天页面

    在uni-app聊天页面中,Vue的组件化思想被用来构建可复用的UI组件,如输入框、消息列表、表情面板等。 3. **聊天界面设计**:这个模板会包含聊天窗口的基本元素,例如输入框、发送按钮、用户头像、消息气泡、时间戳...

    ios中实现仿QQ聊天界面

    在iOS开发中,创建一个类似QQ的聊天界面是一项常见的任务,尤其对于社交应用开发者来说。Xcode 12是Apple官方提供的最新版本的集成开发环境(IDE),它提供了丰富的工具和资源来帮助开发者构建高质量的iOS应用。在这...

    Android聊天界面实现源码

    在Android应用开发中,创建一个聊天界面是一项常见的任务,它涉及到UI设计、数据管理以及用户交互等多个方面。本文将深入探讨如何使用RecyclerView来实现这样一个功能,并结合提供的源码进行分析。 首先,`...

    Android开发的局域网内聊天APP

    综上所述,开发一个Android局域网聊天APP是一项涉及网络编程、多媒体处理、UI设计和用户体验优化等多方面技术的复杂任务。通过熟练掌握和运用这些技术,我们可以创建出高效、稳定的聊天应用,满足用户在局域网内的...

    安卓模仿微信聊天界面(一)

    因为表情包实现比较麻烦,现在还在做,做完了发,还有就是对话框和微信不一样是因为没有合适的对话框的png图片用来做.9的图片. 依赖 implementation 'androidx.recyclerview:recyclerview:1.0.0' 在drawable里新建几个...

    uniapp框架-uniapp聊天实例,支持图片,语音,表情-uni-app项目源码-vue语法格式.zip

    UniApp开发前景分析:专业视角引领未来 随着移动互联网的迅猛发展,跨平台应用开发框架UniApp以其独特的优势,展现出广阔的开发前景。 UniApp基于Vue.js,采用一次编写、多端运行的设计理念,极大降低了开发成本和...

    jQuery仿手机app社交软件聊天特效

    在本项目中,"jQuery仿手机app社交软件聊天特效"是一个使用HTML、CSS和jQuery技术构建的交互式聊天界面,旨在模拟现代手机应用程序中的聊天体验。这个特效为开发者提供了一个平台,可以创建具有动态和吸引人的用户...

    一个社交聊天app_ui_界面设计_sketch素材下载.zip

    本文将深入探讨“一个社交聊天app_ui_界面设计_sketch素材下载.zip”这个资源包中所包含的设计元素,以及它们如何体现优秀的UI设计原则和最佳实践。 首先,让我们聚焦于标题中的“社交聊天app_ui_界面设计”。UI...

    uni-app小程序简单聊天.rar

    - 聊天界面通常包含消息列表、输入框和发送按钮等元素,这些都可以用uni-app的组件来构建。 - 使用uni-app的`&lt;van-list&gt;`组件实现滚动加载历史消息,`&lt;uni-icons&gt;`用于图标展示,`&lt;uni-input&gt;`处理用户输入。 - ...

    H5聊天系统即时通讯/IM聊天APP/微信+安卓/苹果端APP/视频教程

    总之,H5聊天系统即时通讯及IM聊天APP的开发是一个涉及多方面技术的复杂工程,需要理解并掌握网络通信、用户认证、数据存储、界面设计、音视频处理等多个领域的知识。通过深入学习和实践,开发者可以打造出功能强大...

    基于HTML5的聊天App.zip

    在聊天App中,WebRTC可实现语音通话和视频聊天功能,无需借助任何插件。 4. **Canvas和SVG**:HTML5的Canvas提供了画布元素,用于动态渲染图形,如表情、气泡等。SVG则用于创建和展示矢量图,确保图像在不同分辨率...

    即时聊天在线客服系统App

    **聊天App**的设计应注重用户体验,界面简洁易用,功能直观。除了基本的文字聊天,可能还包括表情、图片、文件的发送,以及语音输入等辅助功能。此外,为了提高效率,App通常会提供客服分类,如按产品类别、问题类型...

    H5即时通讯聊天系统源码,IM聊天、交友、客服平台源码,可封装APP+群聊+添加好友【站长亲测】

    此外,为了保证用户体验,还需要优化聊天界面的响应速度,如消息的实时刷新和加载历史记录的流畅性。 在实际应用中,开发者可以根据需求对源码进行二次开发。例如,增加语音和视频通话功能,提升沟通的直观性;添加...

Global site tag (gtag.js) - Google Analytics