notifyDataSetChanged () не может корректно обновиться из-за проблем привязки ArrayList к адаптеру

Это ошибка из-за оптимизации в bash.

При замене шаблона bash first проверяет, соответствует ли шаблон в любом месте в строке. Если это не так, тогда нет смысла выполнять поиск и замену. То, как он это делает, - построить новый шаблон, поместив его с помощью *..* по мере необходимости:

  /* If the pattern doesn't match anywhere in the string, go ahead and
     short-circuit right away.  A minor optimization, saves a bunch of
     unnecessary calls to strmatch (up to N calls for a string of N
     characters) if the match is unsuccessful.  To preserve the semantics
     of the substring matches below, we make sure that the pattern has
     `*' as first and last character, making a new pattern if necessary. */
  /* XXX - check this later if I ever implement `**' with special meaning,
     since this will potentially result in `**' at the beginning or end */
  len = STRLEN (pat);
  if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
    {
      int unescaped_backslash;
      char *pp;

      p = npat = (char *)xmalloc (len + 3);
      p1 = pat;
      if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
    *p++ = '*';

Образец, который он пытается сопоставить со строкой, заканчивается *(*

Открытие *( теперь непреднамеренно распознается как начало extglob, но когда bash не находит закрытие ) , оно соответствует шаблону в виде строки:

 prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */
  if (prest == 0)
    /* If PREST is 0, we failed to scan a valid pattern.  In this
       case, we just want to compare the two as strings. */
    return (STRCOMPARE (p - 1, pe, s, se));

Это означает, что если строка, в которой выполняются замены, буквально *(*, оптимизация неверно отклоняет строку, считая, что делать нечего. Разумеется, это также означает, что он корректно работает для самого *(*:

$ f='*(*'; echo "${f//(/\\(}"
*\(*

Если вы хотите выманить эту проверку оптимизации в исходном коде:

diff --git a/subst.c b/subst.c
index fc00cab0..f063f784 100644
--- a/subst.c
+++ b/subst.c
@@ -4517,8 +4517,6 @@ match_upattern (string, pat, mtype, sp, ep)
   c = strmatch (npat, string, FNMATCH_EXTFLAG | FNMATCH_IGNCASE);
   if (npat != pat)
     free (npat);
-  if (c == FNM_NOMATCH)
-    return (0);

   len = STRLEN (string);
   end = string + len;

, тогда он будет корректно работать в вашем случае:

$ ./bash -c 'f="my string(1) with (parens)"; echo "${f//(/\\(}"'
my string\(1) with \(parens) 

1
задан Jeff 18 January 2019 в 23:08
поделиться

2 ответа

Ссылка, которую вы передаете в ArrayAdapter, отличается от той, которая назначена здесь:

listAssignments = sPetInformationViewModel.getAssignedProviders(petId);

Что касается ArrayAdapter, то listAssignments, к которым он имеет ссылку, очищен OnResume, и ничего не было добавлено вернемся к этому. Он ничего не знает о новой ссылке listAssignments.

Попробуйте сделать это:

public void onResume()
{
    super.onResume();
    Log.d(TAG, "Entered: onResume");
    listAssignments.clear();
    Log.d(TAG, "listAssignments is: " + listAssignments);
    List<Assignment> newList = sPetInformationViewModel.getAssignedProviders(petId);
    listAssignments.addAll(newList);
    mAdapter.notifyDataSetChanged();
}
0
ответ дан pnavk 18 January 2019 в 23:08
поделиться

Хорошо, я собираюсь выйти из этого вопроса и сказать, что notifyDataSetChanged () не работает для ArrayList, потому что при каждой загрузке его адрес меняется, см. Мой оригинальный пост и комментарии к pnavk, чтобы увидеть детали. Насколько я понимаю, Java не предоставляет средств для установки в камне адреса ArrayList, как это делает C или C ++ через указатель, поэтому Adapter устанавливается в ячейку памяти исходного объекта ArrayList и поэтому указывает на одни и те же данные на каждом Вызов notifyDataSetChanged (), даже несмотря на то, что Java использовала новую ячейку памяти для этого объекта ArrayList или создала новый объект ArrayList с тем же именем.

Поэтому, мой ответ для обновления RecyclerView из нового набора данных в ArrayList должен сбросить Adapter в onResume как новый и затем переназначить этот Adapter для вашего RecyclerView, как я упоминал в моем ответе на pnavk:

[110 ]
0
ответ дан Jeff 18 January 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: