Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在不使用notifyDataSetChanged()的情况下更新Listview中的某些数据?_Android_Listview_Notifydatasetchanged - Fatal编程技术网

Android 如何在不使用notifyDataSetChanged()的情况下更新Listview中的某些数据?

Android 如何在不使用notifyDataSetChanged()的情况下更新Listview中的某些数据?,android,listview,notifydatasetchanged,Android,Listview,Notifydatasetchanged,我正在尝试创建一个包含下载任务列表的列表视图 下载任务在服务(下载服务)中管理。每次接收到数据块时,任务都会通过广播发送进度,该广播由包含列表视图的片段(SavedShowListFragment)接收。在收到广播消息时,SavedShowListFragment更新适配器中下载任务的进度,并触发notifyDataSetChanged() 列表中的每一行都包含一个进度条,一个文本视图用于下载文件的标题,一个用于进度的数值,以及一个按钮,用于在下载完成时暂停/恢复下载或播放保存的节目 问题是pa

我正在尝试创建一个包含下载任务列表的
列表视图

下载任务在
服务
(下载服务)中管理。每次接收到数据块时,任务都会通过
广播发送进度,该广播由包含
列表视图的
片段(SavedShowListFragment)接收。在收到
广播
消息时,SavedShowListFragment更新适配器中下载任务的进度,并触发
notifyDataSetChanged()

列表中的每一行都包含一个
进度条
,一个
文本视图
用于下载文件的标题,一个用于进度的数值,以及一个
按钮
,用于在下载完成时暂停/恢复下载或播放保存的节目

问题是pause/resume/play
按钮通常没有响应(
onClick()
没有被调用),我认为这是因为整个列表都会使用
notifyDataSetChanged()频繁更新(每次接收到一个数据块,即1024字节时,每秒可能多次,尤其是在有多个下载任务正在运行时)

我想我可以在下载任务中增加数据块的大小,但我真的认为我的方法根本不是最优的

频繁调用notifyDataSetChanged()
是否会使
ListView
UI无响应

有没有办法只更新
列表视图
行中的一些
视图
,即在我的例子中,
进度条
文本视图
,而不调用更新整个列表的
notifyDataSetChanged()

要更新
列表视图中下载任务的进度,是否有比“getChunk/sendBroadcast/updateData/notifyDataSetChanged”更好的选项

下面是我的代码的相关部分

下载服务中的下载任务

private static final long INTERVAL_BROADCAST = 800;
private long lastUpdate = 0;
SavedShowAdapter

公共类SavedShowAdapter扩展了ArrayAdapter{
私人停车场平面布置;
private List mSavedShowIdList;//列出以更快地查找项目在updateProgress中的位置
私有下载服务mDownloadService;
私有上下文;
静态类视窗夹{
文本视图标题;
文本视图状态;
ProgressBar ProgressBar;
DownloadStateButton downloadStateBtn;
}
公共静态枚举取消原因{暂停,删除};
公共SavedShowAdapter(上下文上下文,列表savedShowList){
超级(上下文,0,savedShowList);
mLayoutInflater=(LayoutInflater)context.getSystemService(context.LAYOUT\u INFLATER\u SERVICE);
mContext=上下文;
mSavedShowIdList=newarraylist();
for(SavedShow SavedShow:savedShowList){
添加(savedShow.getId());
}
}
public void updateItemProgress(长保存的ShowID,长进度){
getItem(mSavedShowIdList.indexOf(savedShowId)).setProgress(progress);
notifyDataSetChanged();
}
public void updateItemFileSize(long savedShowId,int fileSize){
getItem(mSavedShowIdList.indexOf(savedShowId)).setFileSize(fileSize);
notifyDataSetChanged();
}
public void updateItemState(long savedShowId,int state\u ind,String msg){
SavedShow.State State=SavedShow.State.values()[State_ind];
getItem(mSavedShowIdList.indexOf(savedShowId)).setState(state);
if(state==state.ERROR){
getItem(mSavedShowIdList.indexOf(savedShowId)).setError(msg);
}
notifyDataSetChanged();
}
公共void deleteItem(长保存的ShowId){
删除(getItem((mSavedShowIdList.indexOf(savedShowId)));
notifyDataSetChanged();
}
公共无效设置下载服务(下载服务下载服务){
mDownloadService=下载服务;
notifyDataSetChanged();
}
@凌驾
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
视窗座;
视图v=转换视图;
如果(v==null){
v=MLAYOUTINGER.充气(R.layout.saved\u show\u list\u项,父项,false);
holder=新的ViewHolder();
holder.title=(TextView)v.findViewById(R.id.title);
holder.status=(TextView)v.findViewById(R.id.status);
holder.progressBar=(progressBar)v.findViewById(R.id.progress\u bar);
holder.downloadStateBtn=(DownloadStateButton)v.findViewById(R.id.btn\u download\u state);
v、 setTag(支架);
}否则{
holder=(ViewHolder)v.getTag();
}
holder.title.setText(getItem(position.getTitle());
整数fileSize=getItem(位置).getFileSize();
长进度=getItem(position).getProgress();
if(progress!=null&&fileSize!=null){
holder.progressBar.setMax(文件大小);
holder.progressBar.setProgress(progress.intValue());
holder.status.setText(Utils.humanReadableByteCount(进程)+“/”+
humanReadableByteCount(文件大小));
}
holder.downloadStateBtn.setTag(位置);
SavedShow.State State=getItem(position.getState();
/*设置按钮状态*/
//...
/*设置buton onclicklistener*/
holder.downloadStateBtn.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
int position=(整数)v.getTag();
SavedShow.State State=getItem(position.getState();
if(state==SavedShow.state.DOWNLOADING){
getItem(position).setState(SavedShow.State.WAIT\u PAUSE);
notifyDataSetChanged();
mDo
public class SavedShowListFragment extends Fragment {   

    //...

    @Override
    public void onResume() {         
        super.onResume();

        mAdapter = new SavedShowAdapter(getActivity(), MyApplication.dbHelper.getSavedShowList());

        mListView.setAdapter(mAdapter);

        //...
    }


    private ServiceConnection mDownloadServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {

            // Get service instance

            DownloadServiceBinder binder = (DownloadServiceBinder) service;
            mDownloadService = binder.getService();

            // Set service to adapter, to 'bind' adapter to the service

            mAdapter.setDownloadService(mDownloadService);

            //...
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {

            // Remove service from adapter, to 'unbind' adapter to the service

            mAdapter.setDownloadService(null);
        }
    };


    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            if(action.equals(DownloadService.ACTION_UPDATE_PROGRESS)){  
                mAdapter.updateItemProgress(intent.getLongExtra(DownloadService.KEY_SAVEDSHOW_ID, -1),
                        intent.getLongExtra(DownloadService.KEY_PROGRESS, -1));
            }

            //...
        }
    };

    //...

}
public class SavedShowAdapter extends ArrayAdapter<SavedShow> { 

    private LayoutInflater mLayoutInflater;

    private List<Long> mSavedShowIdList; // list to find faster the position of the item in updateProgress

    private DownloadService mDownloadService;

    private Context mContext;

    static class ViewHolder {
        TextView title;
        TextView status;
        ProgressBar progressBar;
        DownloadStateButton downloadStateBtn;
    }

    public static enum CancelReason{ PAUSE, DELETE };

    public SavedShowAdapter(Context context, List<SavedShow> savedShowList) {
        super(context, 0, savedShowList);       
        mLayoutInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); 

        mContext = context;

        mSavedShowIdList = new ArrayList<Long>();

        for(SavedShow savedShow : savedShowList){
            mSavedShowIdList.add(savedShow.getId());
        }
    }

    public void updateItemProgress(long savedShowId, long progress){
        getItem(mSavedShowIdList.indexOf(savedShowId)).setProgress(progress);
        notifyDataSetChanged();
    }

    public void updateItemFileSize(long savedShowId, int fileSize){
        getItem(mSavedShowIdList.indexOf(savedShowId)).setFileSize(fileSize);
        notifyDataSetChanged();
    }


    public void updateItemState(long savedShowId, int state_ind, String msg){

        SavedShow.State state = SavedShow.State.values()[state_ind];

        getItem(mSavedShowIdList.indexOf(savedShowId)).setState(state);

        if(state==State.ERROR){
            getItem(mSavedShowIdList.indexOf(savedShowId)).setError(msg);
        }

        notifyDataSetChanged();
    }

    public void deleteItem(long savedShowId){
        remove(getItem((mSavedShowIdList.indexOf(savedShowId))));       
        notifyDataSetChanged();
    }

    public void setDownloadService(DownloadService downloadService){
        mDownloadService = downloadService;
        notifyDataSetChanged();
    }

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

        ViewHolder holder;
        View v = convertView;

        if (v == null) {

            v = mLayoutInflater.inflate(R.layout.saved_show_list_item, parent, false);

            holder = new ViewHolder();

            holder.title = (TextView)v.findViewById(R.id.title);
            holder.status = (TextView)v.findViewById(R.id.status);
            holder.progressBar = (ProgressBar)v.findViewById(R.id.progress_bar);
            holder.downloadStateBtn = (DownloadStateButton)v.findViewById(R.id.btn_download_state);

            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }

        holder.title.setText(getItem(position).getTitle());

        Integer fileSize = getItem(position).getFileSize();
        Long progress = getItem(position).getProgress();
        if(progress != null && fileSize != null){
            holder.progressBar.setMax(fileSize);

            holder.progressBar.setProgress(progress.intValue());

            holder.status.setText(Utils.humanReadableByteCount(progress) + " / " +
                    Utils.humanReadableByteCount(fileSize));
        }

        holder.downloadStateBtn.setTag(position);

        SavedShow.State state = getItem(position).getState();

        /* set the button state */

        //...

        /* set buton onclicklistener */

        holder.downloadStateBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                int position = (Integer) v.getTag();

                SavedShow.State state = getItem(position).getState();

                if(state==SavedShow.State.DOWNLOADING){

                    getItem(position).setState(SavedShow.State.WAIT_PAUSE);
                    notifyDataSetChanged();

                    mDownloadService.cancelDownLoad(getItem(position).getId(), CancelReason.PAUSE);

                }
                else if(state==SavedShow.State.PAUSED || state==SavedShow.State.ERROR){                 

                    getItem(position).setState(SavedShow.State.WAIT_DOWNLOAD);
                    notifyDataSetChanged();

                    mDownloadService.downLoadFile(getItem(position).getId());

                }
                if(state==SavedShow.State.DOWNLOADED){

                    /* play file */
                }

            }
        });

        return v;
    }
} 
private static final int UPDATE_DOWNLOAD_PROGRESS = 666;

Handler myHandler = new Handler()
{
    @Override
    handleMessage(Message msg)
    {
        switch (msg.what)
        {
            case UPDATE_DOWNLOAD_PROGRESS:
                myAdapter.notifyDataSetChanged();
                break;
            default:
                break;
        }
    }
}



private void runUpdateThread() { 
    new Thread(
     new Runnable() {
         @Override
         public void run() {
             while ( MyFragment.this.getIsDownloading() )
             {
                  try 
                  {    
                      Thread.sleep(1000); // Sleep for 1 second

                      MyFragment.this.myHandler
                          .obtainMessage(UPDATE_DOWNLOAD_PROGRESS)
                          .sendToTarget();
                  } 
                  catch (InterruptedException e) 
                  {
                      Log.d(TAG, "sleep failure");
                  }
             }

         }
     } ).start(); 
}
public boolean updateListView(int position, int newProgress) {
    int first = mListView.getFirstVisiblePosition();
    int last = mListView.getLastVisiblePosition();
    if(position < first || position > last) {
        //just update your DataSet
        //the next time getView is called
        //the ui is updated automatically
        return false;
    }
    else {
        View convertView = mListView.getChildAt(position - first);
        //this is the convertView that you previously returned in getView
        //just fix it (for example:)
        ProgressBar bar = (ProgressBar) convertView.findViewById(R.id.progress);
        bar.setProgress(newProgress);
        return true;
    }
}
private static final long INTERVAL_BROADCAST = 800;
private long lastUpdate = 0;
if(System.currentTimeMillis() - lastUpdate > INTERVAL_BROADCAST) {
    lastUpdate = System.currentTimeMillis();
    Intent intent_progress = new Intent(ACTION_UPDATE_PROGRESS);
    intent_progress.putExtra(KEY_SAVEDSHOW_ID, savedShow.getId());
    intent_progress.putExtra(KEY_PROGRESS, downloaded );
    LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent_progress);
}
holder.downloadStateBtn.setTag(position); 
holder.downloadStateBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) { 
            int position = (Integer) v.getTag(); 
             // your current normal click handling
        }
    });
final OnClickListener btnListener = new OnClickListener() {

    @Override
    public void onClick(View v) { 
        int position = (Integer) v.getTag();
        // your normal click handling code goes here
    }
}
 if (v == null) {
        v = mLayoutInflater.inflate(R.layout.saved_show_list_item, parent, false);
        // your ViewHolder stuff here 
        holder.downloadStateBtn.setOnClickListener(btnClickListener);//<<<<<
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }
holder.downloadStateBtn.setTag(position);