2.反射方式創建UI組件對象時,使用的構造方法爲下面兩個構造方式之一
View(Context context, AttributeSet attrs):
View(Context context, AttributeSet attrs, int defStyle):
View(Context context)
1 自定義View要學習的是重寫3個方法, 寫構造方法
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenW = dm.widthPixels;//這就是屏的寬
int screenH = dm.heightPixels;
自定義view寫文字“中華人民共和國”
<pre name="code" class="java"><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:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="確定" />
<test.act.MyTextView
android:paddingLeft="40dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<pre name="code" class="java">public class MyTextView extends View {
private String text = "中華人民共和國";
private int textSize = 100;
private Context context;
private int textColor = Color.RED;
private int backageColor = Color.BLUE;
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.setBackgroundColor(this.backageColor);
}
private int getHightSize(int measureSpec) {
int size = 0;
int spec_mode = MeasureSpec.getMode(measureSpec);
int spec_size = MeasureSpec.getSize(measureSpec);
if (spec_mode == MeasureSpec.EXACTLY) {
System.out.println("exactly");
size = spec_size;
} else if (spec_mode == MeasureSpec.AT_MOST) {
System.out.println("at_most");
size = textSize;
} else if (spec_mode == MeasureSpec.UNSPECIFIED) {
System.out.println("unspecified");
size = 100;
}
return size;
}
private int getWidthSize(int measureSpec) {
int size = 0;
int spec_mode = MeasureSpec.getMode(measureSpec);
int spec_size = MeasureSpec.getSize(measureSpec);
if (spec_mode == MeasureSpec.EXACTLY) {
System.out.println("exactly");
size = spec_size;
} else if (spec_mode == MeasureSpec.AT_MOST) {
System.out.println("at_most");
size = textSize * text.length();
} else if (spec_mode == MeasureSpec.UNSPECIFIED) {
System.out.println("unspecified");
size = 100;
}
return size;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(this.getWidthSize(widthMeasureSpec), this.getHightSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setTextSize(textSize);
paint.setColor(this.textColor);
System.out.println("核潛艇 =" + this.getMeasuredHeight());
Toast.makeText(this.context, "size" + this.getMeasuredHeight(),
Toast.LENGTH_LONG).show();
// 座標是左下角
float left = this.getPaddingLeft();
float height = this.getMeasuredHeight();//就是textSize的值。
float bottom = height - this.getPaddingBottom() - height*15/100;
canvas.drawText(text, left, bottom, paint);
}
}
用自定義View設置字體變化顏色“<span style="color: rgb(0, 176, 80); font-family: 微軟雅黑; font-size: 22px; line-height: 33px;">讓文字的顏色每隔一秒種變化一次,即文字顏色爲紅色和黃色,每隔一秒變化一次,則把MyTextView類改爲”</span>
<span style="color: rgb(0, 176, 80); font-family: 微軟雅黑; font-size: 22px; line-height: 33px;"></span><pre name="code" class="java">public class MyTextView extends View {
private String text = "中華人民共和國";
private int textSize = 100;
private Context context;
private int textColor = Color.RED;
private int backageColor = Color.BLUE;
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.setBackgroundColor(this.backageColor);
}
private int getHightSize(int measureSpec) {
int size = 0;
int spec_mode = MeasureSpec.getMode(measureSpec);
int spec_size = MeasureSpec.getSize(measureSpec);
if (spec_mode == MeasureSpec.EXACTLY) {
System.out.println("exactly");
size = spec_size;
} else if (spec_mode == MeasureSpec.AT_MOST) {
System.out.println("at_most");
size = textSize;
} else if (spec_mode == MeasureSpec.UNSPECIFIED) {
System.out.println("unspecified");
size = 100;
}
return size;
}
private int getWidthSize(int measureSpec) {
int size = 0;
int spec_mode = MeasureSpec.getMode(measureSpec);
int spec_size = MeasureSpec.getSize(measureSpec);
if (spec_mode == MeasureSpec.EXACTLY) {
System.out.println("exactly");
size = spec_size;
} else if (spec_mode == MeasureSpec.AT_MOST) {
System.out.println("at_most");
size = textSize * text.length();
} else if (spec_mode == MeasureSpec.UNSPECIFIED) {
System.out.println("unspecified");
size = 100;
}
return size;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(this.getWidthSize(widthMeasureSpec),
this.getHightSize(heightMeasureSpec));
}
int i = 0;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int textColor = 0;
i++;
if (i % 2 == 0) {
textColor = this.textColor;
}else {
textColor = Color.YELLOW;
}
Paint paint = new Paint();
paint.setTextSize(textSize);
paint.setColor(textColor);
System.out.println("核潛艇 =" + this.getMeasuredHeight());
Toast.makeText(this.context, "size" + this.getMeasuredHeight(),
Toast.LENGTH_LONG).show();
// 座標是左下角
float left = this.getPaddingLeft();
float height = this.getMeasuredHeight();// 就是textSize的值。
float bottom = height - this.getPaddingBottom() - height * 15 / 100;
canvas.drawText(text, left, bottom, paint);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.invalidate();
}
}
<span style="font-family: 微軟雅黑; font-size: 22px; line-height: 33px;"></span><pre name="code" class="java" style="font-size: 22px; line-height: 33px;"><span style="color:#330033;">在封裝類裏面的set寫invalidate()方法,能給自定義的View跳轉傳值</span><pre name="code" class="java">package xena.act;
import xena.view.MyView;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
public class MainActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
MyView myView = new MyView(this);
myView.setBackgroundColor(Color.YELLOW);
setContentView(myView);
myView.setR(40);
myView.setStr("中華人民共和國");
myView.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
public void onClick(View v) {//v是事件源
MyView myView = (MyView) v;
myView.setStr("華清遠見");
}
}
/*******************************************************
<pre name="code" class="java">package xena.view;
import xena.act.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class MyView extends View {
private Context context;
private float r = 100;
private String str = "小";
private final String NS = "http://www.hqyj.com";// 名稱空間
private boolean flag;
public float getR() {
return r;
}
public void setR(float r) {
this.r = r;
this.invalidate();//觸發onDraw方法的執行
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
// this.invalidate();//觸發onDraw方法的執行View的監聽事件
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
this.invalidate();//觸發onDraw方法的執行
}
// 用於自定義View當作標籤時用的
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 用於new MyView(...)用的
public MyView(Context context) {
super(context);
}
// 用於繪製界面上的內容,當界面顯示時調用
@Override
protected void onDraw(Canvas canvas) {// canvas畫布對象
super.onDraw(canvas);
// 創建筆 畫
Paint paint = new Paint();
paint.setColor(Color.BLUE);
// 畫圓
canvas.drawCircle(30, 30, this.r, paint);
paint.setColor(Color.RED);
if (flag) {
canvas.drawCircle(30, 30, 5, paint);
}
// 畫字
// 參數1:被繪製的字符串, 參數2,3:指字符串每一個字符的左下角座標
paint.setTextSize(30);// 設置文字大小
canvas.drawText(this.str, 30, 30, paint);
}
}