腾讯IM : 如何替换String 表情库

描述: 在使用腾讯Im的时候,表情库是图片+配置文件, 因为当时项目要上国际版,所以需要更换表情库,特在此记录一下. 主要是找到对应的图片库,替换成自己的, 还有关于布局样式做一些适配调整

第一步: String文件中

<string name="emojin">["😄", "😀", "😁", "😂", "😃", "😅", "😆", "😇", "😉", "😊", "😋",
                       "😌", "😍", "😎", "😏", "😐", "😑", "😒", "😓", "😔", "😕", "😖",
                       "😗", "😘", "😙", "😚", "😛", "😜", "😝", "😞", "😟", "😠", "😡",
                       "😢", "😣", "😤", "😥", "😦", "😧", "😨", "😩", "😪", "😫", "😬",
                       "😭", "😮", "😯", "😰", "😱", "😲", "😳", "😴", "😵", "😶", "😷",
                       "💩", "👼", "😸", "😹", "😺", "😻", "😼", "😽", "😾", "😿", "🙀",
                       "🙅", "🙆", "🙇", "🙋", "🙌", "🙍", "🙎", "🙏", "👦", "👧", "👨",
                       "👩", "👪", "👫", "👬", "👭", "👮", "👯", "👰", "👱", "👲", "👳",
                       "👴", "👵", "👶", "👷", "👸", "💁", "💂", "💏", "💑", "🚶", "👽",
                       "👻", "👹", "👺", "😈", "👿", "🙈", "🙉", "🙊", "💓", "💔", "💕",
                       "💖", "💗", "💘", "💙", "💚", "💛", "💜", "💝", "💞", "💟", "💠",
                       "💡", "🌸", "🌹", "🌺", "🌻", "👀", "👂", "👃", "👄", "👅", "👆",
                       "👇", "👈", "👉", "👊", "👋", "👌", "👍", "👎", "👏", "🖖", "✊",
                       "✋", "💪"]</string>

第二步: 腾讯的FaceManager类中进行表情库的替换,这里只帖部分代码

public class FaceManager {

    private static final int drawableWidth = ScreenUtil.getPxByDp(32);
    private static ArrayList<Emoji> emojiList = new ArrayList<>();
    private static LruCache<String, Bitmap> drawableCache = new LruCache(1024);
    private static Context context = TUIKit.getAppContext();
    private static String[] emojiFilters = context.getResources().getStringArray(R.array.emoji_filter);

    private static ArrayList<String> list=new ArrayList<>();


    private static ArrayList<FaceGroup> customFace = new ArrayList<>();

    public static ArrayList<Emoji> getEmojiList() {
        return emojiList;
    }

    public static ArrayList<FaceGroup> getCustomFaceList() {
        return customFace;
    }


    public static Bitmap getCustomBitmap(int groupId, String name) {
        for (int i = 0; i < customFace.size(); i++) {
            FaceGroup group = customFace.get(i);
            if (group.getGroupId() == groupId) {
                ArrayList<Emoji> faces = group.getFaces();
                for (int j = 0; j < faces.size(); j++) {
                    Emoji face = faces.get(j);
                    if (face.getFilter().equals(name)) {
                        return face.getIcon();
                    }
                }

            }
        }
        return null;
    }

    public static void loadFaceFiles() {
        new Thread() {
            @Override
            public void run() {
//                for (int i = 0; i < emojiFilters.length; i++) {
//                    loadAssetBitmap(emojiFilters[i], "emoji/" + emojiFilters[i] + "@2x.png", true);
//                }
                //图片表情,这里用了string文件里的表情库
                String emgion=context.getString(R.string.emojin);
                Gson gson = new Gson();
                list = gson.fromJson(emgion, new TypeToken<List<String>>() {}.getType());

                for(int i=0;i<list.size();i++){
                    Emoji emoji=new Emoji();
                    emoji.setImgEmojistr(list.get(i));
                    emojiList.add(emoji);
                }

//                CustomFaceConfig config = TUIKit.getConfigs().getCustomFaceConfig();
//                if (config == null) {
//                    return;
//                }
//                List<CustomFaceGroup> groups = config.getFaceGroups();
//                if (groups == null) {
//                    return;
//                }
//                for (int i = 0; i < groups.size(); i++) {
//                    CustomFaceGroup groupConfigs = groups.get(i);
//                    FaceGroup groupInfo = new FaceGroup();
//                    groupInfo.setGroupId(groupConfigs.getFaceGroupId());
//                    groupInfo.setDesc(groupConfigs.getFaceIconName());
//                    groupInfo.setPageColumnCount(groupConfigs.getPageColumnCount());
//                    groupInfo.setPageRowCount(groupConfigs.getPageRowCount());
//                    groupInfo.setGroupIcon(loadAssetBitmap(groupConfigs.getFaceIconName(), groupConfigs.getFaceIconPath(), false).getIcon());
//                    ArrayList<CustomFace> customFaceArray = groupConfigs.getCustomFaceList();
//                    ArrayList<Emoji> faceList = new ArrayList<>();
//                    for (int j = 0; j < customFaceArray.size(); j++) {
//                        CustomFace face = customFaceArray.get(j);
//                        Emoji emoji = loadAssetBitmap(face.getFaceName(), face.getAssetPath(), false);
//                        emoji.setWidth(face.getFaceWidth());
//                        emoji.setHeight(face.getFaceHeight());
//                        faceList.add(emoji);
//
//                    }
//                    groupInfo.setFaces(faceList);
//                    customFace.add(groupInfo);
//                }
            }
        }.start();
    }

    private static Emoji loadAssetBitmap(String filter, String assetPath, boolean isEmoji) {
        InputStream is = null;
        try {
            Emoji emoji = new Emoji();
            Resources resources = context.getResources();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inDensity = DisplayMetrics.DENSITY_XXHIGH;
            options.inScreenDensity = resources.getDisplayMetrics().densityDpi;
            options.inTargetDensity = resources.getDisplayMetrics().densityDpi;
            context.getAssets().list("");
            is = context.getAssets().open(assetPath);
            Bitmap bitmap = BitmapFactory.decodeStream(is, new Rect(0, 0, drawableWidth, drawableWidth), options);
            if (bitmap != null) {
                drawableCache.put(filter, bitmap);
                emoji.setIcon(bitmap);
                emoji.setFilter(filter);
                if (isEmoji) {
                    emojiList.add(emoji);
                }

            }
            return emoji;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


    public static int calculateInSampleSize(BitmapFactory.Options options,
                                            int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            // 计算出实际宽高和目标宽高的比率
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
            // 一定都会大于等于目标的宽和高。
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {
        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public static boolean isFaceChar(String faceChar) {
        return drawableCache.get(faceChar) != null;
    }


    public static void handlerEmojiText(TextView comment, String content, boolean typing) {
        SpannableStringBuilder sb = new SpannableStringBuilder(content);
        String regex = "\\[(\\S+?)\\]";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(content);
        boolean imageFound = false;

        while (m.find()) {
            String emojiName = m.group();
          //  Bitmap bitmap = drawableCache.get(emojiName);
            if (emojiName != null) {
                imageFound = true;
                sb.setSpan(emojiName,
                        m.start(), m.end(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
            }
        }
        // 如果没有发现表情图片,并且当前是输入状态,不再重设输入框
        if (!imageFound && typing) {
            return;
        }
        int selection = comment.getSelectionStart();
        comment.setText(sb);
        if (comment instanceof EditText) {
            ((EditText) comment).setSelection(selection);
        }
    }

    public static Bitmap getEmoji(String name) {
        return drawableCache.get(name);
    }
}
第二步: 在Emoji 类中重新声明一个变量,用来存放String对应的emgion

第三步: FaceFragment  里进行表情库的替换

public class FaceFragment extends BaseInputFragment implements View.OnClickListener {

    ViewPager faceViewPager;
    EmojiIndicatorView faceIndicator;
    FaceGroupIcon faceFirstSetTv;
    FaceGroupIcon mCurrentSelected;
    LinearLayout faceGroup;
    ArrayList<View> ViewPagerItems = new ArrayList<>();
    ArrayList<Emoji> emojiList;
    ArrayList<Emoji> recentlyEmojiList;
    ArrayList<FaceGroup> customFaces;
    private int mCurrentGroupIndex = 0;
    private int columns = 7;
    private int rows = 3;
    private int vMargin = 0;
    private OnEmojiClickListener listener;
    private RecentEmojiManager recentManager;

    public static FaceFragment Instance() {
        FaceFragment instance = new FaceFragment();
        Bundle bundle = new Bundle();
        instance.setArguments(bundle);
        return instance;
    }

    public void setListener(OnEmojiClickListener listener) {
        this.listener = listener;
    }

    @Override
    public void onAttach(Activity activity) {
        if (activity instanceof OnEmojiClickListener) {
            this.listener = (OnEmojiClickListener) activity;
        }
        recentManager = RecentEmojiManager.make(activity);
        super.onAttach(activity);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        emojiList = FaceManager.getEmojiList();
        try {
            if (recentManager.getCollection(RecentEmojiManager.PREFERENCE_NAME) != null) {
                recentlyEmojiList = (ArrayList<Emoji>) recentManager.getCollection(RecentEmojiManager.PREFERENCE_NAME);
            } else {
                recentlyEmojiList = new ArrayList<>();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_face, container, false);
        ViewGroup.LayoutParams params = view.getLayoutParams();
        params.height = SoftKeyBoardUtil.getSoftKeyBoardHeight();
        view.setLayoutParams(params);
        faceViewPager = view.findViewById(R.id.face_viewPager);
        faceIndicator = view.findViewById(R.id.face_indicator);
        faceFirstSetTv = view.findViewById(R.id.face_first_set);
        faceGroup = view.findViewById(R.id.face_view_group);
        initViews();
        return view;
    }

    private void initViews() {
        initViewPager(emojiList, 7, 3);
        mCurrentSelected = faceFirstSetTv;
        faceFirstSetTv.setSelected(true);
        faceFirstSetTv.setOnClickListener(this);
        customFaces = FaceManager.getCustomFaceList();

        int width = ScreenUtil.getPxByDp(70);
        for (int i = 0; i < customFaces.size(); i++) {
            final FaceGroup group = customFaces.get(i);
            FaceGroupIcon faceBtn = new FaceGroupIcon(getActivity());
            faceBtn.setFaceTabIcon(group.getGroupIcon());

            faceBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mCurrentSelected != v) {
                        mCurrentGroupIndex = group.getGroupId();
                        ArrayList<Emoji> faces = group.getFaces();
                        mCurrentSelected.setSelected(false);
                        initViewPager(faces, group.getPageColumnCount(), group.getPageRowCount());
                        mCurrentSelected = (FaceGroupIcon) v;
                        mCurrentSelected.setSelected(true);
                    }

                }
            });
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.MATCH_PARENT);
            faceGroup.addView(faceBtn, params);

        }


    }

    private void initViewPager(ArrayList<Emoji> list, int columns, int rows) {
        this.columns = columns;
        this.rows = rows;
        if (list.size() > 0) {
            vMargin = (SoftKeyBoardUtil.getSoftKeyBoardHeight() - (ScreenUtil.getPxByDp(40 + 20) + list.get(0).getHeight() * rows)) / 4;
        }

        intiIndicator(list);
        ViewPagerItems.clear();
        int pageCont = getPagerCount(list);
        for (int i = 0; i < pageCont; i++) {
            ViewPagerItems.add(getViewPagerItem(i, list));
        }
        FaceVPAdapter mVpAdapter = new FaceVPAdapter(ViewPagerItems);
        faceViewPager.setAdapter(mVpAdapter);
        faceViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            int oldPosition = 0;

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                faceIndicator.playBy(oldPosition, position);
                oldPosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    private void intiIndicator(ArrayList<Emoji> list) {
        faceIndicator.init(getPagerCount(list));
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.face_first_set) {
           /* if (faceIndicator.getVisibility() == View.GONE) {
                faceIndicator.setVisibility(View.VISIBLE);
            }*/
            if (mCurrentSelected != v) {
                mCurrentGroupIndex = 0;
                mCurrentSelected.setSelected(false);
                mCurrentSelected = (FaceGroupIcon) v;
                initViewPager(emojiList, 7, 3);
                mCurrentSelected.setSelected(true);

            }

        }
    }

    /**
     * 根据表情数量以及GridView设置的行数和列数计算Pager数量
     *
     * @return
     */
    private int getPagerCount(ArrayList<Emoji> list) {
        int count = list.size();
        int dit = 1;
        if (mCurrentGroupIndex > 0)
            dit = 0;
        return count % (columns * rows - dit) == 0 ? count / (columns * rows - dit)
                : count / (columns * rows - dit) + 1;
    }

    private View getViewPagerItem(int position, ArrayList<Emoji> list) {
        LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout = inflater.inflate(R.layout.layout_face_grid, null);//表情布局
        GridView gridview = layout.findViewById(R.id.chart_face_gv);
        /**
         * 注:因为每一页末尾都有一个删除图标,所以每一页的实际表情columns * rows - 1; 空出最后一个位置给删除图标
         * */
        final List<Emoji> subList = new ArrayList<>();
        int dit = 1;
        if (mCurrentGroupIndex > 0)
            dit = 0;
        subList.addAll(list.subList(position * (columns * rows - dit),
                (columns * rows - dit) * (position + 1) > list
                        .size() ? list.size() : (columns
                        * rows - dit)
                        * (position + 1)));
        /**
         * 末尾添加删除图标
         * */
        if (mCurrentGroupIndex == 0 && subList.size() < (columns * rows - dit)) {
            for (int i = subList.size(); i < (columns * rows - dit); i++) {
                subList.add(null);
            }
        }
        if (mCurrentGroupIndex == 0) {
            Emoji deleteEmoji = new Emoji();
            deleteEmoji.setIcon(BitmapFactory.decodeResource(getResources(), R.drawable.face_delete));
            subList.add(deleteEmoji);
        }


        FaceGVAdapter mGvAdapter = new FaceGVAdapter(subList, getActivity());
        gridview.setAdapter(mGvAdapter);
        gridview.setNumColumns(columns);
        // 单击表情执行的操作
        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mCurrentGroupIndex > 0) {
                    listener.onCustomFaceClick(mCurrentGroupIndex, subList.get(position));
                } else {
                    if (position == columns * rows - 1) {
                        if (listener != null) {
                            listener.onEmojiDelete();
                        }
                        return;
                    }
                    if (listener != null) {
                        listener.onEmojiClick(subList.get(position));
                    }
                }


                //insertToRecentList(subList.get(position));
            }
        });

        return gridview;
    }

    private void insertToRecentList(Emoji emoji) {
        if (emoji != null) {
            if (recentlyEmojiList.contains(emoji)) {
                //如果已经有该表情,就把该表情放到第一个位置
                int index = recentlyEmojiList.indexOf(emoji);
                Emoji emoji0 = recentlyEmojiList.get(0);
                recentlyEmojiList.set(index, emoji0);
                recentlyEmojiList.set(0, emoji);
                return;
            }
            if (recentlyEmojiList.size() == (rows * columns - 1)) {
                //去掉最后一个
                recentlyEmojiList.remove(rows * columns - 2);
            }
            recentlyEmojiList.add(0, emoji);
        }
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        try {
            recentManager.putCollection(RecentEmojiManager.PREFERENCE_NAME, recentlyEmojiList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public interface OnEmojiClickListener {
        void onEmojiDelete();

        void onEmojiClick(Emoji emoji);

        void onCustomFaceClick(int groupIndex, Emoji emoji);
    }

    class FaceGVAdapter extends BaseAdapter {
        private List<Emoji> list;
        private Context mContext;

        public FaceGVAdapter(List<Emoji> list, Context mContext) {
            super();
            this.list = list;
            this.mContext = mContext;
        }


        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            Emoji emoji = list.get(position);
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_face, null);
                holder.iv = convertView.findViewById(R.id.face_image);
                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) holder.iv.getLayoutParams();
                if (emoji != null) {
                    params.width = emoji.getWidth();
                    params.height = emoji.getHeight();
                }
                if (position / columns == 0) {
                    params.setMargins(0, vMargin, 0, 0);
                } else if (rows == 2) {
                    params.setMargins(0, vMargin, 0, 0);
                } else {
                    if (position / columns < rows - 1) {
                        params.setMargins(0, vMargin, 0, vMargin);
                    } else {
                        params.setMargins(0, 0, 0, vMargin);
                    }
                }

                holder.iv.setLayoutParams(params);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            if (emoji != null) {
                if(position == columns * rows - 1){
                    /**
                     * 说明此时是删除按钮的位置下标,单独设置图片
                     */
                    holder.iv.setBackground(mContext.getResources().getDrawable(R.drawable.face_delete));
                }else {
                    holder.iv.setText(emoji.getImgEmojistr());
                }
            }
            return convertView;
        }

        class ViewHolder {
            TextView iv;
        }
    }

    class FaceVPAdapter extends PagerAdapter {
        // 界面列表
        private List<View> views;

        public FaceVPAdapter(List<View> views) {
            this.views = views;
        }

        @Override
        public void destroyItem(View arg0, int arg1, Object arg2) {
            ((ViewPager) arg0).removeView((View) (arg2));
        }

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

        // 初始化arg1位置的界面
        @Override
        public Object instantiateItem(View arg0, int arg1) {
            ((ViewPager) arg0).addView(views.get(arg1));
            return views.get(arg1);
        }

        // 判断是否由对象生成界
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return (arg0 == arg1);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值