Blackberry: смайлики в приложении чата - PullRequest
4 голосов
/ 01 сентября 2011

Я хочу сделать приложение чата, где нужны смайлики. Я пытался написать свой собственный TextBox для обработки некоторых символов Unicode и заменить их на смайлики и смайлики, но это была тяжелая работа, и я столкнулся со многими проблемами.

Затем я попытался создать собственный шрифт, в котором были бы смайлики, но обнаружил, что шрифт сделан черно-белым и не может быть цветным.

Затем я попытался использовать другие поля EditField, поэтому, когда я нахожу растровое изображение, я рисую его и запускаю другое поле EditField, но это не сработало для нескольких линий, и возникли проблемы с выделением.

Лучшим способом было написать свой собственный textField, в котором будет найден специальный символ Unicode, добавить 2 пробела, получить местоположение символа Unicode, а затем нарисовать растровое изображение в этом месте. Но это было очень медленно, когда количество смайликов становится больше

Есть ли какой-нибудь инструмент, API или способ, который я пропустил, который будет делать смайлики для меня на устройствах BlackBerry? Пожалуйста, помогите в этой теме, которую я искал везде и пока ничего не нашел

1 Ответ

3 голосов
/ 22 октября 2011

Мы могли бы попытаться использовать подход веб-форумов:

  • позволяет пользователям вводить коды ASCII для смайликов
  • в режиме редактирования сообщения показывать смайлики в виде текстовых кодов
  • в истории сообщений показывает смайлики в виде изображений (для этой цели используйте BrowserField )
  • использовать дополнительное форматирование HTML

simulator screen shot with chat application

Попробуйте этот код:

public final class ChatScreen extends MainScreen implements FieldChangeListener {
    static final int INT_MSG_MAX_LEN = 200;
    static final DateFormat FRMT_TIME = DateFormat
            .getInstance(DateFormat.TIME_SHORT);
    static final String STR_FRMT_IMG = "<img src=\"{0}\"></img>";
    static final String STR_FRMT_MSG = "<b>{0}</b> [{1}]: {2}</p>";

    // several emoticon ASCII codes
    static final String STR_CODE_SMILE = ":)";
    static final String STR_CODE_SADSMILE = ":(";
    static final String STR_CODE_WINK = ";)";

    // use emoticons from http://www.skypeemoticonslist.com
    static final String STR_IMG_URL = "http://www.skypeemoticonslist.com/images/";
    static final String STR_IMG_NAME_SMILE = "emoticon-0100-smile.png";
    static final String STR_IMG_NAME_SADSMILE = "emoticon-0101-sadsmile.png";
    static final String STR_IMG_NAME_WINK = "emoticon-0105-wink.png";

    static final Hashtable TABLE_URL = new Hashtable();
    static final Hashtable TABLE_IMG = new Hashtable();

    private static void initCode(String code, String imgFName) {
        String tag;
        // prepare table for online use
        // generate img tag with live url
        tag = MessageFormat.format(STR_FRMT_IMG, new Object[] { STR_IMG_URL
                + imgFName });
        TABLE_URL.put(code, tag);

        // prepare table for offline use
        // retrieve image from project resources
        try {
            EncodedImage img = EncodedImage.getEncodedImageResource(imgFName);
            // generate img tag with embedded data url
            String dataStr = getDataUrl(img.getData(), img.getMIMEType());
            tag = MessageFormat.format(STR_FRMT_IMG, new Object[] { dataStr });
            TABLE_IMG.put(code, tag);
        } catch (IOException e) {
            System.out.println("\n Troubles preparing res for code " + code
                    + "  \n");
        }
    }

    static {
        initCode(STR_CODE_SMILE, STR_IMG_NAME_SMILE);
        initCode(STR_CODE_SADSMILE, STR_IMG_NAME_SADSMILE);
        initCode(STR_CODE_WINK, STR_IMG_NAME_WINK);
    }

    boolean mIsOffline = true;
    String mChatHistory = "";

    BrowserField mBrowserField = new BrowserField();
    EditField mTextField = new EditField("Input message: ", "",
            INT_MSG_MAX_LEN, Field.USE_ALL_WIDTH);
    ButtonField mBtnUserLeft = new ButtonField("Send as Mr. Left",
            Field.FIELD_LEFT | ButtonField.CONSUME_CLICK);
    ButtonField mBtnUserRight = new ButtonField("Send as Mr. Right",
            Field.FIELD_RIGHT | ButtonField.CONSUME_CLICK);

    public ChatScreen() {
        super(Manager.NO_VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLLBAR);
        add(mTextField);
        HorizontalFieldManager hfm = new HorizontalFieldManager(
                Field.USE_ALL_WIDTH | Field.FIELD_HCENTER);
        mBtnUserLeft.setChangeListener(this);
        mBtnUserRight.setChangeListener(this);
        hfm.add(mBtnUserLeft);
        hfm.add(mBtnUserRight);
        add(hfm);
        VerticalFieldManager vfm = new VerticalFieldManager(Field.USE_ALL_WIDTH
                | Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
        vfm.add(mBrowserField);
        add(vfm);
    }

    protected void makeMenu(Menu menu, int instance) {
        menu.add(new MenuItem(mIsOffline ? "Go Online" : "Go Offline", 0, 0) {
            public void run() {
                mIsOffline = !mIsOffline;
            }
        });
        super.makeMenu(menu, instance);
    }

    public void fieldChanged(final Field field, int context) {
        if (field == mBtnUserLeft) {
            addMessage("Mr. Left");
        } else if (field == mBtnUserRight) {
            addMessage("Mr. Right");
        }
    }

    private void addMessage(String userName) {
        String message = mTextField.getText();

        // update message with emoticons
        message = replaceCodeWithImg(message, STR_CODE_SMILE);
        message = replaceCodeWithImg(message, STR_CODE_SADSMILE);
        message = replaceCodeWithImg(message, STR_CODE_WINK);
        String timeStr = FRMT_TIME.format(new Date(System.currentTimeMillis()));
        String text = MessageFormat.format(STR_FRMT_MSG, new Object[] {
                userName, timeStr, message });
        mChatHistory = text + mChatHistory;
        mTextField.setText("");
        // fix IllegalStateException up to
        // http://supportforums.blackberry.com/t5/Java-Development/IllegalStateException-at-displayContent-on-browserfield/td-p/1071991
        mBrowserField.setFocus();

        mBrowserField.displayContent("<html>" + mChatHistory + "</html>", "");
    }

    private String replaceCodeWithImg(String message, String code) {
        Hashtable table = mIsOffline ? TABLE_IMG : TABLE_URL;
        int index = message.indexOf(code);
        while (index != -1) {
            String begin = message.substring(0, index);
            String end = message.substring(index + code.length());
            String tag = (String) table.get(code);
            message = begin + tag + end;

            index = message.indexOf(code, index + tag.length());
        }
        return message;
    }

    // src taken from http://bfo.com/blog/files/src/DataStreamHandler.java
    private static final String getDataUrl(byte[] data, String mimetype)
            throws IOException {
        final StringBuffer sb = new StringBuffer();
        sb.append("data:");
        sb.append(mimetype);
        sb.append(";base64,");
        OutputStream out = new OutputStream() {
            public void write(int c) {
                sb.append((char) (c & 0xFF));
            }
        };
        Base64OutputStream fout = new Base64OutputStream(out);
        fout.write(data);
        fout.close();
        return sb.toString();
    }
}
...