Android中带有图像的自定义表情符号键盘 [英] Custom Emoji Keyboard in Android with Images

查看:121
本文介绍了Android中带有图像的自定义表情符号键盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在android中创建自己的表情符号键盘.用户应该可以选择此键盘作为其Android手机的输入法.

I want to create my own emoji keyboard in android. User should be able to select this keyboard as an input method for his android phone.

我尝试创建它,并且可以在我的应用程序中使用它,但是我不知道如何将其用作输入法,因此该键盘可用于手机中的所有其他应用程序.我读过某个地方,我必须为此创建一个服务,以使其与输入服务绑定.除此之外,我无法理解其余内容.

I tried creating it and I am able to use it in my app but I have no idea how to make this as an input method so this keyboard will be available to all other apps in my phone. I read somewhere that I have to create a service for that so that it bind with input service.Other than that I am not able to understand rest of the thing.

这就是我所做的.尽管它与我要执行的操作不同,但是它是开始并且不知道如何进一步进行.

Here is what I did. Though it is different from what I want to do but is start and don't know how to proceed further.

public class MainActivity extends FragmentActivity implements EmoticonsGridAdapter.KeyClickListener {

private static final int NO_OF_EMOTICONS = 100;

private ListView chatList;
private View popUpView;
private ArrayList<Spanned> chats;
private ChatListAdapter mAdapter;

private LinearLayout emoticonsCover;
private PopupWindow popupWindow;

private int keyboardHeight; 
private EditText content;

private LinearLayout parentLayout;

private boolean isKeyBoardVisible;

private Bitmap[] emoticons;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    chatList = (ListView) findViewById(R.id.chat_list);     

    parentLayout = (LinearLayout) findViewById(R.id.list_parent);

    emoticonsCover = (LinearLayout) findViewById(R.id.footer_for_emoticons);

    popUpView = getLayoutInflater().inflate(R.layout.emoticons_popup, null);

    // Setting adapter for chat list
    chats = new ArrayList<Spanned>();
    mAdapter = new ChatListAdapter(getApplicationContext(), chats);
    chatList.setAdapter(mAdapter);
    chatList.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (popupWindow.isShowing())
                popupWindow.dismiss();  
            return false;
        }
    });

    // Defining default height of keyboard which is equal to 230 dip
    final float popUpheight = getResources().getDimension(
            R.dimen.keyboard_height);
    changeKeyboardHeight((int) popUpheight);

    // Showing and Dismissing pop up on clicking emoticons button
    ImageView emoticonsButton = (ImageView) findViewById(R.id.emoticons_button);
    emoticonsButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (!popupWindow.isShowing()) {

                popupWindow.setHeight((int) (keyboardHeight));

                if (isKeyBoardVisible) {
                    emoticonsCover.setVisibility(LinearLayout.GONE);
                } else {
                    emoticonsCover.setVisibility(LinearLayout.VISIBLE);
                }
                popupWindow.showAtLocation(parentLayout, Gravity.BOTTOM, 0, 0);

            } else {
                popupWindow.dismiss();
            }

        }
    });

    readEmoticons();
    enablePopUpView();
    checkKeyboardHeight(parentLayout);
    enableFooterView();

}

/**
 * Reading all emoticons in local cache
 */
private void readEmoticons () {

    emoticons = new Bitmap[NO_OF_EMOTICONS];
    for (short i = 0; i < NO_OF_EMOTICONS; i++) {           
        emoticons[i] = getImage((i+1) + ".png");
    }

}

/**
 * Enabling all content in footer i.e. post window
 */
private void enableFooterView() {

    content = (EditText) findViewById(R.id.chat_content);
    content.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (popupWindow.isShowing()) {

                popupWindow.dismiss();

            }

        }
    });
    final Button postButton = (Button) findViewById(R.id.post_button);      

    postButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (content.getText().toString().length() > 0) {

                Spanned sp = content.getText();                 
                chats.add(sp);
                content.setText("");                    
                mAdapter.notifyDataSetChanged();

            }

        }
    });
}

/**
 * Overriding onKeyDown for dismissing keyboard on key down
 */
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (popupWindow.isShowing()) {
        popupWindow.dismiss();
        return false;
    } else {
        return super.onKeyDown(keyCode, event);
    }
}

/**
 * Checking keyboard height and keyboard visibility
 */
int previousHeightDiffrence = 0;
private void checkKeyboardHeight(final View parentLayout) {

    parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {

                    Rect r = new Rect();
                    parentLayout.getWindowVisibleDisplayFrame(r);

                    int screenHeight = parentLayout.getRootView()
                            .getHeight();
                    int heightDifference = screenHeight - (r.bottom);

                    if (previousHeightDiffrence - heightDifference > 50) {                          
                        popupWindow.dismiss();
                    }

                    previousHeightDiffrence = heightDifference;
                    if (heightDifference > 100) {

                        isKeyBoardVisible = true;
                        changeKeyboardHeight(heightDifference);

                    } else {

                        isKeyBoardVisible = false;

                    }

                }
            });

}

/**
 * change height of emoticons keyboard according to height of actual
 * keyboard
 * 
 * @param height
 *            minimum height by which we can make sure actual keyboard is
 *            open or not
 */
private void changeKeyboardHeight(int height) {

    if (height > 100) {
        keyboardHeight = height;
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LayoutParams.MATCH_PARENT, keyboardHeight);
        emoticonsCover.setLayoutParams(params);
    }

}

/**
 * Defining all components of emoticons keyboard
 */
private void enablePopUpView() {

    ViewPager pager = (ViewPager) popUpView.findViewById(R.id.emoticons_pager);
    pager.setOffscreenPageLimit(3);
    pager.setBackgroundColor(Color.WHITE);
    ArrayList<String> paths = new ArrayList<String>();

    for (short i = 1; i <= NO_OF_EMOTICONS; i++) {          
        paths.add(i + ".png");
    }

    EmoticonsPagerAdapter adapter = new EmoticonsPagerAdapter(MainActivity.this, paths, this);
    pager.setAdapter(adapter);

    // Creating a pop window for emoticons keyboard
    popupWindow = new PopupWindow(popUpView, LayoutParams.MATCH_PARENT,
            (int) keyboardHeight, false);

    /*TextView backSpace = (TextView) popUpView.findViewById(R.id.back);
    backSpace.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
            content.dispatchKeyEvent(event);    
        }
    });*/

    popupWindow.setOnDismissListener(new OnDismissListener() {

        @Override
        public void onDismiss() {
            emoticonsCover.setVisibility(LinearLayout.GONE);
        }
    });
}

/**
 * For loading smileys from assets
 */
private Bitmap getImage(String path) {
    AssetManager mngr = getAssets();
    InputStream in = null;
    try {
        in = mngr.open("emoticons/" + path);
    } catch (Exception e) {
        e.printStackTrace();
    }

    Bitmap temp = BitmapFactory.decodeStream(in, null, null);
    return temp;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    return true;
}

@Override
public void keyClickedIndex(final String index) {

    ImageGetter imageGetter = new ImageGetter() {
        public Drawable getDrawable(String source) {    
            StringTokenizer st = new StringTokenizer(index, ".");
            Drawable d = new BitmapDrawable(getResources(),emoticons[Integer.parseInt(st.nextToken()) - 1]);
            d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
            return d;
        }
    };

    Spanned cs = Html.fromHtml("<img src ='"+ index +"'/>", imageGetter, null);        

    int cursorPosition = content.getSelectionStart();       
    content.getText().insert(cursorPosition, cs);

}

}

这是我已实现的自定义键盘的代码,但无法找到如何向该键盘添加表情符号.

This is the code for custom keyboard that I have implemented but I am unable to find how to add emoji to that keyboard.

  public class SimpleIME extends InputMethodService
        implements KeyboardView.OnKeyboardActionListener {

    private KeyboardView kv;
    private Keyboard keyboard;
    private View popUpView;
    private boolean caps = false;
    @Override
    public View onCreateInputView() {
        kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
        keyboard = new Keyboard(this, R.xml.qwerty);
        kv.setKeyboard(keyboard);
        kv.setOnKeyboardActionListener(this);
        kv.invalidateAllKeys();
        popUpView = getLayoutInflater().inflate(R.layout.emoticons_popup, null);
        return kv;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        InputConnection ic = getCurrentInputConnection();
        playClick(primaryCode);
        switch(primaryCode){
            case Keyboard.KEYCODE_DELETE :
                ic.deleteSurroundingText(1, 0);
                break;
            case Keyboard.KEYCODE_SHIFT:
                caps = !caps;
                keyboard.setShifted(caps);
                kv.invalidateAllKeys();
                break;
            case Keyboard.KEYCODE_DONE:
                ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
                break;
            case -80 :
                Log.d("smiley", "smiley pressed");

                break;
            default:
                char code = (char)primaryCode;
                if(Character.isLetter(code) && caps){
                    code = Character.toUpperCase(code);
                }
                ic.commitText(String.valueOf(code),1);
        }
    }

    private void playClick(int keyCode){
        AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
        switch(keyCode){
            case 32:
                am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);
                break;
            case Keyboard.KEYCODE_DONE:
            case 10:
                am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);
                break;
            case Keyboard.KEYCODE_DELETE:
                am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);
                break;
            default: am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
        }
    }


    @Override
    public void onPress(int primaryCode) {
    }

    @Override
    public void onRelease(int primaryCode) {
    }

    @Override
    public void onText(CharSequence text) {
    }

    @Override
    public void swipeDown() {
    }

    @Override
    public void swipeLeft() {
    }

    @Override
    public void swipeRight() {
    }

    @Override
    public void swipeUp() {
    }

}

我们可以从图像列表中复制图像并将其粘贴到打开键盘的位置吗?

Can we copy an image from images list and paste it where keyboard is open??

推荐答案

我发现的表情符号键盘的最佳实现是滑动表情符号键盘这是一个非常好的实现,也许带有一些冗余代码,但是对于理解如何实现不适合普通的按钮到文本"键盘的键盘仍然非常有用.

The best implementation for an emoji keyboard I found was that of sliding emoji-Keyboard It's a really good implementation, maybe with some redundant code, but still really good for understanding how to implement keyboards that do not fit the normal "button-to-text" keyboards.

更新

好的,我现在已经能够成功集成 滑动emoji键盘 到我自己的项目 8Vim 中,项目.

Okay, I have now been able to successfully able to integrate the sliding emoji-keyboard into my own project 8Vim after a lot of re-factoring in both of the projects.

本质上,表情符号键盘的全部工作是创建键盘大小的视图,然后用与表情符号对应的PNG文件填充该视图.每个图像都像一个按钮,并向inputConnection传递适当的表情符号.

Essentially, all you are doing for the emoji keyboard is to create a view of the size of the keyboard and then populating that view with PNG files corresponding to the emoji's. each image acts like a button and delivers the appropriate emoji to the inputConnection.

更新2

我扩展了滑动emoji键盘,并创建了一个更简洁的版本更容易理解.看看我的表情符号键盘

I have extended the sliding emoji-keyboard and created a much cleaner version that should be easier to understand. Take a look at my emoji-keyboard

这篇关于Android中带有图像的自定义表情符号键盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆