向上滚动时自定义列表视图然后进度条进程隐藏

时间:2013-02-19 12:19:07

标签: android android-progressbar custom-lists

我发现了一些类似的问题,但无法解决问题。我有一个自定义Listview,其中每个项目包含一个水平进度条。但是当列表包含许多项目时,我使用滚动条浏览列表视图,一些ProgressBars会消失。导致这种情况的原因以及如何解决?我的代码如下。感谢。

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

当进度条状态不可见且按钮状态隐藏时,我尝试向上滚动。问题是什么以及如何解决?

enter image description here

我的错误鉴于它::

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)

我使用了下面给出的Url_dto类代码::

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

我的DBADpter类下面给出::::

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;

    }
}

1 个答案:

答案 0 :(得分:2)

当您向上或向下滚动以保存内存时,Android系统会重复使用行项目。

因此,当您单击其中一个控件时,它将设置为Visibility.GONE,然后滚动时,同一控件在其他列表项上不可见,因为进度条以前设置为不可见 - 得到它?

此外,您每次显示视图时都会重新创建视图,因此您将创建新的进度条而不重用已创建的视图。

您只需创建一次控件,并在每次显示时重置控件的可见性和状态。

使用容器类来保存指向已创建视图的指针,这样每次都不会重新创建它们。

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