一个简单的可控的头像列表叠加控件

Posted SiberiaDante

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个简单的可控的头像列表叠加控件相关的知识,希望对你有一定的参考价值。

一个简单的可控的头像列表叠加控件

需求:评论/点赞头像横向排列,第N个叠加在第N+1个上面,并且N小于一个固定的数
分析:1、假设N=4;头像列表最多显示4个,不足4个,有几个显示几个;2、头像第N个叠加在第N+1个上面,无法使用margin负数实现(叠加顺序不对)


1、控件实现代码
要点:控件可以横向滑动,继承HorizontalScrollView;创建RelativeLayout存放头像集合;

public class SDAvatarListLayout extends HorizontalScrollView {
    private Context context;
    /**
     * 存放创建的最大的ImageView集合
     */
    private List<SDCircleImageView> imageViewList;
    /**
     * 默认图片大小
     */
    private int imageSize = Math.round(SDTransitionUtil.dp2px(50));
    /**
     * 默认图片数量
     */
    private int imageMaxCount = 6;
    /**
     * 默认图片偏移百分比 0~1
     */
    private float imageOffset = 0.3f;

    public SDAvatarListLayout(Context context) {
        this(context, null);
    }

    public SDAvatarListLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SDAvatarListLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        TypedArray ta = getResources().obtainAttributes(attrs, R.styleable.SDAvatarListLayout);
        imageMaxCount = ta.getInt(R.styleable.SDAvatarListLayout_image_max_count, imageMaxCount);
        imageSize = (int) ta.getDimension(R.styleable.SDAvatarListLayout_image_size, imageSize);
        imageOffset = ta.getFloat(R.styleable.SDAvatarListLayout_image_offset, imageOffset);
        imageOffset = imageOffset > 1 ? 1 : imageOffset;
        init();
        ta.recycle();
    }

    private void init() {
        setHorizontalScrollBarEnabled(false);
        RelativeLayout relativeLayout = new RelativeLayout(context);
        int offset = imageSize - (int) (imageSize * imageOffset);
        imageViewList = new ArrayList<>(imageMaxCount);
        for (int i = 0; i < imageMaxCount; i++) {
            SDCircleImageView imageView = new SDCircleImageView(context);
            imageView.setId(imageView.hashCode() + i);
            imageView.setBorderColor(Color.WHITE);
            imageView.setBorderWidth(Math.round(SDTransitionUtil.dp2px(1)));
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageSize, imageSize);
            params.addRule(ALIGN_PARENT_LEFT);
            params.setMargins((imageMaxCount - i - 1) * offset, 0, 0, 0);
            relativeLayout.addView(imageView, params);
            imageViewList.add(imageView);
        }
        relativeLayout.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        this.addView(relativeLayout);
    }

    public void setAvatarListListener(ShowAvatarListener listener) {
        hideAllImageView();
        listener.showImageView(imageViewList);
    }


    public void setAvatarListListener(List<Integer> drawableList) {
        if (drawableList == null) {
            return;
        }
        hideAllImageView();
        int i = imageMaxCount - 1;
        for (int url : drawableList) {
            imageViewList.get(i).setImageResource(url);
            imageViewList.get(i).setVisibility(VISIBLE);
            if (i == 0) {
                break;
            }
            --i;
        }
    }

    private void hideAllImageView() {
        for (SDCircleImageView head : imageViewList) {
            head.setVisibility(View.GONE);
        }
    }

    public interface ShowAvatarListener {
        void showImageView(List<SDCircleImageView> imageViewList);
    }
}

2、自定义属性

 

<declare-styleable name="SDAvatarListLayout">
        <!--创建的最大ImageView数量-->
        <attr name="image_max_count" format="integer" />
        <!--创建的ImageView的大小-->
        <attr name="image_size" format="dimension" />
        <!--要叠加的ImageView偏移量-->
        <attr name="image_offset" format="float" />
    </declare-styleable>

 

3、使用

final List<Integer> imageDatas = new ArrayList<>();
        imageDatas.add(R.drawable.ic_launcher_background);
        imageDatas.add(R.drawable.meinv);
        imageDatas.add(R.drawable.meinv);
        imageDatas.add(R.drawable.meinv);
        //加载本地资源
        avatarLayout1.setAvatarListListener(imageDatas);
        //顺序加载图片使用任意框架加载
        avatarLayout2.setAvatarListListener(new SDAvatarListLayout.ShowAvatarListener() {
            @Override
            public void showImageView(List<SDCircleImageView> imageViewList) {
                //创建的ImageView的数量
                int imageSize = imageViewList.size();
                //实际需要显示的图片的数量
                int realDataSize = imageDatas.size();
                int mul = imageSize - realDataSize;
                for (int i = 0; i < imageSize; i++) {
                    if (i >= mul) {//6
                        //可以替换为网络图片处理
                        imageViewList.get(i).setImageResource(imageDatas.get(realDataSize - (i - mul) - 1));
                        imageViewList.get(i).setVisibility(View.VISIBLE);
                    } else {
                        imageViewList.get(i).setVisibility(View.GONE);
                    }
                }
            }
        });
        //逆序加载图片使用任意框架加载
        avatarLayout3.setAvatarListListener(new SDAvatarListLayout.ShowAvatarListener() {
            @Override
            public void showImageView(List<SDCircleImageView> imageViewList) {
                //创建的ImageView的数量
                int imageSize = imageViewList.size();
                //实际需要显示的图片的数量
                int realDataSize = imageDatas.size();
                int mul = imageSize - realDataSize;
                for (int i = 0; i < imageSize; i++) {
                    if (i >= mul) {//6
                        //可以替换为网络图片处理
                        imageViewList.get(i).setImageResource(imageDatas.get(i - mul));
                        imageViewList.get(i).setVisibility(View.VISIBLE);
                    } else {
                        imageViewList.get(i).setVisibility(View.GONE);
                    }
                }
            }
        });

 

### [了解更多资源收集ResourceCollection](https://github.com/SiberiaDante/ResourceCollection)


以上是关于一个简单的可控的头像列表叠加控件的主要内容,如果未能解决你的问题,请参考以下文章

图片大小相关参数可控导致ddos的一个案例

更改片段(子片段)时 RecyclerView 中的奇怪叠加

利用mask-image蒙层编写异形头像

如何设置个人头像

单击ListViewItem时Android加载片段

ASP.NET 用AJAX在页面上传头像,不能异步刷新?