ListView有时不会对元素进行反应

时间:2013-03-05 19:03:33

标签: android listview onclicklistener blocked

我在活动中有一个ListView。列表元素是从BaseAdapter生成的。当用户在屏幕上向下滚动时,该列表不断增长。实际上,AsyncTask负责从互联网上下载数据并为ListView生成View元素。

每个View元素都有一个onClickListener集。 OnClickListener类启动一个新活动...

问题是有时GUI不会对点击操作做出反应。 例如 1.启动应用程序 2.点击第一个元素 - >什么都没发生 3.点击第二个元素 - >什么都没发生 4.向下滚动但是 - >两个相应的活动出现(彼此)

ListAdapter:

private class HirdetesListaAdapter extends BaseAdapter {

    private GSResult hirdetesek;
    private final Context context;
    private LayoutInflater inflater = null;
    private SparseArray<ImageDownloaderThread> imageDownloadThreads;
    private ListViewWorker worker;
    private int thresHold = 45;
    private ArrayList<View> views;
    private boolean isWorkerThreadRunning = false;

    public HirdetesListaAdapter(final Context context, GSResult result) throws IOException {

        this.context = context;

        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        initAdapter(result);

    }

    public void initAdapter(GSResult result) {
        if (views == null) {
            views = new ArrayList<View>();
        } else {
            views.clear();
        }
        hirdetesek = result;
        imageDownloadThreads = new SparseArray<ImageDownloaderThread>();
        worker = new ListViewWorker();
        worker.execute(null, null, null);
    }

    @Override
    public int getCount() {
        // Log.v("bar2", "HirdetesListaAdapter.getCount()=" + views.size());
        return views.size();
    }

    @Override
    public GSHirdetes getItem(int arg0) {
        Log.v("bar", "HirdetesListaAdapter.getItem(" + arg0 + ")");
        // Toast.makeText(getBaseContext(), "Találatok: " + gsr.size(),
        // 100000).show();
        return hirdetesek.get(arg0);
    }

    public void destroy() {
        synchronized (worker) {
            worker.notify();
            Log.v("thread", "Working thread notified");

            worker.cancel(true);
            Log.v("thread", "Working thread cancelled");

            for (int i = 0; i < this.imageDownloadThreads.size(); i++) {
                imageDownloadThreads.get(i).cancel(false);
                Log.v("thread", "ImageDownloadThread " + i + " cancelled");
            }
        }

    }

    @Override
    public long getItemId(int arg0) {
        Log.v("bar", "HirdetesListaAdapter.getItemId(" + arg0 + ")");
        return arg0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {


        if ((lv.getLastVisiblePosition() + thresHold) > views.size()) {
            synchronized (worker) {
                if (!this.isWorkerThreadRunning) {
                    Log.v("wthread", "Resuming worker thread");
                    worker.notify();
                    isWorkerThreadRunning = true;
                }
            }
        }

        synchronized (imageDownloadThreads) {
            if (imageDownloadThreads.get(position) == null) {
                Log.v("ithread", "Storing download thread: " + position);
                ImageDownloaderThread thread = new ImageDownloaderThread();
                imageDownloadThreads.put(position, thread);
                thread.execute(position);
            }
        }

        Log.v("thread", "getview finished for " + position);

        return views.get(position);
    }

    private class ListViewWorker extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... arg0) {
            Log.v("thread", "ListViewWorker started");
            int buffer = 20;
            int i = 0;
            try {
                while ((views.size() != gsr.size()) && !this.isCancelled()) {
                    Log.v("thread", views.size() + "/" + gsr.size());
                    if (buffer != 0) {
                        views.add(i, makeView(i));

                        ResultActivity.this.runOnUiThread(new Runnable() {
                            public void run() {
                                lv.addFooterView(views.get(views.size() - 1));
                            }
                        });
                        i++;
                        buffer--;
                    } else {
                        synchronized (this) {
                            try {
                                Log.v("wthread", "Pausing worker thread");
                                buffer = 20;
                                this.wait();
                                HirdetesListaAdapter.this.isWorkerThreadRunning = false;
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        private View makeView(int position) {
            Log.v("thread", "ListViewWorker.makeView(" + position + ")");
            GSHirdetes hirdetes = hirdetesek.get(position);

            View hirdetesView = inflater.inflate(R.layout.hirdetes_listaelem, null);
            TextView hirdetesName = (TextView) hirdetesView.findViewById(R.id.hirdetesListaElemView_TextView_Name);
            TextView hirdetesAr = (TextView) hirdetesView.findViewById(R.id.hirdetesListaElemView_TextView_Ar);
            TextView hirdetesKategoria = (TextView) hirdetesView.findViewById(R.id.hirdetesListaElemView_TextView_Kategoria);
            hirdetesName.setText(position + ". " + hirdetes.getHirdetesName());
            // hirdetesName.setText(Integer.toString(position));
            hirdetesAr.setText(hirdetes.getHirdetesPrice());
            hirdetesKategoria.setText(hirdetes.getCategory());

            ImageView hirdetesImage = (ImageView) hirdetesView.findViewById(R.id.hirdetesListaElemView_ImageView_HirdetesCover);
            //hirdetesImage.setOnClickListener(new HirdetesImageListener(context, hirdetes));
            //hirdetesView.setOnClickListener(new HirdetesListaListener(context, hirdetes));

            //views.add(position, hirdetesView);
            Log.v("gui", "ListViewWorker.makeView(" + position + ") finished");
            return hirdetesView;
        }
    }

    private class ImageDownloaderThread extends AsyncTask<Integer, Integer, Bitmap> {

        private ProgressBar progressBar;
        private TextView percent;
        private URL imageUrl;
        private View view;
        private int sorszám = -1;

        public void onPreExecute() {
            super.onPreExecute();
            // while (threadCounter >= threadPool) {
            // try {
            // Log.v("konti","threadCounter:"+threadCounter+" threadPool:"+threadPool);
            // Thread.sleep(10);
            // } catch (InterruptedException e) {
            // // TODO Auto-generated catch block
            // e.printStackTrace();
            // }
            //
            // }
            //
            // threadCounter++;

        }

        public void onProgressUpdate(Integer... values) {
            progressBar.setProgress(values[0]);
            float percentValue = (float) progressBar.getProgress() / progressBar.getMax();
            DecimalFormat df = new DecimalFormat("#");
            String percentString = df.format(percentValue * 100) + "%";
            percent.setText(percentString);
            // Log.v("konti", percentString);
        }

        @Override
        protected Bitmap doInBackground(Integer... params) {
            sorszám = params[0];
            imageUrl = hirdetesek.get(sorszám).gethirdetesCoverImageUrl();

            view = views.get(sorszám);
            progressBar = (ProgressBar) view.findViewById(R.id.hirdetesListaElemView_ProgressBar_ImageDLProgressBar);
            progressBar.setIndeterminate(false);
            progressBar.setProgress(0);
            percent = (TextView) view.findViewById(R.id.hirdetesListaElemView_TextView_ImageDLPercent);
            if (imageUrl == null) {
                return null;
            }

            Log.v("thread", "Starting ImageDownloaderThread for " + sorszám);

            int size;
            try {
                size = imageUrl.openConnection().getContentLength();
                progressBar.setMax(size);
                InputStream is = imageUrl.openStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[2048];
                int read = 0;
                Log.v("gui", "Downloading image for " + sorszám + ": " + imageUrl.getPath());
                while ((read = is.read(buffer, 0, buffer.length)) != -1) {
                    baos.write(buffer, 0, read);
                    // Log.v("net", "Image download progress: " +
                    // baos.size());
                    publishProgress(progressBar.getProgress() + read);
                }
                baos.flush();

                byte[] data = baos.toByteArray();
                return BitmapFactory.decodeByteArray(data, 0, data.length);
            } catch (IOException e) {
                Log.v("exception", "thread");
                return null;
            }
        }

        protected void onPostExecute(Bitmap bitmap) {
            ResultActivity.this.runOnUiThread(new Runnable() {
                public void run() {
                    ViewGroup vg = (ViewGroup) (progressBar.getParent());
                    vg.removeView(progressBar);
                    vg.removeView(percent);
                }
            });
            ImageView im = (ImageView) view.findViewById(R.id.hirdetesListaElemView_ImageView_HirdetesCover);
            if (bitmap == null) {
                im.setImageResource(R.drawable.noimage_hu);
            } else {
                im.setImageBitmap(bitmap);
            }
        }
    }

}

监听

public class HirdetesListaListener implements View.OnClickListener {

GSHirdetes hirdetes;
Context context;

public HirdetesListaListener(Context context, GSHirdetes hirdetes){
    this.hirdetes = hirdetes;
    this.context = context;
    Log.v("konti","Listener: "+hirdetes.getHirdetesName());
}

@Override
public void onClick(View v) {
    Log.v("konti","HirdetesListaListener.onClick(v) "+hirdetes.getHirdetesName());
    Intent intent = new Intent(context, HirdetesActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra("data", hirdetes);
    context.startActivity(intent);

}

}

1 个答案:

答案 0 :(得分:0)

你应该使用这段代码:

   lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                    Toast.makeText(MainActivity.this, "item at pos "+arg2+" clicked", Toast.LENGTH_LONG).show();
        }
   });