第一篇:【原】android 中定時器的幾種用法總結
在android中,經常用到的定時器主要有以下幾種實現:
一、採用Handler與線程的sleep(long)方法
二、採用Handler的postDelayed(Runnable, long)方法
三、採用Handler與timer及TimerTask結合的方法。
下面逐一介紹:
一、採用Handle與線程的sleep(long)方法
Handler主要用來處理接受到的消息。這只是最主要的方法,當然Handler裡還有其他的方法供實現,有興趣的可以去查API,這裡不過多解釋。
1.定義一個Handler類,用於處理接受到的Message.Handler handler = new Handler(){
};
2.新建一個實現Runnable接口的線程類。如下:
public class MyThread implements Runnable{} @Override public void run(){} // TODO Auto-generated method stub while(true){} try {} Thread.sleep(10000);//線程暫停10秒,單位毫秒 Message message=new Message();message.what=1;handler.sendMessage(message);//發送消息 // TODO Auto-generated catch block e.printStackTrace();public void handleMessage(Message msg){} //要做的事情 super.handleMessage(msg);} catch(InterruptedException e){
3.在需要啟動線程的地方加入下面語句:
new Thread(new MyThread()).start();
4.啟動線程後,線程每10s發送一次消息。
二、採用Handler的postDelayed(Runnable, long)方法
這個實現比較簡單一些:
1.Handler handler=new Handler();
Runnable runnable=new Runnable(){};@Override public void run(){} // TODO Auto-generated method stub //要做的事情 handler.postDelayed(this, 2000);
2.啟動計時器:
handler.postDelayed(runnable, 2000);//每兩秒執行一次runnable.3.停止計時器:
handler.removeCallbacks(runnable);
三、採用Handler與timer及TimerTask結合的方法。
1.定義定時器、定時器任務及Handler句柄
private final Timer timer = new Timer();private TimerTask task;Handler handler = new Handler(){};@Override public void handleMessage(Message msg){}// TODO Auto-generated method stub //要做的事情 super.handleMessage(msg);
2.初始化計時器任務。
task = new TimerTask(){
};@Override public void run(){} // TODO Auto-generated method stub Message message = new Message();message.what = 1;handler.sendMessage(message);
3.啟動定時器
timer.schedule(task, 2000, 2000);
簡要說一下上面三步提到的一些內容。
1.定時器任務(TimerTask)顧名思義,就是說當定時器到達指定的時間時要做的工作,這裡是想Handler發送一個消息,由Handler類進行處理。
2.java.util.Timer.schedule(TimerTask task, long delay):這個方法是說,dalay/1000秒後執行task.只執行一次。
java.util.Timer.schedule(TimerTask task, long delay, long period):這個方法是說,delay/1000秒後執行task,然後進過period/1000秒再次執行task,這個用於循環任務,執行無數次,當然,你可以用timer.cancel();取消計時器的執行。
一個網友說到了CountDownTimer這個類,從名字上面大家就可以看出來,記錄下載時間。將后臺線程的創建和Handler隊列封裝成為了一個方便的類調用。
查看了一下官方文檔,這個類及其簡單,只有四個方法,上面都涉及到了onTick,onFinsh、cancel和start。其中前面兩個是抽象方法,所以要重寫一下。
下面是官方給的一個小例子:new CountdownTimer(30000, 1000){
2public void onTick(long millisUntilFinished){
mTextField.setText(“seconds remaining: ” + millisUntilFinished 3 / 1000);
4}
5public void onFinish(){
6mTextField.setText(“done!”);
7}
8}.start();主要是重寫onTick和onFinsh這兩個方法,onFinish()中的代碼是計時器結束的時候要做的事情;
onTick(Long m)中的代碼是你倒計時開始時要做的事情,參數m是直到完成的時間,構造方法MyCount()中的兩個參數中,前者是倒計的時間數,后者是倒計每秒中間 的間隔時間,都是以毫秒為單位。例如要倒計時30秒,每秒中間間隔時間是1秒,兩個參數可以這樣寫MyCount(30000,1000)。將后臺線程的創建和Handler隊列封裝成為了一個方便的類調用。
/**
* Cancel the countdown.*
* Do not call it from inside CountDownTimer threads
*/
public final void cancel(){
mHandler.removeMessages(MSG);
mCancelled = true;
}
當你想取消的時候使用mc.cancel()方法就行了,但是不能在CountDownTimer線程的內部調用此方法,要在線程外部使用,使用cancel方法取消後,如果再次調用start方法的話倒計時會重新開始。
希望對你有所幫助。請尊重原創,這裡是ljlkings的空間。
第二篇:Android ToolBar 用法總結(寫寫幫推薦)
Android ToolBar 用法總結
什么是ToolBar
首先,ToolBar是谷歌在5.0版本時推出的一個新的布局控件,目的是為了替代不怎么好用的ActionBar的,ActionBar的不好用,本人是有體會的,谷歌的官方認為(實際上也是這樣的),ActionBar在某些程度上限制了Android App開發與設計的彈性。
其次,谷歌為了保持移動端App界面的一致性體驗,推出了Material Design設計風格,ToolBar就是其中的一個組件。而且,在標題欄這塊,谷歌也給出了新的概念--App Bar。
最后,谷歌也早就不推薦(廢棄)使用ActionBarActivity了,所以,再做新東西的時候就別再創建一個繼承自ActionBarActivity的Activity了,強迫癥患者是絕對不允許代碼中有刪除線的。當然,很多小伙伴早就ToolBar擼起來了,不用多說,公司的新項目也是上的ToolBar,這里做個用法的總結。
如何使用ToolBar
引用兼容包
要開始使用ToolBar首先要做的是引用相關的兼容包: compile 'com.android.support:design:23.3.0'
也就是我們剛才說的Material Design設計風格的兼容包,如果你的APP支持的最低版本是5.0+,就不用使用兼容包了,直接就支持了。
當然,還有一個兼容包:
compile 'com.android.support:appcompat-v7:23.3.0'
因為我的Activity不是繼承自ActionBarActivity,而是AppCompatActivity。
使用ToolBar
引用了上面的design兼容包后,就可以在xml布局文件里這樣來使用了:
剛才說了,ToolBar是用來替換ActionBar的,如果我們的Activity繼承自AppCompatActivity的話,默認是有ActionBar的,那么就會出現下面的情況:
所以,如果在xml中使用了ToolBar來替代ActionBar的話,就要設置Activity的風格沒有ActionBar,或者通過變通的方式實現。比如設置Theme:
假設我們的整個App的頁面都是使用ToolBar的話,可以定義一個AppTheme.Base,內容如上,去掉ActionBar。
然后在設置具體的Theme,比如:
這里的屬性配置,分別決定了對應的內容的顏色,看下圖:
接下來的使用就基本上跟其他控件一樣了,需要在Activity中聲明,然后findViewById,最后拿來使用。xml里面的屬性,代碼同樣有對應的方法去設置,對于xml設置屬性,需要注意一點:命名空間
xmlns:toolBar=“http://schemas.android.com/apk/res-auto” toolBar:popupTheme=“@style/Theme.ToolBar.Base” toolBar:logo=“@drawable/main_ic_home_selected” toolBar:navigationIcon=“@drawable/ic_launcher” toolBar:title=“ToolBar” toolBar:subtitle=“subTitle”>
使用android自帶的命名空間設置對應的屬性是不生效的,但是不會報錯,其實你只要知道這個控件時在兼容包里的,不是sdk自帶的,稍微注意一下就好了。
但是,在java代碼中,關鍵的一點其實是 setSupportActionBar(toolbar);
這句代碼,這句代碼就把用toolbar代替ActionBar體現的非常具體了,一看就能明白是什么意思。要注意的是,ToolBar的有些方法必須要在這句話之前調用才能生效,比如setTitle,而有些方法則必須要在這句話之后調用才能生效,比如setOnMenuItemClickListener,具體哪些之前調用,哪些之后調用,哪些前后無所謂就需要自己去查API了。
另外,ToolBar也支持設置menu,實現方式跟使用ActionBar一樣的,加載xml布局:
@Override public boolean onCreateOptionsMenu(Menu menu){ getMenuInflater().inflate(R.menu.menu_main, menu);return super.onCreateOptionsMenu(menu);}
@Override public boolean onOptionsItemSelected(MenuItem item){ String msg = “";switch(item.getItemId()){ case R.id.action_edit: msg += ”Click edit--111“;break;case R.id.action_share: msg += ”Click share--111“;break;case R.id.action_settings: msg += ”Click setting--111“;break;case android.R.id.home: msg += ”Click back--111“;break;}
if(!msg.equals(”“)){ Toast.makeText(HelloWorldActivity.this, Toast.LENGTH_SHORT).show();} return true;}
msg,還有,ToolBar作為布局控件,可以作為容器在里面再加上自定義布局:
這種使用方式可以輕松的實現標題內容居中等自定義的樣式,如果是使用ActionBar就麻煩了許多。而且ToolBar作為一個布局控件,可以把它布局到xml的任何位置,不只是頭部,ActionBar是固定在頭部的,這點跟ActionBar區別很大,用起來也更加靈活多變,但估計不會有人把ActionBar放到別的位置吧!
ToolBar使用總結
以上基本上就是ToolBar的基本使用了,當然,ToolBar配合Material Design的其他元素使用,以及動畫效果的修飾,使用起來還是挺好看的一種風格,個人比較推薦,我的博客項目也已經換上了ToolBar來實現了,需要具體代碼的可以參考一下,有問題歡迎留言探討。
最后是源碼地址,如果覺得對您有幫助,并且想要一起提高Android開發技能的小伙伴能star一下,以后會繼續在這個項目上添加新的內容,包括一些有用的工具類、各種控件、效果實現、設計模式的使用等等。
第三篇:Android 中 View移動總結:ViewDragHelper學習及用法詳解
Android 中 View移動總結:ViewDragHelper學習及用法詳
解
如上圖簡單呈現出兩個方塊后,提出一個需求: 1.拖動方塊時,方塊(即子View)可以跟隨手指移動。2.一個方塊移動時,另一個方塊可以跟隨移動。
3.將方塊移動到左邊區域(右邊區域)后放開(即手指離開屏幕),它會自動移動到左邊界(右邊界)。
4.移動的時候給方塊加點動畫(duang~duang~duang~)。
View移動的相關方法總結:
1.layout 在自定義控件中,View繪制的一個重寫方法layout(),用來設置顯示的位置。所以,可以通過修改View的坐標值來改變view在父View的位置,以此可以達到移動的效果!但是缺點是只能移動指定的View:
//通過layout方法來改變位置 view.layout(l,t,r,b);
2.offsetLeftAndRight()和offsetTopAndBottom()
非常方便的封裝方法,只需提供水平、垂直方向上的偏移量,展示效果與layout()方法相同。
view.offsetLeftAndRight(offset);//同時改變left和right
view.offsetTopAndBottom(offset);//同時改變top和bottom
3.LayoutParams
此類保存了一個View的布局參數,可通過LayoutParams動態改變一個布局的位置參數,以此動態地修改布局,達到View位置移動的效果!但是在獲取getLayoutParams()時,要根據該子View對應的父View布局來決定自身的LayoutParams。所以一切的前提是:必須要有一個父View,否則無法獲取LayoutParams!
//必須獲取父View的LayoutParams LinearLayout.LayoutParamslayoutParams =(LinearLayout.LayoutParams)getLayoutParams();layoutParams.leftMargin = getLeft()+ dx;layoutParams.topMargin = getTop()+ dy;setLayoutParams(layoutParams);
4.scrollTo和scrollBy
通過改變scrollX和scrollY來移動,但是可以移動所有的子View。scrollTo(x,y)表示移動到一個具體的坐標點(x,y),而scrollBy(x,y)表示移動的增量為dx,dy。
scrollTo(x,y);scrollBy(xOffset,yOffset);
注意:這里使用scrollBy(xOffset,yOffset);,你會發現并沒有效果,因為以上兩個方法移動的是View的content。若在ViewGroup中使用,移動的是所有子View;若在View中使用,移動的是View的內容(比如TextView)。
所以,不可在view中使用以上方法!應該在View所在的ViewGroup中使用:
((View)getParent()).scrollBy(offsetX, offsetY);【視圖坐標系】:
可是即使這樣,你會發現view移動的效果與設想方向相反!這是Android試圖移動原因,若參數為正值,content將向坐標軸負方向移動;參數為負值,content將向坐標軸正方向移動。所以要實現隨手指移動而滑動的效果,應將偏移量設置為負值即可:
((View)getParent()).scrollBy(-offsetX,-offsetY);
5.canvas
通過改變Canvas繪制的位置來移動View的內容,用的少:
canvas.drawBitmap(bitmap, left, top, paint)
總結
但是要完成最開始的提的需求,不管使用哪一種方法,都需要通過onTouchEvent方法來捕捉手勢,自己手動計算移動距離,再改變子View的布局,不免有些麻煩,所以在這里引出正文,介紹一個強大的類來處理移動:ViewDragHelper ViewDragHelper介紹:
1.產生: ViewDragHelper在高版本的v4包(android4.4以上的v4)中,于Google在2013年開發者大會提出的
2.作用:它主要用于處理ViewGroup中對子View的拖拽處理。
3.使用:它主要封裝了對View的觸摸位置,觸摸速度,移動距離等的檢測和Scroller,通過接口回調的方式通知我們。所以我們需要做的只是用接收來的數據指定這些子View是否需要移動,移動多少等。
4.本質:是一個對觸摸事件的解析類。
ViewDragHelper實現
1.ViewDragHelper實例創建
/** * Factory method to create a new ViewDragHelper.* * @paramforParent Parent view to monitor * @param sensitivity Multiplier for how sensitive the helper should be about detecting *the start of a drag.Larger values are more sensitive.1.0f is normal.* @paramcb Callback to provide information and receive events * @return a new ViewDragHelper instance */
viewDragHelper = ViewDragHelper.create(forParent, sensitivity, cb);
create()就是創建ViewDragHelper實例的方法,代碼中的注釋是create()中參數的解釋,來查看:
(1)forParent:“用來監視的父View”。傳入參數父View,即可監視該父View中的所有子View。
(2)sensitivity:“檢測時的敏感度;值越大越敏感,1是正常范圍”。比如說手指在滑動屏幕時速度特別快,敏感度越大時,此時速度快也可以檢測到,反之亦然。
(3)Callback :“提供信息和接受的事件”。最重要的參數!可以從這個回調提供的信息獲取到View滑動的距離、速度等。
2.自定義View繼承FrameLayout
這里來個小提示:之前實現的布局中自定義DragLayout是繼承于ViewGroup,并且實現重寫了onMeasure()方法,如下:
DragLayout.java
publicclassDragLayoutextendsViewGroup{...@Override
protectedvoidonMeasure(intwidthMeasureSpec, intheightMeasureSpec){ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//方法一:對子View的測量需求
/*獲取子View的寬度100dp 的兩種方法:
int size =(int)getResources().getDimension(R.dimen.width);int size = readView.getLayoutParams().width;*/
intmeasureSpec = MeasureSpec.makeMeasureSpec(redView.getLayoutParams().width, MeasureSpec.EXACTLY);//具體指定寬高,為精確模式
redView.measure(measureSpec,measureSpec);//當父控件測量完子控件,才可以填(0,0)
blueView.measure(measureSpec,measureSpec);
/* //方法二:如果說沒有特殊的對子View的測量需求,可用如下方法 measureChild(redView,widthMeasureSpec,heightMeasureSpec);measureChild(blueView,widthMeasureSpec,heightMeasureSpec);*/ } }
但是現在使DragLayout 類繼承于FrameLayout即可!
publicclassDragLayoutextendsFrameLayout{...} 因為在自定義ViewGroup的時候,如果對子View的測量沒有特殊的需求,那么可以繼承系統已有的布局(比如FrameLayout、RelativeLayout),目的是為了讓已有的布局幫我們實現onMeasure()。
所以在繼承之后,我們無需實現onMeasure()方法,以上代碼全部不需要(這里選擇繼承FrameLayout幀布局,原因是在Android源碼中其實現最簡單),所以重寫繼承的onLayout()方法其實是重寫幀布局中的onLayout(),如果也注釋的話,你會發現藍色小方塊覆蓋紅色,一起擺放在左上角(其實就是幀布局的擺放規則)
3.callback回調創建
privateViewDragHelper.Callback callback = new Callback(){ //必須要實現的方法 @Override
publicbooleantryCaptureView(View child, intpointerId){ returnfalse;} };
4.觸摸、攔截事件
以上部分ViewDragHelper的創建部分已完成,可是還沒結束。比如大家熟悉的一個類:GestureDetector手勢識別器,想要它生效,必須傳一個觸摸事件,這樣GestureDetector類才可以解析當前手勢。道理相同,之前在介紹ViewDragHelper已提到,它只是一個對觸摸事件的解析類,需要傳一個觸摸事件,才會生效。
//處理是否攔截 @Override
publicbooleanonInterceptTouchEvent(MotionEventev){ //由viewDragHelper來判斷是否應該攔截此事件
boolean result = viewDragHelper.shouldInterceptTouchEvent(ev);return result;}
@Override
publicbooleanonTouchEvent(MotionEvent event){ //將觸摸事件傳給viewDragHelper來解析處理 viewDragHelper.processTouchEvent(event);//消費掉此事件,自己來處理 returntrue;}
以上則viewDragHelper可以監視并解析我們的手勢了,而且會把信息通過回調傳遞給callback。
5.處理computeScroll()
該方法是Scroller類的核心,系統在繪制View的時候在draw()中調用此方法,實際與scrollTo()相同。
@Override public void computeScroll(){ super.computeScroll();if(scroller.computeScrollOffset()){ scrollTo(scroller.getCurrX(),scroller.getCurrY());invalidate();}
如上,Scroller類提供computeScrollOffset()方法來判斷是否完成了整個滑動,同時getCurrX()和getCurrY()來獲得當前滑動坐標。
重點是invalidate()方法,因為只能在computeScroll()方法中獲取模擬過程中的scrollX 和 scrollY,但computeScroll()方法是不會自動調用的,只能通過invalidate()—> draw()—>computeScroll()來間接調用computeScroll()方法!模擬過程結束,if判斷中computeScrollOffset()方法返回false,中斷循環,完成整個平滑移動過程!
但是!!我們并不采取以上方法,之前介紹過ViewDragHelper已經封裝好了Scroller,用另外一種:
@Override
publicvoidcomputeScroll(){ super.computeScroll();if(viewDragHelper.continueSettling(true)){ ViewCompat.postInvalidateOnAnimation(DragLayout.this);} } } continueSettling()方法判斷是否結束,同Scroller的方法相似,主要是postInvalidateOnAnimation(),此方法不像Scroller的scrollTo,還需要傳值,其實此方法體內已經封裝好移動的方法,它會自動去測量當前位置進行移動,所以我們只需調用即可!(在手指抬起時回調的方法中也會用到它,后面介紹)
6.實現callback回調中的方法
之前在創建callback時,默認只實現了tryCaptureView()方法,完成需求僅僅不夠,還需要其它方法,依次介紹:
(1)tryCaptureView()
此方法用于判斷是否捕獲當前child的觸摸事件,可以指定ViewDragHelper移動哪一個子View。此例中,需要移動兩個方塊,則判斷當前View是否是自己想移動的,返回boolean值。
/**用于判斷是否捕獲當前child的觸摸事件
* @param child 當前觸摸的子View * @return true:捕獲并解析 false:不處理 */ @Override
publicbooleantryCaptureView(View child, intpointerId){ return child == blueView || child == redView;}
(2)onViewCaptured()此方法在View被開始捕獲和解析時回調,即當tryCaptureView()中的返回值為true的時候,此方法才會被調用。
例如tryCaptureView()方法中只捕獲紅色方塊,當移動紅方快時,該方法會回調,移動藍色方塊時則不會!
/** 當View被開始捕獲和解析的回調(用處不大)* @paramcapturedChild當前被捕獲的子View */ @Override
publicvoidonViewCaptured(View capturedChild, intactivePointerId){ super.onViewCaptured(capturedChild, activePointerId);Log.e(“tag”,“onViewCaptures”);}
(3)clampViewPositionHorizontal()和clampViewPositionVertical()
這兩個為具體滑動方法,分別對應水平和垂直方向上的移動。要想子View移動,此方法必須重寫實現!
而方法的返回值則是指定View在水平(left)或垂直(top)方向上變成的值,參數中的dx、dy則是代表相較于上一次位置的增量。
/** 控制child在水平方向的移動 * @param child * @param left ViewDragHelper會將當前child的left值改變成返回的值
* @param dx 相較于上一次child在水平方向上移動的 * @return */ @Override
publicintclampViewPositionHorizontal(View child, int left, int dx){ return left;} /**控制child在垂直方向的移動 * @param child * @param top ViewDragHelper會將當前child的top值改變成返回的值
* @paramdy相較于上一次child在水平方向上移動的 * @return */ @Override
publicintclampViewPositionVertical(View child, int top, intdy){ return top;} };顯示效果:
通過以上GIF動圖和日志打印可以看出,僅將返回值設置成方法中的參數,方塊就可以任意移動了。也證實了方法中提供的參數而dx或dy是每一次移動的距離,left或top 是指定View移動到的位置,這是計算好了的,相當于left = child.getLeft()+ dx。若想要它不移動,則:
return left子控件的寬/高,即控件可以移動的范圍。
//獲取View水平方向的拖拽范圍 @Override
publicintgetViewHorizontalDragRange(View child){ returngetMeasuredWidth()child.getMeasuredHeight();}
可是以上實現后,你會發現拖拽方塊還是可以超出邊界,此方法并沒有起作用!是否代表此方法完全無用?這返回的值有何用? 不是,它目前確實并不可以限制邊界,但此方法返回的值會用在:比如說手指抬起時,View緩慢移動的動畫時間的計算會用到此值,最好不要返回0(返回也不會錯)!
但是我們還想要達到限制View拖拽邊界的效果,這時在第三點介紹的clampViewPositionHorizontal()和clampViewPositionVertical()發揮效果了,該方法是通過返回值來改變View移動的位置,這時可以在方法中加判斷是否有越界:
@Override
publicintclampViewPositionHorizontal(View child, int left, int dx){ if(left <0){ //限制左邊界 left = 0;}elseif(left >(getMeasuredWidth()child.getMeasuredWidth();} return left;} 顯示效果:
(5)onViewPositionChanged()
目前為止,需求已經完成可以任意拖拽View了,接下來完成拖拽View時,另一塊跟隨移動。這時介紹一個新的方法:onViewPositionChanged(),該方法在child(需要捕捉的View)位置改變時執行,參數left(top)跟之前介紹方法中含義相同,為child最新的left(top)位置,而dx(dy)是child相較于上一次移動時水平(垂直)方向上改變的距離。
了解之后,就知道這個方法很強大了,在方法體中判斷具體View,再根據方法提供的參數設置另一View的位置,如下:
/**當child位置改變時執行
* @paramchangedView位置改變的子View * @param left child最新的left位置
* @param top child最新的top位置
* @param dx 相較于上一次水平移動的距離
* @paramdy相較于上一次垂直移動的距離 */ @Override
publicvoidonViewPositionChanged(View changedView, int left, int top, int dx, intdy){ super.onViewPositionChanged(changedView, left, top, dx, dy);if(changedView == blueView){ //拖動藍色方塊時,紅色也跟隨移動
redView.layout(redView.getLeft()+dx , redView.getTop()+dy , redView.getRight()+dx , redView.getBottom()+dy);}elseif(changedView == redView){ //拖動紅色方塊時,藍色也跟隨移動
blueView.layout(blueView.getLeft()+dx , blueView.getTop()+dy , blueView.getRight()+dx , blueView.getBottom()+dy);} } 顯示效果:
(6)onViewReleased()
完成目前需求第三個:手指在左邊(右邊)區域離開屏幕后,方塊自動移動到左邊界(右邊界)。接下來介紹最后一個方法onViewReleased(),手指抬起的時候執行該方法。
這里有兩個新參數:
xvel: x方向移動的速度,若是正值,則代表向右移動,若是負值則向左移動; yvel: y方向移動的速度,若是正值則向下移動,若是負值則向上移動。
手指抬起的時候執行該方法
* @paramreleasedChild當前抬起的View * @paramxvel x方向移動的速度:正值:向右移動負值:向左移動
* @paramyvel y方向移動的速度:正值:向下移動負值:向上移動 */ @Override
publicvoidonViewReleased(View releasedChild, floatxvel, floatyvel){ super.onViewReleased(releasedChild, xvel, yvel);intcenterLeft = getMeasuredWidth()/2releasedChild.getMeasuredWidth(),releasedChild.getTop());ViewCompat.postInvalidateOnAnimation(DragLayout.this);}
} };顯示效果:
7.執行伴隨動畫
還剩下最后一個需求,在方塊移動時加些動畫,說到動畫引入一個概念:百分比(即子View左側占子View可移動寬度的比例)。在移動子View的時候,比如從左到右,那么百分比則是0~1。做個實驗,在回調onViewPositionChanged()加入兩行:
//1.計算view移動的百分比
float fraction = changedView.getLeft()* 1f /(getMeasuredWidth()1 //縮放
// ViewHelper.setScaleX(redView, 1+0.5f*fraction);// ViewHelper.setScaleY(redView, 1+0.5f*fraction);//旋轉
// ViewHelper.setRotation(redView,360*fraction);//圍繞z軸轉
ViewHelper.setRotationX(redView,360*fraction);//圍繞x軸轉
// ViewHelper.setRotationY(redView,360*fraction);//圍繞y軸轉
ViewHelper.setRotationX(blueView,360*fraction);//圍繞z軸轉
//平移
// ViewHelper.setTranslationX(redView,80*fraction);//透明
// ViewHelper.setAlpha(redView, 1-fraction);
}
最終成品:
以上了解后,ViewDragHelper的學習到此為止,接下來利用它做一個側滑什么的更是不在話下,包括現在網上的彷QQ側滑面板都是利用ViewDragHelper完成的,所以工欲善其事,必先利其器呀~ 關于View移動總結的,參照了徐宜生老師的《Android群英傳》,講解了許多View相關知識,重新加深理解了,還是很有幫助的。
第四篇:Android總結
Android四大組件:
Activity—表現屏幕界面
Service—后臺服務
BroadcastReceiver—實現廣播機制
ContentProvider—實現數據存儲
Intent類:用來啟動程序并傳遞信息的類
用于Activity、Receiver、Service之間進行交互的類,通過無參構造方法創建對象,增加其action、category、data、extra等屬性進行信息傳遞,并通過Activity中的startActivity(Intent intent)進行界面的跳轉;通過Context中的StartService(Intent intent)進行服務跳轉;通過Context中的registerReceive(Intent intent)對廣播進行注冊,并通過sendBroadcast()進行無序消息發送,或可以通過SendOrderedBroadcast()進行有序的消息發送。Handler類:
用來發送和處理消息,并配合主線程完成UI的更新;消息Message/Runnable傳遞通過MessageQueue(消息隊列,先進先出)進行傳遞,并通過Lopper進行接收,傳遞的消息可以為Message對象,也可以是Runnable對象;接收方法通過HandleMessage(Message msg)進行獲取。SharedPreferences類:
一般用于第一次登錄時的設置,或者是各個界面的一些小型格式設置,如字體等。是本地的小型共享數據庫,可以通過Context的靜態方法getSharedPreferences獲得其對象,對象內的值均為鍵值對進行儲存。通過SharedPreferences對象調用editor()獲取SharedPreferences.Editor對象,向共享數據庫中增加數據,putString(),并提交數據,commit();通過SharedPreferences對象獲取共享數據庫中的數據,getString()。
ViewPager:實現界面滑動的類;
通過設置OnPagerChangedListener設置ViewPager的監聽事件;
實現流程:
①布局文件中設置ViewPager控件;
②代碼中進行綁定控件;
③通過繼承PagerAdapter抽象類進行設置適配器,并傳遞數據源;
④適配器中實現兩個抽象方法,兩個重寫方法:getCount()—獲取滑動界面的數量,isViewFromObject()—判斷視圖是否是來自于Object文件中;重寫兩個方法,分別為destoryItem—銷毀指定位置的視圖;InstantiateItem(),設置指定位置的視圖;
Timer與TimerTask類:
Timer為計時器的類,通過無參構造方法可以獲取對象,通過Timer.schedule(TimerTask task,long time)進行設置多久后執行某任務,當任務執行完后,取消計時的功能,Timer.cancle();TimerTask類為抽象類,實例化時,必須重寫run方法;執行的內容,均在run方法中進行設置,并且執行時,已在子線程中進行執行。自定義View:用到的類有Paint、Canvas、Spec、SpecF、Path、View.MeasureSpec、Timer、TimerTask;
抽象類,通過子類繼承,獲取對象;在布局文件中綁定后,通過代碼,設置自定義View的屬性;自定義View中,通過重寫OnMeasure方法,對布局文件中的尺寸進行測量,并由View中的setMeasureDimenson()方法,進行數據的保存;通過重寫Ondraw方法,進行繪圖;當需要繪制動態圖形時,使用計時器Timer的schedule(TimerTask,long time,delay time2)方法,在time時間后,每隔time2時間,重寫執行run方法中的內容;將耗時的操作設置在run方法中,并通過View中的invalidate()方法刷新主線程中的繪的圖形,通過postInvalidate()刷新子線程中的圖形。數據庫:
常用的數據庫有Oracle,需要安裝和配置的大型收費數據庫;MySQL是中型數據庫,同樣需要安裝配置,但不需要收費;Sqlite是小型免費的嵌入式數據庫,占用內存低,最新版本為3.0。Sqlite數據庫需要通過SqliteDatabaseOpenHelper進行創建數據庫,并通過SqliteDatabase進行數據庫的操作。輔助類是抽象類,通過繼承,重寫兩個方法,并在子類的構造方法中通過OpenHelper的構造方法(Context context,String SqlName,SqliteDatabase.CursorFactory factory,int version)進行數據庫的創建,在onCreate方法中,進行數據庫表的創建,在onUpdate中進行數據庫的版本更新。在數據庫的操作類中,執行exect方法,通過sql語句對數據庫進行操作。Create table student(_id integer primary key auto increament ,name text);insert into student(_id,name)values(1,zx);delete from student where _id=1;update student set _id=2 where name=zx;select *from student;ListView、GridView適配器的優化:
將布局文件中的控件進行封裝,當視圖加載時,判斷可變視圖是否存在,當不存在時,通過布局文件獲取視圖,并新建封裝類,將地址通過setTag()進行發送;當視圖存在時,重復利用地址—getTag()。反射:
存儲數據的方式:
共享數據庫、數據庫、文件、網絡、內容提供者
廣播:
廣播傳播時,需要接收者、發送者、廣播頻道;根據發送者的發送方式不同,分為有序廣播、無序廣播;有序廣播為接收者有接收順序,根據設置的優先級不同,確定先后順序,接收者同時也是發送者,向后面的廣播發送消息,發送過程中,可以添加信息,也可以停止廣播的傳輸;無序廣播,接收者之間無聯系,均從發送者處接收信息;廣播在傳輸過程中,不能被添加信息,也不可能被停止。廣播在發送前,需要對接收者進行注冊,注冊方式有兩種,動態注冊、靜態注冊。動態注冊,是在代碼中進行,通過Context對象調用靜態方法進行注冊,所有的廣播均可以用動態注冊,其生命周期依賴于應用,相對于靜態注冊,比較節省內存;靜態方法在清單文件中進行注冊,部分系統廣播不能通過靜態注冊進行,其生命周期依賴于系統,當系統啟動,即運行接收廣播,較耗內存。廣播接收者需要繼承BroadcastReceiver,并實現抽象方法onReceive(),通過回調接口,進行數據的傳輸。注意:廣播發送前,必須進行接收者的注冊,并且,當顯示跳轉時,不需要意圖過濾器。安卓布局:九種布局
線性布局,水平或垂直方向兩種格式,主要特點為權重,即規定各控件在視圖中的占有的比例;
相對布局,相對于父控件或兄弟控件的布局,各控件需指定相對位置; 絕對布局,指定各控件在視圖中的絕對位置,幾乎不再使用; 表格布局,子布局放在行中,列由控件表示(TableRow); 幀布局:覆蓋前面布局的布局,一般用于暫停按鈕等; 風格布局:可以跨行、跨列的布局,占滿換行;
左右側滑:可以實現左右側滑,通過設置主菜單和二級菜單設置左右兩個菜單; 下拉刷新:設置下拉刷新、上拉加載的功能; 抽屜布局;
安卓版本及對應的API:
1.6—4;2—7;3—11;4—15;4.3—18;5—20;5.1—21;6—23;7—25; 安卓四層架構:
應用層:Java語言開發,主要從事App開發;
運行庫層:Java語言與C語言,View視圖、管理類等的開發; 架構層:C語言與Linux語言,各種框架、瀏覽器等; 內核層:Linux、C語言,開發各種驅動; 安卓四大組件:
Activity:界面,實現程序與用戶之間的交換,有自己的生命周期,七個生命周期;4種啟動模式 Service:
BroadcastReceive:三要素,發送者、接收者、發送頻道(Intent);類型:有序(接收有序,有數據傳送,可以攔截數據)、無序廣播(相對);注冊方式:靜態注冊,持久監聽,占用內存比較高生命周期跟隨系統,動態注冊(代碼中),所有廣播都可以動態注冊,部分系統廣播不能動態注冊,臨時監聽,占用內存較少,生命周期隨應用進行;
ContentProvide:不能存放數據,五種存放數據方式之一,特點為:①為數據的獲取等操作添加一個統一的接口②可以實現跨應用訪問數據;③可以實現Android中通訊錄、消息、音頻、視頻等的訪問或操作;通過ContentReceive進行數據的訪問,可以對數據進行增刪改查操作。
動畫: IO流: 序列化: AlertDialog:
Set實現類: 手機電量檢測:
自定義SurfaceView:
自定義View:三個構造方法的區別
Message:Handler.obtain/new/Message.obtain
HttpUriConnection訪問網絡
gride 異步任務 動畫
抽象類和接口 反射 克隆 序列化 側滑的實現 數據庫 Socket:
Gson解析
異步任務和子線程區別 WebView 版本更新 照片的圓角化
Collection與Collections Sql語句
MVP框架與MVC: TCP與UDP的區別: 一鍵分享的流程: Http協議的理解: 不使用框架訪問網絡: List集合與set集合: 自定義View的流程: 線性布局的特點: ViewPager的原理: 服務的啟動方式:
Activity的啟動方式: Xml數據解析:
第五篇:英語中介詞用法總結
一.介詞
1.At 表示時間:在.......時刻,在........點鐘。
at seven o'clock 在7點鐘 at noon 在中午 at midnight 在半夜 at dawn 在黎明 The plane will take off at eight o’clock.飛機將在8點起飛。We have lunch at noon.中午我們吃午飯。.表示地點:在........(常用于較小地方)。
at school 在學校
at home 在家
we meet at the bus stop。我們在公交車點見面。
He lives at a small village.他住在一個小村莊里。表示位置:在.........旁邊。
There is a bag of rice at the door.在門旁有一袋大米。表示方向
He aimed at the little bird.他瞄準那只小鳥。
He pointed at the boy in blue coat.他指著穿藍色上衣的那個小孩。表示狀態
The two countries were at war.那兩個國家在打仗。表示速度.價格等
The book is sold at two Yuan.這本書賣兩元錢。
2.In 表示時間:與年 月 周 季節 早晨 下午或晚上等名詞連用。in 1998 在1998年
in October 在10月份 in a week 一周內
in the morning 在上午
in the afternoon 在中午 in the evening 在晚上 in spring 在春季 I'll come back in a week.我將一周后回來。
He became a doctor in 1986.他在1986年成了一名醫生。表示地點
場所(此時多指大的地方)。
China is in Asia.中國位于亞洲。I live in Shanghai.我住在上海。表示穿著 帶著(衣服 帽子等)
The girl in red is Li Ming’s sister.穿紅衣服的女孩是李明的姐姐。There is a wolf in sheep's clothes.這是一只披著羊皮的狼。表示用某種語言
Can you sing the song in English? 你能用英語唱那首歌嗎? Please read the text in Chinese.請用中文讀這篇課文。
3.On 1)表示時間:具體到某一天或某一天的上午.下午或晚上。on Monday 在周一
on May 1st 在5月1號
on Sunday morning 在星期天的早晨 on the morning of June 2nd 在6月2號的上午。2)表示位置:在.......上,與物體接觸。
There is a map on the wall.墻上有一張地圖。He works on a farm.他在一個農場工作。3)表示“關于”
We will have a talk on the history of the Party this afternoon.今天下午我們要聽有關黨史的報告。
This is a book on science.這是一本有關科學方面的書。4)引申意義表示“從事......”“處于......情形”。
He is on duty today.今天他值日。They are on holiday.他們在度假。
4.During 表示“在......時候”(某段時間里)
Where are you going during the holiday? 假期里你要到哪兒去? 表示“在......期間”
He gave us a lot of help during his stay here.他在此逗留期間給了我們許多幫助。during the childhood 在孩提時代 during the summer 在夏季