简体   繁体   English

Listview项目getView一次又一次地重复

[英]Listview items getView repeating itself again and again

I am using following code as Cusotm Array adapter of a ListView in android 我正在使用以下代码作为Android中ListView的Cusotm数组适配器

In View new MyAsyncTask(url, callback); 在视图中新建MyAsyncTask(url,callback); will be run again and again, How can i make it so that the query to the server will be performed only once. 将一次又一次地运行,我该怎么做,这样对服务器的查询将只执行一次。

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

"there is absolutely no guarantee on the order in which getView() will be called nor how many times" (Romain Guy @ here ). “绝对不保证getView()的调用顺序也不能保证多少次”(Romain Guy @ here )。 This method is called for example, when an element goes off-screen and then appears again after scrolling the ListView. 例如,当元素离开屏幕然后在滚动ListView之后再次出现时,将调用此方法。 So you should never make a call to your server from getView: instead, you should execute your asynctask outside the adapter (in a fragment or activity, for example, before instantiating the adapter), and then call notifyDataSetChanged on your list. 因此,永远不要从getView调用服务器:相反,应该在适配器外部(例如,在片段或活动中,在实例化适配器之前)执行异步任务,然后在列表上调用notifyDataSetChanged。

you could try this: 您可以尝试以下方法:

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

* Modifying the answer after seeing the information given by Dhanesh Budhrani in the comment below * * 在下面的评论中看到Dhanesh Budhrani提供的信息后修改答案*

If you want to run new MyAsyncTask(url, callback); 如果要运行新的MyAsyncTask(url,callback); only once, you could try this: 只有一次,您可以尝试以下操作:

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

here firsttime is a boolean variable initialized to true in the adapter's constructor. 这里firsttime是在适配器的构造函数中初始化为true的布尔变量。

As already mentioned in the comments, the adapter's task is to provide views for the ListView to render. 正如评论中已经提到的那样,适配器的任务是为ListView提供视图。 You should handle the data requests in a different class, provide the data to the Adapter and then call notifyDataSetChanged on the ArrayAdapter. 您应该处理其他类中的数据请求,将数据提供给Adapter,然后在ArrayAdapter上调用notifyDataSetChanged。

Since the adapter class is directly interacting with ListView, the correct way is not to call any threads directly on it. 由于适配器类直接与ListView交互,因此正确的方法是不要直接在其上调用任何线程。 As you will scroll your ListView/View, the getView() method will be called up again and again and AsyncTask will be called up hindering the smooth flow of ListView. 当您滚动ListView / View时,将一次又一次调用getView()方法,并且将调用AsyncTask,这阻碍了ListView的顺利进行。

In order to deal with the situation, call the AsyncTask in your Activity class and as soon as the result is fetched in onSuccess() , define the CustomAdapterClass and call the listView.setAdapter(customAdapter) in it and pass the data in ArrayList as a Constructor of CustomArrayAdapter(ArrayList arrayListJsonResponse) and inflate the data. 为了处理这种情况,请在您的Activity类中调用AsyncTask,并在onSuccess()中获取结果后,定义CustomAdapterClass并在其中调用listView.setAdapter(customAdapter)并将ArrayList中的数据作为CustomArrayAdapter(ArrayList arrayListJsonResponse)的构造方法并填充数据。

Hope it helps. 希望能帮助到你。 Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM