本文实例为大家分享了Android仿QQ可拉伸头部控件的具体实现代码,供大家参考,具体内容如下
该控件大致思路:
1.采用继承listview加入头部view。
2.监听listview滚动。
3.自定义动画回弹。
先看效果吧:
activity-main.xml布局如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
< 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布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<? 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布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<? 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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
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(); } } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq1377399077/article/details/49513875