本文实例为大家分享了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(),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();
- }
- }
- }