android 上滑隐藏view,android 手势上下滑动头部自动隐藏View标签

ViewGroup方式写的一个View控件,支持读取子View的表明的属性来表明身份。

效果图:

0f5f226fcce216708de23c2bb291799e.png

代码

/**

* Created by liyang on 2017/3/13.

* 头部自动隐藏控件

*/

public class CollapsingTopBarView extends ViewGroup {

public CollapsingTopBarView(Context context) {

this(context, null);

}

public CollapsingTopBarView(Context context, AttributeSet attrs) {

super(context, attrs);

}

private void initContentView() {

if (contentView == null) return;

contentView.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

pagerTouch = true;

return false;

}

});

}

View collapsingView, contentView;

//执行的位置

int marginHeight;

//移动到最下和最上边的位置

int bottom = 0, top, height;

//记录坐标

float mx, my;

//判断

boolean pagerTouch;

//是否在自动移动中

boolean autoMove = false;

boolean actionMove;

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

boolean f = super.dispatchTouchEvent(ev);

if (!pagerTouch) {

actionMove = ev.getAction() == MotionEvent.ACTION_MOVE;

if (ev.getAction() == MotionEvent.ACTION_DOWN) {

my = ev.getY();

mx = ev.getX();

} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {

if (!pagerTouch) {

float mm = ev.getY() - my;

moveToolbar(mm);

}

my = ev.getY();

mx = ev.getX();

} else {

mx = 0;

my = 0;

if (marginHeight != 0 && Math.abs(marginHeight) != height&&!actionMove) {

autoMove(collapsingView);

}

}

}

pagerTouch = false;

return f;

}

public boolean isTopHide(){

return marginHeight==-height;

}

/**

* 告诉每次移动的距离 来执行移动

*

* @param move

*/

private void moveToolbar(float move) {

//判断是否移动到顶或者到底

if (move > 0 && marginHeight == 0 || move < 0 && marginHeight == -height) {

autoMove = false;

return;

}

//是否在执行回弹下拉动画中

if (inAutoMove) return;

//移动距离不为空

if (move == 0) return;

if (collapsingView.getLayoutParams() != null && collapsingView.getLayoutParams() instanceof LayoutParams) {

LayoutParams layoutParams = (LayoutParams) collapsingView.getLayoutParams();

marginHeight += move;

if (marginHeight > bottom) {

marginHeight = bottom;

} else {

//

marginHeight = Math.abs(marginHeight) >= height ? -height : marginHeight;

}

// layoutParams.setMargins(0, marginHeight, 0, 0);//4个参数按顺序分别是左上右下

layoutParams.setMarginTop(marginHeight);

collapsingView.setLayoutParams(layoutParams);

autoMove = true;

}

}

boolean inAutoMove = false, delayed = true;

/**

* 自动回弹 下拉

*

* @param view

*/

private void autoMove(View view) {

if (delayed) {

delayed = false;

view.postDelayed(new Runnable() {

@Override

public void run() {

inAutoMove = true;

if (autoMove&&!actionMove) {

if (Math.abs(top) - Math.abs(marginHeight) > Math.abs(top) / 2) {

move(true);

} else {

move(false);

}

}

inAutoMove = false;

delayed = true;

}

}, 500);

}

}

MyRunnable autoMoveRunnable;

/**

* 回弹下拉的动画执行

*

* @param up

*/

private void move(boolean up) {

if (autoMoveRunnable == null) {

autoMoveRunnable = new MyRunnable() {

@Override

public void run() {

if (up) {

marginHeight += 4;

} else {

marginHeight -= 4;

}

if (marginHeight >= bottom) {

marginHeight = bottom;

} else if (marginHeight <= top) {

marginHeight = top;

}

// RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);

if (collapsingView.getLayoutParams() != null && collapsingView.getLayoutParams() instanceof LayoutParams) {

LayoutParams layoutParams = (LayoutParams) collapsingView.getLayoutParams();

// layoutParams.setMargins(0, marginHeight, 0, 0);//4个参数按顺序分别是左上右下

// collapsingView.setLayoutParams(layoutParams);

layoutParams.setMarginTop(marginHeight);

collapsingView.setLayoutParams(layoutParams);

}

if (marginHeight == top || marginHeight == bottom) {

autoMove = false;

return;

}

if (autoMove) {

move(up);

}

}

};

}

autoMoveRunnable.setUp(up);

collapsingView.postDelayed(autoMoveRunnable, 10);

}

static class MyRunnable implements Runnable {

boolean up;

public void setUp(boolean up) {

this.up = up;

}

@Override

public void run() {

}

}

@Override

protected void onLayout(boolean b, int l, int i1, int i2, int i3) {

int hg = 0;

int count = getChildCount();

View child;

for (int i = 0; i < count; i++) {

child = getChildAt(i);

if (child.getLayoutParams() instanceof LayoutParams) {

LayoutParams lp = (LayoutParams) child.getLayoutParams();

child.layout(0, hg + lp.getMarginTop(), child.getMeasuredWidth(), hg + child.getMeasuredHeight() + lp.getMarginTop());

hg += child.getMeasuredHeight() + lp.getMarginTop();

// if(child.getLayoutParams() instanceof LayoutParams) {

if (lp.isCollapsing() && this.collapsingView == null) {

this.collapsingView = child;

this.height = child.getMeasuredHeight();

this.top = -this.height;

} else if (lp.isContent() && this.contentView == null) {

this.contentView = child;

initContentView();

}

// }

}

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

measureChildren(widthMeasureSpec, heightMeasureSpec);

}

public static class LayoutParams extends RelativeLayout.LayoutParams {

boolean collapsing, content;

int marginTop;

public int getMarginTop() {

return marginTop;

}

public void setMarginTop(int marginTop) {

this.marginTop = marginTop;

}

public LayoutParams(Context c, AttributeSet attrs) {

super(c, attrs);

TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.collapsing);

collapsing = a.getBoolean(R.styleable.collapsing_collapsing, false);

content = a.getBoolean(R.styleable.collapsing_content, false);

a.recycle();

}

public boolean isCollapsing() {

return collapsing;

}

public boolean isContent() {

return content;

}

public LayoutParams(int width, int height) {

super(width, height);

}

public LayoutParams(ViewGroup.LayoutParams source) {

super(source);

}

}

@Override

protected ViewGroup.LayoutParams generateDefaultLayoutParams() {

return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

}

@Override

protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {

return new LayoutParams(p);

}

@Override

public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {

return new LayoutParams(this.getContext(), attrs);

}

}

dome

只要在使用的地方用该View标签包裹你需要做特殊处理的View即可

注意红色字体的 关键属性 没有指定属性将无法使用

android:orientation="vertical" android:layout_width="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/toolbar1"

app:collapsing="true"

android:layout_width="match_parent"

android:layout_height="50dp"

android:background="@color/colorAccent"

android:gravity="center"

android:text="工具条一">

android:id="@+id/toolbar2"

android:layout_below="@+id/toolbar1"

android:layout_width="match_parent"

android:layout_height="50dp"

android:background="@color/colorPrimary"

android:gravity="center"

android:text="工具条二">

android:layout_below="@+id/toolbar2"

android:id="@+id/ViewPager"

app:content="true"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" />

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值