Android自訂View—滑動控制項

來源:互聯網
上載者:User

MainActivity如下:<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHByZSBjbGFzcz0="brush:java;">package cc.testview4;import cc.testview4.SlideView.SwitchChangedListener;import android.app.Activity;import android.os.Bundle;/** * Demo描述: * 自訂滑動控制項 * * 參考資料: * http://blog.csdn.net/lfdfhl/article/details/8195441 * * 備忘說明: * 在CopyOfSlideView中使用了另外一種方式: * 主要涉及到自訂控制項的Touch和GestureDetector的處理 * 詳細代碼請參見SlideView是一種很好的方式和思路!!! * 該方式中有一點點點(很微小)BUG參見其中代碼的第71行 */public class MainActivity extends Activity {private SlideView mSlideView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();}private void init(){mSlideView=(SlideView) findViewById(R.id.slideView);mSlideView.setSwitchChangedListener(new SwitchChangedListenerImpl());}private class SwitchChangedListenerImpl implements SwitchChangedListener{@Overridepublic void OnChanged(String info) {System.out.println("info="+info);}}}


SlideView如下:

package cc.testview4;import android.content.Context;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;import android.widget.RelativeLayout;public class SlideView extends RelativeLayout{private SwitchChangedListener mSwitchChangedListener;private Context mContext;private View mSlideView;private int dotRawLeft;private int dotRawRight;private int dotRawTop;private int dotRawBottom;private int downX;private int downY;private int dotCurrentLeft;private int dotCurrentRight;private int dotCurrentTop;private int dotCurrentBottom;// 中間圓球    private ImageView mDotImageView;// 上一步private ImageView mPreStepImageView;// 下一步private ImageView mNextStepImageView;// 上一步箭頭線private ImageView mPreArrowImageView;// 下一步箭頭線private ImageView mNextArrowImageView;// 上一步箭頭的左邊相對於parent左邊的位置private int preArrowLeft;private int preArrowWidth;// 上一步箭頭的右邊相對於parent左邊的位置private int preArrowRight;// 下一步箭頭的左邊相對於parent左邊的位置private int nextArrowLeft;// 下一步箭頭的右邊相對於parent左邊的位置private int nextArrowWidth;private int nextArrowRight;public SlideView(Context context) {super(context);init(context);}public SlideView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}private void init(Context context){mContext=context;LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);mSlideView = inflater.inflate(R.layout.slideview, this);mDotImageView = (ImageView) mSlideView.findViewById(R.id.dotImageView);mPreStepImageView = (ImageView) mSlideView.findViewById(R.id.preStepImageView);mNextStepImageView = (ImageView) mSlideView.findViewById(R.id.nextStepImageView);mNextArrowImageView = (ImageView) mSlideView.findViewById(R.id.nextArrowImageView);mPreArrowImageView = (ImageView) mSlideView.findViewById(R.id.preArrowImageView);this.getRawLocation();// 自訂群組件添加觸摸監聽事件mDotImageView.setOnTouchListener(new TouchListenerImpl());}//利用Post方式擷取一些位置座標private void getRawLocation(){mNextArrowImageView.post(new Runnable() {@Overridepublic void run() {dotRawLeft = mDotImageView.getLeft();dotRawRight = mDotImageView.getRight();dotRawTop = mDotImageView.getTop();dotRawBottom = mDotImageView.getBottom();preArrowWidth=mPreArrowImageView.getWidth();nextArrowWidth=mNextArrowImageView.getWidth();}});}private class TouchListenerImpl implements OnTouchListener{@Overridepublic boolean onTouch(View view, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:downX = (int) event.getRawX();downY = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE://手指向左滑動,dx<0//手指向右滑動,dx>0int distanceX =(int)event.getRawX() - downX;//移動的距離int distanceY =(int)event.getRawY() - downY;//移動的距離//防止越界if (distanceX<0) {if (Math.abs(distanceX)>=preArrowWidth) {distanceX=-preArrowWidth;}} else {if (distanceX>=nextArrowWidth) {distanceX=nextArrowWidth;}}dotCurrentLeft= dotRawLeft + distanceX;dotCurrentRight = dotRawRight + distanceX;System.out.println("dotCurrentLeft="+dotCurrentLeft+",dotCurrentRight="+dotCurrentRight);if (distanceX<0&&Math.abs(distanceX)==preArrowWidth) {mSwitchChangedListener.OnChanged("上一步");}if (distanceX>0&&distanceX==nextArrowWidth) {mSwitchChangedListener.OnChanged("下一步");}mDotImageView.layout(dotCurrentLeft, dotRawTop, dotCurrentRight,dotRawBottom);    break;case MotionEvent.ACTION_UP:mDotImageView.layout(dotRawLeft, dotRawTop, dotRawRight,dotRawBottom);break;default:break;}return true;}   }// 回調介面public interface SwitchChangedListener {public void OnChanged(String info);}public void setSwitchChangedListener(SwitchChangedListener switchChangedListener) {        this.mSwitchChangedListener=switchChangedListener;}}

CopyOfSlideView如下:

package cc.testview4;import android.content.Context;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.Toast;public class CopyOfSlideView extends RelativeLayout{private SwitchChangedListener mSwitchChangedListener;private Context mContext;private View mSlideView;private int dotRawLeft;private int dotRawRight;private int dotRawTop;private int dotRawBottom;// 中間圓球    private ImageView mDotImageView;// 上一步private ImageView mPreStepImageView;// 下一步private ImageView mNextStepImageView;// 上一步箭頭線private ImageView mPreArrowImageView;// 下一步箭頭線private ImageView mNextArrowImageView;// 上一步箭頭的左邊相對於parent左邊的位置private int preArrowLeft;// 上一步箭頭的右邊相對於parent左邊的位置private int preArrowRight;// 下一步箭頭的左邊相對於parent左邊的位置private int nextArrowLeft;// 下一步箭頭的右邊相對於parent左邊的位置private int nextArrowRight;// 在X軸上一共移動的距離private int sliddingSumX = 0;private RelativeLayout mSlideViewRelativeLayout;private GestureDetector mGestureDetector;private SlideViewGestureListener mSlideViewGestureListener;public CopyOfSlideView(Context context) {super(context);init(context);}public CopyOfSlideView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}private void init(Context context){mContext=context;LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);mSlideView = inflater.inflate(R.layout.slideview, this);mDotImageView = (ImageView) mSlideView.findViewById(R.id.dotImageView);mPreStepImageView = (ImageView) mSlideView.findViewById(R.id.preStepImageView);mNextStepImageView = (ImageView) mSlideView.findViewById(R.id.nextStepImageView);mNextArrowImageView = (ImageView) mSlideView.findViewById(R.id.nextArrowImageView);mPreArrowImageView = (ImageView) mSlideView.findViewById(R.id.preArrowImageView);mSlideViewRelativeLayout = (RelativeLayout) findViewById(R.id.slideView_RelativeLayout);this.getRawLocation();mSlideViewGestureListener = new SlideViewGestureListener();mGestureDetector = new GestureDetector(mContext,mSlideViewGestureListener);// 自訂群組件添加觸摸監聽事件// 利用以下一句是對整個自訂控制項實現了Touch監聽,滑塊滑動時正常mSlideView.setOnTouchListener(new TouchListenerImpl());// 利用以下一句是對滑塊實現了Touch監聽,滑塊滑動時有抖動現象,原因不明待查//mDotImageView.setOnTouchListener(new TouchListenerImpl());}//利用Post方式擷取一些位置座標private void getRawLocation(){mNextArrowImageView.post(new Runnable() {@Overridepublic void run() {dotRawLeft = mDotImageView.getLeft();dotRawRight = mDotImageView.getRight();dotRawTop = mDotImageView.getTop();dotRawBottom = mDotImageView.getBottom();preArrowLeft = mPreArrowImageView.getLeft();preArrowRight = mPreArrowImageView.getRight();nextArrowLeft = mNextArrowImageView.getLeft();nextArrowRight = mNextArrowImageView.getRight();}});}private class TouchListenerImpl implements OnTouchListener{@Overridepublic boolean onTouch(View view, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_UP:// 滑動距離小於五分之四,回到原位if (Math.abs(sliddingSumX) < (preArrowRight - preArrowLeft) * 4 / 5) {mDotImageView.layout(dotRawLeft, dotRawTop, dotRawRight,dotRawBottom);sliddingSumX = 0;} else {if (mDotImageView.getLeft() < dotRawLeft) {Toast.makeText(mContext, "上一步", 0).show();mSwitchChangedListener.OnChanged("到達了上一步");mDotImageView.layout(dotRawLeft, dotRawTop,dotRawRight, dotRawBottom);sliddingSumX = 0;} else {Toast.makeText(mContext, "下一步", 0).show();mSwitchChangedListener.OnChanged("到達了下一步");mDotImageView.layout(dotRawLeft, dotRawTop,dotRawRight, dotRawBottom);sliddingSumX = 0;}}break;default:break;}/** * 注意: * 在OnTouchListener中把move和down事件處理都轉交給了mGestureDetector. * 在OnTouchListener中只處理了up事件---在手指抬起後顯示dotImageView. */return mGestureDetector.onTouchEvent(event);}   }// 自訂控制項的手勢// 注意:在相應的方法中返回true,表示已經消費完事件private class SlideViewGestureListener implements GestureDetector.OnGestureListener {@Overridepublic boolean onDown(MotionEvent e) {return true;}// 在自訂控制項滑動時候執行此方法@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {sliddingSumX = sliddingSumX + (int) distanceX;// 再次顯示dotImageView時只需要改變X軸方向的值// 往左拉動,X增大;往右拉動,x減小// 注意:往右拉動,distanceX為負值;往左拉動,distanceX為正值.// 所以不是:rawLeft+sumX, rawTop, rawRight+sumX, rawBottom// 而應該是:rawLeft-sumX, rawTop, rawRight-sumX, rawBottomif (dotRawLeft - sliddingSumX >= (preArrowLeft - (mDotImageView.getWidth() * 0.5))&& dotRawRight - sliddingSumX <= nextArrowRight+ ((mDotImageView.getWidth() * 0.5))) {System.out.println("==> distanceX="+distanceX+",sliddingSumX="+sliddingSumX);mDotImageView.layout(dotRawLeft - sliddingSumX, dotRawTop,dotRawRight - sliddingSumX, dotRawBottom);} else {System.out.println("超過了兩頭的邊界");}return true;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}}// 回調介面public interface SwitchChangedListener {public void OnChanged(String info);}public void setSwitchChangedListener(SwitchChangedListener switchChangedListener) {        this.mSwitchChangedListener=switchChangedListener;}}


main.xml如下:

    


slideview.xml如下:

                    


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.