android打造仿qq控件可拉伸头部控件

该控件大致思路:
1.采用继承listview加入头部view。
2.监听listview滚动。
3.自定义动画回弹。

先看效果吧:
这里写图片描述这里写图片描述

activity-main.xml布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <com.example.headerlistview.HeaderListView
        android:id="@+id/header_lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="1dip"
        android:duplicateParentState="true"
        android:scrollbars="none" >
    </com.example.headerlistview.HeaderListView>

</LinearLayout>

headerview.xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView 
        android:id="@+id/header_image"
        android:layout_width="match_parent"
        android:layout_height="150dip"
        android:scaleType="centerCrop"
        android:src="@drawable/lifei987"
        />

</LinearLayout>

list_item布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dip"
    android:gravity="center_vertical"
    android:orientation="horizontal" >
"

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dip"
        android:layout_marginLeft="10dip"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dip"
            android:text="lifei" />

        <TextView
            android:id="@+id/tv_describe"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dip"
            android:text="lifeiasdfasdfasfsadfasf" />
    </LinearLayout>

</LinearLayout>

activity代码:

package com.example.headerlistview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.os.Bundle;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

    private HeaderListView header_lv;

    private ImageView header_iv;

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


    private void initView() {
        // TODO Auto-generated method stub
        header_lv=(HeaderListView) findViewById(R.id.header_lv);
        header_lv.addHeaderView(getHeaderView());
        header_lv.setHeaderView(header_iv);
        header_lv.setAdapter(getSimpleAdapter());
    }

    public BaseAdapter getSimpleAdapter(){
         List<Map<String, Object>> data=new ArrayList<Map<String,Object>>();
         for(int i=0;i<15;i++){
             Map<String, Object> map=new HashMap<String, Object>();
             map.put("name", "郑州___"+i);
             map.put("describe", "asdfasdfasdfasdfasdfsadfsad");
             data.add(map);
         }

        SimpleAdapter simpleAdapter=new SimpleAdapter(this, data, R.layout.list_item, new String[]{"name","describe"}, new int[]{R.id.tv_name,R.id.tv_describe});
        return simpleAdapter;
    }

    public View getHeaderView(){
        View view= getLayoutInflater().inflate(R.layout.headerview, null);
        header_iv =(ImageView) view.findViewById(R.id.header_image);
        return view;
    }

}

自定义控件HeaderListView:

package com.example.headerlistview;

import java.security.spec.ECField;

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

public class HeaderListView extends ListView {

    private ImageView headerView;

    private int headerView_initHeight;//imageview初始高度

    public void setHeaderView(ImageView headerView) {
        this.headerView = headerView;
    }

    public HeaderListView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public HeaderListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public HeaderListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    /**
     * listview焦点改变时--获取iamgeview高度的初始值,该值不能在构造方法中获取
     */
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasWindowFocus);
        if(hasWindowFocus){
            this.headerView_initHeight=headerView.getHeight();
        }
    }

    @SuppressLint("NewApi") @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
            int scrollY, int scrollRangeX, int scrollRangeY,
            int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        // 滑动过头的时候调用
        boolean bl=resizeHeaderView(deltaY);

        return bl?true:super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
                scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    /**
     * 控制imageview高度的增加
     * @param deltaY    偏移量
     */
    private boolean resizeHeaderView(int deltaY) {
        if(Math.abs((double)deltaY)<200){
            if(deltaY<0){
                headerView.getLayoutParams().height=headerView.getHeight()-deltaY;
                //重新绘制
                headerView.requestLayout();
            }else{
                headerView.getLayoutParams().height=headerView.getHeight()-deltaY;
                headerView.requestLayout();
            }
        }

        return false;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        // TODO Auto-generated method stub
        super.onScrollChanged(l, t, oldl, oldt);
        //获取imageview父控件
        View parent=(View) headerView.getParent();
        //当父控件的top值小于零或者高度大于原始高度时触发
        if(parent.getTop()<0||headerView.getHeight()>headerView_initHeight){
            headerView.getLayoutParams().height=headerView.getHeight()+parent.getTop();
            parent.layout(parent.getLeft(),0, parent.getRight(), parent.getHeight());
            headerView.requestLayout();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        if(ev.getAction()==MotionEvent.ACTION_UP||ev.getAction()==MotionEvent.ACTION_CANCEL){
            MyAnimation animation=new MyAnimation(headerView, headerView_initHeight);
            animation.setDuration(200);
            headerView.startAnimation(animation);
        }
        return super.onTouchEvent(ev);
    }

    public class MyAnimation extends Animation{

        private ImageView header_iv;
        private int currentHeight;
        private int targetHeight;
        private int poorHeight;

        public MyAnimation(ImageView iv,int targetHeight){
            this.header_iv=iv;
            this.targetHeight=targetHeight;
            this.currentHeight=iv.getHeight();
            this.poorHeight=this.currentHeight-this.targetHeight;
        }

        /**
         * 动画执行期间执行该方法,不断执行
         * interpolatedTime:当前时间与duration的时间比(时间执行百分比)
         */
        @Override
        protected void applyTransformation(float interpolatedTime,
                Transformation t) {
            // TODO Auto-generated method stub
            super.applyTransformation(interpolatedTime, t);
            this.header_iv.getLayoutParams().height=(int)(currentHeight-poorHeight*interpolatedTime);
            this.header_iv.requestLayout();
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值