Commit c9209662 by 刘鹏

Merge branch 'feat/lp/lp_xlzx_home_4.0.57' into release

# Conflicts:
#	m-audioim/src/main/java/com/ydl/audioim/YDLavManager.kt
parents 6b85513f 6ade7eda
......@@ -27,7 +27,6 @@ android {
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
flavorDimensions "versionCode"
vectorDrawables.useSupportLibrary = true
}
......@@ -49,7 +48,9 @@ android {
ydl {}
xlzx {}
}
dataBinding {
enabled true
}
sourceSets {
main {
res.srcDirs = ['src/main/res']
......
package com.yidianling.home.ui.view
import android.content.Context
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.yidianling.home.R
import com.yidianling.home.databinding.HomeButtonBannerViewBinding
import com.yidianling.home.event.IHomeBaseEvent
import com.yidianling.home.model.bean.HomeHeaderBean
import kotlinx.android.synthetic.xlzx.home_button_banner_view.view.*
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
......@@ -21,6 +20,7 @@ import kotlinx.android.synthetic.xlzx.home_button_banner_view.view.*
*/
class HomeButtonBannerView(private val mContext: Context, private var homeEvent: IHomeBaseEvent?) :
LinearLayout(mContext) {
private var dataBinding: HomeButtonBannerViewBinding? = null
init {
initView()
......@@ -32,33 +32,37 @@ class HomeButtonBannerView(private val mContext: Context, private var homeEvent:
ViewGroup.LayoutParams.WRAP_CONTENT
)
layoutParams = params
View.inflate(mContext, R.layout.home_button_banner_view, this)
dataBinding = DataBindingUtil.inflate(
LayoutInflater.from(mContext),
R.layout.home_button_banner_view,
this,
true
)
Glide.with(context)
.load(R.drawable.qingsu_new_free_dynamic)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(qingsuGif)
homeModuleButtonBannerFirst.setOnClickListener {
dataBinding?.homeModuleButtonBannerFirst?.setOnClickListener {
homeEvent?.reservationExpertsClick()
}
homeModuleButtonBannerSecond.setOnClickListener {
dataBinding?.homeModuleButtonBannerSecond?.setOnClickListener {
homeEvent?.askMoreClick()
}
homeModuleButtonBannerThird.setOnClickListener {
dataBinding?.homeModuleButtonBannerThird?.setOnClickListener {
homeEvent?.nowConfideClick(false)
}
homeModuleButtonBannerFourth.setOnClickListener {
dataBinding?.homeModuleButtonBannerFourth?.setOnClickListener {
homeEvent?.psychologyTestClick()
}
dataBinding?.loopAvatar?.stopLoop()
dataBinding?.loopAvatar?.startLoop()
}
fun initData(
homeCategory: List<HomeHeaderBean.CategoryGoldListDataBean>?
) {
homeEvent?.let { home_category_view.setEvent(it) }
home_category_view.initData(homeCategory)
homeEvent?.let { dataBinding?.homeCategoryView?.setEvent(it) }
dataBinding?.homeCategoryView?.initData(homeCategory)
}
}
\ No newline at end of file
package com.yidianling.home.ui.view
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Activity
import android.content.Context
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.util.Log
import android.widget.ImageView
import android.widget.RelativeLayout
import com.blankj.utilcode.util.SizeUtils
import com.yidianling.home.R
import java.lang.ref.WeakReference
const val START_AVATAR_LOOP = 111
class LoopScrollAvatar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
//动画播放时长
private val animDuration = 500L
//动画间隔播放时间
private val animIntervalTime = 2000L
//两边头像的缩放程度
private val scaleFrom = 0.7F
//头像大小
private val avatarSize = SizeUtils.dp2px(18F)
//从当前位置滚动到下一位置需要移动的距离
private var scrollLength = 0F
//下次要显示的图片角标
private var index = 0
private val res =
arrayOf(
R.mipmap.home_banner_header1,
R.mipmap.home_banner_header2,
R.mipmap.home_banner_header3,
R.mipmap.home_banner_header4,
R.mipmap.home_banner_header5
)
//缓存复用ImageView
private val ivCache = mutableListOf(
createImageView(),
createImageView(),
createImageView(),
createImageView()
)
private val handler by lazy {
LoopHandler(this)
}
init {
//前三位的头像先addView显示出来
//放左边
addImageView(ALIGN_PARENT_LEFT)
//放中间
addImageView(CENTER_HORIZONTAL)
//默认放右边
addImageView()
}
class LoopHandler() : Handler() {
private var lWeak: WeakReference<LoopScrollAvatar>? = null
constructor(loopScrollAvatar: LoopScrollAvatar) : this() {
lWeak = WeakReference(loopScrollAvatar)
}
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
lWeak?.get()?.apply {
if ((context as? Activity)?.isDestroyed == false) {
startAnimMove()
sendLoopMsg()
}
}
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
scrollLength = (width - avatarSize) / 2F
}
/**
* 创建圆形头像ImageView
*/
private fun createImageView(): ImageView {
return XCRoundImageView(context)
}
/**
* 摆放头像ImageView
*/
private fun addImageView(rule: Int = ALIGN_PARENT_RIGHT) {
//复用缓存
val iv = if (ivCache.size > 0) {
ivCache[0]
} else {
createImageView()
}
//当前已在屏幕显示的控件不要复用,防止params混乱
ivCache.remove(iv)
iv.setImageResource(res[index])
iv.scaleType = ImageView.ScaleType.FIT_XY
//图片资源全部播放完之后要从头重播
index = (index + 1) % res.size
//设置在RelativeLayout中的显示位置
val lp = LayoutParams(avatarSize, avatarSize)
lp.addRule(rule)
iv.layoutParams = lp
addView(iv)
}
/**
* 轮播滚动动效
*/
private fun startAnimMove() {
//添加一个即将从右边移进屏幕的ImageView
addImageView()
//上行代码刚添加进来的最右边头像(此时RelativeLayout的mChildrenCount=4)
getChildAt(3)?.apply {
//设置起始的低透明度 和 小size
alpha = 0.6F
scaleX = scaleFrom
scaleY = scaleFrom
//先设置左边部分向左移出控件,即挡住左边不显示(然后才能translationXBy移进屏幕)
translationX = scrollLength
//translationXBy指的是从当前位置开始移动多少距离(区别于translationX)
//alpha是从当前透明度(即0.6F)变为设置的透明度(即1F)
//scaleX是从当前宽度比例(即scaleFrom)变为设置的宽度比例(即1F)
animate().translationXBy(-scrollLength).alpha(1F).scaleX(1F).scaleY(1F)
.setDuration(animDuration).start()
}
//中间俩头像只需设置平移的距离即可
getChildAt(1)?.apply {
animate().translationXBy(-scrollLength).setDuration(animDuration).start()
}
//设置平移的距离
getChildAt(2)?.apply {
animate().translationXBy(-scrollLength).setDuration(animDuration).start()
}
//最左边的头像(从完整显示 到 透明度和大小都变小,并且左移出屏幕)(因为是最先add进来的View,所以index=0)
getChildAt(0)?.let { iv ->
iv.animate().translationXBy(0f).alpha(0F).scaleX(scaleFrom).scaleY(scaleFrom)
.setDuration(animDuration)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
//清除ImageView已有属性,并添加进ivCache缓存
iv.animate().setListener(null)
iv.clearAnimation()
iv.translationX = 0F
iv.scaleX = 1.0F
iv.scaleY = 1.0F
iv.alpha = 1F
//从RelativeLayout移出
removeView(iv)
ivCache.add(0, iv as ImageView)
try {
if ((context as Activity).isFinishing) {
stopLoop()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}).start()
}
}
private fun sendLoopMsg() {
handler.sendEmptyMessageDelayed(START_AVATAR_LOOP, animIntervalTime + animDuration)
}
private var looping = false
/**
* 开始轮播
*/
fun startLoop() {
if (looping) {
Log.e("startLoop", "startLoop cannot be called twice")
}
looping = true
sendLoopMsg()
}
/**
* 停止轮播
*/
fun stopLoop() {
looping = false
handler.removeCallbacksAndMessages(null)
}
}
\ No newline at end of file
package com.yidianling.home.ui.view
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
/**
* @author liupeng
*/
class XCRoundImageView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : AppCompatImageView(
context, attrs, defStyle
) {
private val paint: Paint = Paint()
/**
* 绘制圆形图片
* @author caizhiming
*/
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
val drawable = drawable
if (null != drawable) {
val bitmap = (drawable as BitmapDrawable).bitmap
val b = getCircleBitmap(bitmap, 14)
val rectSrc = Rect(0, 0, b.width, b.height)
val rectDest = Rect(0, 0, width, height)
paint.reset()
canvas.drawBitmap(b, rectSrc, rectDest, paint)
} else {
super.onDraw(canvas)
}
}
/**
* 获取圆形图片方法
* @param bitmap
* @param pixels
* @return Bitmap
* @author caizhiming
*/
private fun getCircleBitmap(bitmap: Bitmap, pixels: Int): Bitmap {
val output = Bitmap.createBitmap(
bitmap.width,
bitmap.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(output)
val color = -0xbdbdbe
val rect = Rect(0, 0, bitmap.width, bitmap.height)
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
val x = bitmap.width
canvas.drawCircle((x / 2).toFloat(), (x / 2).toFloat(), (x / 2).toFloat(), paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment