android 悬浮组件,Android ScrollView Banner悬浮方案

一、滚动过程悬浮

ScrollView悬浮是很常见的用法,之前用过StickScrollView,存在的问题是只是把View图像定位到了顶部,无法处理touch event。这里我们提供一种相对简单的View组件。

二、核心要点

layout方法top设置

bingToFront方法,该方法不会重新布局,但是会改变View层次

三、代码实现

public class FloatScrollView extends ScrollView {

private List mStickView = null;

public FloatScrollView(Context context) {

this(context,null);

}

public FloatScrollView(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public FloatScrollView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

int getRealChildCount(){

int childCount = getChildCount();

if(childCount==0) return 0;

ViewGroup wrapperView = (ViewGroup) getChildAt(0);

if(wrapperView==null) return 0;

return wrapperView.getChildCount();

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

if(!changed) return;

super.onLayout(changed, l, t, r, b);

if(mStickView==null){

mStickView = new ArrayList<>();

}else{

mStickView.clear();

}

int realChildCount = getRealChildCount();

for (int i=0;i

ViewGroup parent = (ViewGroup) getChildAt(0);

View child = parent.getChildAt(i);

Object tag = child.getTag();

if(!(tag instanceof CharSequence)) continue;

if("sticky".equals(tag)){

mStickView.add(new StickView(child));

}

}

}

@Override

protected void onScrollChanged(int sl, int st, int oldsl, int oldst) {

if(mStickView==null){

mStickView = new ArrayList<>();

}

for (int i=0;i

StickView childView = mStickView.get(i);

int offset = childView.srcTop - st;

if(offset>0){

refreshTopOffset(childView.widget,childView.srcTop);

continue;

}

//让前面stickView的回归原始位置

for (int prev=i-1;prev>=0;prev--){

StickView preChildView = mStickView.get(i);

refreshTopOffset(preChildView.widget,preChildView.srcTop);

}

Log.d("FloatScrollView", "offset=" + offset + ", st="+st);

//计算下一个stcikview距离顶部的位置

int nextChildIndex = i+1;

if(nextChildIndex>mStickView.size()-1) {

refreshTopOffset(childView.widget, st);

}else {

StickView nextChildView = mStickView.get(nextChildIndex);

int nextChildOffset = nextChildView.srcTop - st;

if (nextChildOffset > childView.widget.getHeight()) {

refreshTopOffset(childView.widget, st);

} else {

float dx = childView.widget.getHeight() - nextChildOffset;

refreshTopOffset(childView.widget,st-dx);

}

}

}

super.onScrollChanged(sl, st, oldsl, oldst);

}

private void refreshTopOffset(View childView, float offset) {

int topOffset = (int) ( offset);

childView.layout(childView.getLeft(),topOffset,childView.getRight(),topOffset+childView.getHeight());

childView.bringToFront(); //解决被其他view遮挡问题

}

class StickView{

int srcTop;

View widget;

public StickView(View child) {

this.widget = child;

this.srcTop = child.getTop();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值