版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用SlideListView自定義View
Android中怎么利用SlideListView自定義View,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面在下將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。主要用到了Scroller這個滑動類,剛開始攔截觸摸事件在action==MotionEvent.ACTION_DOWN的時候,根據(jù)出點獲取我們點擊的itemView然后根據(jù)滑動模式(左滑動or右滑動)來自動獲取左側(cè)或者右側(cè)的寬度;在action==MotionEvent.ACTION_MOVE中根據(jù)移動判斷是否可以側(cè)滑,以及側(cè)滑的方向,并使用itemView.scrollTo(deltaX,0);來移動itemView;***在ction==MotionEvent.ACTION_UP中判斷模式和移動的距離完成側(cè)滑或者還原到初始狀態(tài)。實現(xiàn)***步初始化Scrollerscroller
=
new
Scroller(context);
mTouchSlop
=
ViewConfiguration.get(getContext()).getScaledTouchSlop();第二步action==MotionEvent.ACTION_DOWNcase
MotionEvent.ACTION_DOWN:
if
(this.mode
==
MOD_FORBID)
{
return
super.onTouchEvent(ev);
}
//
如果處于側(cè)滑完成狀態(tài),側(cè)滑回去,并直接返回
if
(isSlided)
{
scrollBack();
return
false;
}
//
假如scroller滾動還沒有結(jié)束,我們直接返回
if
(!scroller.isFinished())
{
return
false;
}
downX
=
(int)
ev.getX();
downY
=
(int)
ev.getY();
slidePosition
=
pointToPosition(downX,
downY);
//
無效的position,
不做任何處理
if
(slidePosition
==
AdapterView.INVALID_POSITION)
{
return
super.onTouchEvent(ev);
}
//
獲取我們點擊的item
view
itemView
=
getChildAt(slidePosition
-
getFirstVisiblePosition());
/*此處根據(jù)設(shè)置的滑動模式,自動獲取左側(cè)或右側(cè)菜單的長度*/
if
(this.mode
==
MOD_BOTH)
{
this.leftLength
=
-itemView.getPaddingLeft();
this.rightLength
=
-itemView.getPaddingRight();
}
else
if
(this.mode
==
MOD_LEFT)
{
this.leftLength
=
-itemView.getPaddingLeft();
}
else
if
(this.mode
==
MOD_RIGHT)
{
this.rightLength
=
-itemView.getPaddingRight();
}
break;第三步action==MotionEvent.ACTION_MOVEcase
MotionEvent.ACTION_MOVE:
if
(!canMove
&&
slidePosition
!=
AdapterView.INVALID_POSITION
&&
(Math.abs(ev.getX()
-
downX)
>
mTouchSlop
&&
Math.abs(ev
.getY()
-
downY)
<
mTouchSlop))
{
if
(mSwipeLayout
!=
null)
mSwipeLayout.setEnabled(false);
int
offsetX
=
downX
-
lastX;
if
(offsetX
>
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_RIGHT))
{
/*從右向左滑*/
canMove
=
true;
}
else
if
(offsetX
<
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_LEFT))
{
/*從左向右滑*/
canMove
=
true;
}
else
{
canMove
=
false;
}
/*此段代碼是為了避免我們在側(cè)向滑動時同時觸發(fā)ListView的OnItemClickListener時間*/
MotionEvent
cancelEvent
=
MotionEvent.obtain(ev);
cancelEvent
.setAction(MotionEvent.ACTION_CANCEL
|
(ev.getActionIndex()
<<
MotionEvent.ACTION_POINTER_INDEX_SHIFT));
onTouchEvent(cancelEvent);
}
if
(canMove)
{
/*設(shè)置此屬性,可以在側(cè)向滑動時,保持ListView不會上下滾動*/
requestDisallowInterceptTouchEvent(true);
//
手指拖動itemView滾動,
deltaX大于0向左滾動,小于0向右滾
int
deltaX
=
downX
-
lastX;
if
(deltaX
<
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_LEFT))
{
/*向左滑*/
itemView.scrollTo(deltaX,
0);
}
else
if
(deltaX
>
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_RIGHT))
{
/*向右滑*/
itemView.scrollTo(deltaX,
0);
}
else
{
itemView.scrollTo(0,
0);
}
return
true;
}
break;第四步action==MotionEvent.ACTION_UPcase
MotionEvent.ACTION_UP:
if
(mSwipeLayout
!=
null)
mSwipeLayout.setEnabled(true);
//requestDisallowInterceptTouchEvent(false);
if
(canMove){
canMove
=
false;
scrollByDistanceX();
}
break;完整代碼以下是完整代碼package
com.jwenfeng.fastdev.view;
import
android.content.Context;
import
android.support.v4.widget.SwipeRefreshLayout;
import
android.util.AttributeSet;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.ViewConfiguration;
import
android.widget.AdapterView;
import
android.widget.ListView;
import
android.widget.Scroller;
/**
*
當前類注釋:
ListView
側(cè)滑出菜單
*
項目名:fastdev
*
包名:com.jwenfeng.fastdev.view
*
作者:jinwenfeng
on
16/4/11
10:55
*
郵箱:823546371@
*
QQ:
823546371
*
公司:南京穆尊信息科技有限公司
*
©
2016
jinwenfeng
*
©版權(quán)所有,未經(jīng)允許不得傳播
*/
public
class
SlideListView
extends
ListView
{
/**下拉刷新view*/
private
SwipeRefreshLayout
mSwipeLayout;
/**
*
禁止側(cè)滑模式
*/
public
static
int
MOD_FORBID
=
0;
/**
*
從左向右滑出菜單模式
*/
public
static
int
MOD_LEFT
=
1;
/**
*
從右向左滑出菜單模式
*/
public
static
int
MOD_RIGHT
=
2;
/**
*
左右均可以滑出菜單模式
*/
public
static
int
MOD_BOTH
=
3;
/**
*
當前的模式
*/
private
int
mode
=
MOD_FORBID;
/**
*
左側(cè)菜單的長度
*/
private
int
leftLength
=
0;
/**
*
右側(cè)菜單的長度
*/
private
int
rightLength
=
0;
/**
*
當前滑動的ListViewposition
*/
private
int
slidePosition;
/**
*
手指按下X的坐標
*/
private
int
downY;
/**
*
手指按下Y的坐標
*/
private
int
downX;
/**
*
ListView的item
*/
private
View
itemView;
/**
*
滑動類
*/
private
Scroller
scroller;
/**
*
認為是用戶滑動的最小距離
*/
private
int
mTouchSlop;
/**
*
判斷是否可以側(cè)向滑動
*/
private
boolean
canMove
=
false;
/**
*
標示是否完成側(cè)滑
*/
private
boolean
isSlided
=
false;
public
SlideListView(Context
context)
{
this(context,
null);
}
public
SlideListView(Context
context,
AttributeSet
attrs)
{
this(context,
attrs,0);
}
public
SlideListView(Context
context,
AttributeSet
attrs,
int
defStyleAttr)
{
super(context,
attrs,
defStyleAttr);
scroller
=
new
Scroller(context);
mTouchSlop
=
ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
/**
*
初始化菜單的滑出模式
*
*
@param
mode
*/
public
void
initSlideMode(int
mode)
{
this.mode
=
mode;
}
/**
*
處理我們拖動ListView
item的邏輯
*/
@Override
public
boolean
onTouchEvent(MotionEvent
ev)
{
final
int
action
=
ev.getAction();
int
lastX
=
(int)
ev.getX();
switch
(action)
{
case
MotionEvent.ACTION_DOWN:
if
(this.mode
==
MOD_FORBID)
{
return
super.onTouchEvent(ev);
}
//
如果處于側(cè)滑完成狀態(tài),側(cè)滑回去,并直接返回
if
(isSlided)
{
scrollBack();
return
false;
}
//
假如scroller滾動還沒有結(jié)束,我們直接返回
if
(!scroller.isFinished())
{
return
false;
}
downX
=
(int)
ev.getX();
downY
=
(int)
ev.getY();
slidePosition
=
pointToPosition(downX,
downY);
//
無效的position,
不做任何處理
if
(slidePosition
==
AdapterView.INVALID_POSITION)
{
return
super.onTouchEvent(ev);
}
//
獲取我們點擊的item
view
itemView
=
getChildAt(slidePosition
-
getFirstVisiblePosition());
/*此處根據(jù)設(shè)置的滑動模式,自動獲取左側(cè)或右側(cè)菜單的長度*/
if
(this.mode
==
MOD_BOTH)
{
this.leftLength
=
-itemView.getPaddingLeft();
this.rightLength
=
-itemView.getPaddingRight();
}
else
if
(this.mode
==
MOD_LEFT)
{
this.leftLength
=
-itemView.getPaddingLeft();
}
else
if
(this.mode
==
MOD_RIGHT)
{
this.rightLength
=
-itemView.getPaddingRight();
}
break;
case
MotionEvent.ACTION_MOVE:
if
(!canMove
&&
slidePosition
!=
AdapterView.INVALID_POSITION
&&
(Math.abs(ev.getX()
-
downX)
>
mTouchSlop
&&
Math.abs(ev
.getY()
-
downY)
<
mTouchSlop))
{
if
(mSwipeLayout
!=
null)
mSwipeLayout.setEnabled(false);
int
offsetX
=
downX
-
lastX;
if
(offsetX
>
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_RIGHT))
{
/*從右向左滑*/
canMove
=
true;
}
else
if
(offsetX
<
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_LEFT))
{
/*從左向右滑*/
canMove
=
true;
}
else
{
canMove
=
false;
}
/*此段代碼是為了避免我們在側(cè)向滑動時同時觸發(fā)ListView的OnItemClickListener時間*/
MotionEvent
cancelEvent
=
MotionEvent.obtain(ev);
cancelEvent
.setAction(MotionEvent.ACTION_CANCEL
|
(ev.getActionIndex()
<<
MotionEvent.ACTION_POINTER_INDEX_SHIFT));
onTouchEvent(cancelEvent);
}
if
(canMove)
{
/*設(shè)置此屬性,可以在側(cè)向滑動時,保持ListView不會上下滾動*/
requestDisallowInterceptTouchEvent(true);
//
手指拖動itemView滾動,
deltaX大于0向左滾動,小于0向右滾
int
deltaX
=
downX
-
lastX;
if
(deltaX
<
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_LEFT))
{
/*向左滑*/
itemView.scrollTo(deltaX,
0);
}
else
if
(deltaX
>
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_RIGHT))
{
/*向右滑*/
itemView.scrollTo(deltaX,
0);
}
else
{
itemView.scrollTo(0,
0);
}
return
true;
}
break;
case
MotionEvent.ACTION_UP:
if
(mSwipeLayout
!=
null)
mSwipeLayout.setEnabled(true);
//requestDisallowInterceptTouchEvent(false);
if
(canMove){
canMove
=
false;
scrollByDistanceX();
}
break;
}
return
super.onTouchEvent(ev);
}
private
void
scrollByDistanceX()
{
if(this.mode
==
MOD_FORBID){
return;
}
if(itemView.getScrollX()
>
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_RIGHT)){
/*從右向左滑*/
if
(itemView.getScrollX()
>=
rightLength
/
2)
{
scrollLeft();
}
else
{
//
滾回到原始位置
scrollBack();
}
}else
if(itemView.getScrollX()
<
0
&&
(this.mode
==
MOD_BOTH
||
this.mode
==
MOD_LEFT)){
/*從左向右滑*/
if
(itemView.getScrollX()
<=
-leftLength
/
2)
{
scrollRight();
}
else
{
//
滾回到原始位置
scrollBack();
}
}else{
//
滾回到原始位置
scrollBack();
}
}
/**
*
往右滑動,getScrollX()返回的是左邊緣的距離,就是以View左邊緣為原點到開始滑動的距離,所以向右邊滑動為負值
*/
private
void
scrollRight()
{
isSlided
=
true;
final
int
delta
=
(leftLength
+
itemView.getScrollX());
//
調(diào)用startScroll方法來設(shè)置一些滾動的參數(shù),我們在computeScroll()方法中調(diào)用scrollT
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 婁底新化縣農(nóng)村產(chǎn)權(quán)交易中心有限公司招聘真題
- 2023年大連理工大學化學學院招聘行政人員考試真題
- 透視技術(shù)在骨關(guān)節(jié)系統(tǒng)疾病中的應(yīng)用
- 食品銷售工作計劃范文(8篇)
- 急診科臨床診療指南 技術(shù)操作規(guī)范
- 幼兒園開學第一課教案
- 山地租賃合同山權(quán)證
- 超市營業(yè)員工作心得8篇
- 競選環(huán)保社社長演講稿范文5篇
- 生態(tài)園林建設(shè)合同
- 醫(yī)師定期考核表格參考模板
- 英語人教版三年級上冊(教具)動物圖卡
- 泥水平衡頂管施工方案
- 民辦非企業(yè)單位(法人)登記申請表08669
- 霍蘭德人格六角形模型(共享內(nèi)容)
- 寶鋼中央研究院創(chuàng)新戰(zhàn)略與運行機制研究
- 建筑CAD測試多選題
- 支座鑄造工藝設(shè)計
- 2022年學校禁毒工作計劃
- GB-T-30512-2014-汽車禁用物質(zhì)要求
- 生物相容性試驗檢測報告
評論
0/150
提交評論