Android開發實現自定義水平滾動的容器示例

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

本文例項講述了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);
}
}

佈局檔案


<?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>

更多關於Android相關內容感興趣的讀者可檢視本站專題:《Android基本元件用法總結》、《Android開發入門與進階教程》、《Android佈局layout技巧總結》、《Android檢視View技巧總結》、《Android程式設計之activity操作技巧總結》、《Android資源操作技巧彙總》及《Android控制元件用法總結

希望本文所述對大家Android程式設計有所幫助。

您可能感興趣的文章:

Android使用Recyclerview實現圖片水平自動迴圈滾動效果詳解Android使GridView橫向水平滾動的實現方式Android使用RecyclerView實現水平滾動控制元件Android實現Activity水平和垂直滾動條的方法Android中實現多行、水平滾動的分頁的Gridview例項原始碼android listview 水平滾動和垂直滾動的小例子android水平迴圈滾動控制元件使用詳解

相關文章

Android 開發 最新文章