`
v5browser
  • 浏览: 1137118 次
社区版块
存档分类
最新评论

android 阶段总结1

 
阅读更多

 View.java
    /**
     * <p>
     * This is called to find out how big a view should be. The parent
     * supplies constraint information in the width and height parameters.
     * </p>
     *
     * <p>
     * The actual mesurement work of a view is performed in
     * {@link #onMeasure(int, int)}, called by this method. Therefore, only
     * {@link #onMeasure(int, int)} can and must be overriden by subclasses.
     * </p>
     *
     *
     * @param widthMeasureSpec Horizontal space requirements as imposed by the
     *        parent
     * @param heightMeasureSpec Vertical space requirements as imposed by the
     *        parent
     *
     * @see #onMeasure(int, int)
     */
    public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
        if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT ||
                widthMeasureSpec != mOldWidthMeasureSpec ||
                heightMeasureSpec != mOldHeightMeasureSpec) {

            // first clears the measured dimension flag
            mPrivateFlags &= ~MEASURED_DIMENSION_SET;

            if (ViewDebug.TRACE_HIERARCHY) {
                ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_MEASURE);
            }

            // measure ourselves, this should set the measured dimension flag back
            onMeasure(widthMeasureSpec, heightMeasureSpec); //重点是它

            // flag not set, setMeasuredDimension() was not invoked, we raise
            // an exception to warn the developer
            if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) {
                throw new IllegalStateException("onMeasure() did not set the"
                        + " measured dimension by calling"
                        + " setMeasuredDimension()");
            }

            mPrivateFlags |= LAYOUT_REQUIRED;
        }

        mOldWidthMeasureSpec = widthMeasureSpec;
        mOldHeightMeasureSpec = heightMeasureSpec;
    }



    /**
     * <p>
     * Measure the view and its content to determine the measured width and the
     * measured height. This method is invoked by {@link #measure(int, int)} and
     * should be overriden by subclasses to provide accurate and efficient
     * measurement of their contents.
     * </p>
     *
     * <p>
     * <strong>CONTRACT:</strong> When overriding this method, you
     * <em>must</em> call {@link #setMeasuredDimension(int, int)} to store the
     * measured width and height of this view. Failure to do so will trigger an
     * <code>IllegalStateException</code>, thrown by
     * {@link #measure(int, int)}. Calling the superclass'
     * {@link #onMeasure(int, int)} is a valid use.
     * </p>
     *
     * <p>
     * The base class implementation of measure defaults to the background size,
     * unless a larger size is allowed by the MeasureSpec. Subclasses should
     * override {@link #onMeasure(int, int)} to provide better measurements of
     * their content.
     * </p>
     *
     * <p>
     * If this method is overridden, it is the subclass's responsibility to make
     * sure the measured height and width are at least the view's minimum height
     * and width ({@link #getSuggestedMinimumHeight()} and
     * {@link #getSuggestedMinimumWidth()}).
     * </p>
     *
     * @param widthMeasureSpec horizontal space requirements as imposed by the parent.
     *                         The requirements are encoded with
     *                         {@link android.view.View.MeasureSpec}.
     * @param heightMeasureSpec vertical space requirements as imposed by the parent.
     *                         The requirements are encoded with
     *                         {@link android.view.View.MeasureSpec}.
     *
     * @see #getMeasuredWidth()
     * @see #getMeasuredHeight()
     * @see #setMeasuredDimension(int, int)
     * @see #getSuggestedMinimumHeight()
     * @see #getSuggestedMinimumWidth()
     * @see android.view.View.MeasureSpec#getMode(int)
     * @see android.view.View.MeasureSpec#getSize(int)
     */
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        
              setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }



每个view 中一定存在一个必调的方法, measure(int, int) ,它调用onMeasure(int, int)
onMeasure(widthMeasureSpec, heightMeasureSpec)的作用是什么?
测量view和它的content 得出 widthMeasureSpec  heightMeasureSpec 并保存下来。
measure(widthMeasureSpec, heightMeasureSpec)的作用是什么?
通过 父布局提供的 widthMeasureSpec,   widthMeasureSpec 来确定这个View 的 大小, 有多高,有多宽,



特别对于一些实现 ViewGroup 的 控件 在某些情况下,当 android:layout_height android:layout_width 不能达到目的时, 可以通过重写 onMeasure(int, int) 来达到调整view高宽的目的。


    /**
     * <p>This mehod must be called by {@link #onMeasure(int, int)} to store the
     * measured width and measured height. Failing to do so will trigger an
     * exception at measurement time.</p>
     *
     * @param measuredWidth The measured width of this view.  May be a complex
     * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
     * {@link #MEASURED_STATE_TOO_SMALL}.
     * @param measuredHeight The measured height of this view.  May be a complex
     * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
     * {@link #MEASURED_STATE_TOO_SMALL}.
     */
    protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
        mMeasuredWidth = measuredWidth;
        mMeasuredHeight = measuredHeight;

        mPrivateFlags |= MEASURED_DIMENSION_SET;
    }

setMeasuredDimension 在 onMeasure(int, int) 中调用,用来存储跟新测量的宽和高, 若不调,可能产生异常。


MeasureSpec介绍及使用详解 
MeasureSpec 是 view 中的内部类
一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;AT_MOST(至多),子元素至多达到指定大小的值。

1 父布局传下来的
2 子元素布局文件或代码中设置的

  它常用的三个函数:
  1.staticint getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
  2.staticint getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
  3.staticint makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)

  这个类的使用呢,通常在view组件的onMeasure方法里面调用但也有少数例外,看看几个例子:

  a.首先一个我们常用到的一个有用的函数,View.resolveSize(intsize,int measureSpec)


    public static int resolveSize(int size, int measureSpec) {
        return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
    }

    public static int resolveSizeAndState(int size, int measureSpec, int childMe		asuredState) {
        int result = size;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize =  MeasureSpec.getSize(measureSpec);
        switch (specMode) {
        case MeasureSpec.UNSPECIFIED:
            result = size;
            break;
        case MeasureSpec.AT_MOST:
            if (specSize < size) {
                result = specSize | MEASURED_STATE_TOO_SMALL;
            } else {
                result = size;
            }
            break;
        case MeasureSpec.EXACTLY:
            result = specSize;
            break;
        }
        return result | (childMeasuredState&MEASURED_STATE_MASK);
    }

  简单说一下,这个方法的主要作用就是根据你提供的大小和MeasureSpec,返回你想要的大小值,这个里面根据传入模式的不同来做相应的处理。
  再看看MeasureSpec.makeMeasureSpec方法,实际上这个方法很简单:
        public static int makeMeasureSpec(int size, int mode) {
            return size + mode;
        }
这样大家不难理解size跟measureSpec区别了。






******************************************

布局步骤
1 measure          onMeasure(measureWidth, measureHight)          计算大小
2 layout           onLayout(chang, l, t, r, b)   给自己 及 子view分配size, position
3 draw             ondraw(canvas)                 画图



dispatchDraw     空方法体





getWidth() getMeasureWidth() 区别
getWidth() : view 的布局完成后,view的宽度
getMeasureWidth() : 这是一个过程量,得到的是在最近一次調用measure()方法測量後得到的view的寬度,它僅僅用在測量和layout的計算中。
举例: 有时会通过 child.getMeasureWidth() 的值 根据 Gravity 重心 得出 view 的 4个l t r  b  再layout
如 Gridview 中 存在一个方法:
    private void setupChild(View child, int position, int y, boolean flow, int childrenLeft,
            boolean selected, boolean recycled, int where) {
        boolean isSelected = selected && shouldShowSelector();
        final boolean updateChildSelected = isSelected != child.isSelected();
        final int mode = mTouchMode;
        final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
                mMotionPosition == position;
        final boolean updateChildPressed = isPressed != child.isPressed();
        
        boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();

        // Respect layout params that are already in the view. Otherwise make
        // some up...
        AbsListView.LayoutParams p = (AbsListView.LayoutParams)child.getLayoutParams();
        if (p == null) {
            p = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT, 0);
        }
        p.viewType = mAdapter.getItemViewType(position);

        if (recycled && !p.forceAdd) {
            attachViewToParent(child, where, p);
        } else {
            p.forceAdd = false;
            addViewInLayout(child, where, p, true);
        }

        if (updateChildSelected) {
            child.setSelected(isSelected);
            if (isSelected) {
                requestFocus();
            }
        }

        if (updateChildPressed) {
            child.setPressed(isPressed);
        }

        if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
            if (child instanceof Checkable) {
                ((Checkable) child).setChecked(mCheckStates.get(position));
            } else if (getContext().getApplicationInfo().targetSdkVersion
                    >= android.os.Build.VERSION_CODES.HONEYCOMB) {
                child.setActivated(mCheckStates.get(position));
            }
        }

        if (needToMeasure) {
            int childHeightSpec = ViewGroup.getChildMeasureSpec(
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height);

            int childWidthSpec = ViewGroup.getChildMeasureSpec(
                    MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width);
            child.measure(childWidthSpec, childHeightSpec);
        } else {
            cleanupLayoutState(child);
        }

        final int w = child.getMeasuredWidth();
        final int h = child.getMeasuredHeight();

        int childLeft;
        final int childTop = flow ? y : y - h;

        final int layoutDirection = getResolvedLayoutDirection();
        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
            case Gravity.LEFT:
                childLeft = childrenLeft;
                break;
            case Gravity.CENTER_HORIZONTAL:
                childLeft = childrenLeft + ((mColumnWidth - w) / 2);
                break;
            case Gravity.RIGHT:
                childLeft = childrenLeft + mColumnWidth - w;
                break;
            default:
                childLeft = childrenLeft;
                break;
        }

        if (needToMeasure) {
            final int childRight = childLeft + w;
            final int childBottom = childTop + h;
            child.layout(childLeft, childTop, childRight, childBottom);
        } else {
            child.offsetLeftAndRight(childLeft - child.getLeft());
            child.offsetTopAndBottom(childTop - child.getTop());
        }

        if (mCachingStarted) {
            child.setDrawingCacheEnabled(true);
        }

        if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
                != position) {
            child.jumpDrawablesToCurrentState();
        }
    }









ViewGroup.java

 1  measureChildren(measureWidth, measureHight)    measureChild(child, widthMeasureSpec, heightMeasureSpec)

  2 继承 layout(l, t, r, b)      onLayout(chang, l, t, r, b)

  3 继承  dispatchDraw       drawChild


 window                         view      


                                        Window        抽象类
                                              |
                                    PhoneWindow        
                                               |
                                      DecorView(mDecor)       PhoneWindow 内部类, 继承FrameLayout
                                         |             |
                TextView(title)       ViewGroup(mParentContent)
                                                                           |
                                                                     ViewGroup
                                                    |         |              |
                                                View      View         ViewGroup
                                                                                            |       |      |
                                                                                      View    View    ViewGroup

                     Application     Part  main.xml




     window 与 view                                          
    Android系 统中的所有UI类都是建立在View和ViewGroup这两个类的基础上的。所有View的子类成为”Widget”,所有ViewGroup的子类成 为”Layout”。View和ViewGroup之间采用了组合设计模式,可以使得“部分-整体”同等对待。ViewGroup作为布局容器类的最上 层,布局容器里面又可以有View和ViewGroup。
  
   window 抽象类 代表 一个phone 界面。 在 里面有个 DecorView 类, DecorView 继承自
FrameLayout,   DecorView 是 window 与 view 链接的开始。 DecorView显示界面组件。
除此之外 window 中还定义了窗口的 基本属性 和 基本功能。
    Window 在继承关系上 与view 无关系。


   当我们运行程序的时候,有一个setContentView()方法,Activity其实不是显示视图(直观上感觉是它),实际上Activity调用 了PhoneWindow的setContentView()方法,然后加载视图,将视图放到这个Window上,而Activity其实构造的时候初始 化的是Window(PhoneWindow),Activity其实是个控制单元,即可视的人机交互界面。


其他 kan      app课件

<style type="text/css"> <!-- pre {font-family:"DejaVu Sans"} p {margin-bottom:0.21cm} --> </style>

webview
view 的 scrollbar 四种模式
SCROLLBARS_INSIDE_OVERLAY  without increasing the padding
SCROLLBARS_INSIDE_INSET        increasing the padding
SCROLLBARS_OUTSIDE_OVERLAY     without increasing the padding
SCROLLBARS_OUTSIDE_INSET    increasing the padding

boolean  mOverlayHorizontalScrollbar   表示是否水平方向 scrollbar overlay 模式   
boolean  mOverlayVerticalScrollbar     表示是否垂直方向 scrollbar overlay 模式 




isHorizontalScrollBarEnabled() 表示水平方向的 scrollbar 是否被画出。
GetHorizontalScrollbarHeight() 水平方向  scrollbar 高度。  View 里方法

    int getViewHeightWithTitle() {
        int height = getHeight();
        if (isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
            height -= getHorizontalScrollbarHeight();
        }
        return height;
    }

 如果水平方向的 scrollbar 被画出且 属于 增加区域的 某种模式 计算viewHight时要减去这块区域的高。


    private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) {
        long eventTime = ev.getEventTime();

        // Due to the touch screen edge effect, a touch closer to the edge
        // always snapped to the edge. As getViewWidth() can be different from
        // getWidth() due to the scrollbar, adjusting the point to match
        // getViewWidth(). Same applied to the height.
        x = Math.min(x, getViewWidth() - 1);             
        y = Math.min(y, getViewHeightWithTitle() - 1);    

        int deltaX = mLastTouchX – x;         
        int deltaY = mLastTouchY - y;
        int contentX = viewToContentX(x + mScrollX);
        int contentY = viewToContentY(y + mScrollY);

x  x轴坐标      y y轴坐标      一台手机屏幕的宽高是固定的 (x,y) 手机屏幕
mLastTouchX  上一次触点的 x轴坐标
mLastTouchY 上一次触点的 y轴坐标
mScrollX  scrollbar 滑动 x轴距离
mScrollY  scrollbar 滑动 y轴距离
viewToContentX(.) webview content x轴坐标  网页+scrollbar
(contentx, contenty)  webview content 坐标

OverScroller

介绍
IOS上的bounce功能给人的感觉很爽,当一个可以滚动的区域被拖到边界时,它允许用户将内容拖过界,放手后再弹回来,以一种非常棒的方式提示 了用户边界的存在,是IOS的一大特色。android2.3新增了overscroll功能,听名字就知道应该是bounce功能的翻版,但也许是出于 专利方面的考虑,google的默认实现跟IOS有所不同,它只是在list拖到边界处时做了一个发光的动画,个人觉得体验比IOS差远了。而且这个黄色 的发光在黑色背景下虽然效果不错,在其它背景下可就难说了,因此很多人想要关掉它。
日前google上搜索“android overscroll”,对此效果的介绍很多,但关于其具体使用方式和实现,则很少涉及,偶有提及,也经常答非所问或似是而非,反而误导了别人。于是我查阅了android相关源码,并做了一些测试,在此讲讲我的理解。
首先是overscroll功能本身,在最顶层的View类提供了支持,可通过setOverScrollMode函数控制其出现条件。但其实 View中并没有实现overscroll功能,它仅仅提供了一个辅助函数overScrollBy,该函数根据overScrollMode和内容是否 需要滚动控制最大滚动范围,最后将计算结果传给onOverScrolled实现具体的overscroll功能,但此函数在View类中是全空的。
overscroll功能真正的实现分别在ScrollView、AbsListView、HorizontalScrollView和 WebView中各有一份,代码基本一样。以ScrollView为例,它在处理笔点移动消息时调用overScrollBy来滚动视图,然后重载了 overScrollBy函数来实现具体功能,其位置计算通过OverScroller类实现。OverScroller作为一个计算引擎,应该是一个独 立的模块,具体滚动效果和范围都不可能通过它来设置,我觉得没有必要细看。但滚动位置最终是它给出的,那相关数据肯定要传递给它,回头看 overScrollBy函数,它有两个控制overScroll出界范围的参数,几个实现里面都是取自 ViewConfiguration.getScaledOverscrollDistance,而这个参数的值在我的源码中都是0,而且我没找到任何可 以影响其结果的设置。
真悲催,绕了半天,android的默认实现里面根本没有给出overscroll功能,它只是提供了实现机制,要想用起来还得应用程序自己显式重写相关控件,估计还有一层隐含的意思,法律风险自负。在我的系统中一试,果然一个像素都不能拉出界。但那个闪光是怎么回事呢?
在处理笔点消息处,overScrollBy后面不远处有一段mEdgeGlowTop的操作代码,看名字就像,用它一搜,相关机制就全明白了。 mEdgeGlowTop在setOverScrollMode函数时创建,它使用的图片都是系统中固有的,甚至不能通过theme改变。它的实现原理也 很简单,仅仅是两张png图片的合成,通过透明度的变化制造闪光的效果。更无语的是它既不能被应用程序访问,也不受任何控制,要关闭它的唯一办法是 setOverScrollMode(View.OVER_SCROLL_NEVER)。否则就重写onTouchEvent函数吧,想干啥都可以,只是 得自己做。
谈到overScroll,很多文章都提到了ListView的setOverscrollHeader和 setOverscrollFooter,很多人想通过这个来控制那个闪光效果。这两玩意不但可以通过函数设置,也可以在xml中指定,相当方便。但最后 很多人发现没有任何作用,百思不得其解。其实这两张图片是用来作为overScroll拖过界时的背景的,默认系统不能拖过界,自然永远都看不到,有些定 制的系统中能拖出界几个像素,但也很难看清。

Boolean  AllowDoubleTap 允许双击 
    只有 onPageFinish() 后  AllowDoubleTap=true ,其他时候双击无效。

Int mTouchHighlightRequested set mTouchHighlightRequested to 0 to cause an 
  immediate  drawing of the touch rings  设为0, 区域立即开始高亮。
Region MtouchHighlightRegion = new Region() 代表一块区域,点击网页,产生高亮的区域.









页面可见坐标计算流程
  屏幕可见坐标 + view滚动条数据 + webview放缩数据


    /**
     * Given a distance in view space, convert it to content space. Note: this
     * does not reflect translation, just scaling, so this should not be called
     * with coordinates, but should be called for dimensions like width or
     * height.
     */
    private int viewToContentDimension(int d) {
        return Math.round(d * mZoomManager.getInvScale());
    }

    /**
     * Given an x coordinate in view space, convert it to content space.  Also
     * may be used for absolute heights (such as for the WebTextView's
     * textSize, which is unaffected by the height of the title bar).
     */
    /*package*/ int viewToContentX(int x) {  
        return viewToContendtDimension(x);     根据 webview 页面的放缩率  完善 Rect坐标
    }

    private Point mGlobalVisibleOffset = new Point();
    // Sets r to be the visible rectangle of our webview in view coordinates
    private void calcOurVisibleRect(Rect r) {   计算出 webview 可见区域坐标付给Rect
        getGlobalVisibleRect(r, mGlobalVisibleOffset);  计算手机屏幕的可见区域坐标付给Rect
        r.offset(-mGlobalVisibleOffset.x, -mGlobalVisibleOffset.y);  根据页面滚动条的数据如 scrollx scrolly 完善 Rect坐标。
    }

    private void calcOurContentVisibleRect(Rect r) {    传入Rect 对象
        calcOurVisibleRect(r);                 
        r.left = viewToContentX(r.left);
        // viewToContentY will remove the total height of the title bar.  Add
        // the visible height back in to account for the fact that if the title
        // bar is partially visible, the part of the visible rect which is
        // displaying our content is displaced by that amount.
        r.top = viewToContentY(r.top + getVisibleTitleHeightImpl());
        r.right = viewToContentX(r.right);
        r.bottom = viewToContentY(r.bottom);
    }


















webtextview 的尺寸 位置更新
    // These values are possible options for didUpdateWebTextViewDimensions.
    private static final int FULLY_ON_SCREEN = 0;
    private static final int INTERSECTS_SCREEN = 1;
    private static final int ANYWHERE = 2;

    /**
     * Check to see if the focused textfield/textarea is still on screen.  If it
     * is, update the the dimensions and location of WebTextView.  Otherwise,
     * remove the WebTextView.  Should be called when the zoom level changes.
     * @param intersection How to determine whether the textfield/textarea is
     *        still on screen.
     * @return boolean True if the textfield/textarea is still on screen and the
     *         dimensions/location of WebTextView have been updated.
     */
    private boolean didUpdateWebTextViewDimensions(int intersection) {
	    //计算出焦点坐标节点区域
        Rect contentBounds = nativeFocusCandidateNodeBounds();
        Rect vBox = contentToViewRect(contentBounds);
		 offsetByLayerScrollPosition(vBox);
	    //计算出可见区域
        Rect visibleRect = new Rect();
        calcOurVisibleRect(visibleRect);
        
        // If the textfield is on screen, place the WebTextView in
        // its new place, accounting for our new scroll/zoom values,
        // and adjust its textsize.
        boolean onScreen;
        switch (intersection) {
            case FULLY_ON_SCREEN:     vBox 在  visibleRect 之内
                onScreen = visibleRect.contains(vBox);
                break;
            case INTERSECTS_SCREEN:   vBox 与 visibleRect 交互
                onScreen = Rect.intersects(visibleRect, vBox);
                break;
            case ANYWHERE:            
                onScreen = true;
                break;
            default:
                throw new AssertionError(
                        "invalid parameter passed to didUpdateWebTextViewDimensions");
        }
        if (onScreen) {
            mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
                    vBox.height());
            mWebTextView.updateTextSize();
            updateWebTextViewPadding();  设置输入框内的padding,
            return true;
        } else {
            // The textfield is now off screen.  The user probably
            // was not zooming to see the textfield better.  Remove
            // the WebTextView.  If the user types a key, and the
            // textfield is still in focus, we will reconstruct
            // the WebTextView and scroll it back on screen.
            mWebTextView.remove();
            return false;
        }
    }


android 焦点控制
* 父元素分配焦点 

setFocusable()   设置view接受焦点的资格    isFocusable    view是否具有接受焦点的资格   

setFocusInTouchMode()      对应在触摸模式下,设置是否有焦点来响应点触的资格          
isFocusableInTouchMode()  对应在触摸模式下,来获知是否有焦点来响应点触

焦点获取
requestFocus()                                 ------ view
requestFocus(...)          当用户在某个界面聚集焦点
requestFocusFromTouch()    触摸模式下
  ......
requestChildFocus (View child, View focused)   ------viewGroup
1 父元素 调用此方法
2 child  将要获取焦点的子元素

3 focused 现在拥有焦点的子元素

一般也可以通过 配置文件设置
View.FOCUS_LEFT     Move focus to the left
View.FOCUS_UP       Move focus up
View.FOCUS_RIGHT    Move focus to the right
View.FOCUS_DOWN     Move focus down             代码设置实现 其实都是通过这些设置的         

isInTouchMode()    触摸模式


分享到:
评论

相关推荐

    前阶段的Android学习总结

    前阶段的Android学习总结一、Android Studio导入现有工程的几个步骤二、这里推荐一篇好文三、四大应用组件之ContentProvider四、Git五、View学习总结和BUG六、fragment 和 Framelayout七、关于广播接收器的注册销毁...

    Android迷你播放器-第一阶段共6小结-源代码下载.tar.gz

    2、这是Android迷你播放器第一阶段共6次改进的源代码,具体解析可点击博客查看 3、代码内含注释 4、这几个小节分别为 1检索内存卡媒体音乐并添加到List播放列表--媒体库的检索以及list列表使用; 2退出时自动最小化...

    Android高级编程--源代码

    1.10 小结 16 第2章 开始入手 17 2.1 Android开发 18 2.1.1 开始前的准备工作 18 2.1.2 创建第一个Android活动 22 2.1.3 Android应用程序的类型 27 2.2 面向移动设备的开发 28 2.2.1 关于硬件设计的考虑事项 ...

    Android实训报告基于Android游戏开发.docx

    解决问题的方法和措施8(一)、所遇问题8(二)、解决方法与措施9五、心得体会9一、实训目的及其意义1.1、目的及意义了解现阶段互联网发展主流,了解移动互联网,认识移动互联网的发展与展望,认识Android,了解基于...

    Android 4游戏编程入门经典

     1.10 小结 第2章 从android sdk开始  2.1 搭建开发环境  2.1.1 安装jdk  2.1.2 安装android sdk  2.1.3 安装eclipse  2.1.4 安装adt eclipse插件  2.1.5 eclipse快速浏览  2.1.6 一些实用的eclipse快捷键 ...

    Android群英传:神兵利器

    《Android群英传:神兵利器》一共总结了七大神兵利器: 开发环境搭得好,程序设计乐逍遥 项目要想跑得好,版本控制不可少 Android Studio 大揭秘,省出时间玩游戏 与Gradle 的爱恨情仇,让你一次爱个够 珍视身边的朋友,...

    Android代码-AndroidStudyDemo

    第二阶段,直接为每个点提供代码展示和说明,使用Blog或说明文档做专题总结 第三阶段,进阶 该项目包含如下Module Android5Study Android6Study AnimationStudy AnnotationStudy ArithmeticStudy CommonLibsStudy ...

    Android操作系统移植及应用研究

     本文首先对手机的发展阶段、常用智能手机操作系统、Android目前国内外研究状况及本文的组织结构进行了简单的介绍。然后介绍了Android的四个特点,详细分析了Android的系统架构。  其次,介绍了Devkit8000开发板的...

    android游戏编程入门

     1.10 小结 18  第2章 从Android SDK开始 19  2.1 搭建开发环境 19  2.1.1 安装JDK 20  2.1.2 安装Android SDK 20  2.1.3 安装Eclipse 21  2.1.4 安装ADT Eclipse插件 22  2.1.5 Eclipse快速浏览 23  2.1.6...

    android总结

    将自己写的部分代码和找的资料上传 做一个阶段总结吧

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    2.4 本章小结 15 第三章 跨域交互缓存处理设计 17 3.1 跨域交互缓存处理需求 17 3.1.1 缓存技术WebStorage 17 3.1.2 跨域交互缓存处理需求 17 3.1.3 页面回退管理需求 17 3.2 缓存处理机制 18 3.2.1 跨域缓存处理 18...

    Android亮屏速度分析总结

    刚开始的时候,我只在android阶段统计时间,也能看到时间的差异,但是不是最准确的,我统计的时间日志如下 01-18 09:13:40.992 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 743ms 01-...

    android转正报告怎么写.docx

    android转正报告怎么写全文共6页,当前为第1页。android转正报告怎么写全文共6页,当前为第1页。android转正报告怎么写 android转正报告怎么写全文共6页,当前为第1页。 android转正报告怎么写全文共6页,当前为第1...

    Android dex 加密源码

    博客 【Android 安全】DEX 加密 ( 阶段总结 | 主应用 | 代理 Application | Java 工具 | 代码示例 ) ★ 对应源码 https://hanshuliang.blog.csdn.net/article/details/110450891

    Android日程管理系统实训报告.doc

    测试 21 6.1 闹钟提醒测试用例 21 6.2 备忘录测试用例 22 第7章 小结 23 第8章 参考文献 24 第1章 绪论 1.1项目背景 随着计算机技术的飞速发展,计算机应用的迅速推广,计算机及技术给人们的日常生活 、工作、学习...

    Android代码-锁定手机(锁定屏幕,戒手机)

    本应用是作者系统研究安卓的 Window 的阶段性总结 使用须知 本应用通过一点并不复杂的技术实现锁定手机主屏幕,使主屏幕区域无法再接收任何触摸事件(最长锁两天),适用的应用场景有戒一段时间手机以保持专注做其他...

    android ftp4j上传下载带进度条

    前一阶段看了很多的ftp4j的上传和下载的列子,但是都不是自己想要的,就总结了一个给大家参考吧,上传下载是带进度条的,希望对大家有点帮助。

    Android触摸事件传递机制初识

    前言 今天总结的一个知识点是Andorid中View事件传递机制,也是核心知识点,相信很多开发者在面对这个问题时候会觉得困惑,另外,View的另外一个难题... 小结 Activity、View、ViewGroup三者关系 我们都知道Android中

    PopularMoviesStage1:Android Nanodegree Project 2a-流行电影第1阶段

    阶段1:主发现屏幕,详细信息视图和设置用户体验在此阶段,您将构建电影应用程序的核心体验。 您的应用程序将: 启动后,向用户展示电影海报的网格排列。 允许您的用户通过以下设置更改排序顺序: 排序顺序可以是最...

    MTK充电流程详细介绍.docx

    MTK平台充电小结 一、 锂电池基础 1、 锂电池类型主要有普通(4.2V)和高压(4.35V)两种锂电池。现在我们项目用的都是4.35v的高压电池。 2、 电池充电一般分为三个阶段:涓流充电\预充电、恒流充电、恒压充电。 (1)、...

Global site tag (gtag.js) - Google Analytics