车队管理完善
This commit is contained in:
parent
4c51daa245
commit
8dcf3b77c7
@ -0,0 +1,31 @@
|
||||
package com.dahe.gldriver.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.dahe.gldriver.R
|
||||
import com.dahe.glex.bean.WayBillBean
|
||||
|
||||
/**
|
||||
* @ClassName WaybillAdapter
|
||||
* @Author 用户
|
||||
* @Date 2024/1/23 16:27
|
||||
* @Description TODO
|
||||
*/
|
||||
class DriversAdapter :
|
||||
BaseQuickAdapter<WayBillBean, QuickViewHolder>() {
|
||||
override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: WayBillBean?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
context: Context,
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): QuickViewHolder {
|
||||
// 返回一个 ViewHolder
|
||||
return QuickViewHolder(R.layout.item_driver, parent)
|
||||
}
|
||||
}
|
31
app/src/main/java/com/dahe/gldriver/adapter/PagersAdapter.kt
Normal file
31
app/src/main/java/com/dahe/gldriver/adapter/PagersAdapter.kt
Normal file
@ -0,0 +1,31 @@
|
||||
package com.dahe.gldriver.adapter
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName PagersAdapter
|
||||
* @Author john
|
||||
* @Date 2024/2/7 10:26
|
||||
* @Description TODO
|
||||
*/
|
||||
class PagersAdapter(fragmentActivity: FragmentActivity,list:MutableList<Fragment>) : FragmentStateAdapter(fragmentActivity) {
|
||||
private var fragmentList : MutableList<Fragment> =ArrayList()
|
||||
init {
|
||||
this.fragmentList = list
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return fragmentList.size
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return fragmentList[position]
|
||||
}
|
||||
|
||||
fun addFragment(fragment: Fragment){
|
||||
fragmentList.add(fragment)
|
||||
}
|
||||
}
|
@ -95,7 +95,7 @@ class MineFragment : BaseFragment<FragmentMineBinding>(), View.OnClickListener {
|
||||
private fun goTools(pos: Int) {
|
||||
when (pos) {
|
||||
0 -> {
|
||||
ActivityUtils.startActivity(mContext, RulesActivity::class.java)
|
||||
ActivityUtils.startActivity(mContext, CarTeamActivity::class.java)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
|
@ -1,8 +1,25 @@
|
||||
package com.dahe.gldriver.ui.mine.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
import com.dahe.gldriver.adapter.PagersAdapter
|
||||
import com.dahe.gldriver.databinding.ActivityCarTeamBinding
|
||||
import com.dahe.gldriver.ui.mine.fragment.CarsManFragment
|
||||
import com.dahe.gldriver.ui.mine.fragment.DriversManFragment
|
||||
import com.dahe.gldriver.ui.waybill.fragment.AllWaybillFragment
|
||||
import com.dahe.mylibrary.base.BaseActivity
|
||||
import net.lucode.hackware.magicindicator.FragmentContainerHelper
|
||||
import net.lucode.hackware.magicindicator.buildins.UIUtil
|
||||
import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator
|
||||
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter
|
||||
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator
|
||||
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView
|
||||
import net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator
|
||||
import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.ColorTransitionPagerTitleView
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName CarTeamActivity
|
||||
@ -11,11 +28,116 @@ import com.dahe.mylibrary.base.BaseActivity
|
||||
* @Description 车队管理
|
||||
*/
|
||||
class CarTeamActivity : BaseActivity<ActivityCarTeamBinding>() {
|
||||
|
||||
private val mFragmentContainerHelper = FragmentContainerHelper()
|
||||
var mFragments = mutableListOf<Fragment>(
|
||||
DriversManFragment(),
|
||||
CarsManFragment(),
|
||||
AllWaybillFragment()
|
||||
)
|
||||
val titles = mutableListOf(
|
||||
"司机管理",
|
||||
"车辆管理",
|
||||
"车队订单"
|
||||
)
|
||||
|
||||
|
||||
override fun initView(savedInstanceState: Bundle?) {
|
||||
setStatusHeightParams(binding.rlTop)
|
||||
setTitleBar("车队管理",true,true)
|
||||
|
||||
var pagerAdapter = PagersAdapter(this,mFragments)
|
||||
// pagerAdapter.addFragment(AllWaybillFragment())
|
||||
// pagerAdapter.addFragment(AllWaybillFragment())
|
||||
// pagerAdapter.addFragment(AllWaybillFragment())
|
||||
|
||||
|
||||
binding.circleBarView.setProgress(30f,1000)
|
||||
|
||||
binding.circleBarView2.run {
|
||||
text = "高风险"
|
||||
valueText = "0"
|
||||
unitText= "分"
|
||||
progress = 60
|
||||
}
|
||||
|
||||
mFragmentContainerHelper.handlePageSelected(0,true)
|
||||
|
||||
binding.viewPager.adapter = pagerAdapter
|
||||
binding.viewPager.currentItem = 0
|
||||
binding.viewPager.registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
mFragmentContainerHelper.handlePageSelected(position,true)
|
||||
}
|
||||
});
|
||||
|
||||
var commonNavigator = CommonNavigator(mContext)
|
||||
commonNavigator.run {
|
||||
isAdjustMode = true
|
||||
adapter = object : CommonNavigatorAdapter() {
|
||||
override fun getCount(): Int {
|
||||
return titles.size
|
||||
}
|
||||
|
||||
override fun getTitleView(context: Context?, index: Int): IPagerTitleView {
|
||||
val colorTransitionPagerTitleView = ColorTransitionPagerTitleView(context)
|
||||
colorTransitionPagerTitleView.normalColor = Color.BLACK
|
||||
colorTransitionPagerTitleView.selectedColor = Color.RED
|
||||
colorTransitionPagerTitleView.text = titles[index]
|
||||
colorTransitionPagerTitleView.setOnClickListener {
|
||||
mFragmentContainerHelper.handlePageSelected(index)
|
||||
switchPages(index)
|
||||
}
|
||||
return colorTransitionPagerTitleView
|
||||
}
|
||||
|
||||
override fun getIndicator(context: Context?): IPagerIndicator {
|
||||
val indicator = LinePagerIndicator(context)
|
||||
indicator.mode = LinePagerIndicator.MODE_WRAP_CONTENT
|
||||
indicator.yOffset =
|
||||
UIUtil.dip2px(context, 3.0).toFloat()
|
||||
indicator.setColors(Color.RED)
|
||||
return indicator
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
binding.magicIndicator.navigator = commonNavigator
|
||||
mFragmentContainerHelper.attachMagicIndicator(binding.magicIndicator)
|
||||
}
|
||||
|
||||
override fun initDate() {
|
||||
}
|
||||
|
||||
private fun switchPages(index: Int){
|
||||
binding.viewPager.currentItem = index
|
||||
}
|
||||
|
||||
// private fun switchPages(index: Int) {
|
||||
// val fragmentManager = supportFragmentManager
|
||||
// val fragmentTransaction = fragmentManager.beginTransaction()
|
||||
// var fragment: Fragment
|
||||
// var i = 0
|
||||
// val j: Int = mFragments.size
|
||||
// while (i < j) {
|
||||
// if (i == index) {
|
||||
// i++
|
||||
// continue
|
||||
// }
|
||||
// fragment = mFragments[i]
|
||||
// if (fragment.isAdded) {
|
||||
// fragmentTransaction.hide(fragment)
|
||||
// }
|
||||
// i++
|
||||
// }
|
||||
// fragment = mFragments[index]
|
||||
// if (fragment.isAdded) {
|
||||
// fragmentTransaction.show(fragment)
|
||||
// } else {
|
||||
// fragmentTransaction.add(R.id.fragmentContainer, fragment)
|
||||
// }
|
||||
// fragmentTransaction.commitAllowingStateLoss()
|
||||
// }
|
||||
}
|
@ -21,6 +21,8 @@ import com.dahe.mylibrary.utils.ConvertUtils
|
||||
*/
|
||||
class WalletActivity : BaseActivity<ActivityWalletBinding>() {
|
||||
override fun initView(savedInstanceState: Bundle?) {
|
||||
setStatusHeightParams(binding.rlTop)
|
||||
setTitleBar("钱包",true,true)
|
||||
}
|
||||
|
||||
override fun initDate() {
|
||||
|
@ -0,0 +1,58 @@
|
||||
package com.dahe.gldriver.ui.mine.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.widget.LinearLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.LayoutManager
|
||||
import com.dahe.gldriver.R
|
||||
import com.dahe.gldriver.adapter.CarsAdapter
|
||||
import com.dahe.gldriver.adapter.WaybillAdapter
|
||||
import com.dahe.gldriver.databinding.ActivityCarsManBinding
|
||||
import com.dahe.gldriver.databinding.FragmentWaybillListBinding
|
||||
import com.dahe.glex.bean.WayBillBean
|
||||
import com.dahe.mylibrary.base.BaseActivity
|
||||
import com.dahe.mylibrary.base.BaseFragment
|
||||
import com.dahe.mylibrary.recycleviewswipe.RecycleViewDivider
|
||||
import com.dahe.mylibrary.utils.ConvertUtils
|
||||
|
||||
/**
|
||||
* @ClassName CarsManActivity
|
||||
* @Author john
|
||||
* @Date 2024/2/1 08:59
|
||||
* @Description 车辆管理
|
||||
*/
|
||||
class CarsManFragment : BaseFragment<FragmentWaybillListBinding>() {
|
||||
|
||||
override fun onFragmentVisibleChange(isVisible: Boolean) {
|
||||
}
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
var datas = mutableListOf<WayBillBean>(
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean()
|
||||
)
|
||||
|
||||
var adapter = binding.recyclerView.run {
|
||||
layoutManager = LinearLayoutManager(mContext, RecyclerView.VERTICAL, false)
|
||||
addItemDecoration(
|
||||
RecycleViewDivider(
|
||||
LinearLayout.VERTICAL,
|
||||
ConvertUtils.dp2px(16.0f),
|
||||
Color.TRANSPARENT
|
||||
)
|
||||
)
|
||||
adapter = CarsAdapter()
|
||||
adapter as CarsAdapter
|
||||
}
|
||||
|
||||
adapter.submitList(datas)
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.dahe.gldriver.ui.mine.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.widget.LinearLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.LayoutManager
|
||||
import com.dahe.gldriver.R
|
||||
import com.dahe.gldriver.adapter.CarsAdapter
|
||||
import com.dahe.gldriver.adapter.DriversAdapter
|
||||
import com.dahe.gldriver.adapter.WaybillAdapter
|
||||
import com.dahe.gldriver.databinding.ActivityCarsManBinding
|
||||
import com.dahe.gldriver.databinding.FragmentWaybillListBinding
|
||||
import com.dahe.glex.bean.WayBillBean
|
||||
import com.dahe.mylibrary.base.BaseActivity
|
||||
import com.dahe.mylibrary.base.BaseFragment
|
||||
import com.dahe.mylibrary.recycleviewswipe.RecycleViewDivider
|
||||
import com.dahe.mylibrary.utils.ConvertUtils
|
||||
|
||||
/**
|
||||
* @ClassName CarsManActivity
|
||||
* @Author john
|
||||
* @Date 2024/2/1 08:59
|
||||
* @Description 车辆管理
|
||||
*/
|
||||
class DriversManFragment : BaseFragment<FragmentWaybillListBinding>() {
|
||||
|
||||
override fun onFragmentVisibleChange(isVisible: Boolean) {
|
||||
}
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
var datas = mutableListOf<WayBillBean>(
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean(),
|
||||
WayBillBean()
|
||||
)
|
||||
|
||||
var adapter = binding.recyclerView.run {
|
||||
layoutManager = LinearLayoutManager(mContext, RecyclerView.VERTICAL, false)
|
||||
addItemDecoration(
|
||||
RecycleViewDivider(
|
||||
LinearLayout.VERTICAL,
|
||||
ConvertUtils.dp2px(16.0f),
|
||||
Color.TRANSPARENT
|
||||
)
|
||||
)
|
||||
adapter = DriversAdapter()
|
||||
adapter as DriversAdapter
|
||||
}
|
||||
|
||||
adapter.submitList(datas)
|
||||
}
|
||||
}
|
@ -15,11 +15,27 @@
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llTop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_100"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.dahe.mylibrary.weight.CircleBarView
|
||||
android:id="@+id/circleBarView"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="@dimen/dp_150"
|
||||
app:progress_color1="@color/red"
|
||||
/>
|
||||
|
||||
<com.dahe.mylibrary.weight.CircleBarView2
|
||||
android:id="@+id/circleBarView2"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="@dimen/dp_150"
|
||||
app:progress_color1="@color/red"
|
||||
/>
|
||||
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_75"
|
||||
@ -75,60 +91,31 @@
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_50"
|
||||
android:layout_height="@dimen/dp_54"
|
||||
android:layout_marginLeft="@dimen/dp_15"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
android:layout_marginRight="@dimen/dp_15"
|
||||
android:background="@color/white"
|
||||
android:layout_marginBottom="@dimen/dp_14"
|
||||
app:cardCornerRadius="@dimen/dp_8">
|
||||
|
||||
<LinearLayout
|
||||
<net.lucode.hackware.magicindicator.MagicIndicator
|
||||
android:id="@+id/magicIndicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/dp_12">
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dp_48"
|
||||
android:layout_height="@dimen/dp_48"
|
||||
android:background="@drawable/head_defaut" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dp_10"
|
||||
android:text="王师傅的车队"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_14" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dp_6"
|
||||
android:background="@drawable/shape_orange_5"
|
||||
android:paddingLeft="@dimen/dp_4"
|
||||
android:paddingTop="@dimen/dp_2"
|
||||
android:paddingRight="@dimen/dp_4"
|
||||
android:paddingBottom="@dimen/dp_2"
|
||||
android:text="未认证"
|
||||
android:textColor="#FF4A02"
|
||||
android:textSize="@dimen/sp_9" />
|
||||
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/right_gray" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:layout_below="@+id/llTop"
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
|
||||
</RelativeLayout>
|
@ -4,27 +4,13 @@
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rlTop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_237"
|
||||
android:background="@drawable/wallet_bg"
|
||||
android:paddingTop="@dimen/dp_50">
|
||||
android:background="@drawable/wallet_bg">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:text="钱包"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_17" />
|
||||
<include layout="@layout/common_toolbar"></include>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_4"
|
||||
android:background="@drawable/left"
|
||||
android:baselineAlignBottom="@+id/tvTitle" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
|
@ -5,7 +5,7 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
//搜索
|
||||
<!-- //搜索-->
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
|
57
app/src/main/res/layout/item_driver.xml
Normal file
57
app/src/main/res/layout/item_driver.xml
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_70"
|
||||
android:background="@drawable/shape_bg8"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivHead"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/head_defaut" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dp_12"
|
||||
android:layout_toRightOf="@+id/ivHead"
|
||||
android:text="王师傅"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_16" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPhone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/ivHead"
|
||||
android:layout_marginLeft="@dimen/dp_12"
|
||||
android:layout_toRightOf="@+id/ivHead"
|
||||
android:text="15835201103"
|
||||
android:textColor="@color/color_9"
|
||||
android:textSize="@dimen/sp_12" />
|
||||
|
||||
<View
|
||||
android:layout_alignBottom="@+id/tvPhone"
|
||||
android:layout_toRightOf="@+id/tvPhone"
|
||||
android:layout_marginLeft="@dimen/dp_10"
|
||||
android:layout_width="@dimen/dp_1"
|
||||
android:layout_marginBottom="@dimen/dp_2"
|
||||
android:layout_height="@dimen/dp_10"
|
||||
android:background="@color/color_c"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDays"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/ivHead"
|
||||
android:layout_marginLeft="@dimen/dp_22"
|
||||
android:layout_toRightOf="@+id/tvPhone"
|
||||
android:text="加入22天"
|
||||
android:textColor="@color/color_9"
|
||||
android:textSize="@dimen/sp_12" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,323 @@
|
||||
package com.dahe.mylibrary.weight;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.SweepGradient;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.Transformation;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.dahe.mylibrary.R;
|
||||
|
||||
/**
|
||||
* @ClassName CircleBarView
|
||||
* @Author john
|
||||
* @Date 2024/2/7 16:08
|
||||
* @Description TODO
|
||||
*/
|
||||
public class CircleBarView extends View {
|
||||
private Paint rPaint;//绘制矩形的画笔
|
||||
private Paint progressPaint;//绘制圆弧的画笔
|
||||
private Paint anchorPaint, anchorBgPaint;//锚点
|
||||
private float anchorRadius, anchorBgRadius;
|
||||
private int anchorColor, anchorBgColor;
|
||||
private CircleBarAnim anim;
|
||||
private Paint bgPaint;//绘制背景圆弧的画笔
|
||||
private float progress;//可以更新的进度条数值
|
||||
private float maxProgress;//进度条最大值
|
||||
private float progressSweepAngle;//进度条圆弧扫过的角度
|
||||
private int startAngle;//背景圆弧的起始角度
|
||||
private float sweepAngle;//背景圆弧扫过的角度
|
||||
private RectF mRectF;//绘制圆弧的矩形区域
|
||||
private float barWidth;//圆弧进度条宽度
|
||||
private int defaultSize;//自定义View默认的宽高
|
||||
private int[] progressColors;//进度条圆弧颜色
|
||||
private int bgColor;//背景圆弧颜色
|
||||
private SweepGradient sweepGradient;//进度条颜色使用渐变色
|
||||
private LinearGradient linearGradient;
|
||||
private float circleWidth, circleHeight;
|
||||
private float xDiff;
|
||||
|
||||
public CircleBarView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleBarView);
|
||||
int color1 = typedArray.getColor(R.styleable.CircleBarView_progress_color1, Color.RED);
|
||||
int color2 = typedArray.getColor(R.styleable.CircleBarView_progress_color2, color1);
|
||||
int color3 = typedArray.getColor(R.styleable.CircleBarView_progress_color3, color2);//写法巧妙
|
||||
progressColors = new int[]{color1, color1, color2, color3};//必须得4个,
|
||||
bgColor = typedArray.getColor(R.styleable.CircleBarView_bg_color, Color.GRAY);//默认为灰色
|
||||
circleWidth = typedArray.getDimension(R.styleable.CircleBarView_circle_width, dip2px(context, 200));//默认为0
|
||||
circleHeight = typedArray.getDimension(R.styleable.CircleBarView_circle_height, dip2px(context, 80));//默认为360
|
||||
barWidth = typedArray.getDimension(R.styleable.CircleBarView_bar_width, dip2px(context, 10));//默认为10dp
|
||||
anchorRadius = typedArray.getDimension(R.styleable.CircleBarView_anchor_radius, dip2px(context, 5));
|
||||
anchorBgRadius = typedArray.getDimension(R.styleable.CircleBarView_anchor_bg_radius, dip2px(context, 8.5f));
|
||||
anchorColor = typedArray.getColor(R.styleable.CircleBarView_anchor_color, Color.RED);
|
||||
anchorBgColor = typedArray.getColor(R.styleable.CircleBarView_anchor_bg_color, Color.GREEN);
|
||||
maxProgress = typedArray.getInt(R.styleable.CircleBarView_progress_max, 100);
|
||||
typedArray.recycle();//typedArray用完之后需要回收,防止内存泄漏
|
||||
|
||||
rPaint = new Paint();
|
||||
rPaint.setStyle(Paint.Style.STROKE);//只描边,不填充
|
||||
rPaint.setColor(Color.RED);
|
||||
|
||||
progressPaint = new Paint();
|
||||
progressPaint.setStyle(Paint.Style.STROKE);//只描边,不填充
|
||||
|
||||
progressPaint.setStrokeWidth(barWidth);
|
||||
progressPaint.setAntiAlias(true);//设置抗锯齿
|
||||
progressPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
|
||||
//锚点
|
||||
anchorPaint = new Paint();
|
||||
anchorPaint.setAntiAlias(true);//设置抗锯齿
|
||||
anchorPaint.setColor(anchorColor);
|
||||
//锚点背景
|
||||
anchorBgPaint = new Paint();
|
||||
anchorBgPaint.setAntiAlias(true);//设置抗锯齿
|
||||
|
||||
int a = Color.alpha(anchorBgColor);
|
||||
int r = Color.red(anchorBgColor);
|
||||
int g = Color.green(anchorBgColor);
|
||||
int b = Color.blue(anchorBgColor);
|
||||
// LogSuperUtil.i("circle_bar", "a=" + a + ",r=" + r + ",g=" + g + ",b=" + b);
|
||||
anchorBgPaint.setColor(Color.rgb(r, g, b));
|
||||
anchorBgPaint.setAlpha(a);
|
||||
/*raw
|
||||
anchorBgPaint.setColor(anchorBgColor);
|
||||
anchorBgPaint.setAlpha(185);*/
|
||||
|
||||
anim = new CircleBarAnim();
|
||||
bgPaint = new Paint();
|
||||
bgPaint.setStyle(Paint.Style.STROKE);
|
||||
bgPaint.setColor(bgColor);
|
||||
bgPaint.setStrokeWidth(barWidth);
|
||||
bgPaint.setAntiAlias(true);
|
||||
bgPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
mRectF = new RectF();
|
||||
|
||||
//
|
||||
defaultSize = dip2px(context, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
//进度条的总轮廓
|
||||
canvas.drawArc(mRectF, startAngle, sweepAngle, false, bgPaint);
|
||||
float outCircleRadius = mRectF.width() / 2;//带宽度的进度条的中线半径
|
||||
|
||||
if (sweepGradient == null) {
|
||||
float centerX = (mRectF.left + mRectF.right) / 2;
|
||||
float centerY = (mRectF.top + mRectF.bottom) / 2;
|
||||
//
|
||||
int rotateDiff = 30;//为了解决圆弧开头出的圆角颜色不正常的问题,30度够用了吧
|
||||
int rotateDegree = startAngle - rotateDiff;
|
||||
float sweepEndPosition = (rotateDiff + sweepAngle * progress / maxProgress * 1.0f) / 360;
|
||||
// LogSuperUtil.i("circle_bar", "startAngle=" + startAngle + ",sweepEndPosition=" + sweepEndPosition);
|
||||
|
||||
float[] positions = {0, rotateDiff * 1.0f / 360, sweepEndPosition, 1};
|
||||
sweepGradient = new SweepGradient(centerX, centerY, progressColors, positions);
|
||||
Matrix rotateMatrix = new Matrix();
|
||||
//设置渐变色
|
||||
rotateMatrix.setRotate(rotateDegree, centerX, centerY);//180表示从左侧开始往上渐变
|
||||
sweepGradient.setLocalMatrix(rotateMatrix);//sweepGradient默认是从0度方向开始渐变的,所以要逆转一下。
|
||||
progressPaint.setShader(sweepGradient);
|
||||
}
|
||||
/*
|
||||
if(linearGradient==null) {
|
||||
linearGradient = new LinearGradient(0, 0, outCircleRadius*2, 0, progressColors,
|
||||
null, LinearGradient.TileMode.CLAMP);
|
||||
progressPaint.setShader(linearGradient);
|
||||
}*/
|
||||
//进度条
|
||||
canvas.drawArc(mRectF, startAngle, progressSweepAngle, false, progressPaint);
|
||||
float anchorAngle = progressSweepAngle + (startAngle - 180);
|
||||
|
||||
float anchorCoordRedius = outCircleRadius - barWidth / 2;
|
||||
double cosValue = Math.cos(Math.toRadians(anchorAngle));
|
||||
double sinValue = Math.sin(Math.toRadians(anchorAngle));
|
||||
|
||||
float diffByAnchor = anchorBgRadius - barWidth / 2;//x和y的偏移正好都是这个
|
||||
//float cx=(float)(outCircleRadius-cosValue*anchorCoordRedius+diffByAnchor);
|
||||
float cx = (float) (outCircleRadius - cosValue * outCircleRadius + anchorBgRadius);
|
||||
//float cy=(float)(outCircleRadius-sinValue*anchorCoordRedius+diffByAnchor);
|
||||
float cy = (float) (outCircleRadius - sinValue * outCircleRadius + anchorBgRadius);
|
||||
canvas.drawCircle(cx - xDiff, cy, anchorRadius, anchorPaint);//锚点小圆
|
||||
canvas.drawCircle(cx - xDiff, cy, anchorBgRadius, anchorBgPaint);//锚点背景大圆
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
//int height=measureSize(defaultSize,heightMeasureSpec);
|
||||
//int width=measureSize(defaultSize,widthMeasureSpec);
|
||||
//startAngle是计算出来的,因为弦的这种,没法通过观察直接得出圆弧的起始角度
|
||||
//通过数学计算得知x
|
||||
//x是圆心(圆弧所在的圆的圆心)到弦(也就是圆弧的底部)的垂直距离
|
||||
float x = (circleWidth * circleWidth - 4 * circleHeight * circleHeight) / (8 * circleHeight);
|
||||
//画圆弧用到的圆的半径
|
||||
float r = x + circleHeight;
|
||||
//int r=(int)(circleWidth/2/Math.cos(Math.toRadians(startAngle-180)));
|
||||
//弦长/2/半径=cos(startAngle-180)
|
||||
//(startAngle-180)
|
||||
double asin = Math.asin(circleWidth / 2 / r);
|
||||
//LogSuperUtil.i("circle_bar","asin="+asin);
|
||||
int a = (int) Math.toDegrees(asin);
|
||||
//LogSuperUtil.i("circle_bar","a="+a);
|
||||
startAngle = 180 + (90 - a);
|
||||
sweepAngle = 2 * a;
|
||||
//int min=Math.max(width,height);//获取View最短边的长度
|
||||
int width = (int) (Math.sqrt(Math.pow(r + anchorBgRadius, 2) - Math.pow(x, 2)) * 2 + 0.5f + anchorBgRadius);//圆弧的宽度
|
||||
width = (int) (2 * (circleWidth / 2 + anchorBgRadius) + 0.5f);
|
||||
int height = (int) (circleHeight + anchorBgRadius + 0.5f + anchorBgRadius);
|
||||
//height=width;
|
||||
xDiff = r - circleWidth / 2;//画布是从最左边开始画圆且显示的,不偏移的话,显示的效果不对。
|
||||
// LogSuperUtil.i("circle_bar", "xDiff=" + xDiff);
|
||||
setMeasuredDimension(width, height);
|
||||
if (Math.min(width, height) >= barWidth * 2) {//这里简单限制了圆弧的最大宽度
|
||||
//1.mRectF决定着圆画在哪个框框里面
|
||||
//2.mRectF在当前View中,但不是完全占据当前View
|
||||
//3.弧度的粗细画的时候是均分到圆半径线的两侧的
|
||||
//4.之所以矩形设置的四个点有偏移,是因为有弧度宽度。
|
||||
//因为锚点也有宽度,点再次做调整.
|
||||
//mRectF.set(barWidth/2,barWidth/2,min-barWidth/2,min-barWidth/2);
|
||||
float diffByAnchor = anchorBgRadius - barWidth / 2;//受锚点影响需要修正的偏移
|
||||
//是整个圆的矩形,不是弧形区域所在的矩形
|
||||
mRectF.set(barWidth / 2 + diffByAnchor - xDiff, barWidth / 2 + diffByAnchor, barWidth / 2 + diffByAnchor + 2 * r - xDiff, barWidth / 2 + diffByAnchor + 2 * r);
|
||||
}
|
||||
}
|
||||
|
||||
private int measureSize(int defaultSize, int measureSpec) {
|
||||
int result = defaultSize;
|
||||
int specMode = MeasureSpec.getMode(measureSpec);
|
||||
int specSize = MeasureSpec.getSize(measureSpec);
|
||||
if (specMode == MeasureSpec.EXACTLY) {
|
||||
// LogSuperUtil.i("circle_bar", "=EXACTLY");
|
||||
result = specSize;
|
||||
} else if (specMode == MeasureSpec.AT_MOST) {
|
||||
// LogSuperUtil.i("circle_bar", "=AT_MOST");
|
||||
result = Math.min(result, specSize);
|
||||
} else {
|
||||
// LogSuperUtil.i("circle_bar", "=defaultSize");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private TextView textView;
|
||||
private OnAnimationListener onAnimationListener;
|
||||
|
||||
public class CircleBarAnim extends Animation {
|
||||
public CircleBarAnim() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||
super.applyTransformation(interpolatedTime, t);
|
||||
progressSweepAngle = interpolatedTime * sweepAngle * progress / maxProgress;//这里计算进度条的比例
|
||||
postInvalidate();
|
||||
if (textView != null && onAnimationListener != null) {
|
||||
textView.setText(onAnimationListener.howToChangeText(interpolatedTime, progress, maxProgress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置显示文字的TextView
|
||||
*
|
||||
* @param textView
|
||||
*/
|
||||
public void setTextView(TextView textView) {
|
||||
this.textView = textView;
|
||||
}
|
||||
/*
|
||||
* circleBarView.setOnAnimationListener(new CircleBarView.OnAnimationListener() {
|
||||
@Override
|
||||
public String howToChangeText(float interpolatedTime, float progressNum, float maxNum) {
|
||||
DecimalFormat decimalFormat=new DecimalFormat("0.00");
|
||||
String s = decimalFormat.format(interpolatedTime * progressNum / maxNum * 100) + "%";
|
||||
return s;
|
||||
}
|
||||
});*/
|
||||
|
||||
|
||||
public interface OnAnimationListener {
|
||||
/**
|
||||
* 如何处理要显示的文字内容
|
||||
*
|
||||
* @param interpolatedTime 从0渐变成1,到1时结束动画
|
||||
* @param progressNum 进度条数值
|
||||
* @param maxNum 进度条最大值
|
||||
* @return
|
||||
*/
|
||||
String howToChangeText(float interpolatedTime, float progressNum, float maxNum);
|
||||
}
|
||||
|
||||
//写个方法给外部调用,用来设置动画时间
|
||||
public void setProgress(float progress, int time) {
|
||||
anim.setDuration(time);
|
||||
this.startAnimation(anim);
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public static int dip2px(Context context, float dpValue) {
|
||||
float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static int px2dip(Context context, float pxValue) {
|
||||
float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (pxValue / scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* //extraDistance比较小时,TextView离圆弧很近,是正常,因为TextView是从其自身的左上角开始渲染。
|
||||
*
|
||||
* @param sweepAnglePercent
|
||||
* @param extraDistance
|
||||
* @return
|
||||
*/
|
||||
public float getAngleX(float sweepAnglePercent, int extraDistance) {
|
||||
float outCircleRadius = mRectF.width() / 2 + barWidth / 2;//带宽度的进度条的外圆半径
|
||||
float diffByAnchor = anchorBgRadius - barWidth / 2;//x和y的偏移正好都是这个
|
||||
float x = (float) (outCircleRadius + diffByAnchor - Math.cos(Math.toRadians(startAngle - 180 + sweepAnglePercent * sweepAngle)) * (outCircleRadius + dip2px(getContext(), extraDistance)) - xDiff);
|
||||
return x;
|
||||
}
|
||||
|
||||
private static final String TAG = "circle_bar";
|
||||
|
||||
/**
|
||||
* 在当前View中的y坐标
|
||||
* (注意,TextView渲染的时候,这个坐标是作为TextView控件的左上角进行渲染。
|
||||
* 所以,extraDistance小的话,显示的结果TextView可能还在当前View的内部呢,但TextView的左上角是在圆外部的。
|
||||
*
|
||||
* @param sweepAnglePercent
|
||||
* @param extraDistance 从外圆算的往外扩展的距离,不是从锚点背景边缘往外扩展。
|
||||
* @return
|
||||
*/
|
||||
public float getAngleY(float sweepAnglePercent, int extraDistance) {
|
||||
float outCircleRadius = mRectF.width() / 2 + barWidth / 2;//带宽度的进度条的外圆半径
|
||||
float diffByAnchor = anchorBgRadius - barWidth / 2;//x和y的偏移正好都是这个
|
||||
float coordA = startAngle - 180 + sweepAnglePercent * sweepAngle;
|
||||
// LogSuperUtil.i("circle_bar", "coordA=" + coordA);
|
||||
float coordY = (float) Math.sin(Math.toRadians(coordA)) * (outCircleRadius + dip2px(getContext(), extraDistance));
|
||||
// LogSuperUtil.i("circle_bar", "coordY=" + coordY);
|
||||
float tempR = outCircleRadius + diffByAnchor;
|
||||
// LogSuperUtil.i("circle_bar", "tempR=" + tempR + ",=" + circleWidth);//CircleWidth是圆弧宽度
|
||||
// LogSuperUtil.i("circle_bar", "mRectF.width()/2=" + mRectF.width() / 2);
|
||||
float y = (float) (tempR - coordY);
|
||||
return y;
|
||||
}
|
||||
}
|
@ -0,0 +1,259 @@
|
||||
package com.dahe.mylibrary.weight;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
import com.dahe.mylibrary.R;
|
||||
|
||||
/**
|
||||
* @ClassName CircleBarView2
|
||||
* @Author john
|
||||
* @Date 2024/2/7 16:28
|
||||
* @Description TODO
|
||||
*/
|
||||
public class CircleBarView2 extends View {
|
||||
|
||||
private Paint outPaint, innerPaint;
|
||||
|
||||
private Paint mTextPaint, mValueTextPaint, mUnitTextPaint;
|
||||
|
||||
private final RectF oval = new RectF();
|
||||
|
||||
//最大进度
|
||||
private int max = 100;
|
||||
//当前进度
|
||||
private int progress = 0;
|
||||
//文本内容
|
||||
private String text = "";
|
||||
//数值内容
|
||||
private String valueText = "";
|
||||
//单位内容
|
||||
private String unitText = "";
|
||||
// 圆弧颜色
|
||||
private int roundColor = getContext().getColor(R.color.color_f25);
|
||||
// 设置数值颜色
|
||||
private int valueColor = getContext().getColor(R.color.color_f25);
|
||||
//用于动画
|
||||
private float nowPro = 0;
|
||||
private ValueAnimator animator;
|
||||
// 文字间距
|
||||
private int textMargin;
|
||||
// 圆弧宽度、半径和数值、小间距
|
||||
private int roundWidth, radius, smallMargin;
|
||||
// view的高度
|
||||
private int height;
|
||||
// 中心点
|
||||
private final Point centerPoint = new Point();
|
||||
// 测量文字的范围
|
||||
private final Rect textRect = new Rect();
|
||||
|
||||
public CircleBarView2(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CircleBarView2(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CircleBarView2(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initAttrs(context);
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public void setMax(int max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setProgress(int progress) {
|
||||
if (this.progress == progress) {
|
||||
return;
|
||||
}
|
||||
if (animator != null && animator.isRunning()) {
|
||||
animator.cancel();
|
||||
}
|
||||
animator = ValueAnimator.ofFloat(nowPro, progress);
|
||||
animator.setDuration(1000);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.addUpdateListener(animation -> {
|
||||
nowPro = (float) animation.getAnimatedValue();
|
||||
CircleBarView2.this.progress = (int) nowPro;
|
||||
valueText = String.valueOf(CircleBarView2.this.progress);
|
||||
invalidate();
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getValueText() {
|
||||
return valueText;
|
||||
}
|
||||
|
||||
public void setValueText(String valueText) {
|
||||
this.valueText = valueText;
|
||||
}
|
||||
|
||||
public String getUnitText() {
|
||||
return unitText;
|
||||
}
|
||||
|
||||
public void setUnitText(String unitText) {
|
||||
this.unitText = unitText;
|
||||
}
|
||||
|
||||
public void setRoundColor(int roundColor) {
|
||||
this.roundColor = roundColor;
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setValueColor(int valueColor) {
|
||||
this.valueColor = valueColor;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void initAttrs(Context context) {
|
||||
// 文字间距
|
||||
textMargin = dp2px(context, 5);
|
||||
// 圆弧宽度
|
||||
roundWidth = dp2px(context, 5);
|
||||
// 半径
|
||||
radius = dp2px(context, 72);
|
||||
height = radius;
|
||||
// 小间距
|
||||
smallMargin = roundWidth / 2;
|
||||
|
||||
outPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
outPaint.setColor(context.getColor(R.color.color_f6));
|
||||
outPaint.setStyle(Paint.Style.STROKE);
|
||||
outPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
outPaint.setStrokeWidth(roundWidth);
|
||||
|
||||
innerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
innerPaint.setColor(context.getColor(R.color.color_f15));
|
||||
innerPaint.setStyle(Paint.Style.STROKE);
|
||||
innerPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
innerPaint.setStrokeWidth(roundWidth);
|
||||
|
||||
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mTextPaint.setColor(context.getColor(R.color.color_ff3));
|
||||
mTextPaint.setTextSize(sp2px(getContext(), 24));
|
||||
|
||||
mValueTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mValueTextPaint.setColor(valueColor);
|
||||
mValueTextPaint.setTextSize(sp2px(getContext(), 24));
|
||||
|
||||
mUnitTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mUnitTextPaint.setColor(context.getColor(R.color.color_ff3));
|
||||
mUnitTextPaint.setTextSize(sp2px(getContext(), 12));
|
||||
|
||||
//动画
|
||||
animator = ValueAnimator.ofFloat(0, progress);
|
||||
animator.setDuration(1000);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.addUpdateListener(animation -> {
|
||||
nowPro = (float) animation.getAnimatedValue();
|
||||
postInvalidate();
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
|
||||
setMeasuredDimension(widthSpecSize, (int) height);
|
||||
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
|
||||
setMeasuredDimension(widthSpecSize, heightSpecSize);
|
||||
height = heightSpecSize;
|
||||
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
|
||||
setMeasuredDimension(widthSpecSize, (int) height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
// 中心点
|
||||
centerPoint.set(getWidth() / 2, height / 2);
|
||||
// 计算圆弧显示的范围,height * 2 是因为圆弧的高度是根据园来算的,所以双倍才是半个圆
|
||||
oval.set(getWidth() / 2f - radius, (float) roundWidth, getWidth() / 2f + radius, height * 2 - roundWidth*2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
|
||||
// 最外层圆弧
|
||||
canvas.drawArc(oval, 180, 180, false, outPaint); //绘制外层圆弧
|
||||
|
||||
// 进度圆弧
|
||||
if (nowPro > 0) {
|
||||
innerPaint.setColor(roundColor);
|
||||
} else {
|
||||
innerPaint.setColor(getContext().getColor(R.color.color_f6));
|
||||
}
|
||||
canvas.drawArc(oval, 180, 180f * nowPro / max, false, innerPaint); //绘制圆弧
|
||||
|
||||
// 文字从底部从下往上绘制。
|
||||
|
||||
int valueY = height - smallMargin;
|
||||
|
||||
// 值
|
||||
float valueTextWidth = mValueTextPaint.measureText(valueText);
|
||||
float unitTextWidth = mUnitTextPaint.measureText(unitText);
|
||||
canvas.drawText(valueText, centerPoint.x - (valueTextWidth + unitTextWidth) / 2f, valueY, mValueTextPaint);
|
||||
// 单位
|
||||
canvas.drawText(unitText, centerPoint.x + valueTextWidth / 2f - unitTextWidth / 2f + smallMargin, valueY, mUnitTextPaint);
|
||||
|
||||
// 测量值的高度
|
||||
mValueTextPaint.getTextBounds(text, 0, text.length(), textRect);
|
||||
|
||||
// 提示文字("高血压")
|
||||
float textWidth = mTextPaint.measureText(text);
|
||||
// 文字的高度 = 值的高度起点 - 值的高度 - 间距
|
||||
float textY = valueY - textRect.height() - textMargin;
|
||||
canvas.drawText(text, centerPoint.x - textWidth / 2f, textY, mTextPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp 转 px
|
||||
*/
|
||||
private int dp2px(Context context, float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* sp 转 px
|
||||
*/
|
||||
private int sp2px(Context context, float spValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().scaledDensity;
|
||||
return (int) (spValue * scale + 0.5f);
|
||||
}
|
||||
}
|
@ -29,5 +29,10 @@
|
||||
|
||||
|
||||
|
||||
<color name="color_f6">#F6F6F6</color>
|
||||
<color name="color_f15">#F15F15</color>
|
||||
<color name="color_ff3">#FF3FF3</color>
|
||||
<color name="color_f25">#f25f25</color>
|
||||
|
||||
|
||||
</resources>
|
||||
|
@ -52,4 +52,28 @@
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
|
||||
<declare-styleable name="CircleBarView">
|
||||
<attr name="progress_color1" format="reference|color"></attr>
|
||||
<attr name="progress_color2" format="reference|color"></attr>
|
||||
<attr name="progress_color3" format="reference|color"></attr>
|
||||
<attr name="bg_color" format="color"></attr>
|
||||
<attr name="bar_width" format="dimension"></attr>
|
||||
<attr name="circle_width" format="dimension"></attr><!--背景圆弧宽度 -->
|
||||
<attr name="circle_height" format="dimension"></attr><!--背景圆弧高度 -->
|
||||
<attr name="anchor_radius" format="dimension"></attr>
|
||||
<attr name="anchor_bg_radius" format="dimension"></attr>
|
||||
<attr name="anchor_color" format="reference|color"></attr>
|
||||
<attr name="anchor_bg_color" format="reference|color"></attr>
|
||||
<attr name="progress_max" format="integer"></attr>
|
||||
</declare-styleable>
|
||||
<declare-styleable name="CircleTextView">
|
||||
<attr name="paddingRing2Bg" format="dimension"></attr>
|
||||
<attr name="ringStrokeWidth" format="dimension"></attr>
|
||||
<attr name="ringColor1" format="reference|color"></attr>
|
||||
<attr name="ringColor2" format="reference|color"></attr>
|
||||
<attr name="bgColor1" format="reference|color"></attr>
|
||||
<attr name="bgColor2" format="reference|color"></attr>
|
||||
</declare-styleable>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user