在IOS中,在過度滑動時,整體佈局會進行偏移,鬆手後,會出現回彈效果
安卓中則大多數控件都沒有這種功能,在這裏,可以自定義一個ViewGroup
容器,針對該容器包裹的內容,可以進行過度滾動
爲了實現,我 們需要進行接下來的處理
一、 創建ViewGroup佈局
因爲是要實現一個容器,因此需要自定義一個ViewGroup
,然後重載構造函數,這裏定義該控件名字爲:OverScrollContainer
/**
* Created on 2018/10/10 15:31
* function : 包裹容器;用於在view外部形成一個可以over-scroll的視圖
*
*
* 只能有一個子view,否則,視圖將加載錯亂
* 僅支持縱軸過度滑動
*
* @author mnlin
*/
class OverScrollContainer : ViewGroup {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
}
如代碼註釋描述,該控件只支持縱軸
方向的滾動,只能有一個Child
。
二、 定義可使用的屬性
在初始階段,我們定義的屬性會簡單一些,只要可以滿足基本的需要就好。
縱軸滾動有兩種方式:向上、向下
那麼對應的,我們需要暴露以下的基本屬性:
<!--彈性 佈局 距離-->
<declare-styleable name="OverScrollContainer">
<!--彈性滾動頂部的距離-->
<attr name="overScrollDimen_top" format="dimension"/>
<!--彈性滾動底部的距離-->
<attr name="overScrollDimen_bottom" format="dimension"/>
<!--超出滾動部分的顏色-->
<attr name="overScroll_bg_color" format="color"/>
<!--頂部過度滾動效果-->
<attr name="enable_top" format="boolean"/>
<!--底部過度滾動效果-->
<attr name="enable_bottom" format="boolean"/>
</declare-styleable>
這樣,在使用時,就可以根據說明,輕易的配置控件顯示效果
接下來我們需要考慮,怎麼來使用這些屬性;
毋庸置疑的是,這些屬性都將作用於OverScrollContainer
控件,如果我們定義的是View控件
,而非ViewGroup
,那就沒的商量,只要把這些 屬性在xml佈局中,<OverScrollContainer>
標籤上配置一下就好。但對於一個ViewGroup來說,爲了使用這些屬性,一般都會定義自己的LayoutParams
,通過LayoutParams
來處理效果的顯示
就像FrameLayout
一樣:
/**
* Per-child layout information for layouts that support margins.
* See {@link android.R.styleable#FrameLayout_Layout FrameLayout Layout Attributes}
* for a list of all child view attributes that this class supports.
*
* @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
*/
public static class LayoutParams extends MarginLayoutParams {
/**
* Value for {@link #gravity} indicating that a gravity has not been
* explicitly specified.
*/
public static final int UNSPECIFIED_GRAVITY = -1;
/**
* The gravity to apply with the View to which these layout parameters
* are associated.
* <p>
* The default value is {@link #UNSPECIFIED_GRAVITY}, which is treated
* by FrameLayout as {@code Gravity.TOP | Gravity.START}.
*
* @see android.view.Gravity
* @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
*/
public int gravity = UNSPECIFIED_GRAVITY;
public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
super(c, attrs);
final TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.FrameLayout_Layout);
gravity = a.getInt(R.styleable.FrameLayout_Layout_layout_gravity, UNSPECIFIED_GRAVITY);
a.recycle();
}
public LayoutParams(int width, int height) {
super(width, height);
}
/**
* Creates a new set of layout parameters with the specified width, height
* and weight.
*
* @param width the width, either {@link #MATCH_PARENT},
* {@link #WRAP_CONTENT} or a fixed size in pixels
* @param height the height, either {@link #MATCH_PARENT},
* {@link #WRAP_CONTENT} or a fixed size in pixels
* @param gravity the gravity
*
* @see android.view.Gravity
*/
public LayoutParams(int width, int height, int gravity) {
super(width, height);
this.gravity = gravity;
}
public LayoutParams(@NonNull ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(@NonNull ViewGroup.MarginLayoutParams source) {
super(source);
}
/**
* Copy constructor. Clones the width, height, margin values, and
* gravity of the source.
*
* @param source The layout params to copy from.
*/
public LayoutParams(@NonNull LayoutParams source) {
super(source);
this.gravity = source.gravity;
}
}
這樣一來,在FrameLayout
佈局中,子View
只需要指定gravity
,就可以調整自己在父佈局中的顯示效果。
更重要的是,使用LayoutParams
的話,將來想要添加一些新的屬性時,會方便的多。
我們仿照FrameLayout
,來實現OverScrollContainer
對應的LayoutParams
:
/**
* 自定義layoutParams,便於實現自定義的屬性
*/
class LayoutParams : ViewGroup.MarginLayoutParams {
/**
* over-scroll的距離
*/
var overScrollDimenTop: Int = 96
var overScrollDimenBottom: Int = 96
/**
* 是否可以回彈
*/
var topEnable = true
var bottomEnable = true
/**
* 滾動後留存的背景顏色
*/
var bgColor = 0
var bgDrawable: Drawable = ColorDrawable(Color.TRANSPARENT)
constructor(c: Context, attrs: AttributeSet?) : super(c, attrs) {
val a = c.obtainStyledAttributes(attrs, R.styleable.OverScrollContainer)
overScrollDimenTop = a.getDimensionPixelSize(R.styleable.OverScrollContainer_overScrollDimen_top, 96)
overScrollDimenBottom = a.getDimensionPixelSize(R.styleable.OverScrollContainer_overScrollDimen_bottom, 96)
topEnable = a.getBoolean(R.styleable.OverScrollContainer_enable_top, true)
bottomEnable = a.getBoolean(R.styleable.OverScrollContainer_enable_bottom, true)
bgColor = a.getColor(R.styleable.OverScrollContainer_overScroll_bg_color, 0)
bgDrawable = ColorDrawable(bgColor)
a.recycle()
}
constructor(width: Int, height: Int) : super(width, height)
constructor(source: ViewGroup.LayoutParams) : super(source)
constructor(source: ViewGroup.MarginLayoutParams) : super(source)
constructor(source: OverScrollContainer.LayoutParams) : super(source) {
overScrollDimenTop = source.overScrollDimenTop
overScrollDimenBottom = source.overScrollDimenBottom
topEnable = source.topEnable
bottomEnable = source.bottomEnable
bgColor = source.bgColor
bgDrawable = source.bgDrawable
}
}
然後在自定義的 ViewGroup
中,重寫 LayoutParams
的生成方法:
override fun generateDefaultLayoutParams(): OverScrollContainer.LayoutParams {
return OverScrollContainer.LayoutParams(MATCH_PARENT, MATCH_PARENT)
}
override fun generateLayoutParams(attrs: AttributeSet): OverScrollContainer.LayoutParams {
return OverScrollContainer.LayoutParams(context, attrs)
}
override fun generateLayoutParams(lp: ViewGroup.LayoutParams): ViewGroup.LayoutParams {
if (lp is OverScrollContainer.LayoutParams) {
return OverScrollContainer.LayoutParams(lp)
} else if (lp is ViewGroup.MarginLayoutParams) {
return OverScrollContainer.LayoutParams(lp)
}
return OverScrollContainer.LayoutParams(lp)
}
三、自定義 measure 處理
前面也說了,在初期,我們規定該佈局只能管理一個可滾動的View(或者ViewGroup),因此,measure
時,只需要看一下第一個佈局的寬高,然後讓自身寬高等於子佈局的寬高即可:
/**
* 測量子view高度
*/
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (childCount == 1) {
//自身尺寸遵循唯一子佈局的尺寸
val child = getChildAt(0)
val lp = child.layoutParams as LayoutParams
measureChild(child, widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(child.measuredWidth + lp.marginStart + lp.marginEnd + paddingStart + paddingEnd,
child.measuredHeight + lp.topMargin + lp.bottomMargin + paddingTop + paddingBottom)
} else {
setMeasuredDimension(0, 0)
}
}
這裏設定自身的寬爲:child.measuredWidth + lp.marginStart + lp.marginEnd + paddingStart + paddingEnd
設定自身高爲:child.measuredHeight + lp.topMargin + lp.bottomMargin + paddingTop + paddingBottom
當子佈局不存在或者超過一個,那麼自身寬高皆爲 0 ,將不會顯示出來
四、自定義 layout 處理
在 measure
之後,我們確定一下唯一子view
的上下左右位置。
/**
* 規範子view的座標位置
*/
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
val childCount = childCount
if (childCount == 1) {
val child = getChildAt(0)
val lp = child.layoutParams as LayoutParams
val left_p = lp.marginStart + paddingStart
val top_p = lp.topMargin + paddingTop
val right_p = left_p + child.measuredWidth
val bottom_p = top_p + child.measuredHeight
child.layout(left_p, top_p, right_p, bottom_p)
} else {
//當子佈局不存在,或者超過一個,則不進行正常佈局
//setFrame(0,0,0,0);
}
}
同樣的,我們也考慮了padding
與margin
對佈局造成的影響
五、自定義 draw 處理
在處理draw
流程時,需要考慮ScrollX
與ScrollY
對佈局造成的影響,同時,需要繪製出滾動顯示的背景,以及自定義添加的一些文字提示,因此首先定義一些局部變量:
/**
* 手指按下的座標
* 當前的座標
*/
private var down_y: Float = 0.toFloat()
private var current_y: Float = 0.toFloat()
/**
* 控制器
*/
private var controlListener: ControlInterceptListener? = null
/**
* 文字畫筆
*/
private var singlePaint = TextPaint().also {
it.textSize = 28.toFloat()
it.color = Color.RED
}
/**
* 平滑滾動控制
*/
private val singleScroller = Scroller(this.context)
然後根據 scrollY
來繪製背景,scrollY
實際是指該方法的返回值:
/**
* Return the scrolled top position of this view. This is the top edge of
* the displayed part of your view. You do not need to draw any pixels above
* it, since those are outside of the frame of your view on screen.
*
* @return The top edge of the displayed part of your view, in pixels.
*/
public final int getScrollY() {
return mScrollY;
}
根據view的內容滾動原理:
scrollY
小於0時,表示向下滑動手指,頂部出現滾動區域;scrollY
大於0時,表示向上滑動手指;
/**
* 添加頭部的填充內容
*/
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//存在滾動效果時,進行繪製
if (scrollY != 0) {
(getChildAt(0)?.layoutParams as LayoutParams?)?.let { lp ->
//上部過度滾動效果
if (scrollY < 0) {
//繪製默認頂部圖形
lp.bgDrawable.run {
setBounds(lp.marginStart + paddingStart, -lp.overScrollDimenTop, width - lp.marginEnd - paddingEnd, lp.topMargin + paddingTop)
draw(canvas)
}
//繪製文字,保證滑動時,跟隨在最頂部
"你是最棒的!!!".let {
singlePaint.color = Color.argb((-1.0 * scrollY / lp.overScrollDimenTop * 0xFF).toInt(), 0xFF, 0x00, 0x00)
canvas.drawText(it, (width - singlePaint.measureText(it)) / 2, scrollY - singlePaint.fontMetrics.top, singlePaint)
}
}
//下部過度滾動效果
if (scrollY > 0) {
//繪製默認頂部圖形
lp.bgDrawable.run {
setBounds(lp.marginStart + paddingStart, height - lp.bottomMargin - paddingBottom, width - lp.marginEnd - paddingEnd, height + lp.overScrollDimenBottom)
draw(canvas)
}
//繪製文字,保證滑動時,跟隨在最頂部
"我是最棒的!!!".let {
singlePaint.color = Color.argb((1.0 * scrollY / lp.overScrollDimenBottom * 0xFF).toInt(), 0xFF, 0x00, 0x00)
canvas.drawText(it, (width - singlePaint.measureText(it)) / 2, height + scrollY - singlePaint.fontMetrics.bottom, singlePaint)
}
}
}
}
}
六、攔截事件,獲取座標信息
在上面的代碼中,我們使用了 畫筆 singlePaint
等對象,還有一些變量如:手指按壓位置座標
,當前手指座標
等數據,在觸發滑動操作時,是需要考慮在內的,因此需要不斷更新。
當然,還有點擊事件的處理,現在不妨考慮的簡單一些:所有發生在 OverScrollContainer
上的滑動事件,都會被攔截進行處理。
爲了靈活性,我們還向外部提供一個接口,可以控制是否可以攔截事件,不設置監聽器的的話默認的話,默認事件會被OverScrollContainer
攔截
/**
* 判斷是否可以攔截事件
*/
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
down_y = ev.y
}
}
//在滾動時,指定所有父佈局不能攔截自身的點擊事件
return if (ev.action == MotionEvent.ACTION_MOVE
&& childCount != 0
&& (getChildAt(0).layoutParams as LayoutParams).let { it.bottomEnable or it.topEnable }
&& controlListener?.canIntercept(ev) != false) {
var temp_parent = parent ?: null
while (temp_parent != null) {
parent.requestDisallowInterceptTouchEvent(true)
temp_parent = temp_parent.parent ?: null
}
true
} else {
false
}
}
/**
* 處理滑動邏輯
*/
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_MOVE -> {
current_y = event.y
val result = (down_y - current_y).toInt()
(getChildAt(0)?.layoutParams as LayoutParams?)?.let { lp ->
//判斷當前是否可以滑動
when {
result < 0 && lp.topEnable && lp.overScrollDimenTop > 0 -> lp.overScrollDimenTop
result > 0 && lp.bottomEnable && lp.overScrollDimenBottom > 0 -> lp.overScrollDimenBottom
else -> null
}?.let {
scrollTo(0, if (Math.abs(result) > it) result / Math.abs(result) * it else result)
}
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
//迴歸原來位置,平滑滾動
singleScroller.startScroll(scrollX, scrollY, -scrollX, -scrollY, 500)
invalidate()
}
}
return true
}
然後重寫computeScroll
方法,保證可以緩慢滑動:
/**
* smooth-scroll
*/
override fun computeScroll() {
super.computeScroll()
//判斷動畫是否完成
if (singleScroller.computeScrollOffset()) {
scrollTo(singleScroller.currX, singleScroller.currY)
//通知重繪
invalidate()
}
}
ControlInterceptListener
接口代碼爲:
/**
* function : 控制OverScrollContainer是否可以攔截事件
*
* Created on 2018/10/15 17:44
* @author mnlin
*/
public interface ControlInterceptListener {
/**
* 是否可以攔截
*
* @return true表示可以(但實際情況可能並不會去攔截)
*/
default boolean canIntercept(MotionEvent me){
return true;
}
}
這樣一來,就可以完成一個簡單的回彈效果,效果如下:
在這基礎上,還可以添加一些可以修改字體顏色的屬性,或者屏蔽水平豎直滾動的比例來判斷,當前滾動發生的方向等等
七、佈局文件與類文件
最後貼出使用的xml佈局,以及源碼
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.example.test.tv.test_view.wrapper.OverScrollContainer
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="20dp"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="16dp"
android:background="#5500FFFF"
android:paddingBottom="14dp"
android:paddingEnd="10dp"
android:paddingStart="16dp"
android:paddingTop="20dp">
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_margin="10dp"
android:gravity="center"
android:src="#22FF4081"
android:text="456123"
android:textSize="20sp"
app:enable_bottom="true"
app:enable_top="true"
app:overScrollDimen_bottom="48dp"
app:overScrollDimen_top="48dp"
app:overScroll_bg_color="#55aa00aa"/>
</com.example.test.tv.test_view.wrapper.OverScrollContainer>
</LinearLayout>
</ScrollView>
OverScrollContainer
源碼:
/**
* function : 包裹容器;用於在view外部形成一個可以over-scroll的視圖
*
*
* 只能有一個子view,否則,視圖將加載錯亂
* 僅支持縱軸過度滑動
*/
class OverScrollContainer : ViewGroup {
/**
* 手指按下的座標
* 當前的座標
*/
private var down_y: Float = 0.toFloat()
private var current_y: Float = 0.toFloat()
/**
* 控制器
*/
private var controlListener: ControlInterceptListener? = null
/**
* 文字畫筆
*/
private var singlePaint = TextPaint().also {
it.textSize = 28.toFloat()
it.color = Color.RED
}
/**
* 平滑滾動控制
*/
private val singleScroller = Scroller(this.context)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
/**
* 判斷是否可以攔截事件
*/
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
down_y = ev.y
}
}
//在滾動時,指定所有父佈局不能攔截自身的點擊事件
return if (ev.action == MotionEvent.ACTION_MOVE
&& childCount != 0
&& (getChildAt(0).layoutParams as LayoutParams).let { it.bottomEnable or it.topEnable }
&& controlListener?.canIntercept(ev) != false) {
var temp_parent = parent ?: null
while (temp_parent != null) {
parent.requestDisallowInterceptTouchEvent(true)
temp_parent = temp_parent.parent ?: null
}
true
} else {
false
}
}
/**
* 處理滑動邏輯
*/
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_MOVE -> {
current_y = event.y
val result = (down_y - current_y).toInt()
(getChildAt(0)?.layoutParams as LayoutParams?)?.let { lp ->
//判斷當前是否可以滑動
when {
result < 0 && lp.topEnable && lp.overScrollDimenTop > 0 -> lp.overScrollDimenTop
result > 0 && lp.bottomEnable && lp.overScrollDimenBottom > 0 -> lp.overScrollDimenBottom
else -> null
}?.let {
scrollTo(0, if (Math.abs(result) > it) result / Math.abs(result) * it else result)
}
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
//迴歸原來位置,平滑滾動
singleScroller.startScroll(scrollX, scrollY, -scrollX, -scrollY, 500)
invalidate()
}
}
return true
}
/**
* smooth-scroll
*/
override fun computeScroll() {
super.computeScroll()
//判斷動畫是否完成
if (singleScroller.computeScrollOffset()) {
scrollTo(singleScroller.currX, singleScroller.currY)
//通知重繪
invalidate()
}
}
/**
* 測量子view高度
*/
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (childCount == 1) {
//自身尺寸遵循唯一子佈局的尺寸
val child = getChildAt(0)
val lp = child.layoutParams as LayoutParams
measureChild(child, widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(child.measuredWidth + lp.marginStart + lp.marginEnd + paddingStart + paddingEnd,
child.measuredHeight + lp.topMargin + lp.bottomMargin + paddingTop + paddingBottom)
} else {
setMeasuredDimension(0, 0)
}
}
/**
* 規範子view的座標位置
*/
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
val childCount = childCount
if (childCount == 1) {
val child = getChildAt(0)
val lp = child.layoutParams as LayoutParams
val left_p = lp.marginStart + paddingStart
val top_p = lp.topMargin + paddingTop
val right_p = left_p + child.measuredWidth
val bottom_p = top_p + child.measuredHeight
child.layout(left_p, top_p, right_p, bottom_p)
} else {
//當子佈局不存在,或者超過一個,則不進行正常佈局
//setFrame(0,0,0,0);
}
}
/**
* 添加頭部的填充內容
*/
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//存在滾動效果時,進行繪製
if (scrollY != 0) {
(getChildAt(0)?.layoutParams as LayoutParams?)?.let { lp ->
//上部過度滾動效果
if (scrollY < 0) {
//繪製默認頂部圖形
lp.bgDrawable.run {
setBounds(lp.marginStart + paddingStart, -lp.overScrollDimenTop, width - lp.marginEnd - paddingEnd, lp.topMargin + paddingTop)
draw(canvas)
}
//繪製文字,保證滑動時,跟隨在最頂部
"你是最棒的!!!".let {
singlePaint.color = Color.argb((-1.0 * scrollY / lp.overScrollDimenTop * 0xFF).toInt(), 0xFF, 0x00, 0x00)
canvas.drawText(it, (width - singlePaint.measureText(it)) / 2, scrollY - singlePaint.fontMetrics.top, singlePaint)
}
}
//下部過度滾動效果
if (scrollY > 0) {
//繪製默認頂部圖形
lp.bgDrawable.run {
setBounds(lp.marginStart + paddingStart, height - lp.bottomMargin - paddingBottom, width - lp.marginEnd - paddingEnd, height + lp.overScrollDimenBottom)
draw(canvas)
}
//繪製文字,保證滑動時,跟隨在最頂部
"我是最棒的!!!".let {
singlePaint.color = Color.argb((1.0 * scrollY / lp.overScrollDimenBottom * 0xFF).toInt(), 0xFF, 0x00, 0x00)
canvas.drawText(it, (width - singlePaint.measureText(it)) / 2, height + scrollY - singlePaint.fontMetrics.bottom, singlePaint)
}
}
}
}
}
/**
* 添加控制器,可以根據子佈局的狀態來控制OverScrollContainer是否可以滑動
*/
fun setControlInterceptListener(listener: ControlInterceptListener?) {
this.controlListener = listener
}
override fun generateDefaultLayoutParams(): OverScrollContainer.LayoutParams {
return OverScrollContainer.LayoutParams(MATCH_PARENT, MATCH_PARENT)
}
override fun generateLayoutParams(attrs: AttributeSet): OverScrollContainer.LayoutParams {
return OverScrollContainer.LayoutParams(context, attrs)
}
override fun generateLayoutParams(lp: ViewGroup.LayoutParams): ViewGroup.LayoutParams {
if (lp is OverScrollContainer.LayoutParams) {
return OverScrollContainer.LayoutParams(lp)
} else if (lp is ViewGroup.MarginLayoutParams) {
return OverScrollContainer.LayoutParams(lp)
}
return OverScrollContainer.LayoutParams(lp)
}
/**
* 自定義layoutParams,便於實現自定義的屬性
*/
class LayoutParams : ViewGroup.MarginLayoutParams {
/**
* over-scroll的距離
*/
var overScrollDimenTop: Int = 96
var overScrollDimenBottom: Int = 96
/**
* 是否可以回彈
*/
var topEnable = true
var bottomEnable = true
/**
* 滾動後留存的背景顏色
*/
var bgColor = 0
var bgDrawable: Drawable = ColorDrawable(Color.TRANSPARENT)
constructor(c: Context, attrs: AttributeSet?) : super(c, attrs) {
val a = c.obtainStyledAttributes(attrs, R.styleable.OverScrollContainer)
overScrollDimenTop = a.getDimensionPixelSize(R.styleable.OverScrollContainer_overScrollDimen_top, 96)
overScrollDimenBottom = a.getDimensionPixelSize(R.styleable.OverScrollContainer_overScrollDimen_bottom, 96)
topEnable = a.getBoolean(R.styleable.OverScrollContainer_enable_top, true)
bottomEnable = a.getBoolean(R.styleable.OverScrollContainer_enable_bottom, true)
bgColor = a.getColor(R.styleable.OverScrollContainer_overScroll_bg_color, 0)
bgDrawable = ColorDrawable(bgColor)
a.recycle()
}
constructor(width: Int, height: Int) : super(width, height)
constructor(source: ViewGroup.LayoutParams) : super(source)
constructor(source: ViewGroup.MarginLayoutParams) : super(source)
constructor(source: OverScrollContainer.LayoutParams) : super(source) {
overScrollDimenTop = source.overScrollDimenTop
overScrollDimenBottom = source.overScrollDimenBottom
topEnable = source.topEnable
bottomEnable = source.bottomEnable
bgColor = source.bgColor
bgDrawable = source.bgDrawable
}
}
}