سؤال

I found some similar questions, but could not solve the problem. I have a custom Listview, where each item contains a horizontal progressbar. But when the list contains many items, and I use the scrollbar to navigate through listview, some ProgressBars disappear. What causes this and how do I fix it?my code below .Advance thanks .

public class ScrollActivity extends Activity {
    ListView lv;
    // ArrayList<String> list = new ArrayList<String>();
    ArrayList<Url_Dto> list = new ArrayList<Url_Dto>();
    MyListAdapter adtf;

    public static String prf_date_view = "";

    String str_start;
    Button all_detail;
    Button accepted_all, mainDownloadBtn;
    Button not_shown;
    public static SQLiteDatabase db;
    String name;
    File download;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scroll);

        list = DBAdapter.getUrl_Detail();
        Log.v("log_tag", "list  :: " + list.size());
        lv = (ListView) findViewById(R.id.main_list_meet);
        mainDownloadBtn = (Button) findViewById(R.id.not_shown);
        adtf = new MyListAdapter(this, 0, list);
        lv.setAdapter(adtf);

        /*SqliteAdpter dba = SqliteAdpter
                .getAdapterInstance(getApplicationContext());
        dba.createdatabase();
        db = dba.openDataBase();*/

        mainDownloadBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                // Log.v("log_tag","list.toArray()  "+list.size() );
                // new DownloadFileFromURL().equals(list.toArray());
            }
        });

    }

    public class MyListAdapter extends ArrayAdapter<Url_Dto> {
        private LayoutInflater mInflater;

        ArrayList<Url_Dto> emplist = null;
        public Activity activity;


        public MyListAdapter(Activity activity, int layoutResourceId,
                ArrayList<Url_Dto> emplist) {
            super(activity, layoutResourceId, emplist);
            this.activity = activity;
            this.emplist = emplist;
        }

        /*public MyListAdapter(Context context) {
            mInflater = LayoutInflater.from(context);

        }*/

        public int getCount() {
            return list.size();
        }

        /*public Object getItem(int position) {
            return position;
        }*/

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

        private class ListRowViews {
            Button cl;
            Button dl;
            ProgressBar pr;
            ImageView im;

        };

        public View getView(final int position, View convertView,
                ViewGroup parent) {
            final ListRowViews views;

            final Url_Dto itemState = getItem(position);

            // only recreate row if it is null
            if (convertView == null) {
                // store controls in tag of view so you can get them later
                convertView = mInflater.inflate(R.layout.custome_list_view,null);

                views = new ListRowViews();

                views.cl = (Button) convertView
                        .findViewById(R.id.cancle_sedual);
                views.dl = (Button) convertView
                        .findViewById(R.id.download_sedual);
                views.pr = (ProgressBar) convertView
                        .findViewById(R.id.listprogressbar);
                views.im = (ImageView) convertView
                        .findViewById(R.id.list_image);

                views.im.setImageResource(emplist.get(position).images[position]);

                views.cl.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub

                        views.dl.setVisibility(View.VISIBLE);
                        views.cl.setVisibility(View.GONE);

                        itemState.isClicked = true;
                    }
                });

                views.dl.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        str_start = emplist.get(position).url_video;
                        views.dl.setVisibility(View.GONE);
                        views.cl.setVisibility(View.VISIBLE);
                        Log.v("log_tag", "str_start  " + str_start);

                        //
                        // new DownloadFileFromURL().execute(str_start);
                        new DownloadFileFromURL().execute(views.pr, str_start);
                    }
                });

                // store the view pointers for reuse later
                convertView.setTag(views);

            } else {
                views = (ListRowViews) convertView.getTag();
            }

            // you need to get the progress from list item that this view
            // represents
            int progress = itemState.progress;
            views.pr.setProgress(progress);

            views.dl.setVisibility(View.VISIBLE);
            views.cl.setVisibility(View.VISIBLE);

            if (itemState.isVisible) {
                views.dl.setVisibility(View.VISIBLE);
                views.cl.setVisibility(View.GONE);
            } else {
                views.dl.setVisibility(View.GONE);
                views.cl.setVisibility(View.VISIBLE);
            }

            return convertView;
        }
    }

    class DownloadFileFromURL extends AsyncTask<Object, String, String> {

        int count = 0;
        ProgressDialog dialog;
        ProgressBar progressBar;
        int myProgress;

        /**
         * Before starting background thread Show Progress Bar Dialog
         * */

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

        }

        /**
         * Downloading file in background thread
         * */
        @Override
        protected String doInBackground(Object... params) {
            Log.v("log_tag", "params  :::; " + params);
            int count;
            progressBar = (ProgressBar) params[0];
            try {
                // URL url = new URL(f_url[0]);
                URL url = new URL((String) params[1]);
                Log.v("log_tag", "name  ::: " + url);
                name = ((String) params[1]).substring(((String) params[1])
                        .lastIndexOf("/") + 1);
                Log.v("log_tag", "name Substring ::: " + name);
                URLConnection conection = url.openConnection();
                conection.connect();
                // getting file length
                int lenghtOfFile = conection.getContentLength();

                // input stream to read file - with 8k buffer
                InputStream input = new BufferedInputStream(url.openStream(),
                        8192);
                download = new File(Environment.getExternalStorageDirectory()
                        + "/download/");
                if (!download.exists()) {
                    download.mkdir();
                }
                String strDownloaDuRL = download + "/" + name;
                Log.v("log_tag", " down url   " + strDownloaDuRL);
                FileOutputStream output = new FileOutputStream(strDownloaDuRL);

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    // publishProgress("" + (int) ((total * 100) /
                    // lenghtOfFile));

                    // writing data to file
                    progressBar
                            .setProgress((int) ((total * 100) / lenghtOfFile));
                    output.write(data, 0, count);
                }
                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();

            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }

            return null;
        }

        /**
         * Updating progress bar
         * */
        protected void onProgressUpdate(String... values) {

            super.onProgressUpdate(values);
            Log.v("log_tag", "progress :: " + values);
            // setting progress percentage
            // pDialog.setProgress(Integer.parseInt(progress[0]));
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {

            Log.v("log", "login  ::: 4::: " + download);
            String videoPath = download + "/" + name;
            String chpName = name;
            Log.v("log_tag", "chpName  ::::" + chpName + "  videoPath "
                    + videoPath);
            /*db.execSQL("insert into videoStatus (chapterNo,videoPath) values(\""
                    + chpName + "\",\"" + videoPath + "\" )");
*/
        }

    }

}

enter image description here

i try to scroll up when progressbar status invisible and button status hide .what is problem and how to solve it?

enter image description here

My error Given it::

02-20 18:44:39.640: E/AndroidRuntime(4144): FATAL EXCEPTION: main
02-20 18:44:39.640: E/AndroidRuntime(4144): java.lang.NullPointerException
02-20 18:44:39.640: E/AndroidRuntime(4144):     at com.example.testscrollup.ScrollActivity$MyListAdapter.getView(ScrollActivity.java:121)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.AbsListView.obtainView(AbsListView.java:1593)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.ListView.makeAndAddView(ListView.java:1782)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.ListView.fillDown(ListView.java:705)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.ListView.fillFromTop(ListView.java:762)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.ListView.layoutChildren(ListView.java:1633)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.AbsListView.onLayout(AbsListView.java:1423)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.View.layout(View.java:7175)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.LinearLayout.onLayout(LinearLayout.java:1047)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.View.layout(View.java:7175)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.View.layout(View.java:7175)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.LinearLayout.onLayout(LinearLayout.java:1047)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.View.layout(View.java:7175)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.View.layout(View.java:7175)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1146)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.os.Looper.loop(Looper.java:130)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at android.app.ActivityThread.main(ActivityThread.java:3687)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at java.lang.reflect.Method.invokeNative(Native Method)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at java.lang.reflect.Method.invoke(Method.java:507)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
02-20 18:44:39.640: E/AndroidRuntime(4144):     at dalvik.system.NativeStart.main(Native Method)

and i used Url_dto Class code given below::

public class Url_Dto {
    String url_video;
    Integer[] images = { R.drawable.alligator_sm,
            R.drawable.bear_sm, R.drawable.bee_sm, R.drawable.bluejay_sm,
            R.drawable.camel_sm, R.drawable.cat_sm, R.drawable.chimpanzee_sm,
            R.drawable.chipmunk_sm, R.drawable.cheetah_sm, R.drawable.cock_sm,
            R.drawable.cow_sm, R.drawable.coyote_sm, R.drawable.deer_sm,
            R.drawable.dog_sm };
    protected boolean isClicked;
    public int progress;
    public boolean isVisible;
}

My DBADpter Class Given Below::::

public class DBAdapter {
    public static String url = "*****    My Url ********";

    public static ArrayList<Url_Dto> getUrl_Detail() {

        ArrayList<Url_Dto> fetchUrl_Detail = new ArrayList<Url_Dto>();
        String result = "";
        InputStream is = null;

        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

        // http post
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }
        // convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }

        // parse json data
        try {
            JSONObject json_obj = new JSONObject(result);
            JSONArray j_Arr_fn = json_obj.getJSONArray("children");

            for (int i = 0; i < j_Arr_fn.length(); i++) {
                JSONObject json_objs = j_Arr_fn.getJSONObject(i);
                Url_Dto proDto = new Url_Dto();
                proDto.url_video = json_objs.getString("videoUrl");
                Log.v("log_tag", "Url  :::" + json_objs.getString("videoUrl"));
                fetchUrl_Detail.add(proDto);
            }

        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
        return fetchUrl_Detail;

    }
}
هل كانت مفيدة؟

المحلول

The row items are reused by the android system when you scroll up or down to save memory.

So when you click on one of the controls in a row, it is set to Visibility.GONE, then when you scroll, the same control is not visible on other list items, because the progress bar was set to invisible previously - get it?

Also you are recreating the view each time it is displayed, so you are creating new progress bars and not reusing the ones already created.

You need to only create the controls once and reset the visibility and state of the controls each time they are displayed.

Use a container class to hold pointers to the created views so you dont recreate them each time.

    private class ListRowViews
        {
           Button c1;
           Button d1;
           ProgressBar pr;

        };

    public View getView(final int position, View convertView, ViewGroup parent) 
    {
        ListRowViews views;

        final YourStateClass itemState = getItem(position);

        //only recreate row if it is null
        if (convertView == null)
        {
            //store controls in tag of view so you can get them later
            convertView = mInflater.inflate(R.layout.custome_list_view, null);

            views = new ListRowViews();

            views.cl = (Button) convertView.findViewById(R.id.cancle_sedual);
            views.dl = (Button) convertView.findViewById(R.id.download_sedual);
            views.pr=(ProgressBar)convertView.findViewById(R.id.listprogressbar);

            views.cl.setOnClickListener(new View.OnClickListener() {

                            @Override
                            public void onClick(View v) {
                                // TODO Auto-generated method stub

                                views.dl.setVisibility(View.VISIBLE);
                                views.cl.setVisibility(View.GONE);

                                itemState.isClicked = true;
                            }
                        });

             views dl.setOnClickListener(new View.OnClickListener() {

                            @Override
                            public void onClick(View v) {
                                // TODO Auto-generated method stub
                                str_start=list.get(position).url_video;
                                views.dl.setVisibility(View.GONE);
                                views.cl.setVisibility(View.VISIBLE);
                                Log.v("log_tag","str_start  "+ str_start);

                                //
                                //new DownloadFileFromURL().execute(str_start);
                                new DownloadFileFromURL().execute(pr,str_start);
                            }
                        });


              //store the view pointers for reuse later
              convertView.setTag(views);

        }
        else
        {
            views = (ListRowViews)convertView.getTag();        
        }       


        //you need to get the progress from list item that this view represents
        int progress = itemState.progress;
        views.pr.setProgress(progress); 

        views.dl.setVisibility(View.VISIBLE);
        views.cl.setVisibility(View.VISIBLE);

        if (itemState.isVisible)
        {
           views.dl.setVisibility(View.VISIBLE);
           views.cl.setVisibility(View.GONE);
        }
        else
        {
           views.dl.setVisibility(View.GONE);
           views.cl.setVisibility(View.VISIBLE);
        }

        return convertView;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top