第一篇: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 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学习总结
Android学习总结
零零碎碎的总结:
1.客户端的功能逻辑不难,UI界面也不难,但写UI花的时间是写功能逻辑的两倍.2.写代码前的思考过程非常重要,即使在简单的功能,也需要在本子上把该功能的运行过程写出来.3.要有自己的知识库,可以是一个工具类,把写过的,看过的好的代码放进去,也可以是一个笔记本软件.因为只有放在知识库里的东西,才是你最重要的财富.4.如果你想做自由职业者,你需要学英语,因为在国外的盈利比国内多很多.如果你想进大公司,好公司,你需要学英语.你想深入学习android,但中文的android文章太少了,你查查百度,到处都是copy来copy去的hellword,所以,你需要学英语.如果你想出国,你需要学英语.5.Http协议要研究透彻.http的信息头有什么信息,分别代表什么,信息体有什么信息,代表什么,都要搞的明明白白.scoket也是一样.6.在eclipse里的layout文件都有graphical Layout.通过这个好好的把UI调整好.7.Android里的junit每次运行都会打包新的apk到设备上跑.效率非常慢.如果是跟android无关的测试,最好自己建立一个单纯的java项目做测试.8.面试的时候不要觉得自己提的薪水太高,物以稀为贵明白吗?不管你的期望薪资多少,都有可能实现,这只是时间问题.9.如果一家小公司通过猎头找到你,即使公司在小,也比外面那些40,50人的公司还要好.不要觉得公司不行,担心会倒闭.放心吧,至少活1年是没问题的.10.不要把自己绑在android上,有空也研究下IOS(最近小弟就准备研究ios,刚买了6本书...).11.移动互联网最少还有10年的快速增长.android最少还有两年的快速增长.走android这条路是不会错的.12.有空多学点开放平台的SDK.比如新浪微博,腾讯微博,淘宝平台,支付宝移动支付平台,快钱移动支付平台等等..这些都是不愁没市场的.13.即使技术再差,也要发布一个应用到market上去.因为这样你才了解做一个应用的逻辑.14.每个月拿到薪水省500-1000元出来.这些钱投在买学习资料,去培训班上课...在培训班,花再多的钱也是值得的.15.你真正的价值在项目经验和对底层的认识上.不要忽略基础知识.16.如果有空把Android的源代码看一下.底层的东西很枯燥,但这些很值得学.17..程序员其实是艺术家.代码重构和设计模式,是非常非常重要的东西,必须要学
18.不要去维护一个项目,要去做一个项目.19.一开始不要轻易去大公司,虽然大公司是可以让你呆一辈子的.但你的起点低,以后成就也低.20:每天早上提前20分钟上班,5分钟把今天的工作计划写好.15分钟用来看各大It论坛的新闻.21:如果以前没做过java,那就把SSH看下,自己搭建一个小服务器.这是为了接私活用.22:PS一定要学,接私活用.23:多下载市面上好的应用,每天都用,只有这样你才能了解市场.现在所有的APK都可以反编译,看源代码麻烦,但看layout和图片很容易,所以....你懂的.24.要有羞耻心.25.老板仅仅要求你把东西做完,需求完成.但你必须对自己要更严格一点.写一段代码,从网上复制一份代码,并不是可以用就行了,你还必须明白他的原理,为什么这样就可以?这才是对你最有用的地方,这也是你今后薪资增长的保证.26.要懂得舍得.移动领域发展太快,必要时必须要用钱换时间.不然你会远远落后别人(我之前花了4000大洋去培训班学IOS三天).27.要明白自己想要什么,什么才能最大性价比提高你的能力.对我来说,能让我提高最大的,就是Android和IOS同时会,并且自己可以做架构设计.28.看android技术书籍最快的学习方法,先通读一次.然后把书本上的demo一个一个写出来.不要觉得太容易不去写.很多东西都是这样,看起来简单,但做起来难.最后再对照自己写出来的程序代码去理解书本的意思.29.应用和游戏是2个方向,没有一个公司会同时做游戏又做应用,即使是外包公司,大多也只做一块.专精一个就可以了.30.每次做完一个项目,要强迫自己做总结,通过这个项目,我学到了什么新技术?犯了哪些
SB错误?
31.一家小公司,如果有正式财务部,那肯定是正规的,不要担心欠薪问题.如果没有,就说不准了.bbs.12580life.com
第四篇:【原】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学习总结 20110325专题
Android学习总结
在这段时间主要对Android平台有了一定的了解,对一些简单的设计也有了一定的掌握Android概念
Android是一个基于Linux核心的开放手持设备(主要是手机)平台操作系统,与Windows Moble、Symbian等手机操作系统处于同一级别。“Android大奖赛“首页上列出的可能设计方向
多媒体工具社交网络新闻、资讯工具环保、慈善协作生产力工具Android Developer Challenge(ADC)游戏实时资讯服务崭新的用户界面您想到的应用程序项目构架
src/:源代码(sourse)目录
“src”目录包含了“Android应用程序”各个程序源文件。对于上例 ”Bmi.java”是新 序项目中的主要程序块。gen/:自动生成(Generate)目录
gen目录中存放所有自动生成的文件。最关键就是R.java,这个文件是自动产生的,与”res”目录下的XML文件内容同步更新。
Android<版本号>/:参考函数目录
此目录的作用是将AndroidSDK里所有可呼叫的类、方法函数,分门别类的列出,好方便开发者来参考。
assert/:对此目录目前还不是太懂 res/:资源(Resource)目录
res目录存放所有程序中用到的资源文件。在里边还有两个经常访问的目录,分别 “layout/:页面布局(layout)目录”和“values/:参数值(values)目录”
“AndroidManifest.xml”是Android应用程序的功能列表,每个应用程序都在这个文件中,列出该程序所提供的功能。我完成的BMI程序
此程序是我参考书上的例子所完成的程序。
BMI,英文全称:Body Mass Index,中文名称:身高体重指数,是一个计算值,整个程序的思路是当我们在对应的文本框内输入身高(cm)、体重(kg),输入完成后按下“计算BMI”键,屏幕上就会显示计算结果,并弹出“你应该节食”、或“你应该多吃点”等健康建议的信息框。
健康指标的计算方法是:身高(height)/(体重(weight)/100)只要BMI值超过25时就算偏胖、BMI值低于20就算偏瘦,介于这之间算正常。
下面是我完成的程序界面:
计算得到的BMI值是20.57,在20—25之间,体型正常。由于我对两个文本框内输入的内容进行了限制,因此只容许输入数字
BMI值为25.56,信息框弹出“你该节食了”
在界面的下侧有一个“健康小常识按钮”,当点击此按钮时,会链接到一个有关健康生活小常识的网页上:
在每次点击“计算BMI值”按钮后首先会弹出一个消息框,消息框中包括两个按 钮,当点击确认按钮时消息框消失;当点击首页按钮时会连接到相应的网页
下图为点击消息框确认按钮后显示的网页:
总结
通过这段时间的学习,对于Android平台的整个基本框架有了一定的了解,对程序整个运 及相互之间的调用流程也有了一定的掌握,但感觉自己java基本功比较薄弱,还得进一步学习。由于目前还没有什么想法,我打算在后面的一段时间内主要还是继续掌握这方面知识,做一个类似于计算器之类的小软件,以巩固我这方面的知识。在查阅资料方面我还有点欠缺,尤其比较怕读英文资料,这方面还得加强。