第一篇:【原】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 在夏季