3

I put this code from answer Displaying emoticons in Android for showing emoticons in Edittext but I have a problem when I'm typing a lot of text, it becomes slower and slower and almost impossible to type. This is the code: How can I make it faster?

 textS.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                addSmiledText(Main.this, s);
               // Log.e("",s.toString());

            }
        });}


     private static final HashMap<String, Integer> emoticons = new HashMap<String, Integer>();
     static {
         emoticons.put(":)", R.drawable.face_smile);
         emoticons.put(":-)", R.drawable.face_smile);
         emoticons.put(":(", R.drawable.face_sad);
         emoticons.put(":-(", R.drawable.face_sad);
         emoticons.put(":-D", R.drawable.face_smile_big);
         emoticons.put(":D", R.drawable.face_smile_big);
         emoticons.put(":lol:", R.drawable.face_laughing);
            emoticons.put("8)", R.drawable.face_cool);
            emoticons.put(";)", R.drawable.face_wink);
           emoticons.put(";-)", R.drawable.face_wink);
            emoticons.put(";(", R.drawable.face_crying);
           ...

     }
     public static Spannable addSmiledText(Context ch, Editable s) {

            int index;
            for (index = 0; index < s.length(); index++) {
                for (Entry<String, Integer> entry : emoticons.entrySet()) {
                    int length = entry.getKey().length();
                    if (index + length > s.length())
                        continue;
                    if (s.subSequence(index, index + length).toString().equals(entry.getKey())) {
                        s.setSpan(new ImageSpan(ch, entry.getValue()), index, index + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        index += length - 1;
                        break;
                    }
                }
            }
            return s;
        }
Community
  • 1
  • 1
androidEnthusiast
  • 1,140
  • 1
  • 12
  • 21
  • When you profiled your code with Traceview, what did you find? – CommonsWare Sep 26 '12 at 12:20
  • http://developer.android.com/tools/debugging/debugging-tracing.html What you will find is that scanning a character at a time through the entire string is not a very efficient way of seeing if the last-typed character somehow creates an emoticon. – CommonsWare Sep 26 '12 at 13:12
  • I know that is not efficient but how to make it to scan only two last characters? For examle, I insert "ab" it scans=ab, then I add "c"= "abc" it scans only bc. – androidEnthusiast Sep 26 '12 at 14:57
  • Maybe you should look at using TransformationMethod, which seemed to be designed for this sort of thing? – Andrew Mackenzie Dec 03 '12 at 16:28

2 Answers2

2

how to make it to scan only two last characters?

You have:

for (index = 0; index < s.length(); index++)

If you do not want to scan the entire string each time, choose a better starting value for index.

For example, since your minimum-length emoticon has two characters and your maximum-length emoticon has five characters, skip the loop entirely for Editable objects of length 0 or 1, and then have index start at s.length()-5.

Note, though, that afterTextChanged() is not only called for changes at the end. The user might have repositioned the cursor to be somewhere in the middle. Hence, you really should be scanning in onTextChanged() and looking at the window of text around the point of the change.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thank you for guidelines, I'll try to set it like this. Thank you once again. :) – androidEnthusiast Sep 26 '12 at 15:23
  • Ok, I'm trying for two days to make it work and nothing... If I can set it to range from s.length()-5, it won't show emoticons. It only works in this way like I posted above but it is very slow. So I don't really know what to do anymore. Maybe I should try it in some completely other way, what do you think? Is this a bad way to do that? – androidEnthusiast Sep 29 '12 at 22:32
  • @Natasa.M: I have never attempted to implement an emoticon converter algorithm. That being said, others *have* implemented them, probably hundreds of times, so I would focus on finding an efficient existing algorithm. – CommonsWare Sep 30 '12 at 18:39
0

In order to scan last 2 characters instead of

for (index = 0; index < s.length(); index++)

use

int start = s.length() - 1;
int end = start - 2;
for (index = start; index > end; index--)

This way you start looping from the last element backwards until you looped 2 positions.

bancer
  • 7,475
  • 7
  • 39
  • 58