一、需求
1.显示星座运势
2.绘制旋转转盘
二、实现步骤
1.星座运势可看今天、明天、本周的情况
运势指数通过AndRatingBar控件显示,这个控件比Android原生的ratingbar友好很多,大小可以自己定义,颜色背景也可以
<per.wsj.library.AndRatingBar
android:id="@+id/rating_luck"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_height="30dp"
android:numStars="5"
android:rating="3.5"
android:stepSize="0.5"
app:starColor="@color/colorLightPink"
android:isIndicator="true"/>
其中各项运势,用recyclerview显示,明日的运势显示也是一样,具体recyclerview的用法如下:
首先写好要放进去的类DayLuck
class DayLuck {
var mLuck: String = ""
var mLuckNumber: Float = 0.0f
constructor(mLuck: String ,number: Float){
this.mLuck = mLuck
mLuckNumber = number
}
}
然后写recyclerview中每个单元的布局
recyclerview_day_luck.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_marginBottom="5dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/tv_luck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textSize="15sp"
android:text="@string/luck" />
<per.wsj.library.AndRatingBar
android:id="@+id/rating_luck"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_height="30dp"
android:numStars="5"
android:rating="3.5"
android:stepSize="0.5"
app:starColor="@color/colorLightPink"
android:isIndicator="true"/>
</LinearLayout>
接着,画recyclerview所在的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_edit_option"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"
android:background="@color/white"
tools:context=".ui.activity.EditOptionActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/option_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab_edit_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:clickable="true"
app:borderWidth="0dp"
app:elevation="10dp"
app:fabSize="normal"
app:pressedTranslationZ="25dp"
app:rippleColor="@color/colorSkin"
android:backgroundTint="@color/colorLightPink"
android:src="@drawable/ic_add"/>
</RelativeLayout>
写recyclerview的适配器
DayRecyclerViewAdapter
class DayRecyclerViewAdapter : RecyclerView.Adapter<DayRecyclerViewAdapter.ViewHolder>{
private var list : MutableList<DayLuck>?= null
constructor(dayLuckList: MutableList<DayLuck>){
list = dayLuckList
notifyDataSetChanged()
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var luck = itemView.findViewById(R.id.tv_luck) as TextView
val ratingLuck = itemView.findViewById(R.id.rating_luck) as AndRatingBar
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_day_lucy,parent,false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return list!!.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.luck.text = list?.get(position)!!.mLuck + ":"
holder.ratingLuck.rating = list?.get(position)!!.mLuckNumber
}
}
在活动中设置适配器,写入参数
class TodayFragment : SimpleFragment() {
private val dayLuckList = mutableListOf<DayLuck>()
private lateinit var mLuckRecyclerViewAdapter : DayRecyclerViewAdapter
override fun getLayoutId(): Int {
return R.layout.fragment_cons_today
}
override fun initData(savedInstanceState: Bundle?) {
if(dayLuckList.size == 0){
initDayLuck()
}
mLuckRecyclerViewAdapter = DayRecyclerViewAdapter(dayLuckList)
today_recyclerview.layoutManager = LinearLayoutManager(context)
today_recyclerview.adapter = mLuckRecyclerViewAdapter
}
private fun initDayLuck() {
for(i in 0 until 5){
dayLuckList.add(DayLuck("运势",4.5f))
}
}
override fun initView(view: View) {
//TODO("Not yet implemented")
}
}
2.绘制转盘
写类的构造函数,在构造函数中,设置画笔、旋转动画、中心点的点击事件
public CustomTurntableOne(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTurntableOne(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
initAnim();
setOnClickListener(this);
}
重写测量函数和画图
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mPadding = 5;
initRect();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制圆
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(mWidth/2,mWidth/2,mWidth/2-mPadding,mPaint);
//绘制 6个椭圆
mPaint.setStyle(Paint.Style.FILL);
initArc(canvas);
//绘制里面的小圆
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(mWidth/2,mWidth/2,50,mPaint);
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(40);
Rect rect = new Rect();
mPaint.getTextBounds(str, 0, str.length(), rect);
int strWidth = rect.width();//文本的宽度
int textHeight = rect.height();//文本的高度
canvas.drawText(str,mWidth/2-25+25-strWidth/2,mWidth/2+textHeight/2,mPaint);
}
private void initRect() {
rectF = new RectF(0,0,mWidth,mWidth);
}
private void initArc(Canvas canvas) {
for(int i=0;i<6;i++){
mPaint.setColor(colors[i]);
canvas.drawArc(rectF,(i-1)*60+60,60,true,mPaint);
}
for(int i=0;i<6;i++){
mPaint.setColor(Color.BLACK);
Path path = new Path();
path.addArc(rectF,(i-1)*60+60,60);
canvas.drawTextOnPath(contents[i],path,60,60,mPaint);
}
}
每个扇形的颜色设置
public int[] colors = new int[]{getResources().getColor(R.color.colorDeepGreen),
getResources().getColor(R.color.colorLightGreen),
getResources().getColor(R.color.colorDeepOrange),
getResources().getColor(R.color.colorSkin),
getResources().getColor(R.color.colorYellow),
getResources().getColor(R.color.colorLightOrange)};
中心点的点击事件,设置一个查看转盘是否停下的boolean值,只有旋转停下后才能重写旋转
@Override
public void onClick(View view) {
if(!isStart){
setAnim();
}
}
public void setAnim(){
//随机数
isStart = true;
Random random = new Random();
int js = random.nextInt(3240);
int last = random.nextInt(360) + 360;
//旋转动画
RotateAnimation rotateAnimation = new RotateAnimation(startjs, js + last, mWidth / 2, mWidth / 2);
//旋转时间
rotateAnimation.setDuration(3000);
//保留最后执行完的位置
rotateAnimation.setFillAfter(true);
rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isStart = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
//启动动画
startAnimation(rotateAnimation);
startjs = (js + last) % 360;
}