C#: Инициализация обработчика событий с макетом

Я не думаю, что в PagerAdapter есть какая-либо ошибка. Проблема в том, что понять, как это работает, немного сложно. Глядя на решения, объясненные здесь, есть недопонимание и, следовательно, плохое использование воплощенных взглядов с моей точки зрения.

Последние несколько дней я работал с PagerAdapter и ViewPager и обнаружил следующее:

Метод notifyDataSetChanged() в PagerAdapter только уведомит ViewPager, что основные страницы изменились. Например, если вы создали / удалили страницы динамически (добавляя или удаляя элементы из вашего списка), об этом должно позаботиться ViewPager. В этом случае я думаю, что ViewPager определяет, должен ли новый вид быть удален или создан с использованием методов getItemPosition() и getCount().

Я думаю, что ViewPager после вызова notifyDataSetChanged() принимает его дочерние представления и проверяет их положение с помощью getItemPosition(). Если для дочернего представления этот метод возвращает POSITION_NONE, ViewPager понимает, что представление было удалено, вызывает destroyItem() и удаляет это представление.

Таким образом, переопределение getItemPosition() всегда возвращать POSITION_NONE совершенно неправильно, если вы хотите обновить только содержимое страниц, потому что ранее созданные представления будут уничтожены, а новые будут создаваться при каждом вызове. notifyDatasetChanged(). Может показаться, что это не так неправильно только на несколько TextView с, но когда у вас есть сложные представления, такие как ListViews, заполненные из базы данных, это может быть реальной проблемой и пустой тратой ресурсов.

Таким образом, существует несколько подходов для эффективного изменения содержимого представления без необходимости повторного удаления и создания экземпляра представления. Это зависит от проблемы, которую вы хотите решить. Мой подход заключается в использовании метода setTag() для любого экземпляра представления в методе instantiateItem(). Поэтому, когда вы хотите изменить данные или сделать недействительным нужное представление, вы можете вызвать метод findViewWithTag() в ViewPager, чтобы получить ранее созданное представление и изменить / использовать его так, как вам нужно, без необходимости удалять / создавать новый вид каждый раз, когда вы хотите обновить некоторое значение.

Представьте, например, что у вас есть 100 страниц со 100 TextView с, и вы хотите периодически обновлять только одно значение. С подходами, объясненными ранее, это означает, что вы удаляете и создаете 100 экземпляров при каждом обновлении. Это не имеет смысла ...

5
задан Svish 15 July 2009 в 12:43
поделиться

2 ответа

While you don't need to do the nullity checks, if you really want to try to make the event thread-safe, you still need to fetch it in a lock:

protected void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler;
    lock (propertyChangedLock)
    {
        handler = propertyChanged;
    }
    handler(this, new PropertyChangedEventArgs(propertyName));
}

Otherwise you may not be fetching the most recent value - if event handlers are being added in a different thread, you could theoretically raise events forever without ever calling the new handlers. In practice I believe you'll almost always get away without the lock, but in memory-model terms you should have some sort of fence.

Personally I recommend that you don't try to make the events thread-safe.

8
ответ дан 14 December 2019 в 04:45
поделиться

You can see it as an implementation of the NULL Object pattern.

It helps making your code more readable, since you do not need to do NULL - value checks.

The locks in your add / remove logic will have to remain, if they're necessary now. They have nothing to do with it. They're used to avoid race-conditions (but i don't know if they're necessary in your very situation)

0
ответ дан 14 December 2019 в 04:45
поделиться
Другие вопросы по тегам:

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