Custom Listview scroll hiding progressbar process and ImageView

我的未来我决定 提交于 2019-12-04 03:31:39

问题


I have a custom Listview, where each item contains a progressbar. But when the list contains many items, and I use the scrollbar to navigate through listview, some ProgressBars disappear and facing same issue with imageview using to show status of uploaded image(s), what could be the reason and how can i resolve this ? see my code below

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

            }

         }

回答1:


In your ViewHolder class :

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

In your 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);
     }
     //...
}

In your startUpload():

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

Hope it will work.




回答2:


So for your ProgressBar.

Whenever getView() is called, you set its visibility to GONE.

holder.uploadProgressBar.setVisibility(View.GONE);

So when starts to upload something (and sets uploadProgressBar to VISIBLE), and you scroll down (makes the list item invisible), then scroll up, getView() will be called again, and it will make your ProgressBar invisible.

So you need wrap the state in an object, or use a list to record each item state. For example, in your ImageAdapter

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

in your 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);
}

And in your startUpload() method, whenever you set your prograss bar to GONE or VISIBILE, set uploadings[position] to false or true correspondingly.

And I think your ImageView probably has the same problem.




回答3:


try to use a holder for your cell view

put this class at the end of your adapter

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


        }
    }

replace:

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

with:

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

after that do your job with holder...

holder.imageView instead of imageView and so on for all views




回答4:


Check out the Listview with ProgressBar it might help you




回答5:


You must set progress state in getView() method because android reuse ListView items. to get you a clue how to resolve this:

`

 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. You should watch this Google IO video about listviewListView



来源:https://stackoverflow.com/questions/22553802/custom-listview-scroll-hiding-progressbar-process-and-imageview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!