view类型_不兼容的类型 view 无法转换为button - CSDN
精华内容
参与话题
  • Android View

    千次阅读 2017-10-12 11:25:12
    参考:View类详解(游戏开发必备)view基本概念在Activity显示的控件 都叫做ViewView类 是所有的控件类的父类 比如 文本 按钮)在Activity当中获取代表View的对象Activity读取布局文件生成相对应的 各种View对象...

    参考:View类详解(游戏开发必备)

    view基本概念

    在Activity显示的控件 都叫做View(View类 是所有的控件类的父类 比如 文本 按钮)

    在Activity当中获取代表View的对象

    Activity读取布局文件生成相对应的 各种View对象

    TextView textView=(TextView)findViewBy(R.id.textView)
    

    设置view的属性

    Activity_mian.xml 这样的xml布局文件中发现了,类似@+id/和@id/到底有什么区别呢? 这里@可以理解为引用,而多出的+代表自己新声明的。

    View的自定义

    通过继承View,可以很方便地定制出有个性的控件出来。

    自定义View的常用方法:

    onFinishInflate() 当View中所有的子控件均被映射成xml后触发  
    onMeasure(int, int) 确定所有子元素的大小  
    onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发  
    onSizeChanged(int, int, int, int) 当view的大小发生变化时触发  
    onDraw(Canvas) view渲染内容的细节  
    onKeyDown(int, KeyEvent) 有按键按下后触发  
    onKeyUp(int, KeyEvent) 有按键按下后弹起时触发  
    onTrackballEvent(MotionEvent) 轨迹球事件  
    onTouchEvent(MotionEvent) 触屏事件  
    onFocusChanged(boolean, int, Rect) 当View获取或失去焦点时触发   
    onWindowFocusChanged(boolean) 当窗口包含的view获取或失去焦点时触发  
    onAttachedToWindow() 当view被附着到一个窗口时触发  
    onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和  onAttachedToWindow() 是相反的。  
    onWindowVisibilityChanged(int) 当窗口中包含的可见的view发生变化时触发
    
    展开全文
  • android View类详解。

    千次阅读 2019-03-26 13:46:40
    Android中的View类代表用户界面中基本的构建块。一个View在屏幕中占据一个矩形区域、并且负责绘制和事件处理。View是所有widgets的基础类,widgets是我们通常用于创建和用户交互的组件,比如按钮、文本输入框等等。...

    Android中的View类代表用户界面中基本的构建块。一个View在屏幕中占据一个矩形区域、并且负责绘制和事件处理。View是所有widgets的基础类,widgets是我们通常用于创建和用户交互的组件,比如按钮、文本输入框等等。子类ViewGroup是所有布局(layout)的基础类。layout是一个不看见的容器,里面堆放着其他的view或者ViewGroup,并且设置他们的布局属性。

    所有的view在窗口中是以树状结构来管理。你可以通过代码或者编辑xml布局文件来添加一个view。view有很多的子类来负责控制或者有能力展示图片,文字等等。

    使用:

    一旦你创建了一个view的树状结构。你通常做以下的常见操作。

    1,设置属性,比如可以给一个TextView设置文本属性。每一个view都有特定的属性和设置他们的方法。一些可以遇见的属性可以在view的xml文件中提前设置。

    2,设置焦点,Android框架本身可以处理用户移动的焦点事件。你可以强制调用requestFocus()方法,来聚焦一个view。

    3,设置监听器,view允许客户端来设置监听器,监听感兴趣的事件。当感兴趣的事件发生,系统会通知监听器。比如,所有的view都支持你设置获得和失去焦点事件的监听器,你只需要通过方法setOnFocusChangedListener(android.view.View.OnFocusChangedListener)来设置。其他的view子类都支持自己特性的事件监听器设置,比如Button支持设置点击事件监听器。

    4,设置可见性,你可以通过方法setVisibility()来设置view的隐藏和可见。

    Android框架会负责view的测量(measure)、布局(layout)、绘制(draw)。一般情况下你不需要调用相关的方法,除非你自己定义了一个view。

    自定义view

    你如果自定义实现一个view,你需要覆盖重写view中的一些被Android框架调用的标准方法。当然你也没有必要把所有的方法都覆盖重写,但你应该从onDraw方法开始。

    类别 方法 描述
    创建 构造方法 创建view时,分为两种情况,一种是写代码创建,一种是从xml文件中创建,第二种情况会转化和应用你在xml设置的view属性。
    onFinishInflate() 在该view和子view都从xml文件中创建完成时被调用。
    布局 onMeasure(int, int) 确定view和子view的大小要求时被调用。
    onLayout(boolean, int, int, int, int) 给view的子view确定大小和位置的时候调用。
    onSizeChanged(int, int, int, int) 当view的大小变化时被调用
    绘制 onDraw(android.graphics.Canvas) 当view需要渲染他的内容时被调用。
    事件处理 onKeyDown(int, android.view.KeyEvent) 当物理按键按下时,被调用。
    onKeyUp(int, android.view.KeyEvent) 当物理按键抬起时,被调用。
    onTrackballEvent(android.view.MotionEvent) 当轨迹球运动事件发生时,被调用。
    onTouchEvent(android.view.MotionEvent) 当触摸屏幕事件发生时,被调用。
    焦点 onFocusChanged(boolean, int, android.graphics.Rect) 获得、失去焦点时,被调用。
    onWindowFocusChanged(boolean) 包含视图的屏幕获得、失去焦点的时候被调用。
    附着 onAttachedToWindow() 当view附着到window时,被调用。
    onDetachedFromWindow() 当view从window上剥离,被调用。
    onWindowVisibilityChanged(int) 包含视图的window的可见性发生变化时,别调用。

     

    ID

    view都有一个Integer属性的id,这个id一般是在定义viewxml文件中设置的。被用于在指定的view树中查找view。常见的一种形式:

    在布局文件中定义个按钮,并给它设置唯一的id

     <Button
         android:id="@+id/my_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/my_button_text"/>
     

    在Activity的onCreate方法中查找这个按钮:

     Button myButton = findViewById(R.id.my_button);
     

    view的id不需要在整个应用中都保持唯一,但你需要在它所在的view视图树状结构中保持唯一。

    位置:

    一个view的形状是一个矩形,每一个view都有一个位置,被表示为一个坐标(left,top)。还有两个尺寸,width和height。位置和尺寸的单位都是像素(pixel)。

    你可以通过调用getLeft()和getTop()方法来获取一个view 的位置。前者返回的是left或者X坐标,后者返回的是top或者Y坐标。这些方法返回的位置是相对于该view的父view来说的,比如,getLeft()方法返回了20,这就是说这个view位于他的直接父view左边框的右边20像素的地方。

    另外view还提供了另外一些关于位置的方法,减少你的运算。getRight()方法和getBottom()方法返回view矩形的right和botom边对应的坐标。比如调用getRight()方法等同于调用getLeft()+ getWidth()方法。

    Size, padding and margins

    一个view的size被width和height来指定,一个veiw通常情况下有两对width和height值。

    第一对值呢是测量宽(measured width)和测量高(measured height)。这个值的含义是这个view想要在他的父view中有多大。这个值可以通过getMeasuredWidth()和getMeasuredHeight()方法获取。

    第二对就是宽(width)和高(height),有时被称为绘制宽和绘制高,代表这view的实际宽和高,这两个值可能,会和测量宽和高不一样,可以通过getWidth()方法和getHeight()方法来获取相应的值。

    测量一个view的值,会考虑到他的填充(padding)值。padding值同样以像素作为单位,包含left、top、right、bottom四个值。padding用来设置view的内容和view的边界偏离值。比如 left padding的值是2,意味着view的内容相对view的左边移动2个像素。padding可以用方法setPadding(int,int,int,int)或setPaddingRelative(int,int,int,int)方法来设置。可以用方法getPaddingLeft(),getPaddingTop(),getPaddingRight(),getPaddingBottom(),getPaddingStart(),getPaddingEnd()来查询相关值。

    尽管一个view可以设置padding值,但是他不支持margin值,然而,view group可以设置margin。查看VIewGroup.MarginLayoutParams获取更多相关知识。

    Layout(布局)

    Layout包含两个过程,一个测量(mesasure)、一个布局(layout)。测量是在继承的measure(int,int)方法里面来进行,并且是至上而下的遍历view的树状结构,每一个view都将尺寸规格推到tree中,在测量完成后,每一个view都保存了自己的测量值,第二个过程发生在layout(int,int,int,int),并且也是自顶向下,在这个过程中每一个父view都负责用第一个工程测量的值来定位它的子view。

    等view的measure()方法结束,view 的getMeasuredWidth()和getMeasuredHeight()值一定会被设置,***一个view的测量宽和测量高的值都必须遵守父亲节点设置的约束。这样保证了,在measure过程结束后,所有的父亲view节点都接受了其子view节点的测量值,一个父亲view节点针对它的子节点view可能会不止一次的调用measure方法,例如,父亲view节点会测量它的每一个为指定尺寸的(unspecified)子view节点一次,来找出子view节点想要多大,然后,再次调用measure方法使用真实的的值,如果所有的不受约束的子view节点的大小总和太大或者太小。

    测量过程使用两个类来计算大小,MeasureSpec类被用于告诉父亲view节点,它们想要多大和怎么定位。LayoutParams类仅仅描述了view要想多大的宽和高,分以下三种情况。

    • 一个确定的值。
    • MATCH_PARENT,想要和父亲view节点一样大,但是要减去padding值。
    • WRAP_CONTENT, 包裹view的内容大小。但是要加上padding值。

    Android框架中有许多针对不同的ViewGroup有不同的LayoutParams的子类。比如,AbsoluteLayout有它自己的子类,LayoutParmams来添加X,Y值。

    MeasureSpecs被用于将要求由父亲view传递到子view。一个MeasureSpec可以是以下三个值中的任意一种。

    • UNSPECIFIED:被父亲view节点用于来决定子view节点想要的大小,例如,一个LinearLayout可以调用子 view节点的measure()方法来计算它想要多高,这个子view的height被指定为UNSPECIFIED,宽是确定的值240像素。
    • EXACTLY:被父亲view节点用于使用一个确定的值来指定它的子view的大小。这个子 view节点必须是这个大小,另外这个子view的所有子view节点都必须在这个大小范围内来调整自己的大小。
    • AT_MOST:被父亲节点用于来给子view节点一个最大的值,子view节点以及它的子 view节点都必须调整以适合这个大小。

    初始化一个layout,可以调用requestLayout()方法,这个方法通常会被view自身调用,在它自己认为不再适合当前的范围的时候。

    绘制
    绘制是通过遍历树并记录需要更新的任何视图的绘图命令来处理的。在这之后,整个树的绘制命令被发送到screen,剪切到新损坏的区域。

    这棵树很大程度上是按顺序记录和绘制的,而父亲view节点则是在此之前绘制的。他们的孩子和兄弟姐妹按照他们在树上出现的顺序绘制出来。如果您为视图设置了一个背景drawable,那么视图将在调用其onDraw()方法之前绘制它。可以使用ViewGroup中的ViewGroup#setChildrenDrawingOrderEnabled(boolean)和视图上的setZ(float)自定义Z值}覆盖子view绘制顺序。

    若要强制视图绘图,请调用invalidate()。

    事件处理和线程
    视图的基本周期如下:

    • 事件进入并被分派到适当的视图。视图处理事件并通知任何侦听器。
    • 如果在处理事件的过程中,视图的边界可能需要更改,那么视图将调用requestLayout()。
    • 类似地,如果在处理事件的过程中可能需要更改视图的外观,则视图将调用invalidate()。

    如果调用了requestLayout()或invalidate(),框架将根据需要度量、布局和绘制树。

    注意:整个视图树是单线程的。在调用任何视图上的任何方法时,必须始终处于UI线程上。如果您正在处理其他线程,并且希望从该线程更新视图的状态,则应该使用处理程序。

    焦点处理
    该框架将处理响应用户输入的常规焦点移动。这包括在视图被删除或隐藏时,或在新视图可用时更改焦点。视图表明它们愿意通过isfocavailable()方法进行关注。要更改视图是否可以获取焦点,请调用setfocavailable (boolean)。当处于触摸模式(见下面的注释)时,视图指示他们是否仍然希望通过isFocusableInTouchMode()进行聚焦,并且可以通过setFocusableInTouchMode(boolean)进行更改。

    焦点移动是基于在给定方向上找到最近邻居的算法。在极少数情况下,默认算法可能与开发人员的预期行为不匹配。在这些情况下,您可以使用布局文件中的这些XML属性提供显式覆盖:

    nextFocusDown
    nextFocusLeft
    nextFocusRight
    nextFocusUp


    要获得一个特定的视图来获取焦点,请调用requestFocus()。

    触摸模式


    当用户通过方向键(如D-pad)在用户界面中导航时,有必要将焦点放在可操作的项(如按钮)上,这样用户就可以看到需要输入什么。但是,如果设备具有触摸功能,并且用户开始通过触摸与界面交互,则不再需要总是突出显示或关注特定的视图。这激发了一种名为“触摸模式”的交互模式。

    对于具有触摸功能的设备,一旦用户触摸屏幕,设备将进入触摸模式。从现在开始,只有isFocusableInTouchMode()为真的视图才是可聚焦的,比如文本编辑小部件。其他可触摸的视图,如按钮,在触摸时不会聚焦;它们只会触发on click侦听器。

    每当用户按下方向键,例如D-pad方向,视图设备就会退出触摸模式,并找到一个视图进行对焦,这样用户就可以在不再次触摸屏幕的情况下继续与用户界面交互。

    触摸模式状态是跨活动维护的。调用isInTouchMode()查看设备当前是否处于触摸模式。

    滚动
    框架为希望在内部滚动其内容的视图提供了基本支持。这包括跟踪X和Y滚动偏移量以及绘制滚动条的机制。有关详细信息,请参见scrollBy(int, int)、scrollTo(int, int)和awakenScrollBars()。

    标签
    与id不同,标记不用于标识视图。标签本质上是可以与视图关联的额外信息。它们通常用于方便地在视图本身中存储与视图相关的数据,而不是将它们放在单独的结构中。

    标签可以用布局XML中的字符序列值指定,可以使用android:tag属性作为单个标签,也可以使用<tag>子元素作为多个标签:

         <View ...
               android:tag="@string/mytag_value" />
         <View ...>
             <tag android:id="@+id/mytag"
                  android:value="@string/mytag_value" />
         </View>
     

    还可以使用代码中的任意对象使用setTag(java.lang.Object)或setTag(int, java.lang.Object)指定标记。

    主题
    默认情况下,视图是使用提供给其构造函数的上下文对象的主题创建的;但是,可以使用layout XML中的android:theme属性指定不同的主题,或者从代码中将ContextThemeWrapper传递给构造函数。

    当android:theme属性在XML中使用时,指定的主题应用于通胀上下文的主题之上(请参阅LayoutInflater),并用于视图本身和任何子元素。

    在下面的示例中,将使用材质深色方案创建两个视图;但是,由于使用了一个覆盖主题,它只定义了属性的子集,android:colorAccent的值将保留在通货膨胀上下文的主题(例如活动主题)上定义。

         <LinearLayout
                 ...
                 android:theme="@android:theme/ThemeOverlay.Material.Dark">
             <View ...>
         </LinearLayout>
     

    属性
    视图类公开一个ALPHA属性,以及几个与转换相关的属性,如TRANSLATION_X和TRANSLATION_Y。这些属性以属性形式和类似命名的setter/getter方法(如ALPHA的setAlpha(float))都可用。这些属性可用于设置与视图上这些呈现相关属性关联的持久状态。属性和方法也可以与基于动画的动画结合使用,动画部分将对此进行详细描述。

    动画
    从Android 3.0开始,视图动画的首选方式是使用android.animation api。这些基于动画的类更改视图对象的实际属性,如alpha和translationX。这种行为与3.0之前的基于动画的类形成了对比,3.0之前的类只对视图在屏幕上的绘制方式进行动画。特别是,ViewPropertyAnimator类使这些视图属性的动画特别容易和有效。

    或者,您可以使用3.0之前的动画类来动画视图的呈现方式。您可以使用setAnimation(android.view.animation.Animation)或startAnimation(android.view.animation.Animation)将动画对象附加到视图。动画可以随着时间改变视图的缩放、旋转、平移和alpha值。如果动画附加到具有子视图,则动画将影响该节点所根的整个子树。当动画启动时,框架将负责重绘适当的视图,直到动画完成。

    安全
    有时,应用程序必须能够在用户完全知情和同意的情况下验证正在执行的操作,例如批准许可请求、购买或单击广告。不幸的是,恶意应用程序可能通过隐藏视图的预期用途,在不知情的情况下试图欺骗用户执行这些操作。作为补救措施,该框架提供了一个触摸过滤机制,可用于提高视图的安全性,从而提供对敏感功能的访问。

    要启用触摸过滤,请调用setfiltertoucheswhen(boolean)或将android: filtertoucheswhenlayout属性设置为true。当启用时,框架将丢弃视图窗口被另一个可见窗口遮挡时接收到的触摸。因此,当toast、对话框或其他窗口出现在视图窗口上方时,视图将不会接收触摸。

    要对安全性进行更细粒度的控制,请考虑覆盖onFilterTouchEventForSecurity(android.view.MotionEvent)方法来实现您自己的安全策略。参见MotionEvent # FLAG_WINDOW_IS_OBSCURED。

    展开全文
  • android自定义View二(View的种类)

    千次阅读 2016-09-17 12:39:20
    android自定义View一(基础和原理) http://blog.csdn.net/androidxiaogang/article/details/518491361、自定义View的种类自定义View的种类比较多,选择比较合适的自定义方式,能够减少一定的工作量。 在开发中...

    android自定义View一(基础和原理)
    http://blog.csdn.net/androidxiaogang/article/details/51849136

    1、自定义View的种类

    自定义View的种类比较多,选择比较合适的自定义方式,能够减少一定的工作量。
    在开发中一般可以使用下面4种方式实现自定义View:


    这里写图片描述

    第一种方式:继承View,View是android中界中最基础的元素,也就是说是基类,所有控件或者布局都是view的子类。用这种方式实现自定义控件或者View,工作量比较大,我们必须处理一此额外的工作:比如在onMeasure()方法中,必须自已处理wrap_content和match_parent还有处理在自已相对的父布局位置,margin之类的。

    第二种方式:继承View的子类,比如说TextView,ImageView,Button之类的。用这种方式实现自定义View,工作量少了很多,但如果View中元素种类比较少或者单一还行,如果View中有其他的比如有TextView,ImageView,Button之类的,就不合适了。

    第三种方式:继承ViewGroup,这种实现方式也比较复杂,与继承View相信,如果使用用这种方式,我们必须在onMeasure()和onLayout中处理margin,padding之类的工作。

    第四种方式:继承ViewGroup的子类(Linearlayout,Relativelayout),ViewGroup是View的子类,而ViewGroup又是所有layout的基类。通过这种方式自定义View我们可以通过xml布局填充View,也不用管onMeasure(),或者onLayout()中关于padding,margins之类的。

    总结:开发中,尽量使用View的子类和ViewGroup的子类实现自定义View,根据不同的情况选择是View的子类,还是ViewGroup的子类,如果实现的功能比较单一(控件个数)可以用View的子类,如果是组合式布局(包含许多不同的控件种类)可以使用ViewGroup的子类实现。

    2、onMeasure()分析

    通过上面四种方式自定义View,如果直接继承View,和ViewGroup要在onMeasure()中考虑match_parent,padding之类的,那么可以通过onMeasure()方法得出结论。

    首先通过重写onMeasure()方法
    这里写图片描述
    点击进入父类onMeasure()方法中
    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
    getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    也就是调用了 getDefaultSize()方法。
    这里写图片描述
    最终调用的是这个方法
    这里写图片描述

    两个参数,并且这个两参数是调用MeasureSpec类中的一个getMode(),和getSize()方法

    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    进入到MeasureSpec类中:

    1、specSize 很容易理解,就是我们传给view的像素值,比如300,500.

    2、specMode 有三个参数:我们称之为测量规格模式
    UNSPECIFIED,EXACTLY,AT_MOST
    这里写图片描述

    1. UNSPECIFIED:对于控件尺寸来说,没有任何参考意义。
    2. EXACTLY:父View已经检测到子View的大小,它的大小在父View的限制内。
    3. AT_MOST:子View想要多大就多大。

    从传入方法两个getDefaultSize(int size, int measureSpec)这两个值,最终返回的是一个result。因此如果这个是widthMeasureSpec的宽的话,它由这两个值最终决定。
    这里写图片描述

    是match_parent还是warp_content最终是这样形成的

    这里写图片描述

    从上面可以看出onMeasure()方法的实质:测量在父View中的位置:
    EXACTLY——–match_parent
    AT_MOST——-wrap_content
    这是match_parent,wrap_content在内部代码中设置的原理。实际中这情况也要考虑父View的EXACTLY,AT_MOST的情况。实际中见表格。

    2、onLayout()分析

    onLayout()方法具体在继承View和ViewGroup中是有区别的
    首先看在View中源码:


    这里写图片描述
    可以看出在继承View时,源码中onlayout()是一个空的方法。
    而再看看ViewGroup中的源码:


    这里写图片描述


    一个抽象类:
    这下都明白了,因为ViewGruop本身作为容器的作用。它一定有自已的子类,要求子类必须指定在父类中的具体位置。继承ViewGroup时,要求我们必须重写onlayout()方法,也就是Linearlayout,RelativeLayout也都重写这个方法了。

    下面是Linearlayout中onlayout()方法中的代码

      @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            if (mOrientation == VERTICAL) {
                layoutVertical(l, t, r, b);
            } else {
                layoutHorizontal(l, t, r, b);
            }
        }

    进入 layoutVertical(l, t, r, b)中

     void layoutVertical(int left, int top, int right, int bottom) {
            final int paddingLeft = mPaddingLeft;
    
            int childTop;
            int childLeft;
    
            // Where right end of child should go
            final int width = right - left;
            int childRight = width - mPaddingRight;
    
            // Space available for child
            int childSpace = width - paddingLeft - mPaddingRight;
    
            final int count = getVirtualChildCount();
    
            final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
            final int minorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
    
            switch (majorGravity) {
               case Gravity.BOTTOM:
                   // mTotalLength contains the padding already
                   childTop = mPaddingTop + bottom - top - mTotalLength;
                   break;
    
                   // mTotalLength contains the padding already
               case Gravity.CENTER_VERTICAL:
                   childTop = mPaddingTop + (bottom - top - mTotalLength) / 2;
                   break;
    
               case Gravity.TOP:
               default:
                   childTop = mPaddingTop;
                   break;
            }
    
            for (int i = 0; i < count; i++) {
                final View child = getVirtualChildAt(i);
                if (child == null) {
                    childTop += measureNullChild(i);
                } else if (child.getVisibility() != GONE) {
                    final int childWidth = child.getMeasuredWidth();
                    final int childHeight = child.getMeasuredHeight();
    
                    final LinearLayout.LayoutParams lp =
                            (LinearLayout.LayoutParams) child.getLayoutParams();
    
                    int gravity = lp.gravity;
                    if (gravity < 0) {
                        gravity = minorGravity;
                    }
                    final int layoutDirection = getLayoutDirection();
                    final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
                    switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                        case Gravity.CENTER_HORIZONTAL:
                            childLeft = paddingLeft + ((childSpace - childWidth) / 2)
                                    + lp.leftMargin - lp.rightMargin;
                            break;
    
                        case Gravity.RIGHT:
                            childLeft = childRight - childWidth - lp.rightMargin;
                            break;
    
                        case Gravity.LEFT:
                        default:
                            childLeft = paddingLeft + lp.leftMargin;
                            break;
                    }
    
                    if (hasDividerBeforeChildAt(i)) {
                        childTop += mDividerHeight;
                    }
    
                    childTop += lp.topMargin;
                    setChildFrame(child, childLeft, childTop + getLocationOffset(child),
                            childWidth, childHeight);
                    childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);
    
                    i += getChildrenSkipCount(child, i);
                }
            }
        }
    

    在这个方法中它计算出自已的能给viewchild剩余空间,然后得到每个viewchild,再给他们摆放真正的位置。这就是onLayout()方法的作用。

    3、继承LinearLayout示例

    这里写图片描述

    在view中代码

    public class MyView extends LinearLayout implements View.OnClickListener {
        private TextView textValue;
        private ImageView iv_add;
        private ImageView iv_decrease;
    
        private int minValue;
        private int maxValue;
    
        private int value;
    
    
        private Context context;
    
        public int getValue() {
            return Integer.valueOf(textValue.getText().toString());
        }
    
        public void setValue(int value) {
            this.value = value;
        }
        public int getMinValue() {
            return minValue;
        }
    
        public void setMinValue(int minValue) {
            this.minValue = minValue;
        }
    
        public int getMaxValue() {
            return maxValue;
        }
    
        public void setMaxValue(int maxValue) {
            this.maxValue = maxValue;
        }
    
    
    
        public MyView(Context context) {
            super(context);
            this.context = context;
            initView();
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
            initView();
        }
    
        public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.context = context;
            initView();
        }
    
        private void initView() {
            View view = inflate(context, R.layout.myview, this);
            textValue= (TextView)view.findViewById(R.id.textValue);
            iv_decrease = (ImageView) view.findViewById(R.id.decrease);
            iv_add = (ImageView) view.findViewById(R.id.add);
    
            iv_decrease.setOnClickListener(this);
            iv_add.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.decrease:
                    decrease();
                    break;
                case R.id.add:
                    add();
                    break;
            }
        }
    
        private void add() {
           int currentValue=Integer.valueOf(textValue.getText().toString());
            if(currentValue<getMaxValue()){
               textValue.setText(String.valueOf(currentValue+1));
            }
            if(currentValue==getMaxValue()){
                Toast.makeText(context,"不能超过库存 ",Toast.LENGTH_SHORT).show();
           }
        }
    
        private void decrease() {
            int currentValue=Integer.valueOf(textValue.getText().toString());
            if(currentValue>getMinValue()){
                textValue.setText(String.valueOf(currentValue - 1));
            }
            if(currentValue==getMinValue()){
                Toast.makeText(context,"不能小于0 ",Toast.LENGTH_SHORT).show();
            }
        }
    }

    清单文件中引入

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:orientation="vertical"
        tools:context="com.example.yu.customview.MainActivity">
    
        <view.MyView
            android:id="@+id/addAndDecButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"></view.MyView>
    
        <Button
            android:layout_margin="10dp"
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="提交" />
    
        <TextView
            android:layout_margin="10dp"
            android:textSize="15dp"
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="购买数量   " />
        <View
            android:background="#000000"
            android:layout_width="match_parent"
            android:layout_height="2dp"></View>
        <view.MyView2
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    

    在activity中调用

    package com.example.yu.customview;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import view.MyView;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private MyView myView;
    
        private TextView text;
    
        private Button btn;
    
        RelativeLayout rl;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            myView= (MyView) findViewById(R.id.addAndDecButton);
            myView.setMinValue(0);
            myView.setMaxValue(10);
            text=(TextView)findViewById(R.id.text);
            btn= (Button) findViewById(R.id.button);
            btn.setOnClickListener(this);
        }
    
    
        @Override
        public void onClick(View v) {
            text.setText("购买数量为:   "+myView.getValue());
        }
    }
    

    代码下载地址
    http://download.csdn.net/detail/androidxiaogang/9592557

    展开全文
  • View类详解

    2015-07-27 23:33:08
    自定义 View的常用方法:  onFinishInflate() 当View中所有的子控件 均被映射成xml后触发  onMeasure(int, int) 确定所有子元素的大小  onLayout(boolean, int, int, int, int) 当View分配所有的子元素的...

    自定义 View的常用方法:

      onFinishInflate() 当View中所有的子控件 均被映射成xml后触发

      onMeasure(int, int) 确定所有子元素的大小

      onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发

      onSizeChanged(int, int, int, int) 当view的大小发生变化时触发

      onDraw(Canvas) view渲染内容的细节

      onKeyDown(int, KeyEvent) 有按键按下后触发

      onKeyUp(int, KeyEvent) 有按键按下后弹起时触发

      onTrackballEvent(MotionEvent) 轨迹球事件

      onTouchEvent(MotionEvent) 触屏事件

      onFocusChanged(boolean, int, Rect) 当View获取 或失去焦点时触发

      onWindowFocusChanged(boolean) 当窗口包含的view获取或失去焦点时触发

      onAttachedToWindow() 当view被附着到一个窗口时触发

      onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和 onAttachedToWindow() 是相反的。

      onWindowVisibilityChanged(int) 当窗口中包含的可见的view发生变化时触发

      以上是View实现的一些基本接口的回调方法,一般我们需要处理画布的显示时,重写onDraw(Canvas)用的的是最多的:

      view plaincopy to clipboardprint 
    @Override 
    protected void onDraw(Canvas canvas) { 
      //这里我们直接使用canvas对象处理当前的画布,比如说使用Paint来选择要填充的颜色 
    Paint paintBackground = new Paint(); 
    paintBackground.setColor(getResources().getColor(R.color.xxx)); //从Res中找到名为xxx的color颜色定义 
    canvas.drawRect(0, 0, getWidth(), getHeight(), paintBackground); //设置当前画布的背景颜色为paintBackground中定义的颜色,以0,0作为为起点,以当前画布的宽度和高度为重点即整块画布来填充,具体的请查看Android123未来讲到的Canvas和Paint,在Canvas中我们可以实现画路径,图形,区域,线。而Paint作为绘画方式的对象可以设置颜色,大小,甚至字体的类型等等。 
    } 
    当然还有就是处理窗口还原状态问题(一般用于横竖屏切换),除了在Activity中可以调用外,开发游戏时我们尽量在View中使用类似

      view plaincopy to clipboardprint 
    @Override 
    protected Parcelable onSaveInstanceState() { 
       Parcelable p = super.onSaveInstanceState(); 
       Bundle bundle = new Bundle(); 
       bundle.putInt("x", pX); 
       bundle.putInt("y", pY); 
       bundle.putParcelable("android123_state", p); 
       return bundle; 
    } 
    @Override 
    protected void onRestoreInstanceState(Parcelable state) {  
       Bundle bundle = (Bundle) state; 
       dosomething(bundle.getInt("x"), bundle.getInt("y")); //获取刚才存储的x和y信息 
       super.onRestoreInstanceState(bundle.getParcelable("android123_state")); 
       return; 
    }

    展开全文
  • 类型View相关概念

    千次阅读 2013-11-14 12:06:03
    “使用强类型View传递数据到View”对应的概念是“使用ViewData传递数据到View”,即a Strongly-Typed View与a weakly-typed dictionary  现在ASP.NET MVC中普遍使用强类型View,即指定View中的Model的类型。创建...
  • 问题:视图View的各种不同类型比较。 方法: 一、ListView 二、TableView 三、TreeView 四、GridView 五、TabView 六、View
  • Error:(16, 47) 错误: 不兼容的类型: View无法转换为Button Error:Execution failed for task ':app:compileDebugJavaWithJavac'. > Compilation failed; see the compiler error output for details. 以下是...
  • 距离写上一篇文章《自定义菜单的创建及菜单事件响应》整整过了两个月的时间,那时公众平台还没有开放view类型的菜单。在不久前,微信公众平台悄悄开放了view类型的菜单,却没有在首页发布任何通知,貌似微信团队很...
  • input框的23种类型

    万次阅读 多人点赞 2018-06-25 15:29:12
    input框的23种类型input框的类型到底有多少种呢?零零总总算起来有23种。▍总述常用的并且能为大多数浏览器所识别的类型大概有:text、password、number、button、reset、submit、hidden、radio、checkbox、file、...
  • 在我们的开发工作时,findViewById可能是用得最多的函数之一,但它特别讨厌的地方就是我们经常需要对返回的view进行类型转换,输入麻烦、代码抽离。
  • View对象既可以用实现View.OnDragListener接口的拖放事件监听器,也可以用View对象的onDragEvent(DragEvent)回调方法来接收拖拽事件。当系统调用这个回调方法或监听器时,都要给它们传递一个DragEvent对象。 在...
  • 解决方法:检查是否没有实现接口没有加上接口
  • Asp.net mvc 强类型View

    千次阅读 2016-04-13 11:21:53
    上节对ViewData和ViewBag进行比较和实验,并总结了二者的缺点,ViewData和ViewBag引起的问题根源就因为数据类型,参数值的数据类型被封装在ViewData中,即对象,微软针对上述问题,推出了强类型View。 对上节的例子,...
  • 获取activity上所有指定类型的控件

    千次阅读 2015-06-28 12:05:35
    Android获取所有指定类型的子控件,这样就不需要逐个使用findViewByID来获取控件,来达到控制状态的目的了。
  • switch开关组件使用主要属性...<view>switch类型开关</view> <switch type="switch" checked="true" bindchange="listenerSwitch"/><!--checkbox类型开关--> <view>checkbox类型开关</view> <switch type="checkbox" bi
  • Kotlin as 类型转换运算符

    千次阅读 2019-10-17 14:39:59
    起源:封装 DialogFragment 时自定义的 ViewHolder ...T : View> getView(@IdRes viewId: Int): T { var view = mViews?.get(viewId) if (view == null) { view = mConvertView?.findViewById(viewId)...
  • android图形系统详解六:View layer

    万次阅读 2012-04-16 07:47:18
    View layers 在所有版本的Android中,views都有画到离屏缓冲的能力,这包括使用view的绘制cache,或使用Canvas.saveLayer().离屏缓冲,或者说层,有很多用处.你可以使用它们来为复杂的view动画或使用组合效果时...
  • ModelAndView返回json类型数据

    万次阅读 2018-05-30 23:23:31
    ModelAndView返回json类型数据一.自定义bean,手动在返回数据时将数据json化 1.自定义类JacksonUtil.java,类中实现tojson方法(即将数据转成json类型); 2.自定义类JsonView 继承 AbstractView 3.xml中配置bean...
  • 今天咱们是用RecyclerView来实现这个多种Item的加载....其实最关键的是要复写RecyclerView的Adapter中的getItemViewType()方法 这个方法就根据条件返回条目的类型 其实就是从activity中传到adapter中的数据中
  • 本文由Markdown语法编辑器编辑完成。...DebugView is an application that lets you monitor debug output on your local system, or any computer on the network that you can reach via TCP/IP. It is capa
1 2 3 4 5 ... 20
收藏数 782,234
精华内容 312,893
关键字:

view类型