自定义View——设计规则图形及其属性

来源:互联网 发布:阿里云api接口 编辑:程序博客网 时间:2024/05/16 06:02

思路

绘制自定义形状时(圆和矩形)在继承View的同时还得重写一些方法如

  • onMeasure 测量
  • onSizeChanged 获取到测量的属性
  • onLayout 布局
  • onDraw 绘制
    基本的思路是通过onMeasure 我们可以获取到onSizeChanged里的布局大小之类的然后在onDraw里面绘制,既然是绘制以我们正常的思路肯定需要笔,需要勾勒出边框,需要填充整个布局,对于自定义View也是 如此所以这里我们便需要 Region(绘制的区域), Path (绘制的路径),paint(笔)。
    到这里我们的基本方法以及所需要的类就基本上了解了

开始绘制

到这我们就可以用代码来实现我们需要的效果了:

public class MyView extends View {//    画一个圆所要用到的工具        Region region;//绘制的区域        Path path;//绘制的路径        Paint paint;//画笔private int x,y;    public MyView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);            init();    }    //    实例化要用到的工具    private void init() {        region=new Region();        path=new Path();        paint=new Paint();    }//测量    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }//    获取到测量的结果    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);//        设置圆形        x=w/2;  y=h/2;        path.addCircle(x,y,100, Path.Direction.CW);//依次是 圆心坐标,半径,绘制方向        Region region1 = new Region(0, 0, w, h);//设置我们描绘的圆显示在该区域(也就是整个手机屏幕)        region.setPath(path,region1);//绘制的图形  region要显示的面上    }//    布局    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);    }//    绘制    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        paint.setColor(Color.RED);        canvas.drawPath(path,paint);    }}

在布局文件中

<com.example.administrator.huayuan.MyView    android:id="@+id/list"    android:layout_width="match_parent"    android:layout_height="match_parent" />

代码的注解也详细的写了每一步的意思
效果
这里写图片描述
可见这里我们绘制了一个颜色为红色的圆形图,但是如何我们想要对这个圆设置自己的颜色,以及我们想要的点击事件处理效果呢?

完善圆的自定义属性以及点击事件

我们试着想一下如何才能获取圆的点击事件。肯定得获取焦点啊,因为获取到焦点才能执行事件的处理操作。所以这里我们还要重写一个onTouchEvent方法,当获取到焦点时,就可以处理自己的点击事件了。
效果如下
这里写图片描述
所以这里继续完善我们上面的代码
在MyView里面添加

//    定义传值的方法    public  void  getListener(setOnclickListener listener){        this.listener=listener;    }//    触摸圆的方法    @Override    public boolean onTouchEvent(MotionEvent event) {//        获取触摸点的位置        int  x =(int)event.getX();        int  y =(int)event.getY();//        如果是按下的话        if (event.getAction()==MotionEvent.ACTION_DOWN){            if (region.contains(x,y)){                listener.Circleinner();            }else {                listener.Circleouter();            }        }        return super.onTouchEvent(event);    }//    定义点击事件的接口    public  interface  setOnclickListener{    void   Circleinner();    void  Circleouter();}

在MainActivity里面

public class MainActivity extends AppCompatActivity implements MyView.setOnclickListener {    private MyView myView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        myView= (MyView) findViewById(R.id.list);        myView.getListener(this);    }    @Override    public void Circleinner() {        Toast.makeText(MainActivity.this,"点击圆内",Toast.LENGTH_SHORT).show();    }    @Override    public void Circleouter() {        Toast.makeText(MainActivity.this,"点击圆外",Toast.LENGTH_SHORT).show();    }}

到这里就完成了。
自定义属性
当然我们的圆还有缺陷,比如要自定义圆的颜色以及圆的大小呢?这里就需要用到自定义属性了,对于如何自定义属性以及对上面写接口监听不了解的可以看
http://blog.csdn.net/qiaoshi96_bk/article/details/76685570

问题

不知道大家想过没如果要实现类似下图的效果
这里写图片描述
就是矩形内是一种监听,在矩形外圆内也是一种监听,而在圆外又是一种监听。
其实也不难实现,只是在圆的上面覆盖了矩形而已,所以我们只有依次判断在矩形内和在圆内就可以了,因为圆在矩形上的焦点已经被矩形覆盖了。