-
效果展示:用图片看不见特别大的效果,实际效果就是当你用手往下拖拉的时候,上面的热气球部分会往下拉伸,在你的手指松开的时候就会回弹到原来的位置。
-
思路:创建一个HeadZoomScrollView继承ScrollView,用这个自定义SrocllView来包裹布局文件中的组件。给HeadScrollView写上监听事件,首先要监听在加载完布局文件时,获取目标控件,也就是拉伸的控件,这里我写的是头部的背景,还要监听滑动事件,滑动的时候拉伸目标控件,松手的时候,用属性动画回弹。
-
步骤:
-
首先是创建空的Activity和对应的布局文件。
-
接着是创建view包,在包中创建HeadZoomScrolllView继承自ScrollView,代码如下:
-
package com.example.framework.View;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import com.example.framework.utils.LogUtils;
/**
* Created By LicaiWen
* To DO:
*/
public class HeadZoomScrollView extends ScrollView {
// 操控的view
private View mZoomView;
private int mZoomViewWidth;
private int mZoomViewHeight;
//是否滑动
private boolean isScrolling = false;
// 第一次按下的位置
private float firstPosition;
// 滑动系数
private float mScrollrate = 0.3f;
// 回弹系数
private float mReplyRate = 0.5f;
//构造函数
public HeadZoomScrollView(Context context) {
super(context);
}
public HeadZoomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HeadZoomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//在加载完布局的时候调用,获取头部的view(操控的view)
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//getChildAt(0)为LinearLayout
if (getChildAt(0) != null) {
ViewGroup vg = (ViewGroup) getChildAt(0);
//vg.getChildAt(0)为RalativeLayout (操控的view)
if (vg.getChildAt(0) != null) {
mZoomView = vg.getChildAt(0);
}
}
}
// 监听滑动事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mZoomViewHeight <= 0 || mZoomViewWidth <= 0) {
mZoomViewWidth = mZoomView.getMeasuredWidth();
mZoomViewHeight = mZoomView.getMeasuredHeight();
}
switch (ev.getAction()) {
//当滑动的时候
case MotionEvent.ACTION_MOVE:
//第一次的时候还没有滑动,isScrolling默认为false
if (!isScrolling) {
if (getScrollY() == 0) {//再次验证还没滑动
//获取手指点下时的位置
firstPosition = ev.getY();
} else {
break;
}
}
//计算缩放值
int distance = (int) ((ev.getY() - firstPosition) * mScrollrate);
if (distance < 0) {
break;
}
isScrolling = true;
setZoomView(distance);
break;
case MotionEvent.ACTION_UP:
isScrolling = false;
replyZoomView();
break;
//回弹动画
}
return super.dispatchTouchEvent(ev);
}
//回弹动画的方法
private void replyZoomView() {
//要用属性动画
//计算下拉的缩放值再让属性动画根据这个值复原
int distance = mZoomView.getMeasuredWidth() - mZoomViewWidth;
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(distance, 0).setDuration((long) (distance * mReplyRate));//属性动画从distance到distance为0
//监听变化
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
//animation.getAnimatedValue()为变化的distance
public void onAnimationUpdate(ValueAnimator animation) {
setZoomView((Float) animation.getAnimatedValue());
}
});
valueAnimator.start();
}
private void setZoomView(float distance) {
if (mZoomViewHeight <= 0 || mZoomViewWidth <= 0) {
return;
}
ViewGroup.LayoutParams lp = mZoomView.getLayoutParams();
lp.width = (int) (mZoomViewWidth + distance);
//lp.height=lp.width/mZoomViewWidth*mZoomViewHeight;注意高不能这样写,得到的结果都是不变的;
// LogUtils.i("lpHeight:"+lp.width/mZoomViewWidth*mZoomViewHeight);
lp.height = (int) (mZoomViewHeight * ((mZoomViewWidth + distance) / mZoomViewWidth));
//LogUtils.i("真"+lp.height );
//setMargins(-(lp.width-mZoomViewWidth)/2,0,0,0)方法是设置视图到父视图的边距
//要将lp强转为MarginLayoutParams才能使用这个方法
//左边距为放大的宽减去原本的宽除以2,位于中间的组件的左右位置才不会改变
((MarginLayoutParams) lp).setMargins(-(lp.width - mZoomViewWidth) / 2, 0, 0, 0);
mZoomView.setLayoutParams(lp);
}
}
- 接着写布局文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<com.example.framework.View.HeadZoomScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/white"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="240dp">
<ImageView
android:background="@drawable/img_me_bg"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ImageView>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/iv_me_photo"
android:src="@drawable/ic_launcher2"
android:layout_centerInParent="true"
android:layout_width="100dp"
android:layout_height="100dp"
app:civ_border_width="1dp"
app:civ_border_color="@android:color/white">
</de.hdodenhof.circleimageview.CircleImageView>
<TextView
android:id="@+id/tv_me_nickname"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:layout_alignParentBottom="true"
android:text="昵称"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</RelativeLayout>
<!--个人信息,新朋友,隐私设置,分享,设置-->
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--个人信息-->
<LinearLayout
android:id="@+id/ll_me_userinfo"
android:gravity="center_vertical"
android:background="@android:color/white"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:src="@drawable/img_user_info_icon"
android:layout_width="25dp"
android:layout_height="25dp">
</ImageView>
<TextView
android:textColor="@android:color/black"
android:layout_marginLeft="15dp"
android:text="个人信息"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<ImageView
android:src="@drawable/img_right_arrow"
android:layout_width="20dp"
android:layout_height="20dp">
</ImageView>
</LinearLayout>
<!--新朋友-->
<LinearLayout
android:id="@+id/ll_me_newfriend"
android:gravity="center_vertical"
android:background="@android:color/white"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:src="@drawable/img_new_firend_icon"
android:layout_width="25dp"
android:layout_height="25dp">
</ImageView>
<TextView
android:textColor="@android:color/black"
android:layout_marginLeft="15dp"
android:text="新朋友"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<ImageView
android:src="@drawable/img_right_arrow"
android:layout_width="20dp"
android:layout_height="20dp"/>
</LinearLayout>
<!--隐私设置-->
<LinearLayout
android:id="@+id/ll_me_privite"
android:gravity="center_vertical"
android:background="@android:color/white"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:src="@drawable/img_private_setting"
android:layout_width="25dp"
android:layout_height="25dp">
</ImageView>
<TextView
android:textColor="@android:color/black"
android:layout_marginLeft="15dp"
android:text="隐私设置"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<ImageView
android:src="@drawable/img_right_arrow"
android:layout_width="20dp"
android:layout_height="20dp"/>
</LinearLayout>
<!--分享-->
<LinearLayout
android:id="@+id/ll_me_share"
android:gravity="center_vertical"
android:background="@android:color/white"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:src="@drawable/img_share_icon"
android:layout_width="25dp"
android:layout_height="25dp">
</ImageView>
<TextView
android:textColor="@android:color/black"
android:layout_marginLeft="15dp"
android:text="分享"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<ImageView
android:src="@drawable/img_right_arrow"
android:layout_width="20dp"
android:layout_height="20dp"/>
</LinearLayout>
<!--设置-->
<LinearLayout
android:id="@+id/ll_me_stting"
android:gravity="center_vertical"
android:background="@android:color/white"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:src="@drawable/img_setting_icon"
android:layout_width="25dp"
android:layout_height="25dp">
</ImageView>
<TextView
android:textColor="@android:color/black"
android:layout_marginLeft="15dp"
android:text="设置"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<ImageView
android:src="@drawable/img_right_arrow"
android:layout_width="20dp"
android:layout_height="20dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.example.framework.View.HeadZoomScrollView>
布局效果: