Dynamically added bitmaps to Android listview on scrolling down make list jumping

﹥>﹥吖頭↗ 提交于 2019-12-12 01:53:58

问题


I use custom ArrayAdapter to populate listview.
I use Picasso to load images, before loading image I calculate height and width for each image. Thus dynamic ImageView has different height and width. When I scroll up the listview, everything is smooth. But when I scroll the listview down, list starts to jump, when it comes to the rows with images.
I think, it caused by listview elements recycle, it forgets dynamic imageviews heights and produce this jumping effect when it recalculating imageviews again. I attach my dynamic imageview to Holder, but it doesn't help.
Part of my adapter looks like this:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ChatMessageElement el = list.get(position);
        ViewHolder holder = null;
        NewMessagesLabelHolder labelHolder = null;

        if (convertView == null) {
            convertView = el.getView(inflater, parent);

            if (el.isMessage()) {

                holder = new ViewHolder();
                holder.messageLayout = (RelativeLayout) convertView.findViewById(R.id.message_container);
                holder.messageContent = (LinearLayout) convertView.findViewById(R.id.message_content);
                holder.bottomIndicator = (LinearLayout) convertView.findViewById(R.id.bottom_indicators);
                holder.dateTextView = (TextView) convertView.findViewById(R.id.message_date);
                holder.timeAgo = (TextView) convertView.findViewById(R.id.time_ago);
                holder.nameTextView = (TextView) convertView.findViewById(R.id.user_name);
                convertView.setTag(holder);
            }

        } else {
            if (el.isMessage()) {
                holder = (ViewHolder) convertView.getTag();
            }

        }

        if (el.isMessage()) {
            Message currentMessage = (Message) el;
            drawMessage(holder, currentMessage, position);
        }

        return convertView;
    }


private void drawMessage(ViewHolder holder, Message message, int position) {
        String date = message.getCreatedAt();
        String formattedDate = Helper.getInstance().formatDate("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "HH:mm", date);

        String userName = message.getUserName();

        holder.likesLabelImageView.setVisibility(View.GONE);
        holder.likesCountTextView.setVisibility(View.GONE);
        holder.nameTextView.setText(userName);
        holder.dateTextView.setText(formattedDate);

        if (message.isLiked()) {
            holder.likesCountTextView.setText(Integer.toString(message.getLikesCount()));
            holder.likesCountTextView.setVisibility(View.VISIBLE);
            holder.likesLabelImageView.setVisibility(View.VISIBLE);
        }

        List<MessageComponent> messageComponentList;
        messageComponentList = message.getMessageComponents();

        drawMessageContent(holder, messageComponentList, message);

        holder.nameTextView.setTag(position);
        holder.avatarImageView.setTag(position);
        holder.nameTextView.setOnClickListener(userClickListener);
        holder.avatarImageView.setOnClickListener(userClickListener);

        // hang empty onLingClickListener to display context menu when
        // long click on whole message
        holder.nameTextView.setOnLongClickListener(longClickListener);
        holder.avatarImageView.setOnLongClickListener(longClickListener);
    }


private void drawMessageContent(ViewHolder holder, final List<MessageComponent> messageComponentList, final Message msg) {

        holder.messageContent.removeAllViewsInLayout();
        int messageComponentListSize = messageComponentList.size();

        for (final MessageComponent messageComponent : messageComponentList) {
            messageComponentListSize--;
            if (messageComponentListSize == 0)
                iAmLast = true;
            final String type = messageComponent.getType();

            if (type.equals(MessageComponent.MESSAGE_COMPONENT_TEXT_TYPE)) {

                TextView textView = new TextView(context);
                textView.setText(messageComponent.getText());
                setViewBackground(textView, msg);
                //reset margins for texts, caused by margin changes for images
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.bottomIndicator.getLayoutParams();
                params.setMargins(45, -82, 0, 0);
                holder.bottomIndicator.setLayoutParams(params);

                holder.messageContent.addView(textView);
            }

            if (type.equals(MessageComponent.MESSAGE_COMPONENT_IMAGE_TYPE)) {


                ViewGroup.LayoutParams params = new ActionBar.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        thumbHeight
                );

                final RoundedImageView imageView = new RoundedImageView(context);
                imageView.setPadding(20, 0, 20, 20);
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setCornerRadius(15.0f);

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        drawPreview(messageComponent, imageView);
                    }
                });
                imageView.setLayoutParams(params);
                // hang empty onLingClickListener to display context menu when
                // long click on whole message
                imageView.setOnLongClickListener(longClickListener);

                final RelativeLayout mediaContainer = new RelativeLayout(context);

                mediaContainer.addView(imageView);


         }
    }
}


// Calculates restricted dimensions with a maximum of $goal_width by $goal_height
    private ImageSize resize_dimensions(float goal_width, float goal_height, float width, float height) {

        float ratio = Math.min(goal_width/width, goal_height/height);
        int nwidth = Math.round(width*ratio);
        int nheight = Math.round(height*ratio);

        if(nwidth>nheight*2)
            nheight = 400;
        if(nheight>nwidth*2)
            nwidth = 600;

        ImageSize imageSize = new ImageSize(nwidth, nheight);
        return imageSize;

    }


    private void drawPreview(MessageComponent messageComponent, final ImageView imageView) {
        String type = messageComponent.getType();
        String mediaPath = messageComponent.getMediaPath();
        String thumbPath = messageComponent.getThumbPath();
        String thumbUrl = messageComponent.getThumbUrl();
        String videoThumbPath = messageComponent.getVideoThumbPath();
        Uri uri = null;

        if (type.equals(MessageComponent.MESSAGE_COMPONENT_IMAGE_TYPE)) {
            if (!TextUtils.isEmpty(mediaPath)) {
                uri = Uri.parse("file://" + mediaPath);
                File file = new File(uri.getPath());
                if (file.exists()) {
                    resizeAndLoadThumbnail(uri, imageView);
                    return;
                }
            }

            if (!TextUtils.isEmpty(thumbPath)) {
                uri = Uri.parse("file://" + mediaPath);
                File file = new File(uri.getPath());
                if (file.exists()) {
                    resizeAndLoadThumbnail(uri, imageView);
                    return;
                }
            }


            if (thumbUrl != null) {
                uri = Uri.parse(thumbUrl);
            }

            if (uri != null) {
                resizeAndLoadThumbnail(uri, imageView);
                return;
            }
        }


    }

    private void resizeAndLoadThumbnail(Uri uri, final ImageView imageView) {
        Picasso.with(context).load(uri).into(new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                int width = bitmap.getWidth();
                int height = bitmap.getHeight();
                ImageSize imgSize = resize_dimensions(900, 900, width, height);

                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                        imgSize.width,
                        imgSize.height
                );

                imageView.setLayoutParams(params);
                imageView.setImageBitmap(bitmap);
            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }

        });
    }

来源:https://stackoverflow.com/questions/27616574/dynamically-added-bitmaps-to-android-listview-on-scrolling-down-make-list-jumpin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!