My Activity has RecyclerView which items are consisting only of EditTexts. I did it for improving overall performance over one, simple EditText. These items at start are set like that:
public void setText(String text) {
List<String> strings = UtilsJava.splitInParts(text, 2000, 50, {'.', ':', '?', '!', ';', ' '});
if (strings.isEmpty()) {
strings.add(text);
}
adapter.setItems(strings);
adapter.fillBigTextModelList(strings);
}
(...)
public static List<String> splitInParts(String str, int len, int m, char[] splitChars) {
List<String> result = new ArrayList<>();
int cutStart = 0;
for (int i = 0; i < (int) Math.ceil((double) str.length() / len); i++) {
int cutEnd = Math.min(str.length(), (i + 1) * len);
if (cutEnd != str.length() && (cutEnd + m) < str.length()) {
String section = str.substring(cutEnd - m, cutEnd + m);
int index = indexOf(section, splitChars);
cutEnd = cutEnd - m + index + 1;
}
result.add(str.substring(cutStart, cutEnd));
cutStart = cutEnd;
}
return result;
}
So far so good. In my example I have text that is split into 4 items. Now I want to remove a part of zero item, all second item, and a part of third item. I created a custom solution for that (because a system one does not go through multi EditText). I simply set start index and end index by simple click. and choose with specific button which one is this selection. Now that I have start index and end index I call highlightSelection()
:
public void highlightSelection(int startIndexTotal, int endIndexTotal) {
Predicate<BigTextModel> predicate1 = o -> o.getStartIndex() <= endIndexTotal;
Predicate<BigTextModel> predicate2 = o -> o.getEndIndex() >= startIndexTotal;
int vhIndex = Stream.of(bigTextModelList).filter(predicate1).filter(predicate2).findFirst().get().getVhIndex();
BigTextModel bigTextModel = bigTextModelList.get(vhIndex);
List<String> items = new ArrayList<>();
int index3 = 0;
if (isSelectionWithinOneVh(startIndexTotal, endIndexTotal, bigTextModel)) {
// it works
} else if (isSelectionWithinMoreVhs(startIndexTotal, endIndexTotal, bigTextModel)) {
int index1;
int index2 = 0;
int totalProcessedLength = 0;
boolean isNoVhIndexChanged = false;
for (BigTextModel bigTextModel1 : bigTextModelList) {
totalProcessedLength += textList.get(bigTextModel1.getVhIndex()).length();
if (bigTextModel1.getVhIndex() == 0) {
index1 = startIndexTotal;
index2 = textList.get(0).length();
String b = getJoinedText().substring(0, index1);
items.add(b);
}
else {
if (totalProcessedLength < endIndexTotal) {
index2 += textList.get(bigTextModel1.getVhIndex()).length();
} else {
if ((textList.get(bigTextModel1.getVhIndex()).length() - Math.abs(totalProcessedLength - endIndexTotal)) > 0) {
index2 += (textList.get(bigTextModel1.getVhIndex()).length() - Math.abs(totalProcessedLength - endIndexTotal));
String item = getJoinedText().substring(index2, index2 + Math.abs(totalProcessedLength - endIndexTotal));
index2 = index2 + Math.abs(totalProcessedLength - endIndexTotal);
items.add(item);
} else if (!isNoVhIndexChanged) {
index2 = index3;
String item = getJoinedText().substring(index2);
items.add(item);
isNoVhIndexChanged = true;
}
}
}
}
}
setItems(items);
}
public void setItems(List<String> items) {
textList.clear();
textList.addAll(items);
notifyDataSetChanged();
}
When I debugged these items, they seemed to be correct – there were 3 items, as I expected.
Now for example if I remove a single character from first item and then I remove a single character form third item then when I call a method getAllDescChanges()
private LinkedList<Diff> getAllDescChanges() {
(...)
String savedNoteDesc = bundle.getString("noteDesc");
editedNoteDesc = String.join("", adapter.getTextList());
DiffMatchPatch dmp = new DiffMatchPatch();
return dmp.diff_main(savedNoteDesc, editedNoteDesc);
}
I get 9 changes from which 5th, 6th definitely should’t be here and 7th has wrong index – its startIndex should be something like 7003. This DiffMatchPatch
is a github project from here: github_link. Here is a screenshot from debugging this method:
From what I found out is that:
-
if I remove only single character from first item and then from last item without multi removing multi text – DiffMatchPatch shows everything correctly
-
deletion these two characters + deleting from within index 0 – to within index 1 – there’s no problem,
-
deletion these two characters + deleting from within index0 – to within index 2 – there’s problem,
-
deletion these two characters + deletion from within index 0 – to within index 3 – there’s problem
So the question is how to avoid having these two weird changes and to solve this wrong startIndex of 7th change?
I tried:
-
In highlightSelection() I tried working directly on listItem items by setting and removing item – didn’t work
-
In highlightSelection() I tried to create new list and once was ready replace adapter’s listItem with this list (like in attached code)
-
and some other not working solutions that I already have forgotten because it’s been a few weeks since I started working on it
I’m struggling with this bug for about a few weeks without any progress. So thank you so so much if you are willing to help!
Jawegiel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.