In this paper, we share the specific implementation code of Android like QQ stretchable head control for your reference. The specific content is as follows
The general idea of the control is as follows:
1. Add the header view by inheriting listview.
2. Monitor listview scrolling.
3. Custom animation rebound.
Let’s see the effect first
activity- main.xml The layout is as follows:
<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 Layout:
<?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 layout:
<?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 Code:
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, Zhengzhou)___ "+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;
}
}
Custom control 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 initial height
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
}
/**
*When listview focus changes -- gets the initial value of iamview height, which cannot be obtained in the constructor
*/
@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) {
//Called when sliding over the head
boolean bl=resizeHeaderView(deltaY);
return bl?true:super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
/**
*Control the increase of ImageView height
*@ param delta offset
*/
private boolean resizeHeaderView(int deltaY) {
if(Math.abs((double)deltaY)<200){
if(deltaY<0){
headerView.getLayoutParams().height=headerView.getHeight()-deltaY;
//Redraw
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);
//Get ImageView parent control
View parent=(View) headerView.getParent();
//Triggered when the top value of the parent control is less than zero or the height is greater than the original height
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;
}
/**
*The method is executed during the execution of the animation and is executed continuously
*Interpolatedtime: the ratio of current time to duration (time execution percentage)
*/
@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();
}
}
}
The above is the whole content of this article, I hope to help you learn, and I hope you can support developer more.