Android自定义字母导航栏
本文实例为大家分享了Android字母导航栏的具体代码,供大家参考,具体内容如下
效果
实现逻辑
明确需求
字母导航栏在实际开发中还是比较多见的,城市选择、名称选择等等可能需要到。现在要做到的就是在滑动控件过程中可以有内容以及下标的回调,方便处理其他逻辑!
整理思路
1、确定控件的尺寸,防止内容显示不全。相关的逻辑在onMeasure()方法中处理;
2、绘制显示的内容,在按下和抬起不同状态下文字、背景的颜色。相关逻辑在onDraw()方法中;
3、滑动事件的处理以及事件回调。相关逻辑在onTouchEvent()方法中;
动手实现
在需求明确、思路清晰的情况下就要开始动手实现(需要了解自定义View的一些基础API)。核心代码就onDraw()中。在代码中有思路和注释,可以结合代码一起看看。如果有疑惑、优化、错误的地方请在评论区提出,共同进步!
完整代码
/**
*自定义字母导航栏
*
*总的来说就四步
*1、测量控件尺寸{@link#onMeasure(int,int)}
*2、绘制显示内容(背景以及字符){@link#onDraw(Canvas)}
*3、处理滑动事件{@link#onTouchEvent(MotionEvent)}
*4、暴露接口{@link#setOnNavigationScrollerListener(OnNavigationScrollerListener)}
*
*@attrcustomTextColorDefault//导航栏默认文字颜色
*@attrcustomTextColorDown//导航栏按下文字颜色
*@attrcustomBackgroundColorDown//导航栏按下背景颜色
*@attrcustomLetterDivHeight//导航栏内容高度间隔
*@attrcustomTextSize//导航栏文字尺寸
*@attrcustomBackgroundAngle//导航栏背景角度
*/
publicclassCustomLetterNavigationViewextendsView{
privatestaticfinalStringTAG="CustomLetterNavigation";
//导航内容
privateString[]mNavigationContent;
//导航栏内容间隔
privatefloatmContentDiv;
//导航栏文字大小
privatefloatmContentTextSize;
//导航栏文字颜色
privateintmContentTextColor;
//导航栏按下时背景颜色
privateintmBackgroundColor;
//导航栏按下时圆角度数
privateintmBackGroundAngle=0;
//导航栏按下时文字颜色
privateintmDownContentTextColor;
privateTextPaintmTextPaint;
privatePaintmPaintBackgrount;
privatebooleanmEventActionState=false;
privateStringmCurrentLetter="";
privateOnNavigationScrollerListenermOnNavigationScrollerListener;
privatefinalRectFmRectF=newRectF();
publicCustomLetterNavigationView(Contextcontext){
this(context,null);
}
publicCustomLetterNavigationView(Contextcontext,@NullableAttributeSetattrs){
this(context,attrs,0);
}
publicCustomLetterNavigationView(Contextcontext,@NullableAttributeSetattrs,intdefStyleAttr){
super(context,attrs,defStyleAttr);
initDefaultData();//初始化默认数据
initAttrs(context,attrs);
}
@Override
protectedvoidonDraw(Canvascanvas){
/**
*
*这里我们分为两步
*
*1、绘制背景
*这里简单,直接调用Canvas的drawRoundRect()方法直接绘制
*2、绘制显示文本
*绘制文字首先要定位,定位每个字符的坐标
*X轴简单,宽度的一半
*Y轴坐标通过每个字符的高heightShould乘以已绘制字符的数目
*
*/
intmViewWidth=getWidth();
//绘制背景
mRectF.set(0,0,mViewWidth,getHeight());
if(mEventActionState){
mTextPaint.setColor(mDownContentTextColor);
mPaintBackgrount.setColor(mBackgroundColor);
canvas.drawRoundRect(mRectF,mBackGroundAngle,mBackGroundAngle,mPaintBackgrount);
}else{
mTextPaint.setColor(mContentTextColor);
mPaintBackgrount.setColor(Color.TRANSPARENT);
DrawablemBackground=getBackground();
if(mBackgroundinstanceofColorDrawable){
mPaintBackgrount.setColor(((ColorDrawable)mBackground).getColor());
}
canvas.drawRoundRect(mRectF,mBackGroundAngle,mBackGroundAngle,mPaintBackgrount);
}
//绘制文本
floattextX=mViewWidth/2;
//X轴坐标
intcontentLenght=getContentLength();
//Y轴坐标(这里在测量的时候多加入了两个间隔高度要减去,同时还有Padding值)
floatheightShould=(getHeight()-mContentDiv*2-getPaddingTop()-getPaddingBottom())/contentLenght;
for(inti=0;i
*这里做了简单的适应,其目的就是为了能够正常的显示我们的内容
*
*不管设置的是真实尺寸或者是包裹内容,都会以内容的最小尺寸为
*基础,如果设置的控件尺寸大于我们内容的最小尺寸,就使用控件
*尺寸,反之使用内容的最小尺寸!
*
*/
intwidhtMode=MeasureSpec.getMode(widthMeasureSpec);
intheightMode=MeasureSpec.getMode(heightMeasureSpec);
//获取控件的尺寸
intactualWidth=MeasureSpec.getSize(widthMeasureSpec);
intactualHeight=MeasureSpec.getSize(heightMeasureSpec);
intcontentLegth=getContentLength();
//计算一个文字的尺寸
RectmRect=measureTextSize();
//内容的最小宽度
floatcontentWidth=mRect.width()+mContentDiv*2;
//内容的最小高度
floatcontentHeight=mRect.height()*contentLegth+mContentDiv*(contentLegth+3);
if(MeasureSpec.AT_MOST==widhtMode){
//宽度包裹内容
actualWidth=(int)contentWidth+getPaddingLeft()+getPaddingRight();
}elseif(MeasureSpec.EXACTLY==widhtMode){
//宽度限制
if(actualWidth=0&&index
自定义属性
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。