Android自訂ViewGroup實現受邊界限制的滾動操作(3)_Android

來源:互聯網
上載者:User

上一篇文章《自訂viewgroup(2)》地址:http://www.jb51.net/article/100610.htm

代碼

package com.example.libingyuan.horizontallistview.ScrollViewGroup;import android.content.Context;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.Scroller;/** * 自訂ViewGroup * 在滾動的基礎上,增加了邊界限制 */public class ScrollViewGroup extends ViewGroup { //滾動計算輔助類 private Scroller mScroller; //手指落點的X座標 private float mLastMotionX = 0; //螢幕寬度 private int screenWidth; /**  * 使用new關鍵字建立對象的時候調用  * @param context 上下文  */ public ScrollViewGroup(Context context) {  this(context, null); } /**  * 在XML檔案中使用的時候調用  * @param context 上下文  * @param attrs 屬性:如 android:layout_width="wrap_content"  */ public ScrollViewGroup(Context context, AttributeSet attrs) {  this(context, attrs, 0); } /**  * 在xml檔案中調用,並且使用了自訂屬性的時候調用  * @param context 上下文  * @param attrs 屬性:如 android:layout_width="wrap_content"  * @param defStyleAttr 自訂屬性的id  */ public ScrollViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(context); } /**  * 初始化方法  * 初始化滾動輔助類Scroller以及計算出螢幕寬度  * @param context  */ private void init(Context context) {  mScroller = new Scroller(context);  WindowManager manager = (WindowManager) context    .getSystemService(Context.WINDOW_SERVICE);  DisplayMetrics outMetrics = new DisplayMetrics();  manager.getDefaultDisplay().getMetrics(outMetrics);  screenWidth = outMetrics.widthPixels; } /**  * 滾動時需要重寫的方法,用於控制滾動  */ @Override public void computeScroll() {  //判斷滾動時候停止  if (mScroller.computeScrollOffset()) {   //滾動到指定的位置   scrollTo(mScroller.getCurrX(), mScroller.getCurrY());   //這句話必須寫,否則不能即時重新整理   postInvalidate();  } } /**  * 手指觸屏事件監聽  * @param event  * @return  */ @Override public boolean onTouchEvent(MotionEvent event) {  // TODO Auto-generated method stub  int action = event.getAction();  float x = event.getX();  switch (action) {   case MotionEvent.ACTION_DOWN:    if (!mScroller.isFinished()) {     mScroller.abortAnimation();    }    mLastMotionX = event.getX();    break;   case MotionEvent.ACTION_MOVE:    float delt = mLastMotionX - x;    mLastMotionX = x;    scrollBy((int) delt, 0);    break;   case MotionEvent.ACTION_UP:    View lastChild=getChildAt(getChildCount()-1);    int finalyChild= (int) (lastChild.getX()+lastChild.getWidth()-screenWidth);    if (getScrollX()<0){     scrollTo(0,0);    }    if (getScrollX()>=finalyChild)     scrollTo(finalyChild,0);    invalidate();    break;   default:    break;  }  return true; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  //重新設定寬高  this.setMeasuredDimension(measureWidth(widthMeasureSpec, heightMeasureSpec), measureHeight(widthMeasureSpec, heightMeasureSpec)); }  /**  * 測量寬度  */ private int measureWidth(int widthMeasureSpec, int heightMeasureSpec) {  // 寬度  int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);  int modeWidth = MeasureSpec.getMode(widthMeasureSpec);  //父控制項的寬(wrap_content)  int width = 0;  int childCount = getChildCount();  //重新測量子view的寬度,以及最大高度  for (int i = 0; i < childCount; i++) {   View child = getChildAt(i);   measureChild(child, widthMeasureSpec, heightMeasureSpec);   MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();   int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;   width += childWidth;  }  return modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width; } /**  * 測量高度  */ private int measureHeight(int widthMeasureSpec, int heightMeasureSpec) {  //高度  int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);  int modeHeight = MeasureSpec.getMode(heightMeasureSpec);  //父控制項的高(wrap_content)  int height = 0;  int childCount = getChildCount();  //重新測量子view的寬度,以及最大高度  for (int i = 0; i < childCount; i++) {   View child = getChildAt(i);   measureChild(child, widthMeasureSpec, heightMeasureSpec);   MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();   int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;   height += childHeight;  }  height = height / childCount;  return modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height; } /**  * 給子布局設定位置  */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {  int childLeft = 0;//子View左邊的間距  int childWidth;//子View的寬度  int height = getHeight();//螢幕的寬度  int childCount = getChildCount();//子View的數量  for (int i = 0; i < childCount; i++) {   View child = getChildAt(i);   MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();   childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;   child.layout(childLeft, 0, childLeft + childWidth, height);   childLeft += childWidth;  } } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) {  return new MarginLayoutParams(getContext(), attrs); }}

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.