Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android开发实现自定义水平滚动的容器示例大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

本文实例讲述了Android开发实现自定义水平滚动的容器。分享给大家供大家参,具体如下:

public class horizontalscrollview extends ViewGroup {
  //手势
  private GestureDetector mGestureDetector;
  private HorizontalScroller mScroller;
  privatE int curID;
  //快速滑动
  private Boolean isFlying;
  //--回调函数-------------------------------------
  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,defStylE);
    mScroller = new HorizontalScroller();
    isFlying = false;
    initGesture(context);
  }
  @Override
  protected void onLayout(Boolean changed,int l,int t,int r,int b) {
    // 模向移动,
    for (int i = 0; i < getChildCount(); i++) {
      View view = getChildAt(i);
      //给水平方向的每个view定位
      view.layout(i * getWidth(),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()此方法会触发下面的方法
   */
  @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
      /**
       * 快速滑动时
       */
      public Boolean onFling(MotionEvent e1,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;
      }
    });
  }
}

/**
 * 位移计算工具类
 *
 * @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坐标
   * @param scrollY
   *      y坐标
   * @param distanceX
   *      X方向移动的距离
   * @param distanceY
   *      y方向移动的距离
   */
  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();
  }
  /**
   * 计算偏移量,
   *
   * @return true 还在移动 false:移动已经停止
   */
  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);
    // 随便添加一个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);
      // 设置id的编号
      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://@R_262_10906@mas.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>

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android基本组件用法总结》、《Android开发入门与进阶教程》、《Android布局layout技巧总结》、《Android视图View技巧总结》、《Android编程之activity操作技巧总结》、《Android资源操作技巧汇总》及《Android控件用法总结

希望本文所述对大家Android程序设计有所帮助。

大佬总结

以上是大佬教程为你收集整理的Android开发实现自定义水平滚动的容器示例全部内容,希望文章能够帮你解决Android开发实现自定义水平滚动的容器示例所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:容器