代码仅为个人笔记,勿喷
关键代码:
----------------------------------------------------------------------------------------------------------------------------------------------------------
1.设置滑动监听
private void setListener() {
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView listView, final int state) {
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// Log.e(TAG,"ACTION_UP");
isFirst = true;
//抬起手指之后
if(isShow){
if(height > Float.valueOf(0.5f*density).intValue() ){//控件高度大于一定高度时,显示全部控件
showHeader(headerLayout,Float.valueOf(99 * density).intValue(),Float.valueOf(1*density).intValue());
}
isShow = false;
}
if(isHide){
if(height < Float.valueOf(99*density).intValue() ){//控件高度小于一定高度时,隐藏全部控件
hideHeader(headerLayout,Float.valueOf(1 * density).intValue(),Float.valueOf(1*density).intValue());
}
isHide = false;
}
break;
case MotionEvent.ACTION_MOVE:
if(isFirst){//记录第一次按下时的y坐标
downY = event.getY();
isFirst = false;
}
moveY = event.getY();
float dur = moveY - downY;
float temp = Math.abs(dur);
if(temp > 1*density){//手指滑动的高度大于每次加减的高度时才触发高度的修改,避免频繁修改,造成控件抖动
Log.e(TAG,"ACTION_MOVE--------------------------->" + dur);
controlHeader(dur);
}
downY = moveY;
break;
}
return false;
}
});
}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
if(i==0){//当listView滑动到最顶端时,显示header控件,有些不自然,需要优化
showHeader(headerLayout, Float.valueOf(99 * density).intValue(), Float.valueOf(1 * density).intValue());
}
}
});
}
2.控制控件显示或隐藏代码
private void controlHeader(float dur) {
height = headerLayout.getHeight();
Log.e(TAG,"height---------->" + height);
//100*density 父控件原始高度
if(dur>0 && height < Float.valueOf(100*density).intValue()){//下,显示
showHeader(headerLayout,height,Float.valueOf(1*density).intValue());
isShow = true;
}
if(dur<0 && height > 0){//上,隐藏
hideHeader(headerLayout, height, Float.valueOf(1 * density).intValue());
isHide = true;
}
}
3.隐藏控件代码及动画
/**
*
* @param view 需要隐藏的控件
* @param height 此控件的高度(dip,非px)
* @param offset 隐藏时每次减少的高度(dip,非px)
*/
private void hideHeader(View view, int height, int offset) {
ViewGroup.LayoutParams params2 = view.getLayoutParams();
params2.height = height - offset;
view.setLayoutParams(params2);
postScaleInAnimation(headerTabLayout, height, params2.height);
postScaleInAnimation(headerTitleLayout, height, params2.height);
}
/**设置缩小动画
* 每次缩小的是父控件,子控件只是设置一个动画
* @param view 需要添加动画的控件
* @param beforeHeight 父控件缩小之前的高度
* @param afterHeight 父控件缩小之后的高度
*/
private void postScaleInAnimation(View view,int beforeHeight,int afterHeight) {
//100*density 父控件原始高度
float fromValue = beforeHeight / (100*density);
float toValue = afterHeight / (100*density);
Log.e(TAG, "缩小比例: " + toValue);
ScaleAnimation myAnimationScaleIn = new ScaleAnimation(fromValue, toValue, fromValue, toValue,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
myAnimationScaleIn.setInterpolator(new LinearInterpolator());
myAnimationScaleIn.setFillAfter(true);
view.startAnimation(myAnimationScaleIn);
}
4.显示控件代码及动画
/**
*
* @param view 需要显示的控件
* @param height 此控件的高度(dip,非px)
* @param offset 显示时每次增加的高度(dip,非px)
*/
private void showHeader(View view,int height,int offset) {
ViewGroup.LayoutParams params1 = view.getLayoutParams();
params1.height = height + offset;
view.setLayoutParams(params1);
postScaleOutAnimation(headerTabLayout,height,params1.height);
postScaleOutAnimation(headerTitleLayout,height,params1.height);
}
/**设置放大动画
* 每次放大的是父控件,子控件只是设置一个动画
* @param view 需要添加动画的控件
* @param beforeHeight 父控件放大之前的高度
* @param afterHeight 父控件放大之后的高度
*/
private void postScaleOutAnimation(View view,int beforeHeight,int afterHeight) {
//100*density 父控件原始高度
float fromValue = beforeHeight / (100*density);
float toValue = afterHeight / (100*density);
Log.e(TAG, "扩大比例: " + toValue);
ScaleAnimation myAnimationScaleOut = new ScaleAnimation(fromValue, toValue, fromValue, toValue,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
myAnimationScaleOut.setInterpolator(new AccelerateInterpolator());
myAnimationScaleOut.setFillAfter(true);
view.startAnimation(myAnimationScaleOut);
}
完整代码(java)
----------------------------------------------------------------------------------------------------------------------------------------------------------
public class MainActivity extends BaseActivity {
private String TAG = "MainActivity";
private ListView listView;
private LinearLayout headerLayout;
private Integer[] data = new Integer[100];
private float density;
private int height;
private LinearLayout headerTabLayout;
private LinearLayout headerTitleLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
density = dm.density;
findView();
setListener();
}
private float downY;
private float moveY;
private boolean isFirst = true;
private void setListener() {
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView listView, final int state) {
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// Log.e(TAG,"ACTION_UP");
isFirst = true;
//抬起手指之后
if(isShow){
if(height > Float.valueOf(0.5f*density).intValue() ){//控件高度大于一定高度时,显示全部控件
showHeader(headerLayout,Float.valueOf(99 * density).intValue(),Float.valueOf(1*density).intValue());
}
isShow = false;
}
if(isHide){
if(height < Float.valueOf(99*density).intValue() ){//控件高度小于一定高度时,隐藏全部控件
hideHeader(headerLayout,Float.valueOf(1 * density).intValue(),Float.valueOf(1*density).intValue());
}
isHide = false;
}
break;
case MotionEvent.ACTION_MOVE:
if(isFirst){//记录第一次按下时的y坐标
downY = event.getY();
isFirst = false;
}
moveY = event.getY();
float dur = moveY - downY;
float temp = Math.abs(dur);
if(temp > 1*density){//手指滑动的高度大于每次加减的高度时才触发高度的修改,避免频繁修改,造成控件抖动
Log.e(TAG,"ACTION_MOVE--------------------------->" + dur);
controlHeader(dur);
}
downY = moveY;
break;
}
return false;
}
});
}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
if(i==0){//当listView滑动到最顶端时,显示header控件,有些不自然,需要优化
showHeader(headerLayout, Float.valueOf(99 * density).intValue(), Float.valueOf(1 * density).intValue());
}
}
});
}
/**
*
* @param view 需要隐藏的控件
* @param height 此控件的高度(dip,非px)
* @param offset 隐藏时每次减少的高度(dip,非px)
*/
private void hideHeader(View view, int height, int offset) {
ViewGroup.LayoutParams params2 = view.getLayoutParams();
params2.height = height - offset;
view.setLayoutParams(params2);
postScaleInAnimation(headerTabLayout, height, params2.height);
postScaleInAnimation(headerTitleLayout, height, params2.height);
}
/**设置缩小动画
* 每次缩小的是父控件,子控件只是设置一个动画
* @param view 需要添加动画的控件
* @param beforeHeight 父控件缩小之前的高度
* @param afterHeight 父控件缩小之后的高度
*/
private void postScaleInAnimation(View view,int beforeHeight,int afterHeight) {
//100*density 父控件原始高度
float fromValue = beforeHeight / (100*density);
float toValue = afterHeight / (100*density);
Log.e(TAG, "缩小比例: " + toValue);
ScaleAnimation myAnimationScaleIn = new ScaleAnimation(fromValue, toValue, fromValue, toValue,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
myAnimationScaleIn.setInterpolator(new LinearInterpolator());
myAnimationScaleIn.setFillAfter(true);
view.startAnimation(myAnimationScaleIn);
}
/**
*
* @param view 需要显示的控件
* @param height 此控件的高度(dip,非px)
* @param offset 显示时每次增加的高度(dip,非px)
*/
private void showHeader(View view,int height,int offset) {
ViewGroup.LayoutParams params1 = view.getLayoutParams();
params1.height = height + offset;
view.setLayoutParams(params1);
postScaleOutAnimation(headerTabLayout,height,params1.height);
postScaleOutAnimation(headerTitleLayout,height,params1.height);
}
/**设置放大动画
* 每次放大的是父控件,子控件只是设置一个动画
* @param view 需要添加动画的控件
* @param beforeHeight 父控件放大之前的高度
* @param afterHeight 父控件放大之后的高度
*/
private void postScaleOutAnimation(View view,int beforeHeight,int afterHeight) {
//100*density 父控件原始高度
float fromValue = beforeHeight / (100*density);
float toValue = afterHeight / (100*density);
Log.e(TAG, "扩大比例: " + toValue);
ScaleAnimation myAnimationScaleOut = new ScaleAnimation(fromValue, toValue, fromValue, toValue,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
myAnimationScaleOut.setInterpolator(new AccelerateInterpolator());
myAnimationScaleOut.setFillAfter(true);
view.startAnimation(myAnimationScaleOut);
}
private boolean isShow = false;
private boolean isHide = false;
private void controlHeader(float dur) {
height = headerLayout.getHeight();
Log.e(TAG,"height---------->" + height);
//100*density 父控件原始高度
if(dur>0 && height < Float.valueOf(100*density).intValue()){//下,显示
showHeader(headerLayout,height,Float.valueOf(1*density).intValue());
isShow = true;
}
if(dur<0 && height > 0){//上,隐藏
hideHeader(headerLayout, height, Float.valueOf(1 * density).intValue());
isHide = true;
}
}
private void findView() {
listView = (ListView) findViewById(R.id.content_list_view);
headerLayout = (LinearLayout) findViewById(R.id.header);
headerTabLayout = (LinearLayout) findViewById(R.id.header_tab_layout);
headerTitleLayout = (LinearLayout) findViewById(R.id.header_title_layout);
findViewById(R.id.tab1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"tab1",Toast.LENGTH_LONG).show();
}
});
findViewById(R.id.tab2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(ScaleDialog.class);
Toast.makeText(MainActivity.this,"tab2",Toast.LENGTH_LONG).show();
}
});
findViewById(R.id.tab3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"tab3",Toast.LENGTH_LONG).show();
}
});
setListView();
}
private void startActivity(Class<?> cls) {
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setClass(MainActivity.this,cls);
startActivity(intent);
}
private void setListView() {
setData();
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,android.R.layout.simple_list_item_1,data);
listView.setAdapter(adapter);
}
private void setData() {
for(int i=0; i<data.length; i++){
data[i] = i;
}
}
}
完整代码(xml文件)
----------------------------------------------------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<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="vertical"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="100dip"
android:orientation="vertical"
android:background="#44ff0000">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:orientation="horizontal"
android:gravity="center"
android:layout_weight="1"
android:background="#4400ff00">
<LinearLayout
android:id="@+id/header_title_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="Header"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:orientation="horizontal"
android:gravity="center"
android:layout_weight="1">
<LinearLayout
android:id="@+id/header_tab_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:paddingBottom="6dip"
android:paddingTop="6dip">
<Button
android:id="@+id/tab1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tab1"/>
<Button
android:id="@+id/tab2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft = "4dip"
android:layout_marginRight="4dip"
android:text="tab2"/>
<Button
android:id="@+id/tab3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tab3"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<ListView
android:id="@+id/content_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
------------------