仿QQ空间可拉伸头部特效

Tags
先上效果图:
notion image

1、自定义控件

注意点:
  1. 这里引用一个xml文件做为listview的headerView, LayoutInflater. inflate()的时候,注意最后的root为null,而不是this,以防addHeaderView时出问题
  1. 初始化defaultScaleHeight时,需要先手动调用measure()方法,否则高度为0
  1. 监听overScrollBy(),下拉过度时,放大scaleView
  1. 监听onScrollChanged(),scleView被放大了,且正在往上推时,缩小scaleView
  1. 有一种特殊情况要注意:当放大后的scaleView.height+listview.height=屏幕高度时,再往上推时,会触发上拉过度,而不会调用onScrollChanged中的缩小方法,此时需要处理下
  1. 监听onTouchEvent(),松手后,开始恢复默认状态的动画
package com.che.overlistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ListView;

/**
 * 仿QQ空间可拉伸头部特效
 * <p>
 * 作者:余天然 on 16/9/14 下午10:25
 */
public class OverListView extends ListView {

    private View headerView;//头部视图
    private View scaleView;//可拉伸视图
    private View rotateView;//可旋转视图
    private int defaultScaleHeight = 0;//可拉伸视图的默认高度

    public OverListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        headerView = LayoutInflater.from(context).inflate(R.layout.view_header, null);
        scaleView = headerView.findViewById(R.id.iv_header);
        rotateView = headerView.findViewById(R.id.iv_icon);
        addHeaderView(headerView);

        //手动调用测量方法
        scaleView.measure(0, 0);
        //调用measure方法之后才能获取宽高,否则的话getMeasuredHeight()=0
        defaultScaleHeight = scaleView.getMeasuredHeight();
    }

    /**
     * 过度滑动
     * <p>
     * 注意:deltaX与deltaY与坐标系方向相反!!!
     *
     * @param deltaX         水平增量(-右拉过度,+左拉过度)
     * @param deltaY         竖直增量(-下拉过度,+上拉过度)
     * @param scrollX
     * @param scrollY
     * @param scrollRangeX
     * @param scrollRangeY
     * @param maxOverScrollX
     * @param maxOverScrollY
     * @param isTouchEvent
     * @return
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        //下拉过度时
        if (deltaY < 0) {
            //放大scaleView
            scaleView.getLayoutParams().height = scaleView.getHeight() - deltaY;
            scaleView.requestLayout();
            rotateView.setRotation(rotateView.getRotation() - deltaY);
        

2.控件的使用

看,是不是完全就和普通的ListView一样呀!
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        OverListView lv = (OverListView) findViewById(R.id.lv);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, getData());
        lv.setAdapter(adapter);
    }

    private List<String> getData() {
        List<String> data = new ArrayList<>();
        data.add("有心课堂");
        data.add("动脑学院");
        data.add("慕课网");
        data.add("极客学院");
        data.add("菜鸟教程");
        data.add("InfoQ");
        data.add("NewImport");
        data.add("Android开发中文站");
        data.add("泡在网上的日子");
        return data;
    }
}

3.依赖的资源

R.layout.view_header:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv_header"
        android:layout_width="match_parent"
        android:layout_height="@dimen/header_height"
        android:scaleType="centerCrop"
        android:src="@drawable/header"/>

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/iv_header"
        android:layout_margin="10dp"
        android:scaleType="centerCrop"
        android:src="@drawable/icon"/>

</RelativeLayout>
R.layout.activity_main:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.che.overlistview.OverListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>
最后,奉上源码,欢迎拍砖!

© fishyer 2022 - 2023