2017-04-21 15 views
2

我的android應用程序的問題是,當我計算其中包含emojis的字符串的長度時,每個表情符號會計爲兩個或多個字符。我正在研究具有iOS版本的應用的Android版本。 iOS將每個表情符號統計爲一個字符 - 當索引從iOS應用程序返回時,它假定每個表情符號都被計爲一個。通過僅將emojis作爲一個字符來計算字符串中的字符正確索引

「嗨,我愛@team」

我想獲得@team,指數當我的唯一信息是通過iOS版給出的指數是13,在Android這也許14甚至15

回答

1

以爲我應該發佈我的答案,因爲我有兩個upvotes。

決定最好將iOS索引作爲「真實」,Android索引作爲「假」,這導致我不得不將所有內容都轉換爲iOS索引。 graphemeGetIndex從Java的「假」中獲得iOS的「真實」索引,而grahemeGetLength則獲得「真正」的長度以滿足您的需求。

問你是否有任何問題

public static int graphemeLength(String s) { 
     BreakIterator it = BreakIterator.getCharacterInstance(); 
     it.setText(s); 
     int count = 0; 
     while (it.next() != BreakIterator.DONE) { 
      count++; 
     } 
     return count; 
    } 

public static int graphemeGetIndex(String wholeString, int mIndex) { 
    BreakIterator it = BreakIterator.getCharacterInstance(); 
    int realStartIndex = 0; 
    if (mIndex >= 0) { 
     String partString = wholeString.substring(0, mIndex); 
     it.setText(partString); 
     while (it.next() != BreakIterator.DONE) { 
      realStartIndex++; 
     } 
    } 
    return realStartIndex; 
} 

private void recalculateIndices() { 
     for (final UserMention mention : mMentions) { 
      final int startFake = mCurrentText.indexOf("@" + mention.getName()); 
      final int startReal = graphemeGetIndex(mCurrentText, startFake); 
      mention.setRealIndices(new int[]{startReal, startReal + graphemeLength(mention.getName())}); 
      mention.setJavaFakeIndices(new int[]{startFake, startFake + mention.getName().length()}); 
     } 
    } 
1

這個答案建議使用碼點 Java的Unicode支持。

表情符號符號(字形)是Unicode 代碼點。 Java在內部也使用Unicode,但通常是(UTF-16)char一個兩字節的代碼,而且一個表情符號的代碼點的Unicode號碼要高得多。因此,java使用幾個字符。以emojis開頭。

但是可以在java中使用代碼點。 Java 8有一些額外的幫助;不需要,但我希望Android已經達到某種功能。

以在代碼點長度:

int codePointsLength(String s) { 
    int n = 0; 
    for (int i = 0; i < s.length();) { 
     int codePoint = s.codePointAt(i); 
     i += Character.charCount(codePoint); 
     ++n; 
    } 
    return n; 
} 

int codePointsLength(String s) { 
    return (int) s.codePoints().count(); // Java 8. 
} 

使從一個表情符號的字符串,利用Unicode代碼點:

final int RAISED_EYEBROW = 0x1f928; // U+1F928. 
String s = new String(new int[] {RAISED_EYEBROW}, 0, 1); 

查找由代碼點索引的字符串的位置:

int codePointIndexOf(String s, int codePoint) { 
    int n = 0; 
    for (int i = 0; i < s.length();) { 
     int cp = s.codePointAt(i); 
     if (cp == codePoint) { 
      return n; 
     } 
     i += Character.charCount(cp); 
     ++n; 
    } 
    return -1; 
} 

// Java 9 takeWhile. 
int codePointIndexOf(String s, int codePoint) { 
    int totalCount = (int) s.codePoints().count(); 
    int count = (int) s.codePoints().takeWhile(cp -> cp != codePoint).count(); 
    return count >= totalCount ? -1 : count; 
} 
相關問題