ScrollView增加标题并且控制显示和隐藏

来源:互联网 发布:大数据功能ppt 编辑:程序博客网 时间:2024/05/17 01:07

我们知道XLIstview有上拉刷新和下拉加载,现在模拟一下XlistView的下拉刷新,使Scroller也有标题,通过滑动控制标题的显示和隐藏.

我们先来看一下效果:




首先创建标题View

scroller_header.xml

[java] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="@android:color/darker_gray">  
  6.   
  7.     <TextView  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="100dp"  
  10.         android:gravity="center_vertical"  
  11.         android:text="我是第一个孩子"  
  12.         android:textSize="25sp" />  
  13. </LinearLayout>  

自定义标题控件

[java] view plaincopy
  1. public class ScrollHeader extends LinearLayout {  
  2.     private LinearLayout mContainer;  
  3.     private Context mContext;  
  4.   
  5.     public ScrollHeader(Context context, AttributeSet attrs) {  
  6.         super(context, attrs);  
  7.         mContext = context;  
  8.         initView();  
  9.     }  
  10.   
  11.     private void initView() {  
  12.         // 初始情况  
  13.         LayoutParams lp = new LayoutParams(  
  14.                 android.view.ViewGroup.LayoutParams.FILL_PARENT, 0);  
  15.         mContainer = (LinearLayout) LayoutInflater.from(mContext).inflate(  
  16.                 R.layout.scroller_header, null);  
  17.   
  18.         addView(mContainer, lp);  
  19.         setGravity(Gravity.BOTTOM);  
  20.     }  
  21.   
  22.   
  23.     /** 
  24.      * 设置显示的高度 
  25.      * 
  26.      * @param height 
  27.      */  
  28.     public void setVisiableHeight(int height) {  
  29.         if (height < 0)  
  30.             height = 0;  
  31.         LayoutParams lp = (LayoutParams) mContainer  
  32.                 .getLayoutParams();  
  33.         lp.height = height;  
  34.         mContainer.setLayoutParams(lp);  
  35.     }  
  36.   
  37.     /** 
  38.      * 获取显示的高度 
  39.      * 
  40.      * @return 
  41.      */  
  42.     public int getVisiableHeight() {  
  43.         return mContainer.getHeight();  
  44.     }  
  45. }  

开始默认设置mContainer的高度为0,就是默认的不显示, 

setVisiableHeight动态设置标题的高度

getVisiableHeight获取标题的高度


activity_main.xml

[html] view plaincopy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:orientation="vertical">  
  5.   
  6.     <com.example.yang.listviewtitle.view.MyScrollView  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="match_parent">  
  9.   
  10.         <LinearLayout  
  11.             android:layout_width="match_parent"  
  12.             android:layout_height="match_parent"  
  13.             android:orientation="vertical">  
  14.   
  15.             <com.example.yang.listviewtitle.view.ScrollHeader  
  16.                 android:layout_width="match_parent"  
  17.                 android:layout_height="wrap_content" />  
  18.   
  19.             <TextView  
  20.                 android:layout_width="match_parent"  
  21.                 android:layout_height="100dp"  
  22.                 android:layout_marginBottom="10dp"  
  23.                 android:background="@android:color/holo_blue_dark"  
  24.                 android:gravity="center_vertical"  
  25.                 android:padding="10dp"  
  26.                 android:text="我是第2个孩子" />  
  27.   
  28.             <TextView  
  29.                 android:layout_width="match_parent"  
  30.                 android:layout_height="100dp"  
  31.                 android:layout_marginBottom="10dp"  
  32.                 android:background="@android:color/holo_blue_dark"  
  33.                 android:gravity="center_vertical"  
  34.                 android:padding="10dp"  
  35.                 android:text="我是第3个孩子" />  
  36.   
  37.             <TextView  
  38.                 android:layout_width="match_parent"  
  39.                 android:layout_height="100dp"  
  40.                 android:layout_marginBottom="10dp"  
  41.                 android:background="@android:color/holo_blue_dark"  
  42.                 android:gravity="center_vertical"  
  43.                 android:padding="10dp"  
  44.                 android:text="我是第4个孩子" />  
  45.   
  46.             <TextView  
  47.                 android:layout_width="match_parent"  
  48.                 android:layout_height="100dp"  
  49.                 android:layout_marginBottom="10dp"  
  50.                 android:background="@android:color/holo_blue_dark"  
  51.                 android:gravity="center_vertical"  
  52.                 android:padding="10dp"  
  53.                 android:text="我是第5个孩子" />  
  54.   
  55.             <TextView  
  56.                 android:layout_width="match_parent"  
  57.                 android:layout_height="100dp"  
  58.                 android:layout_marginBottom="10dp"  
  59.                 android:background="@android:color/holo_blue_dark"  
  60.                 android:gravity="center_vertical"  
  61.                 android:padding="10dp"  
  62.                 android:text="我是第6个孩子" />  
  63.   
  64.             <TextView  
  65.                 android:layout_width="match_parent"  
  66.                 android:layout_height="100dp"  
  67.                 android:layout_marginBottom="10dp"  
  68.                 android:background="@android:color/holo_blue_dark"  
  69.                 android:gravity="center_vertical"  
  70.                 android:padding="10dp"  
  71.                 android:text="我是第7个孩子" />  
  72.   
  73.             <TextView  
  74.                 android:layout_width="match_parent"  
  75.                 android:layout_height="100dp"  
  76.                 android:layout_marginBottom="10dp"  
  77.                 android:background="@android:color/holo_blue_dark"  
  78.                 android:gravity="center_vertical"  
  79.                 android:padding="10dp"  
  80.                 android:text="我是第8个孩子" />  
  81.   
  82.             <TextView  
  83.                 android:layout_width="match_parent"  
  84.                 android:layout_height="100dp"  
  85.                 android:layout_marginBottom="10dp"  
  86.                 android:background="@android:color/holo_blue_dark"  
  87.                 android:gravity="center_vertical"  
  88.                 android:padding="10dp"  
  89.                 android:text="我是第9个孩子" />  
  90.   
  91.             <TextView  
  92.                 android:layout_width="match_parent"  
  93.                 android:layout_height="100dp"  
  94.                 android:layout_marginBottom="10dp"  
  95.                 android:background="@android:color/holo_blue_dark"  
  96.                 android:gravity="center_vertical"  
  97.                 android:padding="10dp"  
  98.                 android:text="我是第10个孩子" />  
  99.   
  100.         </LinearLayout>  
  101.   
  102.   
  103.     </com.example.yang.listviewtitle.view.MyScrollView>  
  104.   
  105. </LinearLayout>  

这里面使用了自定义的ScrollerView和在自定义的ScrollerView中使用了自定义的标题,这里要注意的是:

1.MyScrllerView的子View是Linearlayout,如果要换成其他的布局,要在代码中做相应的改变

2.要把自定义的标题作为MyScrllerView子View的第一个子View. 


自定义MyScrollerView

[java] view plaincopy
  1. public class MyScrollView extends ScrollView {  
  2.     private ScrollHeader mHeader;  
  3.     private float mLastY = -1;  
  4.     private Context mContext;  
  5.     private int MAX_VISI_HEIGHT;  
  6.     private Scroller mScroller;  
  7.   
  8.     public MyScrollView(Context context, AttributeSet attrs) {  
  9.         super(context, attrs);  
  10.         mContext = context;  
  11.         MAX_VISI_HEIGHT = getScreenHeight() / 3;  
  12.         mScroller = new Scroller(context, new DecelerateInterpolator());  
  13.   
  14.     }  
  15.   
  16.     @Override  
  17.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  18.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  19.         //获取Scroller的第一个孩子,就是包裹所有孩子的View  
  20.         LinearLayout firstLL = (LinearLayout) getChildAt(0);  
  21.         mHeader = (ScrollHeader) firstLL.getChildAt(0);  
  22.     }  
  23.   
  24.     @Override  
  25.     protected void onDraw(Canvas canvas) {  
  26.         super.onDraw(canvas);  
  27.   
  28.     }  
  29.   
  30.     @Override  
  31.     public boolean onTouchEvent(MotionEvent ev) {  
  32.         if (mLastY == -1) {  
  33.             mLastY = ev.getRawY();  
  34.         }  
  35.         switch (ev.getAction()) {  
  36.             case MotionEvent.ACTION_DOWN:  
  37.                 mLastY = ev.getRawY();  
  38.                 break;  
  39.             case MotionEvent.ACTION_MOVE:  
  40.                 final float deltaY = ev.getRawY() - mLastY;  
  41.                 mLastY = ev.getRawY();  
  42.                 if (deltaY > 0) {  
  43.                     int height = mHeader.getVisiableHeight();  
  44.                     if (MAX_VISI_HEIGHT > height) {  
  45.                         //更新header高度  
  46.                         mHeader.setVisiableHeight((int) deltaY + height);  
  47.                     }  
  48.   
  49.                 }  
  50.   
  51.                 break;  
  52.             case MotionEvent.ACTION_UP:  
  53.                 Log.d("MyScrollerView""MOVE_UP");  
  54.                 if (mHeader.getVisiableHeight() > 0) {  
  55.                     resetHeaderHeight();  
  56.                 }  
  57.   
  58.   
  59.                 break;  
  60.         }  
  61.         return super.onTouchEvent(ev);  
  62.     }  
  63.   
  64.     /** 
  65.      * 获取屏幕的高度 
  66.      * 
  67.      * @return 
  68.      */  
  69.     private int getScreenHeight() {  
  70.         WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);  
  71.         DisplayMetrics displayMetrics = new DisplayMetrics();  
  72.         windowManager.getDefaultDisplay().getMetrics(displayMetrics);  
  73.         return displayMetrics.heightPixels;  
  74.     }  
  75.   
  76.     private void resetHeaderHeight() {  
  77.         int height = mHeader.getVisiableHeight();  
  78.         Log.d("MyScrollerView""移动的高度:" + (0 - height));  
  79.         mScroller.startScroll(0, height, 00 - height,  
  80.                 400);  
  81.         invalidate();  
  82.     }  
  83.   
  84.     @Override  
  85.     public void computeScroll() {  
  86.         if (mScroller.computeScrollOffset()) {  
  87.             mHeader.setVisiableHeight(mScroller.getCurrY());  
  88.             postInvalidate();  
  89.         }  
  90.         super.computeScroll();  
  91.     }  
  92. }  

设计思路:

1.获取到不局文件中的标题View

2.通过监听滑动ScrllerView手势,如果是向下拉,那么计算出滑动的距离,

3.讲滑动的距离来移动标题View

4.当手离开了屏幕,那么使用Scroller来平移标题View到初始的位置


在onMeasure中获取要操作的标题View

[java] view plaincopy
  1. //获取Scroller的第一个孩子,就是包裹所有孩子的View  
  2.         LinearLayout firstLL = (LinearLayout) getChildAt(0);  
  3.         mHeader = (ScrollHeader) firstLL.getChildAt(0);  
在onTouchEvent的MotionEvent.MOVE_MOVE中计算出滑动的具体,动态设置标题View的高度

在onTouchEvent的MotionEvent.MOVE_UP:设置标题的回到初始的位置

[java] view plaincopy
  1. mScroller.startScroll(0, height, 00 - height,  
  2.                400);  
  3.        invalidate();  

在computeScroll()方法中动态的设置标题View的高度,否则就不会有平移的效果.

[java] view plaincopy
  1. @Override  
  2.     public void computeScroll() {  
  3.         if (mScroller.computeScrollOffset()) {  
  4.             mHeader.setVisiableHeight(mScroller.getCurrY());  
  5.             postInvalidate();  
  6.         }  
  7.         super.computeScroll();  
  8.     }  

滑动距离的判断:不能操作屏幕的三分之一的高度,这个高度可以根据需求来改变

回弹的时间:现在设置的400毫秒,这个时间可以根据需求来改变.

最主要的标题的显示:需更改变,只需更改scroller_header.xml布局.

到此效果已经实现.


demo下载:Eclipse下载,studio下载

2 0
原创粉丝点击