hanggrian / socialview

Android TextView and EditText with hashtag, mention, and hyperlink support
http://hanggrian.com/socialview/
Apache License 2.0
323 stars 81 forks source link

Mention pattern #70

Closed narimanam closed 4 years ago

narimanam commented 4 years ago

Hi, thanks for your good library.I'm using this library for handling mentions in text, i faced with some usernames that have dot in their string, so i need a solution that can modify PATTERN_MENTION in library. how can i do that?

strangel3t commented 4 years ago
private fun SocialEditText.setPattern(pattern: String) {
    val impl = SocialEditText::class.java.getDeclaredField("impl")
    impl.isAccessible = true
    val socialView = impl.get(this) as SocialView
    val PATTERN_MENTION = SocialView::class.java.getDeclaredField("PATTERN_MENTION")
    PATTERN_MENTION.isAccessible = true
    PATTERN_MENTION.set(socialView, Pattern.compile(pattern))
    impl.set(this, socialView)
}

Had the same problem. Resolved using reflection and kotlin extension functions.

gim- commented 4 years ago

Java variant of @strangel3t solution using reflection API

import android.util.Log;

import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import com.hendraanggrian.appcompat.widget.SocialEditText;
import com.hendraanggrian.appcompat.widget.SocialView;

import java.lang.reflect.Field;
import java.util.regex.Pattern;

public final class MentionUtils {
    private static final String TAG = MentionUtils.class.getName();

    private static final Pattern MENTION_PATTERN = Pattern.compile("@([^.][\\p{L}\\p{N}.]+[^._\\s])");

    private MentionUtils() {
        //no instance
    }

    public static void changeMentionPattern(SocialView view) {
        try {
            Field impl;
            if (view instanceof SocialAutoCompleteTextView) {
                impl = SocialAutoCompleteTextView.class.getDeclaredField("impl");
            } else if (view instanceof SocialTextView) {
                impl = SocialTextView.class.getDeclaredField("impl");
            } else if (view instanceof SocialEditText) {
                impl = SocialEditText.class.getDeclaredField("impl");
            } else {
                throw new IllegalArgumentException("View is unsupported by this method");
            }
            impl.setAccessible(true);
            SocialView socialView = (SocialView) impl.get(view);
            Field pattern = SocialView.class.getDeclaredField("PATTERN_MENTION");
            pattern.setAccessible(true);
            pattern.set(socialView, MENTION_PATTERN);
        } catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
            Log.e(TAG, "Failed to change mention pattern", e);
        }
    }
}
hanggrian commented 4 years ago

Sorry for late reply. In future version, you can set custom pattern for hashtag, mention and hyperlink.

hanggrian commented 4 years ago

In the upcoming version 0.3, you may write your own pattern.