自定义View系列(6)--RatingBarView,这个控件是一个组合控件,继承于LinearLayout,实现的效果类似于Android中的RatingBar,但是比RatingBar更加灵活,使用起来也更加方便.现在已经上传到github,地址:RatingBarView,同时也上传到jCenter,在Android Studio中使用RatingBarView只需要以如下方式引入即可:
这里需要说明的是对于format为reference类型的属性,在获取属性值的时候需要具体对待,因为TypedArray 没有提供直接获取引用的的方法,即没有提供类似a.getReference(attr, DEFAULT);这样的方法,所以我们在获取reference类型的属性时,如果我们目标是需要一个Drawable,那么可以使用
a.getDrawable()方法,获取资源id时可以使用
a.getResourceId()方法等.
2. 获取到点击的view
因为RatingBarView可以添加N个子view(虽然子View就是ImageView),当点击某个子view时,我们需要获取到这个view,还要知道这个子view处在第几个位置.这两个难点可以通过给View设置TAG解决.代码如下:
private void initLayout() {
if (getChildCount() != 0) {
removeAllViews();
}
final LayoutParams lp = new LayoutParams(dpToPx(mChildDimension), dpToPx(mChildDimension));
lp.gravity = Gravity.CENTER_VERTICAL;
lp.rightMargin = dpToPx(childMargin);
for (int position = 0; position < mTotalCount; position++) {
final ImageView imageView = new ImageView(getContext());
imageView.setLayoutParams(lp);
imageView.setTag(DEFAULT_TAG_ID, position);
imageView.setPadding(dpToPx(childPadding), dpToPx(childPadding), dpToPx(childPadding), dpToPx(childPadding));
imageView.setOnClickListener(this);
if (position < mSelectedCount) {
imageView.setImageResource(mSelectedIconResId);
} else {
imageView.setImageResource(mNormalIconResId);
}
addView(imageView);
}
}
可以看到,在初始化时,我们给每个子view设置了一个tag,tag的键就是默认的键,tag的值就是position值,当我们点击某个子view时,通过默认的键获取到当前点击的view所处的位置.这样就解决了上面的两个问题.
这里需要注意的是给view设置tag时,键的值不可随便赋值一个int常量,如果键的值不合适就会抛出异常.那么什么样的键才是合适的呢?通过该方法的注释可以了解到,键的值必须为一个资源的id值才可以,那么怎么定义这样一个id值,要求这个id值不能与任意其他id冲突,且要保证唯一性呢?最简单的方式就是自己定义一个id值,可以通过在attr文件中定义一个item并指定type为id类型来实现,代码如下:
自定义exception
其实这个属于Java中的知识,在学习Java的过程中应该早就了解了这个知识.Java中有各种异常机制,其中最为典型的就是RuntimeException,当我们自定义一个exception时,可以继承Exception.也可以继承RuntimeException或者其他Exception的子类.但是区别在哪里呢?
作用域不同
RuntimeException顾名思义,是在程序运行时才会抛出的异常,比如除数不可为0之类的.其他异常有些是在编译时抛出的.
编译时处理不同
JVM在处理exception时,如果不是RuntimeException,编译器会提示错误,让你捕获异常才可以运行.但是在处理RuntimeException及其子类时,JVM不会提示错误.其实也很好理解,既然是运行时才会出现的异常,在编译时期肯定是发现不了的,比如除数不可为0,在语法上是没有一点问题的,但是在实际的运行中,除数为0是绝对不会被允许的,
总结
自定义RatingBarView其实是很简单的,因为它是个组合控件,但仍有一些细节需要注意.
最后再贴一下RatingBarView的github地址:RatingBarView,如果这个library帮助到了你,还请点个star或fork.不胜感激!!!