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

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

需求:评论/点赞头像横向排列,第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);
                    }
                }
            }
        });


原文地址:https://www.cnblogs.com/shen-hua/p/8124319.html

时间: 2024-08-11 01:37:02

一个简单的可控的头像列表叠加控件的相关文章

动手分析安卓仿QQ联系人列表TreeView控件

因项目需要需要用到仿QQ联系人列表的控件样式,于是网上找到一个轮子(https://github.com/TealerProg/TreeView),工作完成现在简单分析一下这个源码.   一. 需要用到的知识如下: ①安卓事件分发机制:(http://blog.csdn.net/lvxiangan/article/details/9309927  或 http://gundumw100.iteye.com/blog/1052270) ②安卓View绘制:http://blog.csdn.net/

Windows Phone 8.1 新特性 - 控件之列表选择控件

本篇我们来介绍Windows Phone 8.1 新特性中的列表选择控件. 在Windows Phone 8 时代,大家都会使用 LongListSelector 来实现列表选择控件,对数据进行分组显示.比如通讯录中,按照名字首字母进行分组,点击分组标题后跳转到该标题对应的分组. 而Windows Phone 8.1 中会利用 ListView 和 SemanticZoom 来实现,下面我们来看看实现过程. 首先我们来认识一下ListView 和 SemanticZoom: ListView 从

第02讲集合类和列表类控件

集合 有了数组为什么还要集合: 数组是固定长度的,集合长度可变(因此,适应场景不同) 同时存储一对一关系的数据 方便增删改查 不能添加重复数据(如set中) Collection Map 接口 HashMap List Queue Set ArrayList LinkedList HashSet 类 Collection存储类的对象,Map存储键值对. List和Queue存储的对象是有序的,允许重复的,可以为null:Set中存储的对象是无序的,不允许重复的,只能有一个为null. Array

Qt qml中listview 列表视图控件(下拉刷新、上拉分页、滚动轴)

Qt qml中listview 列表视图控件(下拉刷新.上拉分页.滚动轴) 来源 https://www.cnblogs.com/surfsky/p/4352898.html 设置ListView涉及到将contentsY,即视图的可见部分的顶部,设置y为委托的值.另一个更改是interactive将视图设置为false.这样可以防止视图移动.用户不能再滚动列表或更改当前Item. contentY为列表上拉后列表左上角点距显示框左上解点的高度listView1.height为可显示部分的高度,

IOS的一个带动画的多项选择的控件(二)

然后我们来写:TypeSelectView 这个比较简单,我们只要只要每个TypeView的位置,然后作为自己的subview就好了 @interface TypeSelectView : UIView @property(nonatomic) BOOL bShown; @property(nonatomic, strong) TypeView* curSelectedView; -(id)initWithFrame:(CGRect)frame searchType:(int)type; @en

TYAttributedLabel——简单,强大的iOS属性文本控件

本文转载至 http://www.mobile-open.com/2015/86578.html TYAttributedLabel 简单,强大的属性文本的控件(无需了解CoreText),支持图文混排显示,支持添加链接,image和UIView控件,支持自定义排版显示 更新: v2.4 修复imge放大bug,新增imageAlignment 和 autolayout支持,以及相应的demo,感谢xinzhengzhang,nonstriater v2.3 新增 做题demo,代码优化(4s真

CListBox(列表框)控件

CListBox(列表框)控件 CListBox类常用成员 CListBox插入数据 CListBox删除数据 CListBox运用示例     一.CListBox类常用成员 CListBox::ResetContent//清空组合框内容 void ResetContent( );   CListBox::AddString//添加lpszString 至组合框尾部 int AddString( LPCTSTR lpszString );   CListBox::DeleteString//删

列表视图控件

设计登陆窗口 首先创建一个图像列表,并通过SetImageList方法将列表视图控件和图像列表关联到一起. CImageList* SetImageList(CImageList* pImageList,int nImageList); pImageList:标识图像列表指针. nImageList:标识图像列表类型. LVSIL_NORMAL:图像列表具有大图标 LVSIL_SMALL:图像列表具有小图标 LVSIL_STATE:图像列表具有状态图标 然后调用InsertItem方法向列表视图

win32 sdk列表视图控件两个重要的结构体

列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来.与树视图类似,列表控件可以由多个子项目组成,可以设置为Icon(大图标).SmallIcon(小图标).List(列表)或Report(报表). 一.列表视图控件有两个重要的数据结构LVCOLUMN和LVITEM.LVCOLUMN用于定义报表方式下的“列”的结构:LVITEM用于定义“项”的结构.这两个结构的定义及说明如下: typedef struct _L