涅槃重生小白哥 發表於 2019-6-13 16:33:00

Android开发自定义View

<p>  Android中View组件的作用类似于Swing变成中的JPanel,它只是一个空白的矩形区域,View组件中没有任何内容。对于Android应用的其他UI组件来说,它们都继承了View组件,然后在View组件提供的空白区域绘制外观。</p>
<p>  当Android系统提供的UI组件不足以满足项目需求时,我们可以通过继承View并重写View类的一个或多个方法来自定义组件。</p>
<p>  通常可以被用户重写的方法如下:</p>
<p>    1.构造器:重写构造器是定制View的最基本的方式,当Java(或Kotlin)代码创建一个View实例或根据XML布局文件加载并构建界面时将调用该构造器。</p>
<p>    2.onFinishInflate():这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法将会被调用。</p>
<p>    3.onMeasure(int,int):调用该方法来检测View组件及其所包含的所有子组件的大小。</p>
<p>    4.onLayout(boolean,int,int,int,int):当该组件需要分配其子组件的位置、大小时,该方法就会被回调。</p>
<p>    5.onSizeChanged(int,int,int,int):当该组件的大小被改变时回调该方法。</p>
<p>    6.onDraw(Canvas):当该组件将要绘制它的内容时回调该方法。</p>
<p>    7.onKeyDown(int,KeyEvent):当按下某个键时触发该方法。</p>
<p>    8.onKeyUp(int,KeyEvent):当松开某个键时触发该方法。</p>
<p>    9.onTrackballEvent(MotionEvent):当发生轨迹球事件时触发该方法</p>
<p>    10.onTouchEvent(MotionEvent):当发生触摸屏事件时触发该方法</p>
<p>    11.onFocusChanged(boolean gainFocus,int direction,Rect previouslyFocusedRect):当该组件焦点发生改变时触发该方法。</p>
<p>    12.onWindowFocusChanged(boolean):当包含该组件的窗口失去或得到焦点时触发该方法。</p>
<p>    13.onAttachedToWindow():当把该组件放入某个窗口中时触发该方法</p>
<p>    14.onDetachedFromWindow():当把该组件从某个窗口中分离时触发该方法</p>
<p>    15.onWindowVisibilityChanged(int):当包含该组件的窗口的可见性发生改变时触发该方法。</p>
<p>  当我们在开发自定义View时,通常仅需根据业务需求重写上面的部分方法,如果自定义组件仅仅只是组合现有的组件那就更加简单了,仅仅实现自定义组件的构造器然后使用LayoutInflater加载布局文件即可。</p>
<p>&nbsp;⒈实例自定义View</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> cn.coreqi.view;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.content.Context;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.graphics.Canvas;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.graphics.Color;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.graphics.Paint;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.util.AttributeSet;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.MotionEvent;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.View;
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> DrawView <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> View {
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">float</span> currentX =<span style="color: rgba(0, 0, 0, 1)"> 40f;
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">float</span> currentY =<span style="color: rgba(0, 0, 0, 1)"> 50f;
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">定义并创建画笔</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>   <span style="color: rgba(0, 0, 255, 1)">private</span> Paint p = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Paint();
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span>   <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DrawView(Context context) {
</span><span style="color: rgba(0, 128, 128, 1)">19</span>         <span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(context);
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">21</span>
<span style="color: rgba(0, 128, 128, 1)">22</span>   <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DrawView(Context context, AttributeSet attrs) {
</span><span style="color: rgba(0, 128, 128, 1)">23</span>         <span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(context, attrs);
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">25</span>
<span style="color: rgba(0, 128, 128, 1)">26</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当该组件将要绘制它的内容时触发该方法</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">    @Override
</span><span style="color: rgba(0, 128, 128, 1)">28</span>   <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onDraw(Canvas canvas) {
</span><span style="color: rgba(0, 128, 128, 1)">29</span>         <span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onDraw(canvas);
</span><span style="color: rgba(0, 128, 128, 1)">30</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置画笔的颜色</span>
<span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 0, 1)">      p.setColor(Color.RED);
</span><span style="color: rgba(0, 128, 128, 1)">32</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">绘制一个小圆(作为小球)</span>
<span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)">      canvas.drawCircle(currentX,currentY,15F,p);
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">35</span>
<span style="color: rgba(0, 128, 128, 1)">36</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">为该组件的触碰事件重写事件处理方法</span>
<span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)">    @Override
</span><span style="color: rgba(0, 128, 128, 1)">38</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> onTouchEvent(MotionEvent event) {
</span><span style="color: rgba(0, 128, 128, 1)">39</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改currentX,currentY两个成员变量</span>
<span style="color: rgba(0, 128, 128, 1)">40</span>         currentX =<span style="color: rgba(0, 0, 0, 1)"> event.getX();
</span><span style="color: rgba(0, 128, 128, 1)">41</span>         currentY =<span style="color: rgba(0, 0, 0, 1)"> event.getY();
</span><span style="color: rgba(0, 128, 128, 1)">42</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通知当前组件重新绘制自己</span>
<span style="color: rgba(0, 128, 128, 1)">43</span> <span style="color: rgba(0, 0, 0, 1)">      invalidate();
</span><span style="color: rgba(0, 128, 128, 1)">44</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">返回true表明该处理方法已经处理该事件</span>
<span style="color: rgba(0, 128, 128, 1)">45</span>         <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">46</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">47</span> }</pre>
</div>
<p>⒉在代码中创建自定义View</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> cn.coreqi;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> androidx.appcompat.app.AppCompatActivity;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.os.Bundle;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.widget.LinearLayout;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> cn.coreqi.view.DrawView;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> MainActivity <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> AppCompatActivity {
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">    @Override
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCreate(Bundle savedInstanceState) {
</span><span style="color: rgba(0, 128, 128, 1)">14</span>         <span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onCreate(savedInstanceState);
</span><span style="color: rgba(0, 128, 128, 1)">15</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新建LinearLayout布局容器</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>         LinearLayout layout = <span style="color: rgba(0, 0, 255, 1)">new</span> LinearLayout(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">17</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置该Activity显示layout</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">      setContentView(layout);
</span><span style="color: rgba(0, 128, 128, 1)">19</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建我们自定义的View组件</span>
<span style="color: rgba(0, 128, 128, 1)">20</span>         DrawView draw = <span style="color: rgba(0, 0, 255, 1)">new</span> DrawView(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">21</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置自定义组件的最小宽度、高度</span>
<span style="color: rgba(0, 128, 128, 1)">22</span>         draw.setMinimumWidth(300<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">23</span>         draw.setMinimumHeight(500<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">      layout.addView(draw);
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">26</span> }</pre>
</div>
<p>⒊在XML布局文件中创建自定义View</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">&lt;?</span><span style="color: rgba(255, 0, 255, 1)">xml version="1.0" encoding="utf-8"</span><span style="color: rgba(0, 0, 255, 1)">?&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">androidx.constraintlayout.widget.ConstraintLayout </span><span style="color: rgba(255, 0, 0, 1)">xmlns:android</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/apk/res/android"</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(255, 0, 0, 1)">    xmlns:app</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/apk/res-auto"</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(255, 0, 0, 1)">    xmlns:tools</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/tools"</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(255, 0, 0, 1)">    android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(255, 0, 0, 1)">    android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(255, 0, 0, 1)">    tools:context</span><span style="color: rgba(0, 0, 255, 1)">=".MainActivity"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>   <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">cn.coreqi.view.DrawView
</span><span style="color: rgba(0, 128, 128, 1)">10</span>         <span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/drawView"</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(255, 0, 0, 1)">      android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(255, 0, 0, 1)">      android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">androidx.constraintlayout.widget.ConstraintLayout</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/fanqisoft/p/11017395.html
頁: [1]
查看完整版本: Android开发自定义View