车队管理完善
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) {
|
private fun goTools(pos: Int) {
|
||||||
when (pos) {
|
when (pos) {
|
||||||
0 -> {
|
0 -> {
|
||||||
ActivityUtils.startActivity(mContext, RulesActivity::class.java)
|
ActivityUtils.startActivity(mContext, CarTeamActivity::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
1 -> {
|
1 -> {
|
||||||
|
@ -1,8 +1,25 @@
|
|||||||
package com.dahe.gldriver.ui.mine.activity
|
package com.dahe.gldriver.ui.mine.activity
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
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.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 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
|
* @ClassName CarTeamActivity
|
||||||
@ -11,11 +28,116 @@ import com.dahe.mylibrary.base.BaseActivity
|
|||||||
* @Description 车队管理
|
* @Description 车队管理
|
||||||
*/
|
*/
|
||||||
class CarTeamActivity : BaseActivity<ActivityCarTeamBinding>() {
|
class CarTeamActivity : BaseActivity<ActivityCarTeamBinding>() {
|
||||||
|
|
||||||
|
private val mFragmentContainerHelper = FragmentContainerHelper()
|
||||||
|
var mFragments = mutableListOf<Fragment>(
|
||||||
|
DriversManFragment(),
|
||||||
|
CarsManFragment(),
|
||||||
|
AllWaybillFragment()
|
||||||
|
)
|
||||||
|
val titles = mutableListOf(
|
||||||
|
"司机管理",
|
||||||
|
"车辆管理",
|
||||||
|
"车队订单"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
override fun initView(savedInstanceState: Bundle?) {
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
setStatusHeightParams(binding.rlTop)
|
setStatusHeightParams(binding.rlTop)
|
||||||
setTitleBar("车队管理",true,true)
|
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() {
|
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>() {
|
class WalletActivity : BaseActivity<ActivityWalletBinding>() {
|
||||||
override fun initView(savedInstanceState: Bundle?) {
|
override fun initView(savedInstanceState: Bundle?) {
|
||||||
|
setStatusHeightParams(binding.rlTop)
|
||||||
|
setTitleBar("钱包",true,true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initDate() {
|
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>
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/llTop"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/dp_100"
|
android:layout_marginTop="@dimen/dp_100"
|
||||||
android:orientation="vertical">
|
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
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dp_75"
|
android:layout_height="@dimen/dp_75"
|
||||||
@ -75,60 +91,31 @@
|
|||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_marginTop="@dimen/dp_10"
|
|
||||||
android:layout_width="match_parent"
|
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_marginLeft="@dimen/dp_15"
|
||||||
|
android:layout_marginTop="@dimen/dp_10"
|
||||||
android:layout_marginRight="@dimen/dp_15"
|
android:layout_marginRight="@dimen/dp_15"
|
||||||
android:background="@color/white"
|
android:background="@color/white"
|
||||||
|
android:layout_marginBottom="@dimen/dp_14"
|
||||||
app:cardCornerRadius="@dimen/dp_8">
|
app:cardCornerRadius="@dimen/dp_8">
|
||||||
|
|
||||||
<LinearLayout
|
<net.lucode.hackware.magicindicator.MagicIndicator
|
||||||
|
android:id="@+id/magicIndicator"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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>
|
</androidx.cardview.widget.CardView>
|
||||||
</LinearLayout>
|
</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>
|
</RelativeLayout>
|
@ -4,27 +4,13 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
android:id="@+id/rlTop"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dp_237"
|
android:layout_height="@dimen/dp_237"
|
||||||
android:background="@drawable/wallet_bg"
|
android:background="@drawable/wallet_bg">
|
||||||
android:paddingTop="@dimen/dp_50">
|
|
||||||
|
|
||||||
<TextView
|
<include layout="@layout/common_toolbar"></include>
|
||||||
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" />
|
|
||||||
|
|
||||||
<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>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
//搜索
|
<!-- //搜索-->
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
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>
|
</resources>
|
||||||
|
@ -52,4 +52,28 @@
|
|||||||
<item name="android:windowIsFloating">true</item>
|
<item name="android:windowIsFloating">true</item>
|
||||||
<item name="android:windowContentOverlay">@null</item>
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
</style>
|
</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>
|
</resources>
|
Loading…
Reference in New Issue
Block a user