在我的应用程序中使用 Picasso 或其他库加载图像很慢

Image loading using Picasso or other libraries are slow in my application

我在适配器内的应用程序中使用 Picasso,一切都很好,除了滚动时的图像加载性能。如果我滚动列表,在加载每个图像时滚动会停止片刻,这是一个糟糕的表现。我在其他应用程序上没有看到这个问题。

注:我用的是无尽的RecyclerView,图片路径是URL.

public class UltimateViewAdapterr extends UltimateViewAdapter<UltimateViewAdapterr.CellFeedViewHolder>
        implements View.OnClickListener {

    private static final DecelerateInterpolator DECCELERATE_INTERPOLATOR = new DecelerateInterpolator();
    private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
    private static final OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4);

    private static final int ANIMATED_ITEMS_COUNT = 2;

    private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
    private static final int VIEW_TYPE_OBJECT_VIEW = 1;

    private Context context;
    private int lastAnimatedPosition = -1;
    private boolean animateItems = false;
    private List<Post> mPosts;

    private OnFeedItemClickListener onFeedItemClickListener;

    private final Map<RecyclerView.ViewHolder, AnimatorSet> likeAnimations = new HashMap<>();
    private final ArrayList<Integer> likedPositions = new ArrayList<>();

    public UltimateViewAdapterr(Context context, List<Post> postList) {
        this.context = context;
        mPosts = postList;
    }

    @Override
    public CellFeedViewHolder getViewHolder(View view) {
        return null;
    }

    @Override
    public CellFeedViewHolder onCreateViewHolder(ViewGroup viewGroup) {
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.fragment_person_profile_timeline, viewGroup,
                        false);
        CellFeedViewHolder cellFeedViewHolder = new CellFeedViewHolder(view);

        cellFeedViewHolder.btnComments.setOnClickListener(this);
        cellFeedViewHolder.btnMore.setOnClickListener(this);
        cellFeedViewHolder.postPicture.setOnClickListener(this);
        cellFeedViewHolder.likeImageButton.setOnClickListener(this);
        cellFeedViewHolder.pictureImageView.setOnClickListener(this);

        return cellFeedViewHolder;
    }

    private void runEnterAnimation(View view, int position) {
        if (!animateItems || position >= ANIMATED_ITEMS_COUNT - 1) {
            return;
        }

        if (position > lastAnimatedPosition) {
            lastAnimatedPosition = position;
            view.setTranslationY(Utils.getScreenHeight(context));
            view.animate()
                    .translationY(0)
                    .setInterpolator(new DecelerateInterpolator(3.f))
                    .setDuration(700)
                    .start();
        }
    }

    @Override
    public void onBindViewHolder(CellFeedViewHolder viewHolder, int
            position) {
        runEnterAnimation(viewHolder.itemView, position);
        bindFeedItem(position, viewHolder);
    }

    private void bindFeedItem(int position, CellFeedViewHolder holder) {
        Post item = mPosts.get(position);
        holder.nameTextView.setText(item.getSenderProfile().getName());

        int likesCount = item.getLikes().size();
        holder.likesTextView.setText(Integer.toString(likesCount));

        holder.pictureImageView.setTag(item.getSenderProfile());

        if (item.getSenderProfile().getImage() != null) {
            Picasso.with(context).load(Constants.General.PROTOCOL + item.getImage().getImageAddress
                    ()).into(holder.pictureImageView);
        }

        if (item.getImage() != null) {
            int width = Utils.dpToPx(context.getResources().getConfiguration().screenWidthDp);
            int height = Utils.dpToPx(context.getResources().getConfiguration().screenHeightDp);
            Picasso.with(context).load(Constants.General.PROTOCOL + item.getImage()
                    .getImageAddress
                    ()).priority(Picasso.Priority.HIGH).placeholder(R.drawable.ic_file_image_box).into
                    (holder.postPicture);
            holder.postPictureContainer.setVisibility(View.VISIBLE);
        }
        /*else if (item.getVideo() != null) {
            //TODO implement add video
        }*/

        if (!item.getText().isEmpty()) {
            holder.postTextTextView.setText(item.getText());
            holder.postTextTextView.setVisibility(View.VISIBLE);
        }

        if (item.getLikes() != null) {
            holder.likesTextView.setText(Integer.toString(item.getLikes().size()));
        }

        holder.footerContainer.setTag(item);
        holder.btnMore.setTag(item.getId().toString() + "," + position);
        Hashtable<CellFeedViewHolder, Post> hashtagPost = new Hashtable<>();
        hashtagPost.put(holder, item);
        holder.postPicture.setTag(hashtagPost);
        Hashtable<CellFeedViewHolder, String> hashtableTag = new Hashtable<>();
        hashtableTag.put(holder, "false");
        holder.likeImageButton.setTag(hashtableTag);
        for (Profile profile : item.getLikes()) {
            if (profile.getId() == Logged.Models.getUserProfile().getId()) {
                holder.likeImageButton.setTag(hashtableTag.put(holder, "true"));
                holder.likeImageButton.setImageResource(R.drawable.ic_heart);
                break;
            }
        }

        for (Profile profile : item.getLikes()) {
            if (profile.getId() == Logged.Models.getUserProfile().getId()) {
                holder.likeImageButton.setImageDrawable(context.getResources()
                        .getDrawable(R.drawable
                                .ic_heart));
                holder.likeImageButton.setTag(hashtableTag.put(holder, "true"));
                break;
            }
        }

        holder.likesContainer.setTag(item);

        holder.likesContainer.setOnClickListener(this);

        if (likeAnimations.containsKey(holder)) {
            likeAnimations.get(holder).cancel();
        }
        resetLikeAnimationState(holder);
    }

    @Override
    public RecyclerView.ViewHolder onCreateHeaderViewHolder(ViewGroup viewGroup) {
        return null;
    }

    @Override
    public void onBindHeaderViewHolder(RecyclerView.ViewHolder viewHolder, int i) {

    }

    @Override
    public int getItemCount() {
        return mPosts.size();
    }

    @Override
    public int getAdapterItemCount() {
        return 0;
    }

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

    private void updateHeartButton(final CellFeedViewHolder holder, boolean animated) {
        if (animated) {
            if (!likeAnimations.containsKey(holder)) {
                AnimatorSet animatorSet = new AnimatorSet();
                likeAnimations.put(holder, animatorSet);

                ObjectAnimator rotationAnim = ObjectAnimator.ofFloat(holder.likeImageButton, "rotation", 0f, 360f);
                rotationAnim.setDuration(300);
                rotationAnim.setInterpolator(ACCELERATE_INTERPOLATOR);

                ObjectAnimator bounceAnimX = ObjectAnimator.ofFloat(holder.likeImageButton, "scaleX", 0.2f, 1f);
                bounceAnimX.setDuration(300);
                bounceAnimX.setInterpolator(OVERSHOOT_INTERPOLATOR);

                ObjectAnimator bounceAnimY = ObjectAnimator.ofFloat(holder.likeImageButton, "scaleY", 0.2f, 1f);
                bounceAnimY.setDuration(300);
                bounceAnimY.setInterpolator(OVERSHOOT_INTERPOLATOR);
                bounceAnimY.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        holder.likeImageButton.setImageResource(R.drawable.ic_heart);
                    }
                });

                animatorSet.play(rotationAnim);
                animatorSet.play(bounceAnimX).with(bounceAnimY).after(rotationAnim);

                animatorSet.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        resetLikeAnimationState(holder);
                    }
                });

                animatorSet.start();
            }
        } else {
            if (likedPositions.contains(holder.getPosition())) {
                holder.likeImageButton.setImageResource(R.drawable.ic_heart);
            } else {
                holder.likeImageButton.setImageResource(R.drawable.ic_heart_outline);
            }
        }
    }

    public void setOnFeedItemClickListener(OnFeedItemClickListener onFeedItemClickListener) {
        this.onFeedItemClickListener = onFeedItemClickListener;
    }

    private void likePost(final CellFeedViewHolder holder, Post post) {

        updateLikes(holder);

        HttpClient.get(String.format(Constants.Server.GET_POST_LIKE, post.getId(),
                Logged.Models
                        .getUserProfile().getId()), new
                AsyncHttpResponseHandler() {
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                    }

                    @Override
                    public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                        Toast.makeText(context, context.getString(R.string.toast_error_like),
                                Toast.LENGTH_SHORT)
                                .show();
                        updateUnlikes(holder);
                    }
                });
    }

    private void updateLikes(final CellFeedViewHolder holder) {
        int likesCount = Integer.parseInt(holder.likesTextView
                .getText().toString()) + 1;
        holder.likesTextView.setText(Integer.toString(likesCount));
        updateHeartButton(holder, true);
        Hashtable<CellFeedViewHolder, String> hashTags = new Hashtable<>();
        hashTags.put(holder, "true");
        holder.likeImageButton.setTag(hashTags);
    }

    private void updateUnlikes(final CellFeedViewHolder holder) {
        int likesCount = Integer.parseInt(holder.likesTextView
                .getText().toString()) - 1;
        holder.likesTextView.setText(Integer.toString(likesCount));
        holder.likeImageButton.setImageResource(R.drawable.ic_heart_outline);
        Hashtable<CellFeedViewHolder, String> hashTags = new Hashtable<>();
        hashTags.put(holder, "false");
        holder.likeImageButton.setTag(hashTags);
    }

    private void unlikePost(final CellFeedViewHolder holder, Post post) {

        updateUnlikes(holder);

        HttpClient.get(String.format(Constants.Server.GET_POST_UNLIKE, post.getId()
                , Logged.Models
                .getUserProfile().getId()), new
                AsyncHttpResponseHandler() {
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                    }

                    @Override
                    public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                        Toast.makeText(context, context.getString(R.string.toast_error_like),
                                Toast.LENGTH_SHORT)
                                .show();
                        updateLikes(holder);
                    }
                });
    }

    @Override
    public void onClick(final View view) {
        switch (view.getId()) {
            case R.id.image_button_comments:
                LinearLayout footerContainer = (LinearLayout) view.getParent();
                context.startActivity(new Intent(context, PersonProfilePostCommentsActivity
                        .class).putExtra("post", (Post) footerContainer.getTag()));
                break;
            case R.id.image_button_more:
                if (onFeedItemClickListener != null) {
                    onFeedItemClickListener.onMoreClick(view, (String) view.getTag());
                }
                break;
            case R.id.image_button_like:
                Post post = (Post) ((LinearLayout) view.getParent()).getTag();
                final Hashtable hashTags = (Hashtable<CellFeedViewHolder, String>) view
                        .getTag();
                CellFeedViewHolder holder = (CellFeedViewHolder) hashTags.keys().nextElement();
                String isLiked = (String) hashTags.values().iterator().next();
                if (isLiked.equals("false")) {
                    likePost(holder, post);
                } else {
                    unlikePost(holder, post);
                }
                break;
            case R.id.image_view_post_picture:
                final Hashtable postPictureTags = (Hashtable<CellFeedViewHolder, Post>) view
                        .getTag();
                CellFeedViewHolder postPictureHolder = (CellFeedViewHolder) postPictureTags.keys()
                        .nextElement();
                Post postPicturePost = (Post) postPictureTags.values().iterator().next();
                Hashtable<CellFeedViewHolder, String> btnLikeTags = (Hashtable<CellFeedViewHolder, String>) postPictureHolder
                        .likeImageButton.getTag();

                if (btnLikeTags.values().iterator().next().equals("false")) {
                    likePost(postPictureHolder, postPicturePost);
                }
                break;
            case R.id.linear_layout_post_likes:
                context.startActivity(new Intent(context, PostLikesActivity.class).putExtra
                        ("post", (Post) view.getTag()));
                break;

            case R.id.image_view_picture:
                context.startActivity(new Intent(context, PersonProfileActivity
                        .class).putExtra("profile", (Profile) view.getTag()));
                break;
        }
    }

    private void animatePhotoLike(final CellFeedViewHolder holder) {
        if (!likeAnimations.containsKey(holder)) {
            holder.vBgLike.setVisibility(View.VISIBLE);
            holder.ivLike.setVisibility(View.VISIBLE);

            holder.vBgLike.setScaleY(0.1f);
            holder.vBgLike.setScaleX(0.1f);
            holder.vBgLike.setAlpha(1f);
            holder.ivLike.setScaleY(0.1f);
            holder.ivLike.setScaleX(0.1f);

            AnimatorSet animatorSet = new AnimatorSet();
            likeAnimations.put(holder, animatorSet);

            ObjectAnimator bgScaleYAnim = ObjectAnimator.ofFloat(holder.vBgLike, "scaleY", 0.1f, 1f);
            bgScaleYAnim.setDuration(200);
            bgScaleYAnim.setInterpolator(DECCELERATE_INTERPOLATOR);
            ObjectAnimator bgScaleXAnim = ObjectAnimator.ofFloat(holder.vBgLike, "scaleX", 0.1f, 1f);
            bgScaleXAnim.setDuration(200);
            bgScaleXAnim.setInterpolator(DECCELERATE_INTERPOLATOR);
            ObjectAnimator bgAlphaAnim = ObjectAnimator.ofFloat(holder.vBgLike, "alpha", 1f, 0f);
            bgAlphaAnim.setDuration(200);
            bgAlphaAnim.setStartDelay(150);
            bgAlphaAnim.setInterpolator(DECCELERATE_INTERPOLATOR);

            ObjectAnimator imgScaleUpYAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleY", 0.1f, 1f);
            imgScaleUpYAnim.setDuration(300);
            imgScaleUpYAnim.setInterpolator(DECCELERATE_INTERPOLATOR);
            ObjectAnimator imgScaleUpXAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleX", 0.1f, 1f);
            imgScaleUpXAnim.setDuration(300);
            imgScaleUpXAnim.setInterpolator(DECCELERATE_INTERPOLATOR);

            ObjectAnimator imgScaleDownYAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleY", 1f, 0f);
            imgScaleDownYAnim.setDuration(300);
            imgScaleDownYAnim.setInterpolator(ACCELERATE_INTERPOLATOR);
            ObjectAnimator imgScaleDownXAnim = ObjectAnimator.ofFloat(holder.ivLike, "scaleX", 1f, 0f);
            imgScaleDownXAnim.setDuration(300);
            imgScaleDownXAnim.setInterpolator(ACCELERATE_INTERPOLATOR);

            animatorSet.playTogether(bgScaleYAnim, bgScaleXAnim, bgAlphaAnim, imgScaleUpYAnim, imgScaleUpXAnim);
            animatorSet.play(imgScaleDownYAnim).with(imgScaleDownXAnim).after(imgScaleUpYAnim);

            animatorSet.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    resetLikeAnimationState(holder);
                }
            });
            animatorSet.start();
        }
    }

    private void resetLikeAnimationState(CellFeedViewHolder holder) {
        likeAnimations.remove(holder);
        holder.vBgLike.setVisibility(View.GONE);
        holder.ivLike.setVisibility(View.GONE);
    }

    public interface OnFeedItemClickListener {
        public void onCommentsClick(View v, int position);

        public void onMoreClick(View view, String tag);

        public void onProfileClick(View v);
    }

    public static class CellFeedViewHolder extends RecyclerView.ViewHolder {
        @Bind(R.id.image_view_post_picture)
        ImageView postPicture;
        @Bind(R.id.image_button_comments)
        ImageButton btnComments;
        @Bind(R.id.image_button_like)
        ImageButton likeImageButton;
        @Bind(R.id.image_button_more)
        ImageButton btnMore;
        @Bind(R.id.vBgLike)
        View vBgLike;
        @Bind(R.id.ivLike)
        ImageView ivLike;
        @Bind(R.id.text_view_name)
        TextView nameTextView;
        @Bind(R.id.image_view_picture)
        ImageView pictureImageView;
        @Bind(R.id.text_view_likes)
        TextView likesTextView;
        @Bind(R.id.linear_layout_footer_container)
        LinearLayout footerContainer;
        @Bind(R.id.vImageRoot)
        SquaredFrameLayout postPictureContainer;
        @Bind(R.id.text_view_text)
        TextView postTextTextView;
        @Bind(R.id.linear_layout_post_likes)
        LinearLayout likesContainer;

        public CellFeedViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
        }
    }
}

当 scrollview 或 listview 滚动时,视图会清除其子项并设置新值。在您的情况下,毕加索在将图像设置为图像视图之后获取图像。 1- Volley 处理这个问题。如果你能把毕加索换成截击,那就去做吧。 2-您可以第一次缓存图像,之后每当您滚动检查缓存内存然后设置图像。但它会增加应用程序内存。您必须清除已缓存的图像