手勢(shì)
是手指在屏幕上的一切操作辜妓,包括單擊矾克、雙擊、長按捏鱼、滑動(dòng)执庐、滾動(dòng)等。
使用方式
- 聲明一個(gè)GestureDetector對(duì)象
GestureDetector mGestureDetector=null;//聲明成全局變量
- 實(shí)例化手勢(shì)對(duì)象穷躁,并且實(shí)現(xiàn)手勢(shì)的監(jiān)聽OnGestureListener
mGestureDetector=new GestureDetector(MainActivity.this,new MyOnGestureListener());
- 創(chuàng)建一個(gè)類實(shí)現(xiàn)GestureDetector.OnGestureListener耕肩,并重寫里面的6個(gè)方法:
private class MyOnGestureListener implements GestureDetector.OnGestureListener
- onDown:手指按下的監(jiān)聽
/**
* 手指按下的時(shí)候的監(jiān)聽
*/
@Override
public boolean onDown(MotionEvent e) {
Log.e("----------------","onDown");
return false;
}
- onShowPress:手指短按的監(jiān)聽
/**
* 手指按住不放那么都會(huì)觸發(fā)這個(gè)函數(shù)
*/
@Override
public void onShowPress(MotionEvent e) {
Log.e("----------------","onShowPress");
}
- onSingleTapUp:單擊
/**
* 單擊
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.e("----------------","onSingleTapUp");
return false;
}
- onScroll:滾動(dòng)
/**
* 滾動(dòng)
* @param e1:表示的是上一次的開始的時(shí)候的事件
* @param e2 :這一次的時(shí)候的事件
* @param distanceX:在x軸上滾動(dòng)的距離 從左邊往右邊滾動(dòng)那么這個(gè)值是負(fù)值 / 在x軸上從右邊往左邊滾動(dòng)的話那么這個(gè)值是正值
* @param distanceY:在y軸上滾動(dòng)的距離 從上--->下 負(fù)值 從下--->上 正值
* @return
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.e("----------------","onScroll");
// Log.e("------distansX----",distanceX+"-----");
// Log.e("------distansY----",distanceY+"-----");
int startX= (int) e1.getX();
int endX= (int) e2.getX();
int startY= (int) e1.getY();
int endY= (int) e2.getY();
if(Math.abs(startX-endX)>Math.abs(startY-endY)){ //默認(rèn)就是左右的滑動(dòng)
if(startX>endX){ //從右邊往左邊來進(jìn)行滑動(dòng)
Log.e("-----------","從右邊往左邊滑動(dòng)");
}else{ //從左邊往右邊進(jìn)行滑動(dòng)
Log.e("-----------","從左邊往右邊滑動(dòng)");
}
}else{
if(endY>startY){ //從上邊往下邊來進(jìn)行滑動(dòng)
Log.e ("-----------","從上邊往下邊滑動(dòng)");
}else{ //從左邊往右邊進(jìn)行滑動(dòng)
Log.e ("-----------","從下邊往上邊滑動(dòng)");
}
}
return false;
}
- onLongPress:長按,和onSowPress是時(shí)間上的區(qū)別。
/**
* 長按 和上面那個(gè)onShowPress的區(qū)別是時(shí)間上的區(qū)別问潭,也就是說如果觸發(fā)了 onLongPress就一定要觸發(fā)onShowPress
*/
@Override
public void onLongPress(MotionEvent e) {
Log.e("----------------","onLongPress");
}
- onFlinf:滑動(dòng),滑動(dòng)和滾動(dòng)的區(qū)別:滑動(dòng)是在屏幕上面快速的移動(dòng)一段距離婚被,有滑動(dòng)一定有滾動(dòng)狡忙,有滾動(dòng)不一樣有滑動(dòng)。
/**
* 滑動(dòng) 滑動(dòng)和滾動(dòng)的區(qū)別
* 滑動(dòng)是在屏幕上快速的移動(dòng)一段距離
* 滾動(dòng):是在屏幕上慢慢的移動(dòng)一段距離
* 有滑動(dòng)就一定有滾動(dòng)
* 有滾動(dòng)不一定有滑動(dòng)
* @param e1:上一次的那個(gè)開始的事件
* @param e2:上一次結(jié)束的事件
* @param velocityX:表示的是單位時(shí)間內(nèi)在x軸上移動(dòng)的distance
* @param velocityY:表示單位事件內(nèi)在Y軸上移動(dòng)的距離 這個(gè)主要用來判定那個(gè)到底是往哪里滑動(dòng)
* @return
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.e("----------------","onFling");
return false;
}
- 將當(dāng)前觸摸區(qū)域的事件傳遞給手勢(shì)來進(jìn)行處理址芯。
例如:重寫onToucheEvent方法灾茁,將觸摸事件返回給手勢(shì)去處理
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
ViewGroup的用法:
ViewGroup:容器,在ViewGroup里面轉(zhuǎn)的是View,或者新的ViewGroup谷炸。ViewGroup可以看做是所有容器的父類北专。
ViewGroup和View的關(guān)系和區(qū)別?
??View是所有控件和容器的最大的父類旬陡,ViewGroup是繼承于View的拓颓,View也是ViewGroup的父類,在開發(fā)中如果要將View和容器區(qū)分開的話描孟,可以認(rèn)為ViewGroup就是所有容器的父類驶睦。
學(xué)習(xí)ViewGroup的作用:
- 可以自定義布局-->流式布局
- 可以自定義容器-->自己決定容器能夠裝多少數(shù)據(jù)砰左,容器中的控件位置也是自己決定
自定義ViewGroup的步驟:
- 編寫一個(gè)類繼承于ViewGroup,并且重寫有兩個(gè)參數(shù)的構(gòu)造函數(shù)
- 重寫ViewGroup里面的onLayout方法场航。
/**
* 確定那個(gè)兒子的位置
* @param changed
* @param l:兒子的左邊頂部的x的坐標(biāo)
* @param t:兒子左邊頂部的y坐標(biāo)
* @param r:兒子右邊底部的x的坐標(biāo)
* @param b:兒子的右邊的底部的y坐標(biāo)
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//在ViewGroup中獲取那個(gè)兒子的數(shù)量
int childCount = getChildCount();
//給孩子設(shè)置那個(gè)顯示的位置
//得到這個(gè)孩子
View childView=getChildAt(0);
//給兒子設(shè)置個(gè)位置
/* Log.e("---------",childView.getMeasuredWidth()+"");
Log.e("---------",childView.getMeasuredHeight()+"");*/
childView.layout(100,100,childView.getMeasuredWidth()+100,childView.getMeasuredHeight()+100);
}
- 重寫ViewGroup中的onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//測(cè)量兒子的第一種模式:交給他爹來測(cè)咋們不用管缠导,一般情況下都用這種方法
//怎么交給他爹測(cè)
//這句話一旦調(diào)用的話那么他的孩子就有那個(gè)寬高了...
//優(yōu)點(diǎn):方便而且不用謝很多的代碼 孩子的高度就有了....
measureChild(getChildAt(0),widthMeasureSpec,heightMeasureSpec);
//還有第二種測(cè)量模式:這種測(cè)量模式就是:自己編寫代碼來進(jìn)行測(cè)量,較復(fù)雜
//自己測(cè) 獲取測(cè)量模式
int count=getChildCount();
Log.e("------孩子的個(gè)數(shù)---",count+"");
if(tag){
tag=false;
int widthMode=MeasureSpec.getMode(widthMeasureSpec);
int heightMode=MeasureSpec.getMode(heightMeasureSpec);
//獲取那個(gè)建議的寬和高
int widthSize=MeasureSpec.getSize(widthMeasureSpec);
int heightSize=MeasureSpec.getSize(heightMeasureSpec);
//第三步就來確定那個(gè)是使用的具體的值還是那個(gè)wrap_content
//表示的是最終算出來的那個(gè)寬和高
int describleWidth=200;
int describleHeight=200;
int width=0;
int height=0;
if(widthMode==MeasureSpec.AT_MOST){ //這個(gè)情況表示的是那個(gè)wrap_content
width=Math.min(widthSize,describleWidth);
}else if(widthMode==MeasureSpec.EXACTLY){ //這個(gè)表示的是精確的值或者是match_parent
width=widthSize;
}
//玩的是那個(gè)高的測(cè)量模式
if(heightMode==MeasureSpec.AT_MOST){ //這個(gè)表示的是wrap_content
height=Math.min(describleHeight,heightSize);
}else if(heightMode==MeasureSpec.EXACTLY){ //表示的是那個(gè)實(shí)際的值或者是那個(gè)充滿容器
height=heightSize;
}
Log.e("----------------",width+" 之中");
Log.e("------------hei----",height+" 之中");
//下面就將咋們的測(cè)量的結(jié)果傳遞給那個(gè)給兒子測(cè)量的方法 getChildAt(0).measure(MeasureSpec.makeMeasureSpec(width,widthMode),MeasureSpec.makeMeasureSpec(height,heightMode));
}
注意:在ViewGroup中只能使用getMeasuredWidth和getMeasuredHeight來測(cè)量寬和高溉痢。
- 在需要使用該ViewGroup的布局文件聲明控件
<com.fox.ViewGroupDemo.MyViewGroup
android:layout_width="400dp"
android:layout_height="300dp"
android:background="#f07">
<Button
android:layout_width="100dp"
android:layout_height="50dp"
android:text="按鈕"/>
</com.fox.ViewGroupDemo.MyViewGroup>