欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿QQ可拉伸头部控件

程序员文章站 2023-10-31 08:33:58
本文实例为大家分享了android仿qq可拉伸头部控件的具体实现代码,供大家参考,具体内容如下 该控件大致思路: 1.采用继承listview加入头部view。 2.监听lis...

本文实例为大家分享了android仿qq可拉伸头部控件的具体实现代码,供大家参考,具体内容如下

该控件大致思路:

1.采用继承listview加入头部view。
2.监听listview滚动。
3.自定义动画回弹。

先看效果吧:

Android仿QQ可拉伸头部控件

Android仿QQ可拉伸头部控件

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();
 }
 }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。