Android键盘自定义表情包,关于自定义表情键盘...

在做输入的时候,除了可以输入系统的表情符号,项目中通常还要求输入表情图片

518202f26cc5

表情图片

1、正则表达式

一个正则表达式,就是一串有特定意义的字符,首先要编译成为一个Pattern对象,然后使用matcher()方法来生成一个Matcher实例,接着便可以使用该 Matcher实例对目标字符串进行匹配工作。

Pattern类:

static Pattern compile(String regularExpression):将给定的正则表达式编译并赋予给Pattern类

Matcher matcher(CharSequence input) :生成一个match对象

Matcher类:

boolean find()

尝试在目标字符串里查找下一个匹配子串,如果没有,返回false

String group()

返回当前查找,所组匹配的子串

private SpannableString dealExpression(Context context) {

...

// 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊

String zhengze = "\\[[^\\]]+\\]";

// 通过传入的正则表达式来生成一个pattern

Pattern pattern = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);

//得到matcher

Matcher matcher = pattern.matcher(spannableString);

//尝试在目标字符串里查找下一个匹配子串,如果没有,返回false

while (matcher.find()) {

//得到匹配的子串

String key = matcher.group();

...

}

}

2、表情文字到表情图片的转变

如果将表情字符 212[开心]2[调皮] ,转变成表情图片,如下图,可以使用SpannableString。

建立图片名称---资源ID的键值对,得到了名称,就得到了资源ID

通过正则表达式,得到匹配某种规则的字符(图片名称)

根据得到的资源文件ID,生成bitmap,通过Span进行包装

使用SpannableString,把某个区间的字符,替换成资源图片

518202f26cc5

构造函数如下:

public ImageSpan(Drawable d, int verticalAlignment) {

...

}

public ImageSpan(Context context, Bitmap b, int verticalAlignment) {

...

}

public void setSpan(Object what, int start, int end, int flags) {

...

}

注意:

1、verticalAlignment有两个值:

ALIGN_BOTTOM:和baseline下面的descender对齐

ALIGN_BASELINE:和text的baseline对齐

默认是ALIGN_BOTTOM。

2、spannableString的setSpan:

what:这里传入样式,如:ImageSpan等

start:样式作用在文本的起始点(产生的作用包括该点,从0开始)

end:样式作用在文本的结束点(产生的作用不包括该点,从0开始)

flags:是否包含start或者end点的字符

flags的选项在Spanned接口中,分别为:

SPAN_INCLUSIVE_EXCLUSIVE:包含start,不包含end

SPAN_INCLUSIVE_INCLUSIVE:start,end都包含

SPAN_EXCLUSIVE_EXCLUSIVE:start,end都不包含

SPAN_EXCLUSIVE_INCLUSIVE:start不包含,end包含

使用如下:

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options);

ImageSpan imageSpan = new ImageSpan(context,bitmap);

//将start到end之间的字符替换成目标图片

spannableString.setSpan(imageSpan, start, end,Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

Drawable res=context.getResources().getDrawable(R.drawable.test);

res.setBounds(0,0,res.getIntrinsicWidth(),res.getIntrinsicHeight());

ImageSpan span=new ImageSpan(res,ImageSpan.ALIGN_BOTTOM);

//ForegroundColorSpan span=new ForegroundColorSpan(resColor);

spannableString.setSpan(span,start,end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

return spannableString;

代码如下:

public SpannableString getSpannableString(Context context,String str){

initBitmapOption(context);

try {

dealExpression(context, str);

} catch (Exception e) {

Log.e("dealExpression", e.getMessage());

}

return spannableString;

}

private void dealExpression(Context context,String str) {

SpannableString spannableString=new SpannableString(str);

// 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊

String zhengze = "\\[[^\\]]+\\]";

// 通过传入的正则表达式来生成一个pattern

Pattern pattern = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);

Matcher matcher = pattern.matcher(spannableString);

while (matcher.find()) {

String key = matcher.group();

if(AppUtil.getInstance().getFaceMapHX().containsKey(key)){

int resId = AppUtil.getInstance().getFaceMapHX().get(key);

if (resId != 0) {

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options);

if(bitmap!=null){

WeakReference weakReference=new WeakReference<>(bitmap);

// 通过图片资源id来得到bitmap,用一个ImageSpan来包装

ImageSpan imageSpan = new ImageSpan(context,weakReference.get());

// 计算该图片名字的长度,也就是要替换的字符串的长度

int end = matcher.start() + key.length();

// 将该图片替换字符串中规定的位置中

spannableString.setSpan(imageSpan, matcher.start(), end,

Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

}

}

}

}

}

private void initFaceMapHX() {

mFaceMapHX.put("[):]", R.drawable.hx_1);

...

3、定义表情键盘

通过在工具类中建立

private Map mFaceMap = new LinkedHashMap();

public Map getFaceMap() {

if (!mFaceMap.isEmpty())

return mFaceMap;

mFaceMap.put("[):]", R.drawable.hx_1);

...

return mFaceMap;

}

1、表情键盘的布局文件

518202f26cc5

表情键盘

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="#ffffff"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center_vertical"

android:background="@drawable/shape_take_photo"

android:orientation="horizontal">

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1">

android:id="@+id/editText"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:minHeight="48dp"

android:text=""

android:maxLines="3"

android:gravity="center_vertical"

android:background="@drawable/char_bottombar_input_selector"

android:paddingRight="40dp"/>

android:id="@+id/showFace"

android:layout_width="44dp"

android:layout_height="44dp"

android:layout_gravity="center_vertical|right"

android:paddingBottom="10dp"

android:paddingTop="10dp"

android:src="@drawable/chat_bottombar_icon_face_selector"/>

android:id="@+id/viewPagerInfo"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:visibility="gone">

android:id="@+id/viewPager"

android:layout_width="match_parent"

android:layout_height="150dp"/>

android:id="@+id/indicator"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:padding="10dp"/>

2、自定义ViewGroup,初始化刚刚的布局文件,为VIewPager指定adapter

将所有表情图片的名称,存到keyList中(备用)

使用GridVIew填充ViewPager

使用资源图片填充GridView,为其adapter传入currentPage,能够在其中得到当前页资源图片ID

添加点击事件

代码如下:

public class FaceContainerView extends LinearLayout {

//存储表情字符名称,如[开心]

private ArrayList keyList;

//view是每一页,

private ArrayList faceViews;

...

public FaceContainerView(Context context, AttributeSet attrs, int defStyleAttr) {

...

keyList=new ArrayList<>();

//得到表情字符名称

if(AppUtil.getInstance().getFaceMap()!=null){

Set keySet= AppUtil.getInstance().getFaceMap().keySet();

if(!keySet.isEmpty()){

keyList.addAll(keySet);

}

}

}

@Override

protected void onFinishInflate() {

super.onFinishInflate();

...

//初始化表情键盘

initFaceView();

}

private void initFaceView() {

faceViews=new ArrayList<>();

//NUM_PAGE:页数,一页的图片数=7*3-1

for(int index=0;index< AppUtil.getInstance().NUM_PAGE;index++){

faceViews.add(getGridView(index));

}

FacePagerAdapter facePagerAdapter =new FacePagerAdapter(faceViews);

viewPager.setAdapter(facePagerAdapter);

viewPager.setCurrentItem(currentPage);

indicator.setViewPager(viewPager);

indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

...

});

...

}

private View getGridView( int page) {

GridView gridView=new GridView(context);

gridView.setNumColumns(7);

...

FaceAdapter faceAdapter=new FaceAdapter(context, page);

gridView.setAdapter(faceAdapter);

...

return gridView;

}

}

GridView的adapter

public class FaceAdapter extends BaseAdapter {

//当前页

private int currentPage;

//所有的列表

private Map faceMap ;

//所有的资源ID

private ArrayList imageRes=new ArrayList<>();

...

public FaceAdapter(Context context, int currentPage) {

...

faceMap= AppUtil.getInstance().getFaceMapHX();

initDate();

}

private void initDate() {

if(faceMap!=null){

for(Map.Entry entry:faceMap.entrySet()){

imageRes.add(entry.getValue());

}

}

}

@Override

public int getCount() {

return AppUtil.getInstance().NUM + 1;

}

@Override

public Object getItem(int position) {

return faceInCurrentPage.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

<...viewHolder和convertView...>

if (position == AppUtil.getInstance().NUM) {

//每一页最后那个删除图片

...

} else {

int count = AppUtil.getInstance().NUM * currentPage + position;

if (faceMap!=null && count < faceMap.size()) {

int res=imageRes.get(count);

...

} else {

viewHolder.faceIV.setImageDrawable(null);

viewHolder.faceIV.setBackgroundDrawable(null);

viewHolder.faceIV.setEnabled(false);

}

}

return convertView;

}

...

}

4、管理软键盘

1、软键盘本质是一个Dialog,可以通过windowSoftInputMode, 设置Activity主窗口与软键盘的交互模式。它包括两部分:

对Activity窗口的调整(以便腾出空间展示软键盘)

adjustUnspecified:在是默认的,系统会根据界面选择不同的模式。如果有滚动列表,默认是adjustResize;如果没有,默认是adjustPan。

adjustResize:系统总是调整屏幕的大小用以保证软键盘的显示空间( 系统没有移动布局),如果布局不可以滚动,可能会导致输入框不在视野范围内 。

adjustPan:系统会通过布局的移动,来保证用户要进行输入的输入框、肯定在用户的视野范围里面,从而让用户看到自己输入的内容。

对软键盘的状态控制,即控制软键盘是隐藏还是显示

stateUnspecified:默认的,系统会根据界面采取相应的软键盘的显示模式。

stateUnchanged:当前界面的软键盘状态,取决于上一个界面的软键盘状态,无论是隐藏还是显示。

stateHidden:软键盘总是被隐藏,不管是否有输入的需求。

stateAlwaysHidden:软键盘总是被隐藏,和stateHidden不同的是,当我们跳转到下个界面,如果下个页面的软键盘是显示的,而我们再次回来的时候,软键盘就会隐藏起来。

stateVisible:软键盘总是可见的,即使在界面上没有输入框的情况下也可以强制弹出来出来。

stateAlwaysVisible:软键盘总是可见的,和stateVisible不同的是,当我们跳转到下个界面,如果下个页面软键盘是隐藏的,而我们再次回来的时候,软键盘就会显示出来。

518202f26cc5

adjustPan

518202f26cc5

adjustResize

adjustResize,可以调整屏幕的大小,可以实现软键盘顶起页面的效果

代碼如下:

xmlns:...

android:orientation="vertical"

android:fitsSystemWindows="true">

android:hint="one"

android:id="@+id/editText3"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_margin="20dp"

android:layout_weight="1"/>

android:id="@+id/btn"

android:text="下一页"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

518202f26cc5

adjustResize,实现软键盘顶起页面的效果

但是再activity背景透明的情况下,如果模式为 adjustResize ,会再切换键盘的瞬间,显示前一个页面,使用 adjustPan就不会。

2、在隐藏软键盘的时候,可以传入一个ResultReceiver对象。

这个对象需要传入一个Handler,作用是控制回调函数执行在创建Handler的线程。如果这个Handler是null,则回调会在主线程执行。

通过传入ResultReceiver对象,就可以实现,在输入法键盘隐藏之后,回调onReceiveResult,显示表情键盘:

518202f26cc5

在输入法键盘隐藏之后,显示表情键盘

InputMethodManager inputMethodManager= (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

inputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), 0, new ResultReceiver(null){

@Override

protected void onReceiveResult(int resultCode, Bundle resultData) {

...

}

});

关于.9图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Vue项目中的自定义表情包,你可以按照以下步骤进行操作: 1. 准备表情包图片:首先,你需要准备好要使用的表情包图片。这些图片可以是你自己设计的或者从其他地方获取的。确保这些图片是适当的尺寸和格式。 2. 创建组件:在Vue项目中,你可以创建一个专门用于显示表情包的组件。可以使用Vue的单文件组件(.vue)格式来创建这个组件。 3. 导入图片:在你的组件中,使用Vue的`<img>`标签来导入表情包图片。你可以将这些图片放在项目的`assets`文件夹中,并使用相对路径来引用它们。 4. 动态显示表情包:如果你希望能够动态显示不同的表情包,可以在组件中使用Vue的数据绑定功能。通过绑定一个数据属性来控制要显示的表情包图片的路径,然后在模板中使用该属性来动态显示对应的图片。 5. 添加交互功能:如果你希望用户能够与表情包进行交互,例如点击表情包时触发某个动作,你可以为表情包图片添加点击事件。在Vue中,你可以使用`@click`指令来绑定点击事件并执行相应的方法。 6. 样式美化:最后,你可以为你的表情包组件添加样式来美化它们。可以使用CSS来设置表情包的大小、边框、阴影等样式属性。 这些步骤可以帮助你在Vue项目中实现自定义表情包的功能。根据你的具体需求,你还可以进一步扩展和定制这个功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值