notifyDataSetChanged在android中不起作用

时间:2010-12-14 11:45:58

标签: android

当notifyDataChanged()方法调用时,列表视图不会更新数据。

在onCreate()方法中,我初始化了listview而没有数据。

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

在此之后,我开始使用新的VideosCategoryFetchTask()获取视频列表.execute();

在后执行方法中我调用了

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

但列表中没有显示任何内容。如果有人知道解决方案,请帮助......

 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   
        }       
    }
}

这里使用两个异步类,第一个在onPostExecute()上调用一个。

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

        listAdapter.notifyDataSetChanged();
    }
}

我不是一个一个地提取视频......这里会返回一个视频列表......

获取我要刷新列表的视频列表后。

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

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


}

我试过这个,但没有运气,请帮助..

这是使用的适配器类

公共类PHVideosListAdapter扩展了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 = (VideoListViewHolder)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;
}

}

3 个答案:

答案 0 :(得分:4)

首次创建PHVideosListAdapter时,它会保留对我认为属于您的活动成员的Videos列表的引用。在doInBackground方法中,对videoAPI.videosForCategoryId的调用正在更新Activity中的Videos引用,但适配器仍然保留了传递给{{1的构造函数的原始引用}}。您需要在PHVideosListAdapter中重新创建PHVideosListAdapter或在onPostExecute中添加set方法以更改私有变量PHVideosListAdapter

我使用Google提供的videoTitles遇到了同样的问题。您只能在构造函数中设置基础ArrayAdapter,因此您必须重新创建ArrayAdapter或创建自己的类,以允许更改List的基础数据。

答案 1 :(得分:0)

您需要覆盖AsyncTask类的onProgressUpdate()

以下是AsyncTask的示例,假设您的列表为videos,其中包含Video类型的对象,并且您的扩展适配器为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();

    }    
}    

答案 2 :(得分:0)

在任何地方描述都不是很好,但是当你打电话时你会做什么

listAdapter.notifyDataSetChanged();

你告诉你的机器“哦,你的代码不合法​​”,现在你停下来!所以基本上你的机器不知道下一步做什么!我的解决方案是:

创建一个私有的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);
    }

我有一个带有3个textviews的自定义布局(第a行&gt;标题,第b行&gt;字幕,第c行&gt;时间见xml底部页面)。所以基本上我会使用这个私有空来告诉我的机器在调用&gt;之后通过使用setupData()告诉我的机器2做什么。我主线程中的notifydatasetchanged()

my_data.notifyDataSetChanged();
setupData();

最后一件事!我在我的主xml文件中使用了我的listview的android listview id!哦,如果你在使用'onItemClickListener'时遇到问题(不给你正确的id,只需给我发短信!我遇到了这个问题并解决了它很糟糕但是有效:p)

我的listview的xml文件:

<?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>