android自定义横竖双向滚动,Android开发实现自定义水平滚动的容器示例

皇甫雨华
2023-12-01

Android开发实现自定义水平滚动的容器示例

发布时间:2020-09-12 01:25:56

来源:脚本之家

阅读:71

作者:CharlinGod

本文实例讲述了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, attrs, 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(), 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()此方法会触发下面的方法

*/

@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, 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;

}

});

}

}

/**

* 位移计算工具类

*

* @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);

}

}

布局文件

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

android:id="@+id/radiogroup"

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

android:id="@+id/body_layout"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

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

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

 类似资料: