上代码,下边是核心代码

public class ImitateQQListView extends ListView {    public View mHeaderView;    private int mHeaderHeight;    public View mHeaderTitleView;    public float mMaxScrollY;    public ImitateQQListView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @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) {            //表示下拉,需要改变高度            if (mHeaderView != null) {                mHeaderView.getLayoutParams().height = mHeaderView.getHeight() - deltaY;                mHeaderView.requestLayout();            }        }        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        super.onScrollChanged(l, t, oldl, oldt);        if (t < 0) {            mHeaderView.getLayoutParams().height = mHeaderHeight;            mHeaderView.requestLayout();        }        //获取到listview滚动的y轴距离        if (mHeaderView != null) {            calculationAlpha(mHeaderView.getTop());        }    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        int action = ev.getAction();        switch (action) {            case MotionEvent.ACTION_UP:                //判断头部的高度是否与初始化时候的高度一致,如果不一致则需要执行动画缓慢撤回到原来状态                if (mHeaderHeight != mHeaderView.getHeight()) {                    //执行动画缓慢回到原来位置                    resetHeadViewHeight();                }                break;        }        return super.onTouchEvent(ev);    }    /***     * 执行动画缓慢回到原来状态     * 计算思路:总共多出(mHeaderView.getHeight() - mHeaderHeight)     */    private void resetHeadViewHeight() {        ValueAnimator mValueAnimator = ValueAnimator.ofFloat(1.0f);        mValueAnimator.setDuration(600);        mValueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float value = (float) animation.getAnimatedValue();                //计算高度                mHeaderView.getLayoutParams().height = (int) (mHeaderView.getHeight() - value * (mHeaderView.getHeight() - mHeaderHeight));                mHeaderView.requestLayout();            }        });        mValueAnimator.start();    }    /****     * 根据滚动距离计算alpha值     *     * @param top     */    private void calculationAlpha(int top) {        mHeaderTitleView.setAlpha(Math.abs(1.0f / mMaxScrollY * top));    }    @Override    public void addHeaderView(View v, Object data, boolean isSelectable) {        super.addHeaderView(v, data, isSelectable);        if (mHeaderView == null) {            mHeaderView = v;            mHeaderHeight = v.getMeasuredHeight();            mMaxScrollY = mHeaderHeight - DensityUtil.dip2px(getContext(), 50);        }    }}

然后是mainActivity中的代码

public class QQMainActivity extends Activity {    private Context mContext;    private ImitateQQListView listview;    private List mList;    private FrameLayout id_fl_title;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_qq);        listview = (ImitateQQListView) findViewById(R.id.listview);        id_fl_title = (FrameLayout) findViewById(R.id.id_fl_title);        listview.mHeaderTitleView = id_fl_title;        mContext = getApplicationContext();        mList = new ArrayList<>();        for (int i = 0; i < 20; i++) {            mList.add("哈哈哈,条目" + i);        }        //添加头部布局        LayoutInflater inflater = LayoutInflater.from(this);        View view = inflater.inflate(R.layout.layout_listview_head_imageview, null);        //测量view的高度        measureHeadViewHeight(view);        listview.addHeaderView(view, null, false);        listview.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, mList));    }    /***     * 测量view的高度     *     * @param view     */    private void measureHeadViewHeight(View view) {        AbsListView.LayoutParams params = (AbsListView.LayoutParams) view.getLayoutParams();        if (params == null) {            params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);        }        int width = params.width;        int widthSpec = 0;        if (width <= 0) {            widthSpec = View.MeasureSpec.makeMeasureSpec(DevicesUtils.getScreenWidth(mContext), View.MeasureSpec.EXACTLY);        }        //获取高度        int height = params.height;        int heightMeasureSpec = 0;        if (height <= 0) {            heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(DensityUtil.dip2px(mContext, 220), View.MeasureSpec.EXACTLY);        }        view.measure(widthSpec, heightMeasureSpec);        height = view.getMeasuredHeight();        params.height = height;        view.setLayoutParams(params);    }}

布局也贴上

<?xml version="1.0" encoding="utf-8"?>                    

头部布局

<?xml version="1.0" encoding="utf-8"?>

全部代码都在上边,资源文件可以自己替换.

另外附上写的很好的一篇博客

http://blog.csdn.net/llew2011/article/details/51559694



更多相关文章

  1. android EditText设置不可写
  2. android 使用html5作布局文件: webview跟javascript交互
  3. android studio调试c/c++代码
  4. IM-A820L限制GSM,WCDMA上网的原理(其他泛泰机型可参考)7.13
  5. 锁屏界面
  6. android(NDK+JNI)---Eclipse+CDT+gdb调试android ndk程序
  7. Android(安卓)version and Linux Kernel version
  8. Android(安卓)闹钟管理类的使用
  9. Android学习篇之Menu的使用

随机推荐

  1. Android中的布局管理
  2. Android SDK开发 -- TitleBar重构 (代理模
  3. Android 常用样式设置
  4. Android学习之文件存储
  5. 写在前面
  6. 关于Edittext的一些事情
  7. android EditText 属性
  8. Android设置弹出键盘与View的交互方式[学
  9. Android开发新手学习总结(一)——使用And
  10. 关于华为P10(Android 8.0系统)出现的一个