您的位置:首页 > 移动开发 > Android开发

Android 自定义水平滚动的容器

2016-04-24 22:42 417 查看
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);
}

}


布局文件

<?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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: