2

我正在使用以下代码作为 android 中 ListView 的 Cusotm Array 适配器

在视图中 new MyAsyncTask(url, callback); 将一次又一次地运行,我怎样才能使对服务器的查询只执行一次。

@Override
        public View getView(int position, View convertView, ViewGroup parent) 
        {       
            final Question question = quesions.get(position);
            final OpenionUser myUser = question.getUser();

            View view = convertView;
            ViewHolder viewHolder = new ViewHolder();

            if (convertView == null)
            {
                view = inflator.inflate(R.layout.question_adapter_layout, parent, false);

                viewHolder.firstPhotoPercent  = (TextView) view.findViewById(R.id.firstPhotoProgressText);
                viewHolder.secondPhotoPercent = (TextView) view.findViewById(R.id.secondPhotoProgressText);

                viewHolder.comments = (LinearLayout) view.findViewById(R.id.commentsListView);      

                viewHolder.profilePic = (ImageButton) view.findViewById(R.id.profile);
                viewHolder.leftPic = (ImageButton) view.findViewById(R.id.photo1);
                viewHolder.rightPic = (ImageButton) view.findViewById(R.id.photo2);

                viewHolder.firstPhotoBg = (RelativeLayout) view.findViewById(R.id.firstPhotoProgress);
                viewHolder.secondPhotoBg = (RelativeLayout) view.findViewById(R.id.secondPhotoProgress);

                view.setTag(viewHolder);
            }
            else
                viewHolder = (ViewHolder) view.getTag();

    //      //imageLoader.displayImage(myUser.getProfilePicture(), viewHolder.profilePic, options);
    //      
            viewHolder.username.setText(myUser.getUserName());
            viewHolder.question.setText(question.getQuestion());

            imageLoader.displayImage(question.getRightThumbnailLink(), viewHolder.rightPic, options);
            imageLoader.displayImage(question.getLeftThumbnailLink(), viewHolder.leftPic, options);

            String url = String.format(Constants.GET_QUESTION_COMMENTS, 
                        question.getId(),
                        0,
                        2);

            ResponseCallback callback = new ResponseCallback() 
            {
                @Override
                public void onSuccess(HttpResponse response) 
                {
                    try {
                            JSONObject obj = new JSONObject(Utilities.convertStreamToString(response.getEntity().getContent()));
                            JSONArray array = obj.getJSONArray("comments");
                            ArrayList<Comment> comments = new ArrayList<Comment>();
                            for (int i = 0; i < array.length(); i ++)
                            {
                                Comment comment = Utilities.getCommentFromJSON(array.getJSONObject(i));
                                comments.add(comment);                          
                            }
                            addFeaturedViews(comments, viewHolder.comments);

                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }




                }


                @Override
                public void onFailure(HttpResponse exception) 
                {

                }
            };

            new MyAsyncTask(url, callback);
4

4 回答 4

1

“绝对不能保证调用 getView() 的顺序,也不能保证调用多少次”(Romain Guy @此处)。例如,当元素离开屏幕,然后在滚动 ListView 后再次出现时,就会调用此方法。因此,您永远不应该从 getView 调用您的服务器:相反,您应该在适配器外部(例如在片段或活动中,在实例化适配器之前)执行您的 asynctask,然后在您的列表中调用 notifyDataSetChanged。

于 2013-06-11T14:03:39.663 回答
0

你可以试试这个:

if(position==0)
{
    new MyAsyncTask(url, callback);
}

*在看到Dhanesh Budhrani在下面的评论中提供的信息后修改答案*

如果你想运行 new MyAsyncTask(url, callback); 只有一次,你可以试试这个:

 if(firsttime)
 {
     firsttime = false;
     new MyAsyncTask(url, callback);
 }

这里firsttime是在适配器的构造函数中初始化为 true 的布尔变量。

于 2013-06-11T13:35:40.340 回答
0

正如评论中已经提到的,适配器的任务是为 ListView 提供要呈现的视图。您应该在不同的类中处理数据请求,将数据提供给适配器,然后在 ArrayAdapter 上调用 notifyDataSetChanged。

于 2013-06-11T13:44:21.467 回答
0

由于适配器类是直接和ListView交互的,所以正确的做法是不要直接在上面调用任何线程。当您滚动您的 ListView/View 时,getView() 方法将被一次又一次地调用,并且 AsyncTask 将被调用,从而阻碍了 ListView 的流畅运行。

为了处理这种情况,请在 Activity 类中调用 AsyncTask ,一旦在onSuccess()中获取结果,定义 CustomAdapterClass 并在其中调用listView.setAdapter(customAdapter)并将 ArrayList 中的数据作为CustomArrayAdapter(ArrayList arrayListJsonResponse)的构造函数并膨胀数据。

希望能帮助到你。谢谢。

于 2013-06-11T13:47:05.823 回答