自定义Listview滚动隐藏进度条进程和ImageView

时间:2014-03-21 08:35:54

标签: android android-listview

我有一个自定义Listview,其中每个项目都包含一个进度条。但是当列表包含许多项目,并且我使用滚动条浏览列表视图时,一些ProgressBars消失并面临与imageview相同的问题,以显示上传图像的状态,可能是什么原因以及如何解决此问题?看下面的代码

    static class ViewHolder {
        public ViewHolder(View convertView) {
            // TODO Auto-generated constructor stub
        }
        TextView imageNameTextView;
        ImageView sdCardImageView, statusImageView;
        ProgressBar uploadProgressBar;
        ImageButton uploadImageButton, dataImageButton, printImageButton, viewImageButton, deleteImageButton ;
    }  
     public class ImageAdapter extends BaseAdapter
        {
            public ImageAdapter(Context c)
            {
            }

            public int getCount() {
                // TODO Auto-generated method stub
                return ImageList.size();
            }

            public Object getItem(int position) {
                // TODO Auto-generated method stub
                return position;
            }

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

    public View getView(final int position, View convertView, ViewGroup parent) {
        // Avoid unneccessary calls to findViewById() on each row, which is expensive!
        holder = null;

            // If this item is to be synced
            if(flags.get(position)) {
                startUpload(position);

            // Mark as synced
            flags.put(position, false);
            }

            /*
             * If convertView is not null, we can reuse it directly, no inflation required!
             * We only inflate a new View when the convertView is null.
             */
            if (convertView == null) {
            convertView = getLayoutInflater().inflate(R.layout.list_upload, null);
            holder = new ViewHolder(convertView);

            // Create a ViewHolder and store references to the children views
            holder.imageNameTextView = (TextView) convertView.findViewById(R.id.ColImgName);
            holder.sdCardImageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
            holder.statusImageView = (ImageView) convertView.findViewById(R.id.ColStatus);
            holder.uploadProgressBar = (ProgressBar) convertView.findViewById(R.id.progressBar);
            holder.uploadImageButton = (ImageButton) convertView.findViewById(R.id.btnUpload);
            holder.dataImageButton = (ImageButton) convertView.findViewById(R.id.btnData);
            holder.printImageButton = (ImageButton) convertView.findViewById(R.id.btnPrint);
            holder.viewImageButton = (ImageButton) convertView.findViewById(R.id.btnView);
            holder.deleteImageButton = (ImageButton) convertView.findViewById(R.id.btnDelete);

                // The tag can be any Object, this just happens to be the ViewHolder
                convertView.setTag(holder);
            } else {

                holder = (ViewHolder) convertView.getTag();
            }

            strPath = ImageList.get(position).toString();

            // Get File Name
            fileName = strPath.substring( strPath.lastIndexOf('_')+1, strPath.length() );
            file = new File(strPath);
            @SuppressWarnings("unused")
            long length = file.length();
            holder.imageNameTextView.setText(fileName);

            final BitmapFactory.Options options = new BitmapFactory.Options();

            options.inSampleSize = 8;

            Bitmap bm = BitmapFactory.decodeFile(strPath,options);
            holder.sdCardImageView.setImageBitmap(bm);       

            holder.statusImageView.setImageResource(R.drawable.bullet_button);

            holder.uploadProgressBar.setVisibility(View.GONE);

            //btnUpload
            holder.uploadImageButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            // Upload
                 cd = new ConnectionDetector(getApplicationContext());

                    // Check for internet connection
                    if (!cd.isConnectingToInternet()) {
                        // Internet Connection is not present
                        alert.showAlertDialog(UploadActivity.this, "Internet not available",
                                "Please connect to working Internet connection", false);
                        // stop executing code by return
                        return;
                    }

                    startUpload(position);
                }
            });

         //Upload
    public void startUpload(final int position) {      

        Runnable runnable = new Runnable() {

        public void run() {

            handler.post(new Runnable() {

        public void run() {

            v = lstView.getChildAt(position - lstView.getFirstVisiblePosition());

            holder.uploadProgressBar.setVisibility(View.VISIBLE);

            holder.statusImageView.setImageResource(R.drawable.bullet_button);

                new UploadFileAsync().execute(String.valueOf(position));   
                        }
                    });
                }
            };
            new Thread(runnable).start();
            }

            // Async Upload
            public class UploadFileAsync extends AsyncTask<String, Void, Void> {

                String resServer;

            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected Void doInBackground(String... params) {
            // TODO Auto-generated method stub
                position = Integer.parseInt(params[0]);

                int bytesRead, bytesAvailable, bufferSize;
                byte[] buffer;
                int maxBufferSize = 1 * 1024 * 1024;
                int resCode = 0;
                String resMessage = "";

                String lineEnd = "\r\n";
                String twoHyphens = "--";
                String boundary =  "*****";

                // File Path
                String strSDPath = ImageList.get(position).toString();

                // Upload to PHP Script
                String strUrlServer = "http://domein/fiile.php";

                try {
                    /** Check file on SD Card ***/
                    File file = new File(strSDPath);
                    if(!file.exists())
                    {   
                        resServer = "{\"StatusID\":\"0\",\"Error\":\"Please check path on SD Card\"}";
                        return null;
                    }

                FileInputStream fileInputStream = new FileInputStream(new File(strSDPath));

                URL url = new URL(strUrlServer);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.setUseCaches(false);
                    conn.setRequestMethod("POST");

                    conn.setRequestProperty("Connection", "Keep-Alive");
                    conn.setRequestProperty("Content-Type",
                            "multipart/form-data;boundary=" + boundary);

                DataOutputStream outputStream = new DataOutputStream(conn
                        .getOutputStream());
                    outputStream.writeBytes(twoHyphens + boundary + lineEnd);
                    outputStream
                    .writeBytes("Content-Disposition: form-data; name=\"filUpload\";filename=\""
                            + strSDPath + "\"" + lineEnd);
                    outputStream.writeBytes(lineEnd);

                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                buffer = new byte[bufferSize];

                // Read file
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0) {
                    outputStream.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                }

                outputStream.writeBytes(lineEnd);
                outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                // Response Code and  Message
                resCode = conn.getResponseCode();
                    if(resCode == HttpURLConnection.HTTP_OK)
                    {
                        InputStream is = conn.getInputStream();
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();

                int read = 0;
                while ((read = is.read()) != -1) {
                    bos.write(read);
                }

                byte[] result = bos.toByteArray();
                    bos.close();

                resMessage = new String(result);

                }

                Log.d("resCode=",Integer.toString(resCode));
                Log.d("resMessage=",resMessage.toString());

                fileInputStream.close();
                outputStream.flush();
                outputStream.close();

                resServer = resMessage.toString();


                } catch (Exception ex) {
                    ex.printStackTrace();
                }

                return null;
                }

                protected void onPostExecute(Void unused) {
                    statusWhenFinish(position,resServer);
                    }

                }


            // When UPload Finish
            @SuppressWarnings("unused")
            protected void statusWhenFinish(int position, String resServer) {

            View v = lstView.getChildAt(position - lstView.getFirstVisiblePosition());

            // hide ProgressBar
            holder.uploadProgressBar.setVisibility(View.GONE);


            /*** Default Value ***/
            String strStatusID = "0" ;
            String strError = "" ;

            try {      

            JSONObject c = new JSONObject(resServer);
            strStatusID = c.getString("StatusID");
            strError = c.getString("Message");
            } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }

            // using if - else if
            if(strStatusID.equals("0"))
            {   
                // already exist
              holder.statusImageView.setImageResource(R.drawable.already_exist);
            }
            else if(strStatusID.equals("1"))                {
                // upload done
                holder.statusImageView.setImageResource(R.drawable.upload_done);
            }
            else // if upload failed
            {
                 // upload failed
                holder.statusImageView.setImageResource(R.drawable.upload_failed);
            }

            }

         }

5 个答案:

答案 0 :(得分:3)

所以对你的ProgressBar。

每当调用getView()时,都会将其可见性设置为GONE。

holder.uploadProgressBar.setVisibility(View.GONE);

因此,当开始上传某些内容(并将uploadProgressBar设置为VISIBLE),然后向下滚动(使列表项不可见),然后向上滚动,将再次调用getView(),它将使您的ProgressBar不可见。< / p>

因此,您需要将状态包装在对象中,或使用列表记录每个项目状态。例如,在ImageAdapter

boolean[] uploadings = new boolean[getCount()];
Arrays.fill(uploadings, false);

getView()

if (uploadings[position]) {
    // You need this, since you are not sure whether you are
    // using newly inflated view or ConvertView
    holder.uploadProgressBar.setVisibility(View.VISIBLE);
} else {
    holder.uploadProgressBar.setVisibility(View.GONE);
}

startUpload()方法中,每当您将prograss栏设置为GONE或VISIBILE时,请将uploadings[position]设置为falsetrue

我认为您的ImageView可能存在同样的问题。

答案 1 :(得分:3)

ViewHolder课程中:

static class ViewHolder {
     //...
     boolean isUploading = false;
     //...
}

getView()

public View getView(final int position, View convertView, ViewGroup parent) {
     //...
     if(holder.isUploading) {
           holder.uploadProgressBar.setVisibility(View.VISIBLE);
     } else {
           holder.uploadProgressBar.setVisibility(View.GONE);
     }
     //...
}

startUpload()

public void startUpload(final int position) { 
     //...
     holder.uploadProgressBar.setVisibility(View.VISIBLE);
     holder.isUploading = true;
     //...
}

希望它能奏效。

答案 2 :(得分:1)

尝试使用持有人进行单元格视图

将此类放在适配器的末尾

class ViewHolder {
        TextView txtName,txtStatus;

        ImageView imageView;

        public ViewHolder(View convertview) {
            txtName = (TextView) convertview.findViewById(R.id.txtName );
            imageView = (ImageView) convertview.findViewById(R.id.ColImgPath);
          //and so on...


        }
    }

取代:

 if (convertView == null) {
        convertView = inflater.inflate(R.layout.list_upload, null);
    }

使用:

 if (convertview == null) {
            convertview = activity.getLayoutInflater().inflate(R.layout.list_upload, null);
            holder = new ViewHolder(convertview);
            convertview.setTag(holder);
        } else {
            holder = (ViewHolder) convertview.getTag();
        }

之后与持有人一起做你的工作......

holder.imageView代替所有视图的imageView等等

答案 3 :(得分:1)

您必须在getView()方法中设置进度状态,因为android重用ListView项。 为了解你如何解决这个问题:

`

 public View getView(final int position, View convertView, ViewGroup parent) {
    .
    .
    .
Int rowId = holder.id;
UploadTask task = Uploader.getTaskById(rowId);
if (task == null) {
holder.progressBar.setVisibility(View.Gone);
} else {
int progress = task.getUploadProgress();
holder.progressBar.setVisibility(View.Visible);
holder.progressBar.setProgress(progress);
}
    }

P.S。你应该看一下Google IO video about listviewListView

答案 4 :(得分:1)

查看可能对您有用的Listview with ProgressBar