自定义View总结(一)

继承ViewGroup自定义View

前奏

  这段时间研究了下自定义view相关的知识,重写onMeasue,onLayout,onDraw这几个方法,大家估计都说的上来,但是,什么时候重写哪个方法,其实不见得每个Android开发都能说的上来。
  自定义view应该有差不多四种情况:
1,继承View,重写onMeasure,onDraw,或者重写其中一个来达到自己的目的;
2,继承某个控件,重写其中的某个方法,达到自己的目的;
3,继承ViewGroup,重写onMeasure(有必要重写,因为通他是View中的实现,在ViewGroup中没有实现),onLayout(必须重写,因为是个抽象方法),onDraw(根据自己的需求来是否重写);
4,继承某个ViewGroup,重写某个方法来达到自己的目的;
  在这篇文章中重点实现一个类似LinearLayout中横向排列的ViewGroup,重点讲一下第三个的自定义实现;

过程

第一步:新建个java类继承ViewGroup

public class CustomViewGroup extends ViewGroup {

public CustomViewGroup(Context context) {
    super(context);
}

public CustomViewGroup(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public CustomViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}}
第二步,重写onMeare
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int width = 0;//viewGroup的宽度
    int height = 0;//viewGroup的高度
    //计算每个子view的长宽
    for (int i = 0; i < getChildCount(); i++) {
        View view = getChildAt(i);
        //调用计算子View的宽高,传入的参数主要是父View对子View的限制
        measureChild(view, widthMeasureSpec, heightMeasureSpec);
        int childWidth = view.getMeasuredWidth();
        int childHeight = view.getMeasuredHeight();
		
        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
        //这里把margin计算进来,要不然子View设置margin不起作用
        width = width + childWidth + params.leftMargin + params.rightMargin;
        //取最高的那个View的高度
        height = Math.max(height, (childHeight + params.topMargin + params.bottomMargin));
    }
    //把计算出来的宽高保存起来
    setMeasuredDimension(width, height);
}
第三步 重写onLayout
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childcount = getChildCount();
    int leftPadding = getPaddingLeft();
    int rightPadding = getPaddingRight();
    int topPadding = getPaddingTop();
    int bottomPadding = getPaddingBottom();
    int width = leftPadding;
    int top = topPadding;
    //摆放每个子view
    for (int i = 0; i < childcount; i++) {
        View view = getChildAt(i);
        int viewWidth = view.getMeasuredWidth();
        int viewHeight = view.getMeasuredHeight();
        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
        int lv = width + params.leftMargin;
        int tv = top + params.topMargin;
        int rv = lv + viewWidth;
        int bv = tv + viewHeight;
        //注意调用的是view.layout方法,layout方法会去调onlayout,把计算出来的左上右下传进去
        view.layout(lv, tv, rv, bv);
        width = width + viewWidth + params.leftMargin + params.rightMargin;
    }
}

最后说一点,如果复制上边的代码,会报错 ,因为MarginLayoutParams是不能被转化的,可以重写一下方法:

public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new MarginLayoutParams(getContext(), attrs);
}

@Override
protected LayoutParams generateLayoutParams(LayoutParams p) {
    return new MarginLayoutParams(p);
}

@Override
protected LayoutParams generateDefaultLayoutParams() {
    return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}

以上一个简单的ViewGroup完成,主要带大家熟悉下onMeare,onLayout的过程,今天先到这里,后期计划加入滑动的功能,敬请期待~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android自定义View是指基于Android原生控件的一种扩展,可以根据自己的需求和设计规范来创建更加个性化和独特的控件。而歌词控件是一种针对音乐播放器或者视频播放器等应用场景中的需求,用于显示音乐或者视频的歌词的控件。 Android自定义View歌词控件的实现思路如下: 1. 首先需要自定义一个View,并继承自View或者其子类,如TextView。 2. 在自定义View中重写onDraw方法,在其中实现绘制歌词的逻辑。 3. 在onDraw方法中,使用Canvas对象进行绘制,可以使用drawText方法绘制歌词文本,也可以使用drawBitmap方法绘制图片背景等。 4. 可以通过自定义属性,如字体大小、字体颜色、歌词滚动速度等,来对歌词控件进行配置。 5. 如果需要实现歌词的滚动效果,可以使用ValueAnimator或者Scroller来实现歌词的平滑滚动。 6. 如果需要实现点击歌词跳转播放进度的功能,可以通过添加点击事件监听器,在触摸事件中判断点击位置对应的歌词行,并根据歌词的时间戳跳转到指定的播放进度。 总结来说,Android自定义View歌词控件的实现需要重写onDraw方法进行绘制,可以通过Canvas对象进行绘制文本或者图像,通过自定义属性进行配置,使用动画或者滚动实现歌词的平滑滚动,通过监听触摸事件实现点击歌词跳转播放进度的功能。通过以上步骤,我们可以创建一个个性化的歌词控件,满足不同应用场景的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值