Harshit
Harshit

Reputation: 41

what happens when notifyDataSetChanged() is called on object of a class extending Base Adapter

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

Answers (2)

Steve Kamau
Steve Kamau

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 .

See an example here.

Upvotes: 1

jyanks
jyanks

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

Related Questions