Closed ClarkXP closed 7 years ago
you can make something like this
MentionsEditText text;
//your MentionsEditText setup here (Tokenizer, etc...)
text.setText("your full text here that include Tags too");
for (UserTag tag : taggedUsers)
{
int si = TextUtils.indexOf(text.getText(), tag.UserName);
int ei = si + tag.UserName.length();
if (si >= 0)
{
text.getText().replace(si, ei, "");
Selection.setSelection(text.getText(), si);
text.insertMention(tag);
}
}
How can I do the same thing for RichEditorView
Can you pls help me with this
First, note that there is not really any difference between using a RichEditorView
and a MentionsEditText
here. Note that RichEditorView
is just a custom view that wraps a MentionsEditText
to make basic use cases easier to handle. In both cases, the text inside the view is represented by a MentionsEditable
.
A similar use case we already handle is saving and restoring the text when your activity is destroyed and recreated. We do this by implementing the Parcelable
interface in the MentionsEditable
. You could try to reuse this mechanism (i.e. call onSaveInstanceState()
and persist the parcelable to disk, then restore it later via onRestoreInstanceState()
), but this is not recommended (see the docs for Parcel
, which point out that it should not be used since changes in the underlying implementation of data in the Parcel can render older data unreadable).
Other than preserving the view state via the Android system callbacks, the library itself does not handle generically persisting this text. This was intentional. There are a lot of different use cases (i.e. persisting to a disk/cache, database, or over the network) and formats for this data (JSON, XML, binary formats, etc.). In this case, you'll need to implement something similar to what @AhmedHashemNTS suggested above. The basic idea is that you need to persist both the text and the spans (specifically, the starting index, the length, and any custom data within the span).
I'll walk-through a concrete example. Let's say that you decide to model the mentions data you want to persist with a schema like this. Note that I'm using plain POJOs here, but this would be whatever data structure you would use to handle persisting (i.e. you could also use JSONObject for transmitting over the network or use tables/rows in a database):
class MentionsTextData {
String text;
List<Mentions> mentions;
}
class Mention {
int startIndex;
int endIndex;
}
class EntityMention extends Mention {
int entityId;
}
Note that for this example, all of our MentionSpan
s will use the following concrete implementation of the Mentionable
interface. I'm including this just to help showcase how you can handle custom, arbitrary data.
class MentionableEntity implements Mentionable {
// Any mention span will reference some entity (i.e. a person or company) with this id
int entityId;
}
Now to save this data, you will need to write a function to convert a MentionsEditable
to a MentionsTextData
(where the MentionsTextData
is just an example POJO class that you can persist to disk, a database, send over the network, etc.). This would look something like:
// Get text from a RichEditorView and convert to MentionsTextData
MentionsTextData data = toMentionsTextData(richEditorView.getText());
@NonNull
public MentionsTextData toMentionsTextData(@NonNull MentionsEditable editable) {
MentionsTextData data = new MentionsTextData();
data.text = editable.toString();
data.mentions = new ArrayList<>();
List<MentionSpan> spans = getMentionSpans();
for (MentionSpan span : spans) {
EntityMention mention = new EntityMention();
mention.startIndex = editable.getSpanStart(span);
mention.endIndex = editable.getSpanEnd(span);
mention.entityId = ((MentionableEntity) span.mentionable).entityId;
data.mentions.add(mention);
}
return data;
}
To restore the data, you will need to write the reverse function to convert this MentionsTextData
that was persisted into a MentionsEditable
, then assign it to the RichEditorView
. This would look something like:
richEditorText.setText(toMentionsEditable(mentionsTextData));
@NonNull
public MentionsEditable toMentionsEditable(@NonNull MentionsTextData data) {
MentionsEditable editable = new MentionsEditable(data.text);
for (Mention mention : data.mentions) {
// You'll need to be able to recreate the MentionSpan from the data, including any arbitrary data
// Here, we just make sure we correct restore our custom entityId field
EntityMentionable mentionable = new EntityMentionable();
mentionable.entityId = mention.entityId;
MentionSpan span = new MentionSpan(mentionable);
ediable.setSpan(span, mention.startIndex, mention.endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return editable;
}
Hope this helps. Let me know if you have any questions :)
I'm working in a app that must save drafts texts to edit them later. How can I persist this text and restore it, without lost the mentions?