可拉伸头部控件

来源:互联网 发布:湖北省软件行业协会 编辑:程序博客网 时间:2024/05/18 00:29
可拉伸头部控件
原理:滑动时设置包含背景控件的大小。

自定义属性: values>attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="TractionScrollView">        <attr name="bg" format="reference" />        <attr name="head" format="reference" />        <attr name="body" format="reference" />    </declare-styleable></resources>


 自定义 View
package com.adevil.ui.HeadScrollView;import android.animation.ObjectAnimator;import android.animation.PropertyValuesHolder;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.ScrollView;import com.adevil.ui.R;/** * 自定义View 头部可拉伸ScrollView * 思路:头部一个RelativeLayout,放一个ImageView和头部控件(用户添加) * 拉伸时放大ImageView,移动头部控件 * * @author Adevil */public class TractionScrollView extends ScrollView {    private LinearLayout mLinearLayout;// ScrollView只能有一个子节点    private LinearLayout headLinear;    /**     * 头     */    private View headview;    /**     * 身体     */    private View bodyview;    /**     * 是否头部变换     */    private boolean isHeadTractin = false;    private boolean mIsBeingDragged = false;    private int mTouchSlop;    private boolean isScale = false;    private int mheadHeight;    private int mheadWidth;    private Context context;    private float startY;// 拖动时时高度。    private int bg, head, body;//自定义属性,背景,头,身体  资源ID    private int topmargin;//头部topmargin    public TractionScrollView(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;        final ViewConfiguration configuration = ViewConfiguration.get(getContext());        mTouchSlop = configuration.getScaledTouchSlop();        TypedArray t = getContext().obtainStyledAttributes(attrs, R.styleable.TractionScrollView);        bg = t.getResourceId(R.styleable.TractionScrollView_bg, 0);        head = t.getResourceId(R.styleable.TractionScrollView_head, 0);        body = t.getResourceId(R.styleable.TractionScrollView_body, 0);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        /**         * *********         *         * 自定义View onMeasure和onLayout都可能被多次调用,这和包含的子节点相关         * 但是ScrollView只能有一个子节点,所以加上一个判断         *         * ************         * */        if (this.getChildCount() == 0) {            mLinearLayout = new LinearLayout(context);            mLinearLayout.setOrientation(LinearLayout.VERTICAL);            mLinearLayout.setLayoutParams(new LayoutParams(                    LinearLayout.LayoutParams.MATCH_PARENT,                    LinearLayout.LayoutParams.WRAP_CONTENT));            /******************************** 添加头 **********************************************/            headLinear = new LinearLayout(context);            headLinear.setOrientation(LinearLayout.VERTICAL);            headLinear.setLayoutParams(new LayoutParams(                    LinearLayout.LayoutParams.MATCH_PARENT,                    LinearLayout.LayoutParams.WRAP_CONTENT));            headLinear.setBackgroundResource(bg);            headview = LinearLayout.inflate(context, head, null);            headview.setBackgroundColor(getResources().getColor(android.R.color.transparent));            headLinear.addView(headview);            mLinearLayout.addView(headLinear);            /********************************* 添加身体 *********************************************/            bodyview = LinearLayout.inflate(context,body, mLinearLayout);            this.addView(mLinearLayout);        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // TODO Auto-generated method stub        super.onLayout(changed, l, t, r, b);    }    @Override    protected void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        super.onDraw(canvas);    }    /**     * 是否在顶部     */    protected boolean isTop() {        if (this.getScrollY() == 0) {            return true;        }        return false;    }    /**     * 是否在顶部底部     */    protected boolean isBottom() {//    getScrollY()+getHeight()==getChildAt(0).getHeight()//    滑动高度加上ScrollView的显示高度等于整体内容高度        int height = getChildAt(0).getHeight();        if (this.getScrollY() + getHeight() >= height) {            return true;        }        return false;    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        // TODO Auto-generated method stub        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                startY = ev.getY();                mheadHeight = headLinear.getHeight();                mheadWidth = headLinear.getWidth();                topmargin=((LinearLayout.LayoutParams)headview.getLayoutParams()).topMargin;                break;            case MotionEvent.ACTION_UP:                if (isScale) {                    isScale = false;                    changeHead(mheadWidth, mheadHeight,0);                }                mIsBeingDragged = false;                break;            case MotionEvent.ACTION_MOVE:                int delta = (int) (ev.getY() - startY);                if (isTop() && delta > 0) {                    isScale = true;                    int w = (delta + mheadWidth);                    int h = (delta + mheadHeight);                    changeHead(w, h,delta);                    invalidate();                } else {                    if (!isScale) {                        if (mIsBeingDragged) {                            scrollBy(0, -delta);                            startY = (int) ev.getY();                        } else if (Math.abs(delta) > mTouchSlop) {                            mIsBeingDragged = true;                            startY = (int) ev.getY();                            scrollBy(0, -delta);                        }                    }                }                break;            default:                break;        }        return super.onTouchEvent(ev);    }    private void changeHead(int w, int h,int delta) {        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(w, h);        headLinear.setLayoutParams(params);        LinearLayout.LayoutParams params2= (LinearLayout.LayoutParams) headview.getLayoutParams();        params2.topMargin=topmargin+delta;        headview.setLayoutParams(params2);    }}

 布局使用:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tsv="http://schemas.android.com/apk/res/com.adevil.ui"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <com.adevil.ui.HeadScrollView.TractionScrollView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scrollbarStyle="outsideOverlay"        tsv:bg="@mipmap/first"        tsv:head="@layout/test_scrollview_head"        tsv:body="@layout/test_scrollview_body"         >    </com.adevil.ui.HeadScrollView.TractionScrollView></LinearLayout>

运行,完工 。

0 0