Android ListView缓慢滚动

时间:2015-04-23 05:02:12

标签: android listview scroll

我有一个listview,它使用游标适配器连接到数据库。它以前滚动得很好。现在它滚动缓慢并在日志中抛出此消息

I/Choreographer﹕ Skipped 115 frames!  The application may be doing too much work on its main thread.

如何追踪导致缓慢的原因?

getview代码

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    context = parent.getContext();
    View vi = super.getView(position, convertView, parent);

    image_comment = (ImageView) vi.findViewById(R.id.outbox_comment);
    image_more = (ImageView) vi.findViewById(R.id.outbox_details);
    feedbackText = (TextView) vi.findViewById(R.id.outbox_feedback_text);
    RelativeLayout outbox_bg = (RelativeLayout) vi.findViewById(R.id.outbox_msg_layout);
    LinearLayout outbox_option = (LinearLayout) vi.findViewById(R.id.outbox_option_layout);
    avatarText = (TextView) vi.findViewById(R.id.avatar_text);
    avatarImage = (ImageView) vi.findViewById(R.id.avatar_image);
    avatarText.setVisibility(View.GONE);
    avatarImage.setVisibility(View.GONE);
    myWebView = (WebView) vi.findViewById(R.id.out_webView);
    myWebView.setVisibility(View.GONE);
    askFeedbackAnswer = (TextView) vi.findViewById(R.id.ask_feedback_answer_text);

    pollChoice1 = (TextView) vi.findViewById(R.id.poll_choice1);
    pollChoice2 = (TextView) vi.findViewById(R.id.poll_choice2);
    pollChoice3 = (TextView) vi.findViewById(R.id.poll_choice3);
    pollChoice4 = (TextView) vi.findViewById(R.id.poll_choice4);
    pollChoice5 = (TextView) vi.findViewById(R.id.poll_choice5);

    lockImage = (ImageView) vi.findViewById(R.id.lock_image);
    pollVisible = (ImageView) vi.findViewById(R.id.poll_visible);

    starWhite1 = (ImageView) vi.findViewById(R.id.star_white_first);
    starWhite2 = (ImageView) vi.findViewById(R.id.star_white_second);
    starWhite3 = (ImageView) vi.findViewById(R.id.star_white_third);
    starWhite4 = (ImageView) vi.findViewById(R.id.star_white_fourth);
    starWhite5 = (ImageView) vi.findViewById(R.id.star_white_fifth);

    greenTick1 = (ImageView) vi.findViewById(R.id.green_tick1);
    greenTick2 = (ImageView) vi.findViewById(R.id.green_tick2);
    greenTick3 = (ImageView) vi.findViewById(R.id.green_tick3);
    greenTick4 = (ImageView) vi.findViewById(R.id.green_tick4);
    greenTick5 = (ImageView) vi.findViewById(R.id.green_tick5);

    final MessageThread message = MessageThreadDBAction.getMessageFromCursor(getCursor());

    Resources res = context.getResources();
    avatars = res.getStringArray(R.array.avatar);
    avatarColors = res.getStringArray(R.array.colors);
    redArray = res.getIntArray(R.array.red_array);
    greenArray = res.getIntArray(R.array.green_array);
    blueArray = res.getIntArray(R.array.blue_array);

    int avatarIndex = message.getIcon() - 1;
    int avatarColorIndex = message.getIconColor() - 1;
    if (avatarIndex > 0 && avatarColorIndex > 0) {
        String avatarName = avatars[avatarIndex];
        String avatarColor = avatarColors[avatarColorIndex];
        int avatar_id = getDrawable(context, "avatar" + (avatarIndex + 1));
        int shape_id = getDrawable(context, "round" + (avatarColorIndex + 1));
        avatarText.setText(avatarColor + "_" + avatarName);
        avatarImage.setImageResource(avatar_id);
        Drawable drawable = res.getDrawable(shape_id);
        avatarImage.setBackgroundDrawable(drawable);

    }

    int padding_in_dp = 15;  // 6 dps
    final float scale = activity.getResources().getDisplayMetrics().density;
    int padding_in_px = (int) (padding_in_dp * scale + 0.5f);

    pollChoice1.setTypeface(null, Typeface.NORMAL);
    pollChoice2.setTypeface(null, Typeface.NORMAL);
    pollChoice3.setTypeface(null, Typeface.NORMAL);
    pollChoice4.setTypeface(null, Typeface.NORMAL);
    pollChoice5.setTypeface(null, Typeface.NORMAL);

    pollChoice1.setTextSize(18);
    pollChoice2.setTextSize(18);
    pollChoice3.setTextSize(18);
    pollChoice4.setTextSize(18);
    pollChoice5.setTextSize(18);

    pollChoice1.setEnabled(true);
    pollChoice2.setEnabled(true);
    pollChoice3.setEnabled(true);
    pollChoice4.setEnabled(true);
    pollChoice5.setEnabled(true);

    pollChoice1.setTextColor((Color.parseColor("#838383")));
    pollChoice2.setTextColor((Color.parseColor("#838383")));
    pollChoice3.setTextColor((Color.parseColor("#838383")));
    pollChoice4.setTextColor((Color.parseColor("#838383")));
    pollChoice5.setTextColor((Color.parseColor("#838383")));

    if(message.getType() == MessageThread.OUT_MESSAGE){
        pollChoice1.setEnabled(false);
        pollChoice2.setEnabled(false);
        pollChoice3.setEnabled(false);
        pollChoice4.setEnabled(false);
        pollChoice5.setEnabled(false);
    }

    if (message.getAnswered() || (message.getType() == MessageThread.OUT_MESSAGE)) {
        String answer_string = message.getAnswer();
        if (message.isQuiz()) {
            int correctAnswer = message.getCorrectAnswer();

            if (correctAnswer == 0) {
                pollChoice1.setTextColor((Color.parseColor("#838383")));
                greenTick1.setVisibility(View.VISIBLE);
            } else if (correctAnswer == 1) {
                pollChoice2.setTextColor((Color.parseColor("#838383")));
                greenTick2.setVisibility(View.VISIBLE);
            } else if (correctAnswer == 2) {
                pollChoice3.setTextColor((Color.parseColor("#838383")));
                greenTick3.setVisibility(View.VISIBLE);
            } else if (correctAnswer == 3) {
                pollChoice4.setTextColor((Color.parseColor("#838383")));
                greenTick4.setVisibility(View.VISIBLE);
            } else if (correctAnswer == 4) {
                pollChoice5.setTextColor((Color.parseColor("#838383")));
                greenTick5.setVisibility(View.VISIBLE);
            }
        }

        if (answer_string != null) {
            int answer = Integer.parseInt(answer_string);
            if (message.getPollType().equals("score")) {
                starWhite1.setBackground(null);
                starWhite2.setBackground(null);
                starWhite3.setBackground(null);
                starWhite4.setBackground(null);
                starWhite5.setBackground(null);

                if (answer == 1) {
                    starWhite1.setBackground(activity.getResources().getDrawable(R.drawable.textlines));
                } else if (answer == 2) {
                    starWhite2.setBackground(activity.getResources().getDrawable(R.drawable.textlines));
                } else if (answer == 3) {
                    starWhite3.setBackground(activity.getResources().getDrawable(R.drawable.textlines));
                } else if (answer == 4) {
                    starWhite4.setBackground(activity.getResources().getDrawable(R.drawable.textlines));
                } else if (answer == 5) {
                    starWhite5.setBackground(activity.getResources().getDrawable(R.drawable.textlines));
                }
            } else {
                if (answer == 0) {
                    pollChoice1.setTextColor((Color.parseColor("#ffcc33")));
                } else if (answer == 1) {
                    pollChoice2.setTextColor((Color.parseColor("#ffcc33")));
                } else if (answer == 2) {
                    pollChoice3.setTextColor((Color.parseColor("#ffcc33")));
                } else if (answer == 3) {
                    pollChoice4.setTextColor((Color.parseColor("#ffcc33")));
                } else if (answer == 4) {
                    pollChoice5.setTextColor((Color.parseColor("#ffcc33")));
                }
            }
        }
    } else {
        pollChoice1.setEnabled(true);
        pollChoice2.setEnabled(true);
        pollChoice3.setEnabled(true);
        pollChoice4.setEnabled(true);
        pollChoice5.setEnabled(true);
    }

    lockImage.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            String displayText = "This is a ";
            if (message.getScope().equals("domain")) {
                displayText = displayText + "public ";
            } else {
                displayText = displayText + "private ";
            }

            if (message.isQuiz()) {
                displayText = displayText + "quiz";
            } else {
                displayText = displayText + "poll";
            }

            Toast toast = Toast.makeText(context.getApplicationContext(),
                    displayText, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
            toast.show();
        }
    });

    pollVisible.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            String displayText = "";
            if (message.getVisibility().equals("public")) {
                displayText = "Aggregate answer will be visible";
            } else {
                displayText = "Aggregate answer will not be visible";
            }

            toast = Toast.makeText(context.getApplicationContext(),
                    displayText, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
            toast.show();


        }
    });

    feedbackTypeIcon.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            String displayText = "";
            if (message.isQuiz()) {
                displayText = "This is a quiz";
            } else if (message.isPoll()) {
                displayText = "This is a poll";
            } else {
                if (message.isAskForFeedback() || (!StringUtility.isNullOrEmpty(message.getSolicitationId()) && !message.equals("null")))
                {
                    if(message.getType() == MessageThread.IN_MESSAGE) {
                        String requestor[] = message.getRequestor().trim().split("@");
                        displayText = requestor[0]+ " is asking for feedback";
                    }
                    else{
                        displayText = "feedback that I have requested";
                    }

                } else {
                    if(message.getType() == MessageThread.IN_MESSAGE){
                        displayText = "feedback received";
                    }
                    else{
                        displayText = "feedback sent";
                    }

                }
            }

            toast = Toast.makeText(context.getApplicationContext(),
                    displayText, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
            toast.show();


        }
    });

    message.setRandomcode(StringUtility.generateRandomDigits(6));

    pollChoice1.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if(message.getAnswered()){
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            else{
                message.setAnswered(true);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption1Count(message.getOption1Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }

                message.setAnswer("" + 0);
                action.update(message);
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    pollChoice2.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if(message.getAnswered()){
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            else{
                message.setAnswered(true);
                message.setAnswer("" + 1);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption2Count(message.getOption2Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    pollChoice3.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if(message.getAnswered()){
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            else{
                message.setAnswered(true);
                message.setAnswer("" + 2);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption3Count(message.getOption3Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    pollChoice4.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if(message.getAnswered()){
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            else{
                message.setAnswered(true);
                message.setAnswer("" + 3);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption4Count(message.getOption4Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    pollChoice5.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if(message.getAnswered()){
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            else{
                message.setAnswered(true);
                message.setAnswer("" + 4);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption5Count(message.getOption5Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    starWhite1.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!message.getAnswered()) {
                message.setAnswered(true);
                message.setAnswer("" + 1);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption1Count(message.getOption1Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            else{
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    starWhite2.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!message.getAnswered()) {
                message.setAnswered(true);
                message.setAnswer("" + 2);

                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption2Count(message.getOption2Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            else{
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    starWhite3.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!message.getAnswered()) {
                message.setAnswered(true);
                message.setAnswer("" + 3);
                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption3Count(message.getOption3Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            else{
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    starWhite4.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!message.getAnswered()) {
                message.setAnswered(true);
                message.setAnswer("" + 4);

                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption4Count(message.getOption4Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);
            }
            else{
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    starWhite5.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!message.getAnswered()) {
                message.setAnswered(true);
                message.setAnswer("" + 5);

                if((message.getScope().equals("private") && message.getResponseCount() > 0) || message.getScope().equals("domain")){
                    message.setOption5Count(message.getOption5Count() + 1);
                    message.setResponseCount(message.getResponseCount() + 1);
                }
                action.update(message);

            }
            else{
                if(message.getScope().equals("private") && message.getResponseCount() < 1){
                    showAlert("Not enough people have responded to display answers");
                }
            }
            PollReplyAsyncTask asyncTask = new PollReplyAsyncTask(activity, false, message, message.getUserId());
            asyncTask.execute();
        }
    });

    emailCount.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(activity.getApplicationContext(), RecipientListActivity.class);
            i.putExtra(AppConstants.INTENT_VALUE_USERID, message.getUserId());
            i.putExtra(AppConstants.INTENT_VALUE_THREADID, message.getThreadId());
            activity.startActivity(i);
        }
    });

    askFeedbackAnswer.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(activity.getApplicationContext(),
                    InboxDetailActivity.class);
            i.putExtra(AppConstants.INTENT_VALUE_USERID,
                    message.getUserId());
            i.putExtra(AppConstants.INTENT_VALUE_THREADID,
                    message.getThreadId());
            i.putExtra(AppConstants.INTENT_VALUE_THREADTYPE,
                    message.getType());
            i.putExtra("curs", String.valueOf((Integer) v.getTag()));
            i.putExtra("TYPE_COMMENT", "true");
            activity.startActivity(i);
        }
    });


    if (message.getType() == MessageThread.OUT_MESSAGE) {
  //            outbox_bg.setPadding(padding_in_px, padding_in_px, padding_in_px, padding_in_px);

        image_like = (ImageView) vi.findViewById(R.id.outbox_like);
        image_dislike = (ImageView) vi.findViewById(R.id.outbox_dislike);

        image_like.setEnabled(false);
        image_dislike.setEnabled(false);

        myWebView.setVisibility(View.GONE);
        outbox_option.setVisibility(View.VISIBLE);
        feedbackText.setVisibility(View.VISIBLE);

        image_more.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!message.isPoll()) {
                    if (message.isClosed()) {
                        AppUtils.showError(activity,
                                "This thread has been closed");
                    } else if (message.isBlocked()) {
                        AppUtils.showError(activity,
                                "This thread has been blocked");
                    } else {
                        showContextMenu(message, v);
                    }
                }
            }
        });

        image_comment.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                if (message.isClosed()) {
                    AppUtils.showError(activity,
                            "This thread has been closed");
                } else if (message.isBlocked()) {
                    AppUtils.showError(activity,
                            "This thread has been blocked");
                } else {
                    Intent i = new Intent(activity.getApplicationContext(),
                            OutboxDetailActivity.class);
                    i.putExtra(AppConstants.INTENT_VALUE_USERID,
                            message.getUserId());
                    i.putExtra(AppConstants.INTENT_VALUE_THREADID,
                            message.getThreadId());
                    i.putExtra(AppConstants.INTENT_VALUE_THREADTYPE,
                            message.getType());
                    i.putExtra("VIA_COMMENT", true);
                    int purpose = getCursor().getPosition();
                    //                  purpose=purpose+1;
                    i.putExtra("curs", String.valueOf(purpose));
                    i.putExtra("TYPE_COMMENT", "true");
                    activity.startActivity(i);
                }
            }
        });

        } else {
            myWebView.setVisibility(View.GONE);
            outbox_option.setVisibility(View.VISIBLE);
            feedbackText.setVisibility(View.VISIBLE);

            image_like = (ImageView) vi.findViewById(R.id.outbox_like);
            image_dislike = (ImageView) vi.findViewById(R.id.outbox_dislike);
            if (!message.isPoll() && !message.isAskForFeedback()) {
                image_like.setVisibility(View.VISIBLE);
                image_dislike.setVisibility(View.VISIBLE);
                image_like.setEnabled(true);
                image_dislike.setEnabled(true);
            } else {
                image_like.setVisibility(View.

        }
    }

    return vi;
}

3 个答案:

答案 0 :(得分:0)

在UI线程上使用Run。

RN = ROW_NUMBER() OVER(ORDER BY N)

答案 1 :(得分:0)

try adding following two lines into xml code android:fastScrollEnabled="true" android:smoothScrollbar="true"

答案 2 :(得分:0)

首先介绍持有人模式。我不打算更改你的代码,因为它有很多,但我在下面发布一个示例。通过引入支架模式,您将只对布局进行一次充气,并消除CPU浪费findViewByIds

public class DemosAdapter extends BaseAdapter {

    public List<ActivityItem> listOfItems;
    private View v;
    private ViewWrapper wrapper;
    private Context context;

    public DemosAdapter(Context c, List<ActivityItem> listOfItems) {
        this.context = c;
        this.listOfItems = listOfItems;
    }

    @Override
    public int getCount() {
        return listOfItems.size();
    }

    @Override
    public ActivityItem getItem(int i) {
        return listOfItems.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    public void sort() {
        Collections.sort(listOfItems, new Comparator<ActivityItem>() {
            @Override
            public int compare(ActivityItem activityItem, ActivityItem activityItem2) {
                return activityItem.getName().compareTo(activityItem2.getName());
            }
        });
    }

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

        ActivityItem itm = listOfItems.get(position);

        v = convertView;

        if (v == null) {
            // This happens when it is not yet inflated
            LayoutInflater inflater = LayoutInflater.from(context);
            v = inflater.inflate(R.layout.activity_item, null, false);
            wrapper = new ViewWrapper(v);
            v.setTag(wrapper);
        }
        else {
            // Recycle the row item
            wrapper = (ViewWrapper) v.getTag();
        }

        // Use the recycled holder or the just inflated one
        wrapper.getTvDemoName().setText(itm.getName());

        return v;
    }

    /**
     * This is the view holder class. It holds all the fields you need in your ListView
     * so you need to add all your images views and stuff you need to this guy
     * **/
    private class ViewWrapper {

        private View base;
        private TextView tvDemoName;

        public ViewWrapper(View v) {
            this.base = v;
        }

        public TextView getTvDemoName() {
            if (tvDemoName == null) {
                tvDemoName = (TextView) base.findViewById(R.id.tvDemoName);
            }
            return tvDemoName;
        }

    }
}

您似乎正在加载大量图片。加载图像是一个缓慢的过程,您应该在UI线程中执行此操作。但这是一个更复杂的过程,你应该只在遇到问题时才这样做。

接下来的事情......不要在ListView getView中执行DB I / O,因为这会阻止您的UI线程,从而降低性能。当你装配适配器然后将所有内容保存在内存中时,只需执行一次。