У меня есть следующие одноточечно работает для моего Android приложенияStop Андроида adapter.notifyDataSetChanged() от работы параллельно с функцией, которая содержит код notifyDataSetChanged()
public class ListsApplication extends Application {
public DbxDatastoreManager datastoreManager;
public HashMap<String, ViewItemContainer> itemsSync;
public Typeface Font;
public boolean Fetch;
private static ListsApplication singleton;
public static ListsApplication getInstance() {
return singleton;
}
@Override
public void onCreate() {
super.onCreate();
singleton = this;
itemsSync = new HashMap<>();
Font = Typeface.createFromAsset(getAssets(), "fonts/GoodDog.otf");
Fetch = true;
}}
затем из дома активности я сохраняю одиночки экземпляр через
ListsApplication app = app.getInstance
в настройках Главная деятельность I слушатель, который запускается из хранилища данных онлайн сервера всякий раз, когда есть изменение в онлайн датасторов через
private void setUpListeners() {
app.datastoreManager.addListListener(new DbxDatastoreManager.ListListener() {
@Override
public void onDatastoreListChange(DbxDatastoreManager dbxDatastoreManager) {
// Update the UI when the list of datastores changes.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
app.Fetch = true;
Home.this.updateList();
app.Fetch = false;
}
}, 7000/* 3sec delay */);
Toast toast = Toast.makeText(getApplicationContext(), "RECEIVED", Toast.LENGTH_SHORT);
toast.show();
}
});
updateList();
app.Fetch = false;
}
Я разрешаю некоторое время до запуска updateList(), поскольку обновление хранилища данных не является атомарным, поэтому требуется, чтобы все строки в онлайновом хранилище данных занимали 2 секунды, игнорируйте приложение. позже объясним.
updateList() очищает ArrayList элементов, которые должны заполнить listAdapter и работает adapter.notifyDataSetChanged()
В моей пользовательской listAdapter, я задал GetView следующим образом:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder mHolder;
if (convertView == null) {
/*Toast toast = Toast.makeText(context, "nullConvertView", Toast.LENGTH_SHORT);
toast.show();*/
mHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.listitem, parent, false);
mHolder.PetName = (TextView) convertView.findViewById(R.id.PetName);
mHolder.BuyFood = (ImageView) convertView.findViewById(R.id.PetBuyFood);
mHolder.PetImage = (RoundedImageView) convertView.findViewById(R.id.PetImage);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
updateItem(mHolder, this.getItem(position));return convertView;}
и updateItem (mHolder, this.getItem (позиция))
public void updateItem(final ViewHolder currentViewFromList, final DbxDatastoreInfo info){
app = ListsApplication.getInstance();
if (app.itemsSync.containsKey(info.id) && !app.Fetch){
/*Toast toast = Toast.makeText(context, "not fetching "+info.title, Toast.LENGTH_SHORT);
toast.show();*/
ViewItemContainer cont = app.itemsSync.get(info.id);
currentViewFromList.PetName.setTypeface(app.Font);
currentViewFromList.PetName.setText(cont.PetName);
currentViewFromList.PetImage.setImageBitmap(cont.PetImage);
if (cont.BuyFood) currentViewFromList.BuyFood.setVisibility(View.VISIBLE);
else currentViewFromList.BuyFood.setVisibility(View.INVISIBLE);
}
else{
ViewItemContainer cont = new ViewItemContainer();
try {
Toast toast = Toast.makeText(context, "entrato"+info.title, Toast.LENGTH_SHORT);
toast.show();
DbxDatastore datastore = app.datastoreManager.openDatastore(info.id);
datastore.sync();
if (info.title!=null){
currentViewFromList.PetName.setTypeface(app.Font);
cont.PetName = info.title;
currentViewFromList.PetName.setText(cont.PetName);
}
DbxTable table = datastore.getTable("ITEMS");
DbxRecord record = table.get("INFO");
if (record!=null && record.hasField("PETPICTURE")){
byte[] b = record.getBytes("PETPICTURE");
//Bitmap picture = Misc.ByteArrayToImg(b);
cont.PetImage = Misc.ByteArrayToImg(b);
if (cont.PetImage!=null) currentViewFromList.PetImage.setImageBitmap(cont.PetImage);
} else currentViewFromList.PetImage.setImageResource(R.drawable.ic_launcher);
if (record!=null){
cont.BuyFood = record.getBoolean("BUYFOOD");
if (cont.BuyFood) currentViewFromList.BuyFood.setVisibility(View.VISIBLE);
else currentViewFromList.BuyFood.setVisibility(View.INVISIBLE);
}
datastore.close();
} catch (DbxException e) {
e.printStackTrace();
}
app.itemsSync.put(info.id,cont);
}
}
в основном при запуске приложения, app.Fetch устанавливается истина, updateList() из дома создает тыс e адаптер и вызовы adapter.notifyDataSetChanged().
На данный момент listAdapter GetView вызывается для каждого элемента в списке, проверяет идентификатор в качестве ключа в HashMap и не находит поэтому она извлекает данные из хранилища данных, и вставляет данные в hashmap и на представлении.
До этого момента все хорошо. Список просматривается правильно, и когда прокручиваются представления, данные извлекаются правильно из хэш-карты, а не извлекаются из хранилища данных снова и снова.
Затем с другого телефона я добавляю новое хранилище данных, которое запускает слушателя, и на моем телефоне отображается «ПОЛУЧЕННЫЙ» тост, что означает, что слушатель был запущен. app.Fetch возвращает true, а затем вызывается updateList().
Если я проверяю значение app.Fetch в любом месте updateList(), оно по-прежнему установлено в true, тогда как если я проверю его при запуске кода getView, оно будет установлено в false, чтобы оно снова извлекало данные из хэш-карты, а не получение обновленных онлайновых хранилищ данных.
Я думаю, что код GetView начинает работать параллельно с функцией updateList поэтому она показывает следующее поведение:
булевой правда updateList() начать adapter.notifyDataSetChanged() работает ListAdapter GetView начать updateList () заканчивается boolean false getView проверяет логическое значение, и поскольку в данный момент он является ложным, он извлекает данные из хэш-карты.
Есть ли способ получить updateList, чтобы ждать, пока все элементы в представлении списка будут проходить через getView?
Существует ли имя этого метода адаптера 'getView' или' fetchTheData'? – Selvin
Это getView (int position, View convertView, родительская группа ViewGroup) – Venzo92