Android實(shí)現(xiàn)View滑動(dòng)的6種方式
本文實(shí)例為大家分享了Android實(shí)現(xiàn)View滑動(dòng)的具體方法,供大家參考,具體內(nèi)容如下
1.View的滑動(dòng)簡(jiǎn)介
View的滑動(dòng)是Android實(shí)現(xiàn)自定義控件的基礎(chǔ),同時(shí)在開發(fā)中我們也難免會(huì)遇到View的滑動(dòng)的處理。其實(shí)不管是那種滑動(dòng)的方式基本思想都是類似的:當(dāng)觸摸事件傳到View時(shí),系統(tǒng)記下觸摸點(diǎn)的坐標(biāo),手指移動(dòng)時(shí)系統(tǒng)記下移動(dòng)后的觸摸的坐標(biāo)并算出偏移量,并通過(guò)偏移量來(lái)修改View的坐標(biāo)。
實(shí)現(xiàn)View滑動(dòng)有很多種方法,這篇文章主要講解六種滑動(dòng)的方法,分別是:layout()、offsetLeftAndRight()與offsetTopAndBottom()、LayoutParams、動(dòng)畫、scollTo與scollBy和Scroller;在下一篇文章我們會(huì)詳細(xì)介紹屬性動(dòng)畫。
2.實(shí)現(xiàn)View滑動(dòng)的六種方法
1.layout()
view進(jìn)行繪制的時(shí)候會(huì)調(diào)用onLayout()方法來(lái)設(shè)置顯示的位置,因此我們同樣也可以通過(guò)修改View的left、top、right、bottom這四種屬性來(lái)控制View的坐標(biāo)。首先我們要自定義一個(gè)View,在onTouchEvent()方法中獲取觸摸點(diǎn)的坐標(biāo):
public boolean onTouchEvent(MotionEvent event) { //獲取到手指處的橫坐標(biāo)和縱坐標(biāo) int X = 0, newX = 0; int Y = 0, newY = 0; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("hahahhaha", "屏幕位置被按下"); X = (int) event.getX(); Y = (int) event.getY(); break;
接下來(lái)我們?cè)贏CTION_MOVE事件中計(jì)算偏移量,再調(diào)用layout()方法重新放置這個(gè)自定義View的位置就好了:
public boolean onTouchEvent(MotionEvent event) { //獲取到手指處的橫坐標(biāo)和縱坐標(biāo) int X = 0, newX = 0; int Y = 0, newY = 0; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("hahahhaha", "屏幕位置被按下"); X = (int) event.getX(); Y = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: Log.d("hahahhaha", "屏幕位置在移動(dòng)"); newX = (int) event.getX(); newY = (int) event.getY(); int offsetX = newX - X; int offsetY = newY - Y; Log.d("hahaha", "offsetX=" + offsetX + ",offsetY=" + offsetY); //1.調(diào)用layout方法來(lái)重新放置它的位置 layout(getLeft()+offsetX, getTop()+offsetY, getRight()+offsetX , getBottom()+offsetY);
當(dāng)我們每次移動(dòng)時(shí)都會(huì)調(diào)用layout()方法來(lái)對(duì)自己重新布局,從而達(dá)到移動(dòng)View的效果。
2.offsetLeftAndRight()與offsetTopAndBottom()
這兩種方法和layout()方法效果方法差不多,使用也差不多,我們將ACTION_MOVE中的代碼替換成如下代碼:
case MotionEvent.ACTION_MOVE: //計(jì)算移動(dòng)的距離 int offsetX = x - lastX; int offsetY = y - lastY; //對(duì)left和right進(jìn)行偏移 offsetLeftAndRight(offsetX); //對(duì)top和bottom進(jìn)行偏移 offsetTopAndBottom(offsetY); break;
3.LayoutParams(改變布局參數(shù))
LayoutParams主要保存了一個(gè)View的布局參數(shù),因此我們可以通過(guò)LayoutParams來(lái)改變View的布局的參數(shù)從而達(dá)到了改變View的位置的效果。同樣的我們將ACTION_MOVE中的代碼替換成如下代碼:
LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) getLayoutParams(); layoutParams.leftMargin = getLeft() + offsetX; layoutParams.topMargin = getTop() + offsetY; setLayoutParams(layoutParams);
因?yàn)楦缚丶荓inearLayout,所以我們用了LinearLayout.LayoutParams,如果父控件是RelativeLayout則要使用RelativeLayout.LayoutParams。除了使用布局的LayoutParams外,我們還可以用ViewGroup.MarginLayoutParams來(lái)實(shí)現(xiàn):
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams(); layoutParams.leftMargin = getLeft() + offsetX; layoutParams.topMargin = getTop() + offsetY; setLayoutParams(layoutParams);
4.scollTo與scollBy
scollTo(x,y)表示移動(dòng)到一個(gè)具體的坐標(biāo)點(diǎn),而scollBy(dx,dy)則表示移動(dòng)的增量為dx、dy。其中scollBy最終也是要調(diào)用scollTo的。scollTo、scollBy移動(dòng)的是View的內(nèi)容,如果在ViewGroup中使用則是移動(dòng)他所有的子View。我們將ACTION_MOVE中的代碼替換成如下代碼:
((View)getParent()).scrollBy(-offsetX,-offsetY);
這里要實(shí)現(xiàn)CustomView隨著我們手指移動(dòng)的效果的話,我們就需要將偏移量設(shè)置為負(fù)值。
5.Scroller
我們用scollTo/scollBy方法來(lái)進(jìn)行滑動(dòng)時(shí),這個(gè)過(guò)程是瞬間完成的,所以用戶體驗(yàn)不大好。這里我們可以使用Scroller來(lái)實(shí)現(xiàn)有過(guò)度效果的滑動(dòng),這個(gè)過(guò)程不是瞬間完成的,而是在一定的時(shí)間間隔完成的。Scroller本身是不能實(shí)現(xiàn)View的滑動(dòng)的,它需要配合View的computeScroll()方法才能彈性滑動(dòng)的效果。
在這里我們實(shí)現(xiàn)CustomView平滑的向右移動(dòng)。
首先我們要初始化Scroller:
public CustomView(Context context, AttributeSet attrs) { super(context, attrs); mScroller = new Scroller(context); }
接下來(lái)重寫computeScroll()方法,系統(tǒng)會(huì)在繪制View的時(shí)候在draw()方法中調(diào)用該方法,這個(gè)方法中我們調(diào)用父類的scrollTo()方法并通過(guò)Scroller來(lái)不斷獲取當(dāng)前的滾動(dòng)值,每滑動(dòng)一小段距離我們就調(diào)用invalidate()方法不斷的進(jìn)行重繪,重繪就會(huì)調(diào)用computeScroll()方法,這樣我們就通過(guò)不斷的移動(dòng)一個(gè)小的距離并連貫起來(lái)就實(shí)現(xiàn)了平滑移動(dòng)的效果:
@Override public void computeScroll() { super.computeScroll(); if(mScroller.computeScrollOffset()){ ((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY()); //通過(guò)不斷的重繪不斷的調(diào)用computeScroll方法 invalidate(); } }
調(diào)用Scroller.startScroll()方法。我們?cè)贑ustomView中寫一個(gè)smoothScrollTo()方法,調(diào)用Scroller.startScroll()方法,在2000毫秒內(nèi)沿X軸平移delta像素:
public void smoothScrollTo(int destX,int destY){ int scrollX=getScrollX(); int delta=destX-scrollX; //1000秒內(nèi)滑向destX mScroller.startScroll(scrollX,0,delta,0,2000); invalidate(); }
最后我們?cè)赩iewSlideActivity.java中調(diào)用CustomView的smoothScrollTo()方法:
//使用Scroll來(lái)進(jìn)行平滑移動(dòng)
mCustomView.smoothScrollTo(-400,0);
這里我們是設(shè)定CustomView沿著X軸向右平移400像素。
6.動(dòng)畫
可以采用View動(dòng)畫來(lái)移動(dòng),在res目錄新建anim文件夾并創(chuàng)建translate.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="300" android:duration="1000"/> </set>
在Java代碼中引用:
mCustomView.setAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));
當(dāng)然使用屬性動(dòng)畫移動(dòng)那就更簡(jiǎn)單了,我們讓CustomView在1000毫秒內(nèi)沿著X軸像右平移300像素:
ObjectAnimator.ofFloat(mCustomView,"translationX",0,300).setDuration(1000).start();
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android中實(shí)現(xiàn)監(jiān)聽(tīng)ScrollView滑動(dòng)事件
- android 通過(guò)向viewpage中添加listview來(lái)完成滑動(dòng)效果(類似于qq滑動(dòng)界面)
- 解析Android中實(shí)現(xiàn)滑動(dòng)翻頁(yè)之ViewFlipper的使用詳解
- Android中實(shí)現(xiàn)水平滑動(dòng)(橫向滑動(dòng))ListView示例
- Android利用ViewPager實(shí)現(xiàn)滑動(dòng)廣告板實(shí)例源碼
- Android App中使用ViewPager+Fragment實(shí)現(xiàn)滑動(dòng)切換效果
- Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼
- android配合viewpager實(shí)現(xiàn)可滑動(dòng)的標(biāo)簽欄示例分享
- Android編程中ViewPage判斷左右滑動(dòng)方向的方法
- Android App中ViewPager所帶來(lái)的滑動(dòng)沖突問(wèn)題解決方法
相關(guān)文章
Android使用Kotlin和RxJava 2.×實(shí)現(xiàn)短信驗(yàn)證碼倒計(jì)時(shí)效果
本篇文章主要介紹了Android使用Kotlin和RxJava 2.×實(shí)現(xiàn)短信驗(yàn)證碼倒計(jì)時(shí)效果,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-12-12Android點(diǎn)擊Button實(shí)現(xiàn)功能的幾種方法總結(jié)
當(dāng)Button有多個(gè)或者Button的使用次數(shù)很多時(shí),我們需要采用綁定監(jiān)聽(tīng)器的做法,其實(shí),綁定監(jiān)聽(tīng)器也有幾種方法,不過(guò),我在這里就不一一列舉了,畢竟那些方法在實(shí)際的應(yīng)用中也不常見(jiàn)2013-10-10Android自定義View實(shí)現(xiàn)鐘擺效果進(jìn)度條PendulumView
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)鐘擺效果進(jìn)度條PendulumView,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Android之沉浸式狀態(tài)欄的實(shí)現(xiàn)方法、狀態(tài)欄透明
本篇文章主要介紹了Android之沉浸式狀態(tài)欄的實(shí)現(xiàn)方法、狀態(tài)欄透明,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-02-02Android中微信搶紅包助手的實(shí)現(xiàn)詳解
本篇文章主要介紹了Android中微信搶紅包助手的實(shí)現(xiàn)詳解,通過(guò)利用AccessibilityService輔助服務(wù),監(jiān)測(cè)屏幕內(nèi)容,如監(jiān)聽(tīng)狀態(tài)欄的信息,屏幕跳轉(zhuǎn)等,以此來(lái)實(shí)現(xiàn)自動(dòng)拆紅包的功能,有興趣的可以了解一下。2017-02-02Android studio button 按鈕 四種綁定事件的方法【實(shí)例代碼】
這篇文章主要介紹了Android studio button 按鈕 四種綁定事件的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08Android實(shí)現(xiàn)語(yǔ)音數(shù)據(jù)實(shí)時(shí)采集、播放
這篇文章主要介紹了android實(shí)現(xiàn)語(yǔ)音數(shù)據(jù)實(shí)時(shí)采集、播放的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-1220行Android代碼寫一個(gè)CircleImageView
這篇文章主要介紹了20行Android代碼寫一個(gè)CircleImageView,制作圓形頭像,感興趣的小伙伴們可以參考一下2016-08-08android view實(shí)現(xiàn)橫向滑動(dòng)選擇
這篇文章主要為大家詳細(xì)介紹了android view實(shí)現(xiàn)橫向滑動(dòng)選擇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07