最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android開發(fā)實(shí)現(xiàn)自定義水平滾動(dòng)的容器示例

 更新時(shí)間:2017年10月18日 09:55:24   作者:CharlinGod  
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)自定義水平滾動(dòng)的容器,涉及Android滾動(dòng)容器的事件響應(yīng)、屬性運(yùn)算與修改相關(guān)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Android開發(fā)實(shí)現(xiàn)自定義水平滾動(dòng)的容器。分享給大家供大家參考,具體如下:

public class HorizontalScrollView extends ViewGroup {
  //手勢(shì)
  private GestureDetector mGestureDetector;
  private HorizontalScroller mScroller;
  private int curID;
  //快速滑動(dòng)
  private boolean isFlying;
  //--回調(diào)函數(shù)-------------------------------------
  private OnChangeListener mListener;
  public void setOnChangeListener(OnChangeListener listener) {
    if (listener != null) {
      mListener = listener;
    }
  }
  public interface OnChangeListener{
    void move2dest(int curID);
  }
  public HorizontalScrollView(Context context) {
    this(context, null);
  }
  public HorizontalScrollView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }
  public HorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mScroller = new HorizontalScroller();
    isFlying = false;
    initGesture(context);
  }
  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    // 模向移動(dòng),
    for (int i = 0; i < getChildCount(); i++) {
      View view = getChildAt(i);
      //給水平方向的每個(gè)view定位
      view.layout(i * getWidth(), 0, getWidth() + i * getWidth(), getHeight());
    }
  }
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    for (int i = 0; i < getChildCount(); i++) {
      View view = getChildAt(i);
      view.measure(widthMeasureSpec, heightMeasureSpec);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    mGestureDetector.onTouchEvent(event);
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      if (!isFlying) {
        move2dest();
      }
      isFlying = false;
      break;
    case MotionEvent.ACTION_MOVE:
      break;
    case MotionEvent.ACTION_UP:
      break;
    default:
      break;
    }
    return true;
  }
  public void move2dest() {
    //
    int destID = (getScrollX() + getWidth() / 2) / getWidth();
    move2dest(destID);
  }
  public void move2dest(int destID) {
    curID = destID;
    if (destID > getChildCount() - 1) {
      destID = getChildCount() - 1;
    }
    if (mListener != null) {
      mListener.move2dest(curID);
    }
    int distance = (int) (destID * getWidth() - getScrollX());
    // scrollBy(distance, 0);
    mScroller.startScroll(getScrollX(), getScrollY(), distance, 0);
    invalidate();
  }
  /**
   * invalidate()此方法會(huì)觸發(fā)下面的方法
   */
  @Override
  public void computeScroll() {
    // 如果存在偏移,就不斷刷新
    if (mScroller.computeScrollOffset()) {
      scrollTo(mScroller.getCurrX(), 0);
      invalidate();
    }
    super.computeScroll();
  }
  private void initGesture(Context context) {
    mGestureDetector = new GestureDetector(context, new OnGestureListener() {
      @Override
      public boolean onSingleTapUp(MotionEvent e) {
        return false;
      }
      @Override
      public void onShowPress(MotionEvent e) {
      }
      @Override
      public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        scrollBy((int) distanceX, 0);
        return false;
      }
      @Override
      public void onLongPress(MotionEvent e) {
      }
      @Override
      /**
       * 快速滑動(dòng)時(shí)
       */
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        isFlying = true;
        if (curID > 0 && velocityX > 0) {// 表示向左移
          move2dest(curID - 1);
        } else if (curID < getChildCount() && velocityX < 0) {
          move2dest(curID + 1);// 向右
        } else {
          move2dest();// 移到原位
        }
        return false;
      }
      @Override
      public boolean onDown(MotionEvent e) {
        return false;
      }
    });
  }
}

/**
 * 位移計(jì)算工具類
 *
 * @author chenlin
 *
 */
public class HorizontalScroller {
  private int startX;
  private int startY;
  private int distanceX;
  private int distanceY;
  private int currentX;
  private int currentY;
  private long startTime;
  private long duration = 1000L;
  private boolean isFinish;
  /**
   *
   * @param scrollX
   *      x坐標(biāo)
   * @param scrollY
   *      y坐標(biāo)
   * @param distanceX
   *      X方向移動(dòng)的距離
   * @param distanceY
   *      y方向移動(dòng)的距離
   */
  public void startScroll(int scrollX, int scrollY, int distanceX, int distanceY) {
    startX = scrollX;
    startY = scrollY;
    this.distanceX = distanceX;
    this.distanceY = distanceY;
    isFinish = false;
    startTime = SystemClock.uptimeMillis();
  }
  /**
   * 計(jì)算偏移量,
   *
   * @return true 還在移動(dòng) false:移動(dòng)已經(jīng)停止
   */
  public boolean computeScrollOffset() {
    if (isFinish) {
      return false;
    }
    long timePassed = SystemClock.uptimeMillis() - startTime;
    if (timePassed < duration) {
      currentX = (int) (startX + distanceX * timePassed / duration);
      currentY = (int) (startY + distanceY * timePassed / duration);
      System.out.println("currentX:::" + currentX);
    } else if (timePassed >= duration) {
      currentX = startX + distanceX;
      currentY = startY + distanceY;
      isFinish = true;
    }
    return true;
  }
  public int getCurrX() {
    return currentX;
  }
  public void setCurrentX(int currentX) {
    this.currentX = currentX;
  }
  public int getCurrentY() {
    return currentY;
  }
  public void setCurrentY(int currentY) {
    this.currentY = currentY;
  }
}

使用方法

public class ScrollActivity extends Activity implements OnCheckedChangeListener, OnChangeListener {
  private int[] ids = { R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6 };
  private HorizontalScrollView mView;
  private LinearLayout mLayout;
  private RadioGroup mGroup;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_myscrollview);
    init();
  }
  private void init() {
    mLayout = (LinearLayout) findViewById(R.id.body_layout);
    mGroup = (RadioGroup) findViewById(R.id.radiogroup);
    mView = new HorizontalScrollView(this);
    for (int i = 0; i < ids.length; i++) {
      ImageView imageView = new ImageView(this);
      imageView.setBackgroundResource(ids[i]);
      mView.addView(imageView);
    }
    mLayout.addView(mView);
    // 隨便添加一個(gè)view
    View view = getLayoutInflater().inflate(R.layout.activity_progressview, null);
    mView.addView(view, 3);
    for (int i = 0; i < mView.getChildCount(); i++) {
      RadioButton radioButton = new RadioButton(this);
      // 設(shè)置id的編號(hào)
      radioButton.setId(i);
      mGroup.setOrientation(LinearLayout.HORIZONTAL);
      mGroup.addView(radioButton);
      if (i == 0) {
        radioButton.setChecked(true);
      }
    }
    mGroup.setOnCheckedChangeListener(this);
    mView.setOnChangeListener(this);
  }
  @Override
  public void onCheckedChanged(RadioGroup group, int checkedId) {
    mView.move2dest(checkedId);
  }
  @Override
  public void move2dest(int curID) {
    RadioButton radioButton = (RadioButton) mGroup.getChildAt(curID);
    radioButton.setChecked(true);
  }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >
  <RadioGroup
    android:id="@+id/radiogroup"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
  </RadioGroup>
  <LinearLayout
    android:id="@+id/body_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
  </LinearLayout>
</LinearLayout>

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android基本組件用法總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android布局layout技巧總結(jié)》、《Android視圖View技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android資源操作技巧匯總》及《Android控件用法總結(jié)

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 往Android系統(tǒng)中添加服務(wù)的方法教程

    往Android系統(tǒng)中添加服務(wù)的方法教程

    最近因?yàn)槠脚_(tái)升級(jí),需要在系統(tǒng)中添加一些服務(wù),所以將整個(gè)過(guò)程總結(jié)一下,下面這篇文章主要給大家介紹了往Android系統(tǒng)中添加服務(wù)的方法教程,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-05-05
  • Android入門之BroadCast模擬實(shí)現(xiàn)異地登錄事件發(fā)生后的主動(dòng)退出

    Android入門之BroadCast模擬實(shí)現(xiàn)異地登錄事件發(fā)生后的主動(dòng)退出

    隨著對(duì)BroadCast的越來(lái)越深入,我們今天要實(shí)現(xiàn)一個(gè)稍微復(fù)雜一點(diǎn)的BroadCast。即只允許一個(gè)設(shè)備登錄一個(gè)帳號(hào)時(shí),APP會(huì)彈一個(gè)對(duì)話框如:您的賬號(hào)在別處登錄,請(qǐng)重新登陸!感興趣的可以了解一下
    2022-12-12
  • Android文件讀寫的幾種方式

    Android文件讀寫的幾種方式

    文件讀寫作為Android四大數(shù)據(jù)存儲(chǔ)方式之一,又分為內(nèi)部存儲(chǔ)和外部存儲(chǔ)兩種,下面這篇文章主要給大家介紹了關(guān)于Android文件讀寫的幾種方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Android開發(fā)懸浮窗踩坑解決

    Android開發(fā)懸浮窗踩坑解決

    這篇文章主要為大家介紹了Android懸浮窗踩坑解決示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • android實(shí)現(xiàn)藍(lán)牙app代碼

    android實(shí)現(xiàn)藍(lán)牙app代碼

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)藍(lán)牙app的代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Fresco加載手機(jī)圖片墻

    Fresco加載手機(jī)圖片墻

    這篇文章主要為大家詳細(xì)介紹了Fresco加載手機(jī)圖片墻,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Android中的Handler與多線程應(yīng)用實(shí)例

    Android中的Handler與多線程應(yīng)用實(shí)例

    這篇文章主要介紹了Android中的Handler與多線程應(yīng)用實(shí)例,本文首先解釋一下handler是用來(lái)干嘛的,然后通過(guò)例子介紹其在多線程中的應(yīng)用,需要的朋友可以參考下
    2015-03-03
  • 詳解Android跨進(jìn)程IPC通信AIDL機(jī)制原理

    詳解Android跨進(jìn)程IPC通信AIDL機(jī)制原理

    本篇文章主要介紹了詳解Android跨進(jìn)程IPC通信AIDL機(jī)制原理,詳細(xì)的介紹了AIDL的概念和使用,具有一定的參考價(jià)值,有興趣的可以了解一下
    2018-01-01
  • android中強(qiáng)制更新app實(shí)例代碼

    android中強(qiáng)制更新app實(shí)例代碼

    本篇文章主要介紹了android中強(qiáng)制更新app實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Android編程基礎(chǔ)之獲取手機(jī)屏幕大小(DisplayMetrics應(yīng)用)示例

    Android編程基礎(chǔ)之獲取手機(jī)屏幕大小(DisplayMetrics應(yīng)用)示例

    這篇文章主要介紹了Android獲取手機(jī)屏幕大小的方法,結(jié)合實(shí)例形式分析了TextView ,Button ,以及DisplayMetrics的使用方法,并重點(diǎn)分析了DisplayMetrics的應(yīng)用技巧,需要的朋友可以參考下
    2016-10-10

最新評(píng)論

漳州市| 武城县| 旅游| 卢龙县| 依安县| 广丰县| 泌阳县| 汝州市| 云和县| 宿迁市| 沈阳市| 巴楚县| 积石山| 南华县| 安吉县| 云和县| 双江| 略阳县| 专栏| 吉隆县| 安西县| 陇川县| 北流市| 桐庐县| 宜川县| 金阳县| 淮南市| 报价| 达州市| 大宁县| 普格县| 二连浩特市| 高青县| 永宁县| 醴陵市| 河西区| 邹城市| 二手房| 浦城县| 水富县| 时尚|