【问题标题】:Update listview row in asynctask更新异步任务中的列表视图行
【发布时间】:2014-07-15 06:18:51
【问题描述】:

我有一个带有基本适配器的列表视图。我的列表视图中的每一行都包含图像、标题、下载和查看按钮以及进度条。最初进度条和视图按钮的可见性已消失。当用户按下下载按钮时,应该可以看到进度条。下载完成后,下载按钮应该消失,查看按钮应该可见。

我的问题是:我无法从 asynctask 更改视图的可见性。

这是我的代码。

public class PdfListAdapter extends BaseAdapter {

    ArrayList<PdfDetails> arylstPdf = new ArrayList<PdfDetails>();
    Context context;
    String extStorageDirectory;
    ViewHolder holder;
    Activity activity;


    public PdfListAdapter(Context context, ArrayList<PdfDetails> arylstPdf) {
        super();
        this.arylstPdf = arylstPdf;
        this.context = context;

        extStorageDirectory = Environment.getExternalStorageDirectory()
                .toString();
        holder = new ViewHolder();
    }

    @Override
    public int getCount() {
        return arylstPdf.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater mInflater = LayoutInflater.from(context);
        activity = (Activity) context;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.layout_pdf_list, null);

            holder.tvPdfTitle = (TextView) convertView
                    .findViewById(R.id.tvPdfTitle);

            holder.imgPdfImage = (ImageView) convertView
                    .findViewById(R.id.imgPdfImage);

            holder.btnDownload = (Button) convertView
                    .findViewById(R.id.btnDownload);

            holder.btnView = (Button) convertView.findViewById(R.id.btnView);

            holder.pbDownload = (ProgressBar) convertView
                    .findViewById(R.id.pbDownload);

            holder.tvProgress = (TextView) convertView.findViewById(R.id.tvProgress);

            holder.llProgress = (LinearLayout) convertView.findViewById(R.id.llProgress);

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

        File file = new File(extStorageDirectory + "/pdf", arylstPdf.get(
                position).getPostTitle()
                + ".pdf");

        if (file.exists()) {
            holder.btnDownload.setVisibility(View.GONE);
            holder.btnView.setVisibility(View.VISIBLE);
        } else {
            holder.btnDownload.setVisibility(View.VISIBLE);
            holder.btnView.setVisibility(View.GONE);
        }


        holder.tvPdfTitle.setText(arylstPdf.get(position).getPostTitle());

        ImageLoader objImageLoader = new ImageLoader(context);
        objImageLoader.DisplayImage(arylstPdf.get(position).getAttachedImage(),
                holder.imgPdfImage);

        holder.btnDownload.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                 // NOT WORKING
                holder.llProgress.setVisibility(View.VISIBLE);
                Async async = new Async();
                async.execute(Integer.toString(position));

            }
        });

        holder.btnView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                readPDF(arylstPdf.get(position).getPostTitle());
            }
        });

        return convertView;
    }

    class ViewHolder {
        ImageView imgPdfImage;
        TextView tvPdfTitle, tvProgress;
        Button btnDownload;
        Button btnView;
        ProgressBar pbDownload;
        LinearLayout llProgress;
    }



    class Async extends AsyncTask<String, String, String> {

        File file, folder;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            folder = new File(extStorageDirectory, "pdf");
            folder.mkdir();
        }

        @Override
        protected String doInBackground(String... params) {

            String fileName = arylstPdf.get(Integer.parseInt(params[0]))
                    .getPostTitle();

            file = new File(folder, fileName + ".pdf");

            try {
                file.createNewFile();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            int count;

            try {
                URL url = new URL(arylstPdf.get(Integer.parseInt(params[0]))
                        .getAttachedPdf());
                URLConnection conection = url.openConnection();
                conection.connect();

                int lenghtOfFile = conection.getContentLength();

                InputStream input = new BufferedInputStream(url.openStream(),
                        8192);
                OutputStream output = new FileOutputStream(file);

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;

                    publishProgress(Integer
                            .toString((int) ((total * 100) / lenghtOfFile)));


                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();

            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onProgressUpdate(String... progress) {
            holder.tvProgress.setText(progress[0]);
            holder.pbDownload.setProgress(Integer.parseInt(progress[0]));
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            // NOT WORKING
            holder.btnDownload.setVisibility(View.GONE);
            holder.btnDownload.setVisibility(View.VISIBLE);
            Toast.makeText(context, "Downloaded", Toast.LENGTH_SHORT).show();
        }

    }

}

【问题讨论】:

    标签: android android-layout android-listview android-asynctask


    【解决方案1】:

    PdfDetails 类更改下载中添加一个布尔标志,并在getView 方法中查看按钮可见性。

    所以只需在 arraylist 位置更改该特定行的布尔标志。

    和用户adapter.notifyDataStateChanged();

    在 PdfDetails 类中添加 getter setter 方法。

    在getView()方法中

    使用

    PdfDetails detailBin = list.get(position);
    
    if(detailBin.isDownloaded)
       // view button visible and download button hide
    else 
      // download button visible and view button hide
    

    在 postExecute() 中

    list.get(position).setDownload(true);
    adapter.notifyDataStateChanged();
    

    【讨论】:

    • 嘿@Sanket 谢谢.. 它有效!但请解决我的另一个问题。我也想在下载时显示进度条.. 上面的代码,我不能这样做
    • 是的,对于正在进行下载过程的每一行
    • 您应该需要从 AsyncTask 通知您的列表视图。
    • 您能提供一些示例代码或与此相关的任何链接吗?
    【解决方案2】:

    除了在 Adapter 类本身中创建 holder 之外,您还可以让它在 getView 本身中并将其传递给 AsyncTask 构造函数。

    public class PdfListAdapter extends BaseAdapter {
    
    ArrayList<PdfDetails> arylstPdf = new ArrayList<PdfDetails>();
    Context context;
    String extStorageDirectory;
    Activity activity;
    
    
    public PdfListAdapter(Context context, ArrayList<PdfDetails> arylstPdf) {
        super();
        this.arylstPdf = arylstPdf;
        this.context = context;
    
        extStorageDirectory = Environment.getExternalStorageDirectory()
                .toString();
    }
    
    @Override
    public int getCount() {
        return arylstPdf.size();
    }
    
    @Override
    public Object getItem(int position) {
        return position;
    }
    
    @Override
    public long getItemId(int position) {
        return position;
    }
    
    
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater mInflater = LayoutInflater.from(context);
        activity = (Activity) context;
        final ViewHolder holder= null;
    
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.layout_pdf_list, null);
            holder = new ViewHolder();
    
            holder.tvPdfTitle = (TextView) convertView
                    .findViewById(R.id.tvPdfTitle);
    
            holder.imgPdfImage = (ImageView) convertView
                    .findViewById(R.id.imgPdfImage);
    
            holder.btnDownload = (Button) convertView
                    .findViewById(R.id.btnDownload);
    
            holder.btnView = (Button) convertView.findViewById(R.id.btnView);
    
            holder.pbDownload = (ProgressBar) convertView
                    .findViewById(R.id.pbDownload);
    
            holder.tvProgress = (TextView) convertView.findViewById(R.id.tvProgress);
    
            holder.llProgress = (LinearLayout) convertView.findViewById(R.id.llProgress);
    
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
    
        File file = new File(extStorageDirectory + "/pdf", arylstPdf.get(
                position).getPostTitle()
                + ".pdf");
    
        if (file.exists()) {
            holder.btnDownload.setVisibility(View.GONE);
            holder.btnView.setVisibility(View.VISIBLE);
        } else {
            holder.btnDownload.setVisibility(View.VISIBLE);
            holder.btnView.setVisibility(View.GONE);
        }
    
    
        holder.tvPdfTitle.setText(arylstPdf.get(position).getPostTitle());
    
        ImageLoader objImageLoader = new ImageLoader(context);
        objImageLoader.DisplayImage(arylstPdf.get(position).getAttachedImage(),
                holder.imgPdfImage);
    
        holder.btnDownload.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
    
                 // NOT WORKING
                holder.llProgress.setVisibility(View.VISIBLE);
                Async async = new Async(holder);
                async.execute(Integer.toString(position));
    
            }
        });
    
        holder.btnView.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                readPDF(arylstPdf.get(position).getPostTitle());
            }
        });
    
        return convertView;
    }
    
    class ViewHolder {
        ImageView imgPdfImage;
        TextView tvPdfTitle, tvProgress;
        Button btnDownload;
        Button btnView;
        ProgressBar pbDownload;
        LinearLayout llProgress;
    }
    
    
    
    class Async extends AsyncTask<String, String, String> {
    
        File file, folder;
        ViewHolder holder;
    
        public Async(ViewHolder holder) {
            this.holder=holder;
        }
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
    
            folder = new File(extStorageDirectory, "pdf");
            folder.mkdir();
        }
    
        @Override
        protected String doInBackground(String... params) {
    
            String fileName = arylstPdf.get(Integer.parseInt(params[0]))
                    .getPostTitle();
    
            file = new File(folder, fileName + ".pdf");
    
            try {
                file.createNewFile();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
    
            int count;
    
            try {
                URL url = new URL(arylstPdf.get(Integer.parseInt(params[0]))
                        .getAttachedPdf());
                URLConnection conection = url.openConnection();
                conection.connect();
    
                int lenghtOfFile = conection.getContentLength();
    
                InputStream input = new BufferedInputStream(url.openStream(),
                        8192);
                OutputStream output = new FileOutputStream(file);
    
                byte data[] = new byte[1024];
    
                long total = 0;
    
                while ((count = input.read(data)) != -1) {
                    total += count;
    
                    publishProgress(Integer
                            .toString((int) ((total * 100) / lenghtOfFile)));
    
    
                    output.write(data, 0, count);
                }
    
                output.flush();
                output.close();
                input.close();
    
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        @Override
        protected void onProgressUpdate(String... progress) {
            holder.tvProgress.setText(progress[0]);
            holder.pbDownload.setProgress(Integer.parseInt(progress[0]));
        }
    
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
    
            // NOT WORKING
            holder.btnDownload.setVisibility(View.GONE);
            holder.btnDownload.setVisibility(View.VISIBLE);
            Toast.makeText(context, "Downloaded", Toast.LENGTH_SHORT).show();
        }
    
    }
    
    }
    

    【讨论】:

    • 在将 asynctask 更新计数设置为 viewholders textview android 后
    【解决方案3】:

    您不能在主 ui 线程以外的其他线程(Asynctasks)中对 UserInterface(UI) 进行任何更改。 所以你需要遵循这个

               runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
            //Any UI changes can be done here            
            holder.btnDownload.setVisibility(View.GONE);
            holder.btnView.setVisibility(View.VISIBLE);
                        }
                    });
    

    【讨论】:

    • 他在 onPostExecute 中做的,所以没有任何问题
    • Ya ur crct..post 执行在主 UI 线程上运行...我认为它在 DoinBackground 上完成
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多