android自定義view之地圖(一)
最近參加了一個比賽,要用到自己做一個自定義的小地圖,所以在網上查找了一些關於自定義view的有關資料,也瞭解了自定義控制元件的初步知識。
效果圖
第一階段我畫了一個自制的網格圖,點哪個網格就會哪個網格就會顯示。
工作環境圖
程式碼介紹
1。我們都知道當使用android的原始控制元件時,每個控制元件都可以定義屬性,比如android:id ,android:layout_width等等大家並不陌生的屬性,有些屬性是每個控制元件都有的比如上面兩個,還有一些是控制元件自己有的。我們自定義的控制元件可以定義自己想要的屬性,方便我們以後自己使用。
那就是在values目錄下建立一個attrs.xml檔案。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MapView">
<attr name="border_color" format="color" />
<attr name="border_width" format="dimension" />
</declare-styleable>
</resources>
這樣就給我們的我們就給控制元件加了 border_color 和border_width 兩個屬性,在這裡的format裡定義的是我們的屬性的值是什麼型別,比如border_color是color,border_width是dimension,每個不同的資料型別對應不同的型別。
2.第二部分也是最重要的自定義控制元件的類。
首先我們的自定義類要繼承View
public class CustomView extends View {
}
接下來我們完成view要實現的三個不同引數的建構函式,其中init是我們自己寫的初始化資訊的函式。在第二個建構函式中,我們獲取了我們在attrs.xml中定義的值。
public CustomView(Context context) {
super(context);
//初始化資訊
init();
}
public CustomView(Context context, AttributeSet attrs) {
super (context, attrs);
//獲取我們自己的屬性
TypedArray typedArray = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.MapView, 0, 0);
try {
mBorderColor = typedArray.getColor(
R.styleable.MapView_border_color, 0xff000000);
mBorderWidth = typedArray.getDimension(
R.styleable.MapView_border_width, 2);
} finally {
typedArray.recycle();
}
init();
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
然後是覆些view中這幾個函式
onSizeChanged(int w, int h, int oldw, int oldh) {}這個函式是獲取我們view的設定的大小
onDraw(Canvas canvas){}是設定view中的繪畫,也是view中最重要的函式
onTouchEvent(MotionEvent event){}是設定點選事件
package com.example.myview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CustomView extends View {
private float mBorderWidth;
private int mBorderColor;
private Paint mPaint;
private RectF mBounds;
private float width;
private float height;
float radius;
// 格子的數量
private int boxnum = 50;
// 每個方塊的長度
float lenOfWidth;
float lenOfHeight;
PointF pointF;
public CustomView(Context context) {
super(context);
init();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
MyPoint point = getMyPoint(event.getX(), event.getY());
if (point == null)
return false;
pointF = getPointF(point.getX(), point.getY());
invalidate();
return true;
}
// 把xy的座標轉換我座標
public MyPoint getMyPoint(float eventX, float eventY) {
// 注意觸碰的x,y座標軸與計算機的陣列相反- -
int y = (int) ((eventX - (mBounds.centerX() - (float) 0.9 * width / 2)) / lenOfWidth);
int x = (int) ((eventY - (mBounds.centerY() - (float) 0.9 * height / 2)) / lenOfHeight);
if (x < 0 || x >= boxnum || y < 0 || y >= boxnum)
return null;
return new MyPoint(x, y);
}
// 把座標轉換成螢幕座標
public PointF getPointF(int x, int y) {
// 注意觸碰的x,y座標軸與計算機的陣列相反- -
float temp_x = y * lenOfWidth
+ (mBounds.centerX() - (float) 0.9 * width / 2);
float temp_y = x * lenOfHeight
+ (mBounds.centerY() - (float) 0.9 * height / 2);
PointF pointF = new PointF(temp_x, temp_y);
return pointF;
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.MapView, 0, 0);
try {
mBorderColor = typedArray.getColor(
R.styleable.MapView_border_color, 0xff000000);
mBorderWidth = typedArray.getDimension(
R.styleable.MapView_border_width, 2);
} finally {
typedArray.recycle();
}
init();
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mBorderWidth);
mPaint.setColor(mBorderColor);
mPaint.setAlpha(255);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBounds = new RectF(getLeft(), getTop(), getRight(), getBottom());
width = mBounds.right - mBounds.left;
height = mBounds.bottom - mBounds.top;
if (width < height) {
radius = width / 4;
} else {
radius = height / 4;
}
lenOfWidth = (float) 0.9 * width / boxnum;
lenOfHeight = (float) 0.9 * height / boxnum;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(0x66555555);
canvas.drawRoundRect(
new RectF(mBounds.centerX() - (float) 0.9 * width / 2, mBounds
.centerY() - (float) 0.9 * height / 2, mBounds
.centerX() + (float) 0.9 * width / 2, mBounds.centerY()
+ (float) 0.9 * height / 2), 30, 30, mPaint);
float lenOfWidth = (float) 0.9 * width / boxnum;
float lenOfHeight = (float) 0.9 * height / boxnum;
// 畫豎線
for (int i = 0; i < boxnum; i++) {
canvas.drawLine(mBounds.centerX() - (float) 0.9 * width / 2 + i
* lenOfWidth, mBounds.centerY() - (float) 0.9 * height / 2,
mBounds.centerX() - (float) 0.9 * width / 2 + i
* lenOfWidth, mBounds.centerY() + (float) 0.9
* height / 2, mPaint);
canvas.drawLine(mBounds.centerX() - (float) 0.9 * width / 2,
mBounds.centerY() - (float) 0.9 * height / 2 + i
* lenOfHeight, mBounds.centerX() + (float) 0.9
* width / 2, mBounds.centerY() - (float) 0.9
* height / 2 + i * lenOfHeight, mPaint);
}
if (pointF != null) {
// 畫出自己在哪裡
mPaint.setColor(Color.BLUE);
canvas.drawRect(new RectF(pointF.x, pointF.y,
pointF.x + lenOfWidth, pointF.y + lenOfHeight), mPaint);
}
}
}
3.最後是我們acitivity檔案和xml佈局檔案
package com.example.myview;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private CustomView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view=(CustomView) findViewById(R.id.view1);
}
}
佈局檔案
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.example.myview.CustomView
android:id="@+id/view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:border_color="#ff1ff41f"
app:border_width="1dp"/>
</FrameLayout>
</LinearLayout>