开发者

notifyDataSetChanged not working in android

The list view is not updating data when the notifyDataChanged() method called.

In onCreate() method i initialized the the listview with no data.

            ListView videoList = (ListView)findViewById(R.id.videos_list);
    videoList.setOnItemClickListener(listener);
    listAdapter = new PHVideosListAdapter(PHVideosActivity.this, videos);
    videoList.setAdapter(listAdapter);

After this I started fetching list of video using new VideosCategoryFetchTask().execute();

in the post execute method I called

            @Override
    protected void onPostExecute(Boolean success) {
        if(success) {
             listAdapter.notifyDataSetChanged();
        } else {
            //show dialog
        }
    }

but nothing is displayed on the list. If anybody knew the solution please help...

 private class VideosDetailsFetchTask extends AsyncTask<String, Void, Boolean> {
    @Override
    public void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Boolean doInBackground(String... params) {
        Boolean success = false;
        try {
            if (params.length >= 0) {
                videos = (Videos)videoAPI.videosForCategoryId(params[0],new VideosParser());
                success = true;
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return success;
    }

    @Override
    protected void onPostExecute(Boolean success) {

        if(success) {
              progressBar.setVisibility(View.INVISIBLE);
              onFinishVideoFetch();
        } else {
            //show dialog   
        }       
    }
}

here using two Async classes sec one is called on the onPostExecute() of first one..

   private void onFinishVideoFetch() {
    if(videos != null) {

        listAdapter.notifyDataSetChanged();
    }
}

I 'm not fetching videos one by one.. here a list of videos is returned....

After getting the list of videos i wanted to refresh the list.

@Override
protected void onProgressUpdate(Videos... values) {

    videos = values[0];
 //add published object to list which holds
    listAdapter.notifyDataSetChanged();


}

I tried this but no luck please help..

this is the adapter class used

public class PHVideosListAdapter extends BaseAdapter{

private Videos videoTitles;
private LayoutInflater inflater;

public PHVideosListAdapter(Context context, Videos videoTitles) {

    inflater = LayoutInflater.from(context);
    this.videoTitles = videoTitles;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    if(videoTitles != null) {
        return videoTitles.size();
    }
    else {
        return 0;
    }
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return videoTitles.get(position);
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    VideoListViewHolder holder = null;

    if (convertView == null) {

            holder = new VideoListViewHolder();
            convertView = inflater.inflate(R.layout.videos_list, null);
            holder.videoTitle = (TextView) convertView.findViewById(R.id.video_title);
            holder.videoImage = (ImageView) convertView.findViewById(R.id.video_image);
            holder.videoDuration = (TextView) convertView.findViewById(R.id.video_duration);

            convertView.setTag(holder);
    } else {
        holder = (VideoListViewHo开发者_C百科lder)convertView.getTag();
    }

    holder.videoImage.setImageResource(R.drawable.icon);
    holder.videoDuration.setText("00:10");
    holder.videoTitle.setText(videoTitles.get(position).getVideoTitle());
    return convertView;
}


   private class VideoListViewHolder {

     ImageView videoImage;
     TextView  videoTitle;
     TextView  videoDuration;
}

}


When you first create your PHVideosListAdapter, it is holding a reference to the Videos list that I assume is a member of your Activity. In your doInBackground method, the call to videoAPI.videosForCategoryId is updating the Videos reference in your Activity, but the adapter is still holding the original reference that was passed in to the constructor for PHVideosListAdapter. You need to either recreate the PHVideosListAdapter in onPostExecute or add a set method in PHVideosListAdapter to change the private variable videoTitles.

I ran into the same issue with using the ArrayAdapter provided by Google. You can only set the underlying List in the constructor, so you must recreate the ArrayAdapter or create your own class that allows changing of the underlying data for notifyDataSetChanged to work.


You need to override onProgressUpdate() of AsynTask class

Heres an example of AsyncTask assuming your list is videos which holds Objects of type Video and your extended adapter is VideosAdapter

private class VideosDetailsFetchTask extends AsyncTask<String, Video, Boolean> {    
    @Override    
    public void onPreExecute() {    
        super.onPreExecute();    
    }    

    @Override    
    protected Boolean doInBackground(String... params) {    
    //utilize string you are passing otherwise use Void as first generic param.        
    Boolean success = false;    
        try {    
            if (params.length >= 0) {    
                Videos videoFetched = (Videos)PrimeraHoraAPI.videosForCategoryId(params[0],new VideosParser());    
                success = true;
                publishProgress(videoFetched);
            }    
        } catch (Exception e) {    
            // TODO: handle exception    
        }    
        return success;    
    }    

    @Override    
    protected void onPostExecute(Boolean success) {    

        if(success) {    
              progressBar.setVisibility(View.INVISIBLE);    
              onFinishVideoFetch();    
        } else {    
            //show dialog       
        }           
    }

    @Override
    protected void onProgressUpdate(Video... values) {
        videos.add(values[0]);//add published object to list which holds
        ((VideosAdapter)getListAdapter()).notifyDataSetChanged();

    }    
}    


It's not very good descript anywhere but what you do when u call

listAdapter.notifyDataSetChanged();

u tell your machine "oke, your code is not legit" and now u stop! so basically ur machine has no clue what 2 do next! My solution is:

create a private void setupData()

private void setupData() {
        ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
        final List<Table_Follow> data = db.getAllData(); // from database
        HashMap<String,String> item;
        for(Table_Data td : data){
            item = new HashMap<String,String>();
            item.put("name1", td.getName_One());
            item.put("name2", td.getName_Two());
            item.put("date", td.getDate());
            list.add(item);
        };

        my_data = new SimpleAdapter(this, list, R.layout.my_listview_row, new String[] { "name1","name2", "date" }, new int[] {R.id.lv_line_a, R.id.lv_line_b, R.id.lv_line_c});
        listview.setAdapter(my_data);
    }

I have a custom layout with 3 textviews (line a > title, line b > subtitle, line c > time see bottom page for xml). So basicly i ll use this private void to tell my machine what 2 do next by using setupData() after calling > notifydatasetchanged() in my main thread

my_data.notifyDataSetChanged();
setupData();

One last thing! I use the android listview id for my listview in my main xml file! Oh and if you have trouble using your 'onItemClickListener' (not giving u the right id, just text me! I faced that problem and solved it pretty shitty but it works :p)

My xml file for my listview:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <TextView
        android:id="@+id/lv_line_c"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FFFFFF"
        android:textSize="15sp" />

    <LinearLayout
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/lv_line_a"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFF"
            android:textSize="24sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/lv_line_b"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFF"
            android:textSize="15sp" />
    </LinearLayout>

</RelativeLayout>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜