盒子
盒子
文章目录
  1. 在自定义视图中绘制一个图形
    1. PointF
    2. Paint
    3. Canvas
    4. 实例:绘制一个矩形
  2. Drawable
    1. Selector
    2. Shape
    3. Selector与Shape结合使用
  3. layer-list
  4. AttributeSet

视图绘制与自定义视图

在自定义视图中绘制一个图形

PointF

用于保存两个浮点坐标x,y

1
2
3
4
5
6
7
float x,y;
PointF location
...
location=new PointF(x,y)

location=new PointF();
location.set(x,y);

Paint

存储绘制信息,决定如何绘制

1
2
3
4
5
6
7
...
boxPaint=new Paint();
boxPaint.setColor(Color.RED);
backgrounPaint=new Paint();
backgrounPaint.setColor(Color.BLACK);
canvas.drawPaint(backgrounPaint);
canvas.drawRect(left,top,right,bottom,boxPaint);

Canvas

拥有需要的所有绘制操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
....
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制自定义视图的背景色
canvas.drawPaint(backgrounPaint);
for(Boxer boxer:boxers){
float left=Math.min(boxer.getOrigiin().x,boxer.getCurrent().x);
float right=Math.max(boxer.getOrigiin().x,boxer.getCurrent().x);
float top=Math.min(boxer.getOrigiin().y,boxer.getCurrent().y);
float bottom=Math.max(boxer.getOrigiin().y,boxer.getCurrent().y);
//画出一个矩形
canvas.drawRect(left,top,right,bottom,boxPaint);
}
}

实例:绘制一个矩形

Boxer.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import android.graphics.PointF;
public class Boxer {
private PointF origiin;
private PointF current;
public Boxer(PointF origiin){
this.origiin=origiin;
this.current=origiin;
}
public void setCurrent(PointF current){
this.current=current;
}
public PointF getCurrent() {
return current;
}
public PointF getOrigiin() {
return origiin;
}
}

BoxVieWer.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class BoxVieWer extends View {
private static final String TAG=BoxVieWer.class.getSimpleName();
private Boxer boxer;
private List<Boxer> boxers;
private Paint boxPaint;
private Paint backgrounPaint;
public BoxVieWer(Context context) {
super(context);
}
public BoxVieWer(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
boxers=new ArrayList<>();
boxPaint=new Paint();
boxPaint.setColor(Color.RED);
backgrounPaint=new Paint();
backgrounPaint.setColor(Color.BLACK);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
PointF pointF=new PointF(event.getX(),event.getY());
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
boxer=new Boxer(pointF);
boxers.add(boxer);
break;
case MotionEvent.ACTION_MOVE:
if(boxer!=null){
boxer.setCurrent(pointF);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
boxer=null;
break;
case MotionEvent.ACTION_CANCEL:
boxer=null;
break;

}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPaint(backgrounPaint);
for(Boxer boxer:boxers){
float left=Math.min(boxer.getOrigiin().x,boxer.getCurrent().x);;
float right=Math.max(boxer.getOrigiin().x,boxer.getCurrent().x);
float top=Math.min(boxer.getOrigiin().y,boxer.getCurrent().y);
float bottom=Math.max(boxer.getOrigiin().y,boxer.getCurrent().y);
canvas.drawRect(left,top,right,bottom,boxPaint);
}
}
}

ViewerActivity.class

1
2
3
4
5
6
7
8
9
10
11
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import io.githubs.grooters.luffy.R;
public class ViewerActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_drawer);
}
}

view_drawer.xml

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<luffy_viewer.BoxVieWer
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Drawable

Selector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8" ?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 默认时的背景图片-->
<item android:drawable="@drawable/pic1" />
<!-- 没有焦点时的背景图片-->
<item android:state_window_focused="false" android:drawable="@drawable/pic1" />
<!-- 非触摸模式下获得焦点并单击时的背景图片-->
<item android:state_focused="true" android:state_pressed="true"
android:drawable="@drawable/pic2" />
<!-- 触摸模式下单击时的背景图片-->
<item android:state_focused="false" android:state_pressed="true"
android:drawable="@drawable/pic3" />
<!--选中时的图片背景-->
<item android:state_selected="true" android:drawable="@drawable/pic4" />
<!--获得焦点时的图片背景-->
<item android:state_focused="true" android:drawable="@drawable/pic5" />
</selector>

Shape

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="utf-8"?>
    <shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    android:useLevel="false">
    <stroke
    android:color="@color/colorAccent"
    android:width="1dp"/>
    <size
    android:width="20dp"
    android:height="20dp"/>
    </shape>

  • 矩形
  • 1
    android:shape="rectangle"

  • 线
  • 1
    android:shape="line"

    必须结合stroke使用,solid无效

  • 实心
  • 1
    <solid android:color="@color/colorAccent"/>

    Selector与Shape结合使用

    以下代码摘抄自互联网

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--第一种方法-->
    <!--<item android:drawable="@drawable/shape_border_press" android:state_pressed="true" />-->
    <!--<item android:drawable="@drawable/shape_border_nor" android:state_window_focused="false"/>-->
    <!--第二种方法-->
    <!--默认情况下是一个带圆角,白色背景,蓝色边框的矩形-->
    <item android:state_window_focused="false">
    <shape android:shape="rectangle">
    <!-- 圆角 -->
    <corners android:radius="5dp" />
    <!--填充颜色为白色-->
    <solid android:color="@color/white" />
    <!-- 描边 -->
    <stroke android:width="1dp" android:color="@color/blue" />
    </shape>
    </item>
    <!--单击时是一个带圆角,白色背景,绿色边框的矩形-->
    <item android:state_pressed="true">
    <shape android:shape="rectangle">
    <!--圆角-->
    <corners android:radius="5dp" />
    <!--填充颜色为白色-->
    <solid android:color="@color/white" />
    <!--描边-->
    <stroke android:width="1dp" android:color="@color/green" />
    </shape>
    </item>
    </selector>

    layer-list

    层叠图画,让两个drawable合二为一

    以下实现一种输入框样式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
    <shape android:shape="rectangle" >
    <solid android:color="@color/red" />
    </shape>
    </item>
    <item android:bottom="15dp">
    <shape android:shape="rectangle" >
    <solid android:color="#ffffff" />
    </shape>
    </item>
    <item
    android:bottom="2dp"
    android:left="1dp"
    android:right="1dp">
    <shape android:shape="rectangle" >
    <solid android:color="#ffffff" />
    </shape>
    </item>

    </layer-list>

    AttributeSet

    使用步骤:

  • 创建attrs.xml文件
  • 1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <declare-styleable name="MyView">
    <attr name="textColor" format="color" />
    <attr name="textSize" format="dimension" />
    </declare-styleable>
    </resources>

  • 创建自定义View类
  • 继承原生View类,通过构造方法获得默认AttributeSet,以默认attr和xml文件为参数创建TypedArray实例,eg:

    1
    TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.MyView);

  • 设置属性
  • 获取attrs.xml中的对应属性,并赋值,然后初始化自定义控件属性

    1
    2
    3
    4
    int color=typedArray.getColor(R.styleable.MyView_textColor,getResources().getColor(R.color.colorAccent,null));
    float textSize=typedArray.getDimension(R.styleable.MyView_textSize,36);
    setText("test");
    setTextColor(color);
    支持一下
    扫一扫,支持Grooter
    • 微信扫一扫
    • 支付宝扫一扫