2015-04-22 17 views
1

У меня есть фрагмент, с GridView загруженный с помощью CustomAdapter (расширение BaseAdapter). Данные извлекаются с сервера, и, следовательно, я пытаюсь вызвать notifyDataSetChanged на адаптере после завершения загрузки. Но GridView не загружает контент после загрузки.GridView CustomAdapter notifyDataSetChanged issue issue

Вот несколько моих фрагментов кода:

GridView gridview; 
CustomAdapter mCustomAdapter; 
List<Item> listItems = new ArrayList<Item>(); 

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 

View view = inflater.inflate(R.layout.fragment_main, container, false); 
.... 
.... 

     mCustomAdapter = new CustomAdapter(activity, listItems); 
     gridview = (GridView) view.findViewById(R.id.gridview); 
     gridview.setAdapter(mCustomAdapter); 

     // This is the call for retrieving data from Server 
     checkRefreshTimeAndGetData(); 

return view; 

} 

После получения данных, я звоню notifyDataSetChanged() в приведенном ниже способом:

public void checkRefreshTimeAndGetData(){ 

.... 
.... 

     listItems.clear(); 

     if (!mMainTableDbAdapter.isTableEmpty(
       prefs.getInt(Const.Prefs.MAIN_INDEX, DEFAULT_VALUE), 
       prefs.getInt(Const.Prefs.SUB_INDEX, DEFAULT_VALUE))) 
      listItems = mMainTableDbAdapter.getTitles(
        prefs.getInt(Const.Prefs.MAIN_INDEX, DEFAULT_VALUE), 
        prefs.getInt(Const.Prefs.SUB_INDEX, DEFAULT_VALUE)); 

     // At this point, i checked if listItems has values, 
     // and it has 100 items in it. So, its not empty. 

     mCustomAdapter.notifyDataSetChanged(); 
} 

CustomAdapter:

public class CustomAdapter extends BaseAdapter { 

private List<Item> items; 
private LayoutInflater vi; 
private List<Boolean> selectedState = new ArrayList<Boolean>(); 
String imagepath = ""; 

int curPos = 0; 

public CustomAdapter(Context context, List<Item> items) { 
    this.items = items; 
    vi = (LayoutInflater) context 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

@Override 
public int getCount() { 
    return items.size(); 
} 

@Override 
public Object getItem(int position) { 
    return position; 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 

@Override 
public View getView(final int position, View convertView, 
     final ViewGroup parent) { 

    .... 
    .... 

    } 
} 

Что я делаю неправильно? если требуется какой-либо другие данные, пожалуйста, дайте мне знать ..

ответ

3

Вот один выход

сделать refresh(..) в вашем Adapter

public void refresh(List<Item> items) 
{ 
    this.items = items; 
    notifyDataSetChanged(); 
} 

и использовали его как

listItems.clear(); 
mCustomAdapter.refresh(listItems); //pass update list 
+1

Хорошо, но есть ли причина, почему мой код выше не работает? Просто хочу знать .. Есть ли проблемы с моим адаптером? –

+0

@ VamsiChalla 'notifyDataSetChanged();' ничего не изменит. Вы должны работать с исходной ссылкой 'List' remove/add items на этот' List'. ИЛИ другим способом создается все «новый объект адаптера» и снова назначается «List». Кстати ваш код в порядке. –

1

Причина, по которой ваш код не работает:

Вы не обновляете адаптер с последними данными. В вашем checkRefreshTimeAndGetData вы берете новые данные, но вы не указали эти данные на адаптер. Так что mCustomAdapter.notifyDataSetChanged() ничего не делает.


Для этого вы можете добавить еще один способ в адаптер, который обновит элементы в адаптере.

public void updateItems(List<Item> newItems) { 
    // Either you can add or replace all data 
    // Here I am replacing all data with new 
    this.items = newItems; 
    notifyDataSetChanged(); 
} 

и вызвать этот метод в checkRefreshTimeAndGetData на месте mCustomAdapter.notifyDataSetChanged()

mCustomAdapter.updateItems(listItems); 
+0

@PK Также другой способ заключается в том, что если вы создадите новый «объект адаптера», тогда он должен работать, но это не очень хорошая идея. Я протестировал. –

+1

@MD Вы правы. Создание ненужных объектов всегда плохая идея. –

0

вам нужно реализовать слушателя, чтобы узнать, когда данные загружены. например, реализовать интерфейс, который получит уведомление, когда вы успешно получите данные с сервера, а затем вы вызываете notifyDatasetChanged()

В текущем сценарии ваш метод будет вызываться только при запуске фрагмента. а не при загрузке данных.

+0

Код в вопросе, это всего лишь фрагмент. У меня есть обратный вызов при загрузке данных. –