Reputation: 41
I was reviewing code on Android but don't understand what is happenning when notifyDataSetChanged()
is called on an object of a class extending BaseAdapter
.
In the code, channelListAdapter.notifyDataSetChanged()
was called.
Here is the code of the ChannelListAdapter
class:
public class ChannelListAdapter extends BaseAdapter {
Field[] fields;
Context context;
List<Channels> channelList = null;
String dateString, likeData, ab, imageData;
Channels item;
DBVideos dbVideos;
VideoListAdapter videoListAdapter;
MostRecentFragment parentFragment;
public boolean loadingMoreChannels;
public boolean noMoreChannelFound;
Map<String, Boolean> map = new HashMap<String, Boolean>();
Map<String, Integer> totalLikeCount = new HashMap<String, Integer>();
public Map<String, Boolean> timerMap = new HashMap<String, Boolean>();
Map<String, List<Videos>> mapVideos = new HashMap<String, List<Videos>>();
public ChannelListAdapter(Context context) {
this.context = context;
}
public Map<String, List<Videos>> getMapVideos() {
return mapVideos;
}
public void setMapVideos(Map<String, List<Videos>> mapVideos) {
this.mapVideos = mapVideos;
}
public ChannelListAdapter(Context context, List<Channels> channelList) {
this.context = context;
// listener = new NewsFeedListener(context, map, totalLikeCount);
// listener.setListAdapter(this);
this.channelList = channelList;
}
public ChannelListAdapter(Context context, List<Channels> channelList, MostRecentFragment parentFragment) {
this.context = context;
this.parentFragment = parentFragment;
this.channelList = channelList;
}
public String getLastFeedModificationTime() {
Channels lastNews = channelList.get(channelList.size() - 1);
return lastNews.getLastModifyDate();
}
public void setNewsList(List<Channels> channelList) {
this.channelList = channelList;
}
@Override
public int getCount() {
return channelList.size();
}
@Override
public Object getItem(int position) {
return channelList.get(position);
}
@Override
public long getItemId(int position) {
return channelList.indexOf(getItem(position));
}
public static class ViewHolder {
public TextView channelTitle;
public ImageView imgProcess;
ListView videoListView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = (View) mInflater.inflate(R.layout.channel_list_item, null);
holder.channelTitle = (TextView) convertView.findViewById(R.id.tv_channel_name);
holder.imgProcess = (ImageView) convertView.findViewById(R.id.img_process);
holder.videoListView = (ListView) convertView.findViewById(R.id.list_videos);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
item = (Channels) getItem(position);
final ViewHolder finalHolder = holder;
holder.channelTitle.setText(item.getTitle());
if (mapVideos.size() > 0 && mapVideos.containsKey(item.getId())) {
} else {
Glide.with(context).load("http://4.bp.blogspot.com/-rSoHhekcu9A/T6PQ6d8mKSI/AAAAAAAAASg/hStx9Mg18fc/s1600/22.gif").asGif().placeholder(R.drawable.img_loading).crossFade()
.into(holder.imgProcess);
String url = null;
url = context.getString(R.string.url_6e_channel_context)+CommonUtils.getEncodedUrl(context, context.getString(R.string.url_to_retive_all_video_selected_channel_first)+item.getId())+"+ContentType:Indigo+Video'&rowlimit=3&"+CommonUtils.getEncodedUrl(context,context.getString(R.string.url_to_retive_all_video_selected_channel_sec));
System.out.println("url ="+url);
ServiceCallAsync sca = new ServiceCallAsync(context, null,"Get", null, url, new AsyncResponse() {
@Override
public void processFinish(Object output) {
ServiceResponse serviceResponse = (ServiceResponse) output;
if(serviceResponse.getCode()==200){
parseDataAndStoreinDb(serviceResponse.getData(),finalHolder);
}else{
}
}
});
sca.execute();
}
if (position == channelList.size() - 1) {
if (parentFragment != null && !loadingMoreChannels && !noMoreChannelFound) {
loadingMoreChannels = true;
parentFragment.loadMore();
}
}
return convertView;
}
protected void parseDataAndStoreinDb(String data, ViewHolder finalHolder) {
List<Videos> videosList = new ArrayList<>();
try {
JSONObject mainObj = new JSONObject(data);
JSONObject dObj = mainObj.getJSONObject("d");
JSONObject queryObj = dObj.getJSONObject("query");
JSONObject primaryQueryObj = queryObj.getJSONObject("PrimaryQueryResult");
JSONObject releventObj = primaryQueryObj.getJSONObject("RelevantResults");
JSONObject tableObj = releventObj.getJSONObject("Table");
JSONObject rowsObj = tableObj.getJSONObject("Rows");
JSONArray resultArray = rowsObj.getJSONArray("results");
for(int i = 0; i<resultArray.length();i++){
Map<String ,String> videoFieldsMap=new HashMap<String, String>();
JSONObject resultObj= resultArray.getJSONObject(i);
JSONObject cellesObj= resultObj.getJSONObject("Cells");
JSONArray resultInnerArray = cellesObj.getJSONArray("results");
for(int j = 0; j<resultInnerArray.length();j++){
JSONObject obj= resultInnerArray.getJSONObject(j);
//System.out.println("obj ="+obj.getString("Key"));
videoFieldsMap.put(obj.getString("Key"), obj.getString("Value"));
}
videoFieldsMap.put("ListId", item.getId());
Videos video = convertMapToVideoModel(videoFieldsMap);
System.out.println("video convertedMap ="+video);
videosList.add(video);
}
if(dbVideos == null ){
dbVideos = new DBVideos(context);
}
dbVideos.insertVideos(videosList);
// mapVideos.put(item.getId(), videosList);
setVideoListAdapter(videosList,finalHolder);
} catch (JSONException e) {
e.printStackTrace();
}
}
private void setVideoListAdapter(List<Videos> list, ViewHolder finalHolder) {
if(videoListAdapter == null){
videoListAdapter = new VideoListAdapter(context, list,parentFragment);
}
videoListAdapter.setVideoList(list);
System.out.println("list ="+list.size());
System.out.println("list ="+list.get(1));
finalHolder.videoListView.setAdapter(videoListAdapter);
finalHolder.videoListView.setVisibility(View.VISIBLE);
finalHolder.imgProcess.setVisibility(View.GONE);
ListHeightUtils.setListViewHeightBasedOnChildren(finalHolder.videoListView);
}
private Videos convertMapToVideoModel(Map<String, String> videoFieldsMap){
Class clazz=Videos.class;
Object object = null;
System.out.println("videoFieldsMap ="+videoFieldsMap);
try{
object=clazz.newInstance();
for(Field field:clazz.getDeclaredFields()){
field.setAccessible(true);
System.out.println("field =="+videoFieldsMap.get(field));
field.set(object, videoFieldsMap.get(field.getName()));
}
System.out.println("object ="+object.toString());
}catch(Exception e){
e.printStackTrace();
}
return (Videos)object;
}
}
Upvotes: 2
Views: 2614
Reputation: 2785
From the docs notifyDataSetChanged() :
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
There might be requirement in your application where you want to update the ListView
when ever the data set binded to that listview
has undergone change like add
, update
or delete
.
To achieve this Android provides a way to call notifyDataSetChanged() for an ArrayAdapter
or a BaseAdapter
which will update the listview
.
Upvotes: 1
Reputation: 2396
The Adapter defines the rules to display a list of items in a View - it is usually in the context of a ListView or RecyclerView (but really can be a multitude of things). The view is not aware of when the underlying dataset changes, so after its initial draw, it needs to be told when its data is no longer the most up-to-date.
Say you have the following list:
[A, B, C]
At some point, the user hits an API and the list is updated:
[A, B, C, D, E, F]
The ListView where this list is displayed will still only show:
[A, B, C]
When you call notifyDataSetChanged() on the adapter that is attached to the ListView, it will then update the ListView to show the full new dataset:
[A, B, C, D, E, F]
It is possible too, depending on what kind of adapter you're using, to notify that the entire dataset has changed, or to do more specific update calls like RecyclerView's notifyItemChanged
, notifyItemRemoved
, notifyItemMoved
etc.
Upvotes: 3