getScrollY之类的 是不是就是滑动摩擦力的Y轴距离

[android]&ScrollView&滑动后回弹&的实现
要实现的效果是:上下滑动 ScrollView
,松手时其回到一个固定的位置,
参考了很多资料以及编码调试,终于研究出来了~~ 与大家分享:
—————————————— 事件处理代码 ——————————————
在触摸监听事件中,设立对onKeyUp的监听,在手指离开屏幕后用
&handler.sendMessageDelayed(
&&&&&&handler.obtainMessage(TOUCH_EVENT_ID,scroller),
每隔5毫秒getScrollY()一次,然后比较getScrollY()的值,
直到与上次得到的相等时,就是scrollview停止滑动了。
代码如下:
& mScrollView.setOnTouchListener(new
OnTouchListener() {
&private int lastY = 0;
&&&&&&private
static final int TOUCH_EVENT_ID = 1;
public boolean onTouch(View v, MotionEvent event) {
&// TODO Auto-generated method stub
&& if(event.getAction() ==
MotionEvent.ACTION_UP) {//触摸松手时
&&&&&&&&&&&
&handler.sendMessageDelayed(handler.obtainMessage(TOUCH_EVENT_ID,v),
&&&&&&Handler
handler = new Handler() {
&@Override
&public void handleMessage(Message msg) {
&&&&&&&&&&&
super.handleMessage(msg);
&&&&&&&&&&
&View scroller = (View)msg.
&&&&&&&&&&&
if(msg.what==TOUCH_EVENT_ID) {
&&&&&&&&&&&&
&if(lastY ==scroller.getScrollY()) {
&&&&&&&&&&&&&&&
&handleStop(scroller);//调用停止时处理方法
&&&&&&&&&&&&
&&handler.sendMessageDelayed(
&&&&&&&&&&&&&&&&&&&&&&handler.obtainMessage(TOUCH_EVENT_ID,scroller),
&lastY = scroller.getScrollY();
&&&&&&&&&&&
&&&&&&//这里写真正的事件
&private void handleStop(Object view)
{//滑动停止时要进行的处理
&& & ScrollView
scroller = (ScrollView)
scroller.scrollTo(0, mScrollOffset);
————————————————& 关于布局 ————————————————————
若ScrollView内包围的东西没超出一屏时,是不会滚动的,所以要弄些添补组件使整个界面超出一屏,比如以下边红色的
TextView 作添充,可以这样做:
&ScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
&android:layout_height="fill_parent"&
&&&&&&LinearLayout
android:id="@+id/linearLayout"
android:orientation="vertical"
&android:layout_width="fill_parent"
&&&&&&&&&android:layout_height="fill_parent"
&android:gravity="center_horizontal"&
& &&&TextView
&android:layout_width="fill_parent"
&android:layout_height="70dp"
&&ImageView
android:layout_width="wrap_content"
android:layout_height="240dp"
android:scaleType="matrix"
&android:src="@drawable/tip"
android:id="@+id/conversation_emptyImageView"
android:layout_width="wrap_content"
&android:layout_height="wrap_content"
&android:text="@string/tip"
&&& &TextView
android:layout_width="fill_parent"
android:layout_height="160dp"
/&&&&/LinearLayout&
&/ScrollView&&
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Android开发实例IMF(Android SDK Sample—SoftKeyboard)详解2 - 贪吃蛇 - ITeye知识库频道
四、源代码解析
(一)概述
从InputMethodServiceSample项目可以看出实现一个输入法至少需要CandidateView, LatinKeyboard, LatinKeyboardView,SoftKeyboard这四个文件:
&&& CandidateView负责显示软键盘上面的那个候选区域。
&&& LatinKeyboard负责解析并保存键盘布局,并提供选词算法,供程序运行当中使用。其中键盘布局是以XML文件存放在资源当中的。比如我们在汉字输入法下,按下b、a两个字母。LatinKeyboard就负责把这两个字母变成爸、把、巴等显示在CandidateView上。
&&& LatinKeyboardView负责显示,就是我们看到的按键。它与CandidateView合起来,组成了InputView,就是我们看到的软键盘。
&&& SoftKeyboard继承了InputMethodService,启动一个输入法,其实就是启动一个InputMethodService,当SoftKeyboard输入法被使用时,启动就会启动SoftKeyboard这个Service。
(二)LatinKeyboard.java
软键盘类,直接继承了Keyboard类,并定义一个xml格式的Keyboard的布局,来实现一个输入拉丁文的键盘。这里只是创建一个键盘对象,并不对具体的布局给出手段。
为了更好的理解LatinKeyboard类,这里简单介绍一下Keyboard类。Keyboard可以载入一个用来显示键盘布局的xml来初始化自己,并且可以保存这些键盘的键的属性。他有三个构造函数:
&&& Keyboard(Context context, int xmlLayoutResId),用语境和xml资源id索引xml文件来创建。
&&& Keyboard(Context context, int xmlLayoutResId, int modeId),这个和上面差不多,只不过多了一个modeld。
&&& Keyboard(Context context, int layoutTemplateResId, CharSequence characters, int columns, int horizontalPadding),这个比较复杂,用一个空xml布局模板创建一个键盘,然后用指定的characters按照从左往右,从上往下的方式填满这个模板。
本文件源码前面完全继承keyboard,直接用了父类构造函数进行初始化。
这里因为重写了Keyboard类的createKeyFromXml(Resources res, Row parent, int x, int y, XmlResourceParser parser),为了要返回一个Key对象,干脆直接创建LatinKey对象好了。从这里我们能看出面向对象和使用框架的要求。
接着,本文件重载了一个createKeyFromXml的函数,这是一个回调函数,它在键盘描绘键的时候调用,从一个xml资源文件中载入一个键,并且放置在(x,y)坐标处。它还判断了该键是否是回车键,并保存起来。在这里,为了要返回一个Key对象,于是直接创建内部类的LatinKey对象。从这里我们能看出面向对象和使用框架的要求。
此外,还有一个函数是:setImeOptions,它是根据编辑框的当前信息,来为这个键盘的回车键设置适当的标签。输入框的不同,会产生不同的回车键的label或者icon。在这个函数中,有一个技巧是用了一些imeOption的位信息,比如IME_MASK_ACTION等等。主要是查看的EditorInfo的Action信息,这里有:
&&& IME_ACTION_GO: go操作,将用户带入到一个该输入框的目标的动作。确认键将不会有icon,只有label: GO
&&& IME_ACTION_NEXT: next操作,将用户带入到该文本框的写一个输入框中。如: 编辑短消息的时候,内容就是收件人手机号码框的next文字域。它也只是一个NEXT label就行了。
&&& IME_ACTION_SEARCH: search操作,默认动作就是搜索。如: 在URL框中输入的时候,默认的就是search操作,它提供了一个像放大镜一样的icon。
&&& IME-ACTION_SEND: send操作,默认动作就是发送当前的内容。如: 短消息的内容框里面输入的时候,后面通常就是一个发送操作。它也是只提供一个Label:SEND
&&& DEFAULT: 默认情况下表示文本框并没有什么特殊的要求,所以只需要设置return的icon即可。
最后,它还定义了一个内部类——LatinKey,它直接继承了Key,来定义一个单独的键,它唯一重载的函数是isInside(int x , int y ),用来判断一个坐标是否在该键内。它重载为判断该键是否是CANCEL键,如果是则把Y坐标减少10px,按照他的解释是用来还原这个可以关掉键盘的键的目标区域。
(三)LatinKeyboardView.java
这里就是个View,自然也继承自View,因为前面创建的键盘只是一个概念,并不能实例出来一个UI,所以需要借助于一个VIEW类来进行绘制。这个类简单的继承了KeyboardView类,然后重载了一个动作方法,就是onLongPress。
它在有长时间按键事件的时候会调用,首先判断这个按键是否是CANCEL键,如果是的话就通过调用 KeyboardView被安置好的OnKeyboardActionListener对象,给键盘发送一个OPTIONS键被按下的事件。它是用来屏蔽CANCEL键,然后发送了一个未知的代码的键。
(四)CandidateView.java
CandidateView是一个候选字显示view,它提供一个候选字选择的视图,直接继承于View类即可。在我们输入字符时,它应该能根据字符显示一定的提示,比如拼音同音字啊,联想的字啊之类的。
1. 先看它定义了那些重要变量:
&&& mService: candidateView的宿主类,即该view是为什么输入法服务的。
&&& mSuggestions: 建议。比如说当我们输入一些字母之后输入法希望根据输入来进行联想建议。
&&& mSelectedIndex: 用户选择的词的索引。
&&& mSelectionHighlight: 描绘选择区域高亮的类。
&&& mTypedWordValid: 键入的word是否合法正确。
&&& mBgPadding: 背景填充区域。
&&& mWordWidth: 每个候选词的宽度。
&&& mWordX:每个候选词的X坐标。有了这两个变量,就能够在屏幕上准确的绘制出该候选键。
&&& mColor*:定义了各种颜色。
&&& mPaint: 一个绘图类,后面会用到
&&& mVerticalPadding: 垂直填充区域。
&&& mTargetScrollX: 目标滚动的横坐标,即要将目标滚动到何处。
&&& mTotalWidth: 总的宽度
&&& mGestureDetector: 声明一个手势监测器
GestureDetector对象似乎很少见,让我们了解一下android.view.GestureDetector。这是一个与动作事件相关的类,可以用来检测各种动作事件,这里称之为:手势监测器。它的回调函数是GestureDetector.OnGestureListener,在动作发生时执行,而且只能在触摸时发出,用滚动球无效。要使用这个通常要先建立一个对象,如同代码里体现的,然后设置GestureDetector.OnGestureListener 同时在 onTouchEvent(MotionEvent)中写入动作发生要执行的代码。
2. 构造函数,主要是对一些变量的初始化工作。
首先初始化了mSelectionHighlight,这是一个drawable对象,并利用drawable的setState方法设置这个drawable的初始状态。同时在res目录下加入一个color.xml文件来定义用到的所有颜色资源,然后用R索引,这些资源可以被加入到自己的R.java的内容里,可以直接引用。 剩下的内容就是初始化背景,选中,未选中时的view的背景颜色,这里都是在前面color.xml内定义的了。用这样的方式获得:
Resources r = context.getResources();
获得当前资源对象的方法。
setBackgroundColor(r.getColor(R.color.candidate_background));
然后初始化了一个手势检测器(gesturedetector),它的Listener重载了一个方法,就是onScroll,这个类是手势检测器发现有scroll动作的时候触发。在这个函数里,主要是进行滑动的判断。
这里用到了很多view下的方法:getScrollX();getWidth();scrollTo(sx, getScrollY());invalidate();我们分别解释如下:
&&& getScrollX():获得滚动后view的横坐标
&&& scrollTo():滚动到目标坐标
&&& getScrollY():获得滚动后view的纵坐标
&&& invalidate():使view重画
在这里,distanceX是上次调用onscroll后滚动的X轴距离。假设这个view之前没有被滚动过,第一次滚动且坐标在显示区域内,sx=getScrollX()+distanceX,则view就scrollTo这个位置。如果sx超过了最大显示宽度,则scrollTo就滚想原先sx处,也就是不动。也就是说:系统滚动产生一个惯性的感觉,当你把view实际到了X坐标点,系统再给你加一个distanceX,这个distanceX不是两个动作之间的距离,应该是上一个滚动动作的停止点和本次滚动动作的停止点之间的距离,这个距离系统自己算,我们不用管,只要到了最大边界,view就不再滚动,或者说是原地滚动。
&&& setHorizontalFadingEdgeEnabled(true);// 设置view在水平滚动时,水平边是否淡出。
&&& setWillNotDraw(false);// view不自己绘制自己
&&& setHorizontalScrollBarEnabled(false);// 不设置水平滚动条
&&& setVerticalScrollBarEnabled(false);// 不设置垂直滚动条
3. setService 是设置宿主输入法。
4. computeHorizontalScrollRange ,表示这个view的水平滚动区域,返回的是候选视图的总体宽度。
5. onMeasure ,重载自view类,在布局阶段被父视图所调用。比如当父视图需要根据其子视图的大小来进行布局时,就需要回调这个函数来看该view的大小。当调用这个函数时必须在内部调用setMeasureDimension来对宽和高进行保存,否则将会有异常出现。这里重载它是为了系统检测要绘制的字符区的大小,因为字体可能有大小,应根据字体来。它首先计算自己的期望的宽度,调用resolveSize来看是否能够得到50px的宽度;然后是计算想要的高度,根据字体和显示提示区的padding来确定。
6. onDraw ,view的主要函数,每个view都必须重写这个函数来绘制自己。它提供了一块画布,如果为空,则直接调用父类来画。
在这里的内部逻辑大概如下:
判断是否有候选词,没有的话就不用绘制。
初始化背景的填充区域,直接view的背景中得到即可。
对于每一个候选词,得到其文本,然后计算其宽度,然后再加上两边的空隙。
判断是否选择了当前词:触摸的位置+滚动了的位置。如果是在当前词的左边到右边之间,则将高亮区域绘制在画布上面,高亮区域设置的大小即为当前词的大小,并且保存被选词的索引。
将文本绘制在这个候选词的画布上面,它进行了一个判断,判断哪个才是推荐词。默认情况下是候选词的第一个词,但是它判断第一个词是否是合法的,如果是,则第一个词是候选词,否者第二个词才是候选粗,然后进行绘制。
绘制一条线,来分割各个候选词。上面提到的总共的宽度在所有的词都绘制出来之后,就能够得到了。
判断目标滚动是否是当前的,不是就需要滚动过去。
7. scrollToTarget ,滚到到目标区域。得到当前值,然后加上一个滚动距离,看是否超过并进行相应调整,之后滚动到相应坐标。
8. setSuggestions ,设置候选词,之后进行绘制。
9. onTouchEvent ,触摸事件产生时调用。首先判断是否为gesturedetector监听的动作,如果不是就进行下面处理。初始化动作,把发生的动作记录下来,点触的坐标也记录下来。然后,根据动作类型分类反应:
&&& 向下:没动作;
&&& 移动:如果是向左移动就要手动的选择候选词;
&&& 向上:需要手动选择候选词。
10. takeSuggestionAt ,选择在坐标x处的词,这个处理的是用户轻轻点击键盘,也就是选择候选词。
11. removeHighlight ,去除高亮显示。
(五)SoftKeyboard.java
整个输入法的总体的框架,包括什么时候创建,什么时候显示输入法,和怎样和文本框进行通讯等等。上面的文件,都是为了这个类服务的。总体来说,一个输入法需要的是一个输入视图,一个候选词视图,还有一个就是和应用程序的链接。
基本时序图如下:
输入法在Android中的本质就是一个Service,假设用户刚刚启动Android,用户移动焦点首次进入文本编辑框时,Android便会通知Service开始进行初始化工作。于是便有了如图中的一系列动作。
追根溯源,onCreate方法继承至Service类,其意义和其他Service的是一样的。Sample在这里,做了一些非UI方面的初始化,即字符串变量词汇分隔符的初始化。
接下来执行onInitializeInterface,这里是进行UI初始化的地方,创建以后和配置修改以后,都会调用这个方法。Sample在这里对Keyboard进行了初始化,从XML文件中读取软键盘信息,封装进Keyboard对象。
第三个执行的就是onStartInput方法,在这里,我们被绑定到了客户端,接收所有关于编辑对象的详细信息。
第四个执行的方法是onCreateInputView,在用户输入的区域要显示时,这个方法由框架调用,输入法首次显示时,或者配置信息改变时,该方法就会被执行。在该方法中,对inputview进行初始化:读取布局文件信息,设置onKeyboardActionListener,并初始设置 keyboard。
第五个方法是onCreateCandidatesView,在要显示候选词汇的视图时,由框架调用。和onCreateInputView类似。在这个方式中,对candidateview 进行初始化。
第六个方法,也是最后一个方法,即onStartInputView,正是在这个方法中,将inputview和当前keyboard重新关联起来。
在上面的六个方法中,onCreateInputView和onCreateCandidatesView两个方法只有在初始化时才会执行一次,除非有配置信息发生改变。那么究竟什么是配置信息发生改变呢?在看InputMethodService的API文档时,可以看到有一个方法onConfigurationChanged,根据文档解释,这个方法主要负责配置更改的情况。在示例中,其没有override这个方法,但是在android源码包中的PinyinIME中,有使用这个方法,有兴趣的朋友可以在看完SoftKeyboard Sample之后,看看PinyinIME的源码。
关于本类中其它的一些方法,由于比较直观,就不进行讲解了,感兴趣的朋友可以参考《android sdk中 softkeyboard的自己解析(4) 》。
五、输入法调试
通过使用调试模式加断点的方式,有助于我们更好的理解输入法的时序和每个类及其方法的功能和调用持续。
这里使用Eclipse的DDMS透视图进行调试,具体介绍参考《用Eclipse开发和调试Android应用程序 》
首先切换到DDMS模式,在这个模式下面,DDMS将链接到正在运行的手机或模拟器,并且能够提取手机上面的各种信息,比如线程,还有各个正在后台运行的服务等等。点击工具条上的“Debug selected Process”,就能够将调试器植入到这个服务上面。
之后切换到debug模式,就会发现调试器已经链接到了这个模拟器,然后就可以像调试普通的程序一样调试这个输入法了。
通过debug模式,我们可以发现,输入法首先执行的onCreateInputView-& onCreateCandidatesView,而在这个时候,这个输入法的界面一点儿都还没有显现出来。当我们在一个输入框中点击鼠标时,系统会产生一个事件,最开始就被输入法捕获,然后再将控制权交给这个输入法。另外,切换对象的时候,输入法总是认为是一次输入的结束,然后进行一系列的reset工作。所有的键盘等事件,都会首先传递给输入法,所以,如果一个按键事件不是我们所能够处理的问题,我们需要将这个事件继续传递下去,而不要丢弃了,因为这可能是别的控件的事情。
在发送消息的界面,在输入完TO某人之后,点击content输入框,首先调用的是onFinishInput,也就是结束上一次的输入,准备这次的输入。之后调用的是onStartInputView,让界面显示出来。接着调用onStartInput,表示开始正式的输入。在这过程中,要完成根据不同的输入框,选择不同的键盘,当你输入一个键,首先触发的是onKey回调,在这里要判断是输入的普通字符,还是控制性的字符,比如删除,返回等等。比如这里输入一个 'g',然后会调用处理普通字符的函数handleCharacter。这里的策略就是,输入一个普通字符,就将Composing增加,并且更新这个候选词的列表。这里有一个很微妙的开关,就是mPrediction,它就是判断是否是需要保存这个Composing。在比如说URL框中输入的时候,就会置这个开关为关,直接将键入的输入到文本框中去。
为了测试所有的函数,你必须想出一种输入方式,让每个函数你都能执行到,那你就能够看清楚输入法的本来面目。
请各位朋友自己试试,对阅读和理解源代码的流程、时序和生命周期很有好处。也可以方便的找到自己的代码的bug。
六、输入法的调用
希望从一个View上调用输入法和接收输入法传过来的字符串,可以通过调用EditText这个widget。但是,如果要做出很炫很个性的输入法,就必须自己去和EditText一样连接输入法,介绍如下:
首先,定义一个继承自BaseInputConnection的类。前文提到过,输入法是通过commitText来提交选中字符。
&&& public class MyBaseInputConnection extends BaseInputConnection{
&&& public MyBaseInputConnection(View targetView, boolean fullEditor) {
&&& super(targetView, fullEditor);
&&& public static String tx="";
&&& //输入法程序就是通过调用这个方法把最终结果输出来的
&&& @Override
&&& public boolean commitText(CharSequence text, int newCursorPosition) {
&&& tx = text.toString();
BaseInputConnection相当于一个InputMethodService和View之间的一个通道。每当InputMethodService产生一个结果时,都会调用BaseInputConnection的commitText方法,把结果传递出来。
之后,采用如下方式,呼出输入法,并且把自定义的BaseInputConnection通道传递给InputMethodService。
&&& public class MyView extends XXView ...{
&&& //得到InputMethodManager
&&& InputMethodManager input = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
&&& //定义事件处理器
&&& ResultReceiver receiver = new ResultReceiver(new Handler() {
&&& public void handleMessage(Message msg) {
&&& //在你想呼出输入法的时候,调用这一句
&&& input.showSoftInput(this, 0, mRR);
&&& @Override
&&& //这个方法继承自View。把自定义的BaseInputConnection通道传递给InputMethodService
&&& public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
&&& return new MyBaseInputConnection(this, false);
低级界面上面,自己调用输入法并接收输入法的输出结果,就是这样的。
标签: Android, 移动开发, 游戏开发, snake, 贪吃蛇, 安卓1)">1)">1" ng-class="{current:{{currentPage==page}}}" ng-repeat="page in pages"><li class='page' ng-if="(endIndex<li class='page next' ng-if="(currentPage
相关文章阅读说来说去都不如 画图示意 简单易懂啊!!!真是的! 来吧~~先上张图~~!
(一)首先明确一下&android 中的坐标系统&:
&&&&&屏幕的左上角是坐标系统原点(0,0)
&&&&&原点向右延伸是X轴正方向,原点向下延伸是Y轴正方向
(二)关于Scroll: 屏幕显示的内容很多时,会有超出一屏的情况,于是就产生了Scroll的概念。
&&&&&&在View类中有个方法:
&&&&&&getScrollY()&&英文原文描述是:
&&&&&&Return the scrolled top position of this view. This is the top edge of the displayed part&of your view....
&&&&&&其实理解起来仍然就是:就是这个view相对于“坐标系统原点”(见上图)在Y轴上的偏移量.(getScrollX同理)
&&&&&【哇哈,有了图就是好说明啊~ 省了多少语言描述啊,而且还不一定能说清楚~】
& & &&getScrollY()就是当前视图相对于屏幕原点在Y轴上的偏移量.
(三)MotionEvent类中&getRowX()和&getX()的区别:
&&&&&&event.getRowX():触摸点相对于屏幕原点的x坐标
&&&&&&event.getX():&&&触摸点相对于其所在组件原点的x坐标
&&&&&于是乎: view.getScrollY() &#43; event.getY() 就得到了view中的触摸点在Y轴上的偏移量
(四)TextView类中
&&&&&&&有个 getLayout()方法:the Layout that is currently being used to display the text. This
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&can be null if the text or width has recently changes.
&&&&&&&其返回类型是Layout ,也就是返回textView的布局。
&&&&&&&然后重要的是通过这个 layout调用一个方法:
&&&&&&&getLineForVertical(int verticalPointPosition)&&//得到某点在垂直方向上的行数&#20540;
&&&&&&&于是综上所述,在实际的触摸事件中可以这样使用:
&&&&&&&Layout layout=textView.getLayout();
&&&&&&&int line = layout.getLineForVertical(textView.getScrollY() &#43; (int) event.getY());
&&&&&&&//得到触摸点在textView中垂直方向上的行数&#20540;。参数是触摸点在Y轴上的偏移量
&&&&&&接下来继续介绍一个方法,要用到上边的 layout 和 line:
&&&&&&layout.getOffsetForHorizontal( line ,&&(int) event.getX() );
&&&&&&//得到触摸点在某一行水平方向上的偏移量。
&&&&&&&&参数分别是: 该行行数&#20540; 和 触摸点在该行X轴上的偏移量。
&&&&&&&&此方法得到的该&#20540;会根据该行上的文字的多少而变化,并不是横向上的像素大小;&
整个坐标系是以手机屏幕左上角为原点(0,0),如果在屏幕没有滑动之前,这一理解肯定是ok的,但在滑屏之后,就会产生很多歧义和混淆,原因在于使用过程当中,很多方法的参数并非是参照屏幕,而是相对于父视图,对这整个过程和后面自定义控件的坐标变化带来的各个参数变化来说理解起来就并不那么适合了,最开始给人的感觉是越来越不清楚这个坐标该怎么设置,好像坐标系总在发生变化,后来才慢慢在思维当中构建起视图与视图容器以及屏幕之间的关系。
android.view.View.layout(int l, int t, int r, int b)& &&layout的过程就是确定View在屏幕上显示的具体位置,在代码中就是设置其成员变量mLeft,mTop,mRight,mBottom的&#20540;,这几个&#20540;构成的矩形区域就是该View显示的位置,不过这里的具体位置都是相对与父视图的位置。mLeft代表当前view.layout的这个view的左边缘离它的父视图左边缘的距离,拿上面“子视图2.layout(int
l, int t, int r, int b)&”来说,它的父视图便是子视图1,2,3合起来形成的整个大矩形,那么这里将父视图的左上角定为(0,0),那么可以确定mLeft为一个子视图宽度320,以此类推,mTop指当前view的上边缘离父视图上边缘的距离。而以此为界,mRight所指的是当前view的右边缘离父视图左边缘的距离,一&#30524;可以看出&#20540;为640(mLeft&#43;自己的宽度),mBottom也是指当前view的下边缘离父视图的上边缘的距离。至于为何如此,大概是因为坐标系的缘故,坐标中的任何点都必须以(0,0)为起点,XY轴为衡量。
视图左侧位置&&view.getLeft()&
视图右侧位置 view.getRight()
视图顶部位置 view.getTop();
视图底部位置 view.getBottom();
这四个方法所获取到的各个左上右下的&#20540;与layout的四个参数代表的是一样的,都是相对父视图的左边缘与上边缘。
视图宽度 view.getWidth();
视图高度 view.getHeight()&;
这两个方法获取的是该view的高和宽,仅仅在滑动的情况下,或者说该view的大小如果不发生变化,它的&#20540;是不会变的。
getMeasuredWidth();
getMeasuredHeight();
说到这里就不得不提getWidth()、getHeight()和getMeasuredWidth()、getMeasuredHeight()这两对函数之间的区别,getMeasuredWidth()、getMeasuredHeight()返回的是measure过程得到的mMeasuredWidth和mMeasuredHeight的&#20540;,而getWidth()和getHeight()返回的是mRight
- mLeft和mBottom - mTop的&#20540;。一般情况下layout过程会参考measure过程中计算得到的mMeasuredWidth和mMeasuredHeight来安排子视图在父视图中显示的位置,但这不是必须的,measure过程得到的结果可能完全没有实际用处,特别是对于一些自定义的ViewGroup,其子视图的个数、位置和大小都是固定的,这时候我们可以忽略整个measure过程,只在layout函数中传入的4个参数来安排每个子视图的具体位置。
view.getX();
view.getY();
getX和getY获取到的&#20540;为相对于父视图而言的两个左边缘和上边缘的距离。
view.getLocationOnScreen(location);&&该方法可以获取到当前view与屏幕的关系,location(0)代表X&#20540;,表示该view的左边缘与屏幕的左边缘之间的距离。可以想象,当滑屏产生,view开始移动该&#20540;肯定会改变的。location(1)代表Y&#20540;,表示该view的上边缘与屏幕的上边缘之间的距离,该距离肯定是包含标题栏的高度的。
getLocationInWindow();&&
ps:View.getLocationInWindow()和 View.getLocationOnScreen()在window占据全部screen时,返回&#20540;相同,不同的典型情况是在Dialog中时。当Dialog出现在屏幕中间时,View.getLocationOnScreen()取得的&#20540;要比View.getLocationInWindow()取得的&#20540;要大。
VelocityTracker.getXVelocity() 指滑动速度包括速率和方向两个方面,往左滑动小于0,&#20540;为负;往右滑动大于0,&#20540;为正。
view.scrollTo(x,y)&&将整个父视图的左上角定为(0,0),再移动这个屏幕的左上角到父视图的点(x,y)处,注意此处的x和y是根据父视图的坐标系来定的。
view.scrollBy(x,y)&&x代表横向移动的距离,y代表纵向移动的距离
view.getScrollX
view.getScrollY
将整个父视图的左上角定为(0,0),那么子view.getScrollX会获取到屏幕左边缘减去父视图的左边缘为0的距离,特别当滑屏时,父视图会被迫隐藏一部分,因为屏幕的大小是固定的。getScrollY以此类推。
event.getX()
event.getY()
该方法是不受视图影响的,X和Y的&#20540;仅仅代表手指在以左上角(0,0)为原点的屏幕触摸点的坐标&#20540;。
Scroller.getCurrY()
Scroller.getCurrX()
该方法拿横轴来说,代表屏幕的左边缘离父视图的左边缘的距离。
Scroller.startScroll(int startX, int startY, int dx, int dy)&
四个参数分别表示起点的坐标和滑动的向量,即从(startX,startY)开始滑动,横向滑动dx的距离,纵向滑动dy的距离(正&#20540;向左滑,负&#20540;向右滑),而这里的startX,startY又是参照的父视图左上角为原点坐标的坐标系,滑屏时经常使用getScrollX()和getScrollY()来代表屏幕左边缘和上边缘处于父视图坐标系的具体位置
TranslateAnimation()
参数参照:.cn/s/blog_90b91bf10101ai3e.html
以上是在做滑屏控件经常用到的方法,一方面需要了解layout和measure的基本流程,更重要一方面,当你想要实现某一个效果的时候,比如slidingmenu那样的控件,查看源码我们可以知道它是继承的ViewGroup,该怎样入手去做呢。
首先,需要了解它的父视图是什么,slidingmenu为例,打开程序,第一&#30524;,是一个很普通的视图页面,当向右滑动手指,这个视图页面开始向右边移动,而从左边会慢慢移出来另一部分视图,看上去像是抽出来的或者是隐藏的,事实上抛开阴影效果来讲,想象手机屏幕的左边有一部分我们看不到的视图,它就是这个被抽出来的menu视图了。概括来说,一个主view,一个menu其实是并排于一个大视图上面的。
找到了父视图,接下来就好办了,认定这个父视图的宽度就是主view的宽度和menu的宽度之和(暂不考虑padding之类),高度就是屏幕的高度,那么在思维当中这个二维平面就产生了,将它想成一张纸,然后对准主view将这张纸贴到手机屏幕上,左右滑动,会看到其实slidingmenu也就是这么个效果。
然后,实现的思路会清晰很多。定义这个父视图为myview继承viewgroup,原因在于尽管主view和menu并排在一个大view下,但毕竟两者的内容不同,后面需要放进不同的控件处理不同的事件,这个父视图内包含着两个view,到时候处理起来会方便很多,setcontentview为这个父视图,那么打开程序的第一&#30524;就会看到它。再定义这两个view设置好两个内容布局,并将它们addview添加到myview当中。外部工作基本就完成了,可以呈现父视图,并且父视图内有两个子view。
接下来,需要去完善一些细节,父视图内的子view该如何放置,这是关乎成败的一环,也就是如何将这张纸贴到我们希望的位置,这时就是onlayout的处理了,处理好屏幕,父视图子view之间的位置关系,通过各自的layout参数设置来摆放妥当各个view,比如开始的时候menu是隐藏的,这个就是通过位置的摆放设置的,然后它是从左边滑出来的,说明它处于父视图的左边位置,而主view处于相对右边的位置,而屏幕刚好也处于父视图右边的位置,恰好能看到主view的全貌,在脑海里如果能有清晰的画面出现,实现起来就会轻松很多。当实现了这个摆放,就可以理解menudrawer里面上下左右都可以滑出menu的结构了。
最后,便是滑动效果,请相信这样的控件里面,任何处理肯定都会和view位置的摆放扯上关系,滑动方向,滑动距离等等都涉及到坐标的处理。这也是为何上面列出那些常用的获取view坐标的方法。
总结下来,构建类&#20284;这样的控件,也就这三点,明确父子视图和屏幕的关系,通过坐标和位置参数设置它们的关系,处理这些关系发生变化的情况。
当然,事实上slidingmenu远远没这么简单,其中为了方便后续开发,它内置了很多接口和处理,大多数都是位置坐标和事件监听相关联,而万变不离其宗的是,它也肯定有这三个方面的构建,理解了这些基本的东西,尝试做一些自己想象的效果,对自定义的理解来说,进步会非常大。
资料来自互联网
getLocalVisibleRect&, 返回一个填充的Rect对象, 感觉是这个View的Rect大小,left,top取到的都是0
getGlobalVisibleRect&, 获取全局坐标系的一个视图区域, 返回一个填充的Rect对象;该Rect是基于总整个屏幕的
getLocationOnScreen&,计算该视图在全局坐标系中的x,y&#20540;,(注意这个&#20540;是要从屏幕顶端算起,也就是索包括了通知栏的高度)//获取在当前屏幕内的绝对坐标&
getLocationInWindow&,计算该视图在它所在的widnow的坐标x,y&#20540;,//获取在整个窗口内的绝对坐标 (不是很理解= =、)
getLeft&,&getTop,&getBottom,&getRight,& 这一组是获取相对在它父亲里的坐标
**注**:如果在Activity的OnCreate()事件输出那些参数,是全为0,要等UI控件都加载完了才能获取到这些
&&& int[] location = new int[2];
&&& v.getLocationOnScreen(location);
&&& int x = location[0];
&&& int y = location[1];
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15834次
积分:3430
积分:3430
排名:第3360名
原创:261篇
转载:402篇
(160)(52)(72)(111)(58)(125)(56)(29)

我要回帖

更多关于 滑动轴承 的文章

 

随机推荐