介绍:
1) 自定义绘制一个View控件
2)加载button、image、text、自定义控件View对象
3)通过加载 activity_main 中的 “com.yline.layoutinflatertwo.View.MyViewGroup” 将界面显示出来
文件介绍:
// MainActivity.java 主函数,对应的布局文件为activity_main.xml
// MyView.java 重绘一个自定义View
// MyViewGroup.java 加载 自定义控件、已有控件
// activity_main.xml 主界面,加载MyViewGroup.java
代码:
// MainAvtivity.java
package com.yline.layoutinflatertwo;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.yline.layoutinflatertwo.View.MyViewGroup;
public class MainActivity extends Activity {
private Button btn;
private TextView txt;
private MyViewGroup myViewGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
txt = (TextView)findViewById(R.id.txt);
myViewGroup = (MyViewGroup)findViewById(R.id.custemViewGroup);
btn.setOnClickListener(new View.OnClickListener() {
// 设置 其 是否可见
@Override
public void onClick(View v) {
if(txt.getVisibility() == View.VISIBLE)
txt.setVisibility(View.INVISIBLE);
else
txt.setVisibility(View.INVISIBLE);
myViewGroup.invalidate();
if(myViewGroup.getVisibility() == View.VISIBLE)
myViewGroup.setVisibility(View.GONE);
else
myViewGroup.setVisibility(View.VISIBLE);
myViewGroup.requestFocus();
}
});
}
}
// MyView.java
package com.yline.layoutinflatertwo.View;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
//自定义View对象
public class MyView extends View{
private Paint paint = new Paint() ;
public MyView(Context context) {
super(context);
}
public MyView(Context context , AttributeSet attrs){
super(context,attrs);
}
/**
* //设置该View大小为 50 50
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension(50 , 50) ;
}
//存在canvas对象,即存在默认的显示区域
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
//加粗
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
paint.setColor(Color.RED);
canvas.drawColor(Color.BLUE);
canvas.drawRect(0, 0, 30, 30, paint);
canvas.drawText("MyView", 10, 40, paint);
}
}
// MyViewGroup.java
package com.yline.layoutinflatertwo.View;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.yline.layoutinflatertwo.R;
//自定义ViewGroup 对象
public class MyViewGroup extends ViewGroup{
private static String TAG = "MyViewGroup" ;
private Context mContext ;
public MyViewGroup(Context context) {
super(context);
mContext = context ;
init() ;
}
//xml定义的属性,需要该构造函数
public MyViewGroup(Context context , AttributeSet attrs){
super(context,attrs);
mContext = context;
init();
}
//为MyViewGroup添加三个子View
private void init(){
//调用ViewGroup父类addView()方法添加子View
//child 对象一 : Button
Button btn= new Button(mContext);
btn.setText("I am Button");
this.addView(btn);
//child 对象二 : ImageView
ImageView img = new ImageView(mContext);
img.setBackgroundResource(R.drawable.ic_launcher);
this.addView(img) ;
//child 对象三 : TextView
TextView txt = new TextView(mContext);
txt.setText("Only Text");
this.addView(txt) ;
//child 对象四 : 自定义View
MyView myView = new MyView(mContext) ;
this.addView(myView) ;
}
/**
* 对每个子View进行measure():设置每子View的大小,即实际宽和高
* 接收两个参数,
* widthMeasureSpec 实际宽度
* heightMeasureSpec 实际高度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int childCount = getChildCount(); // ViewGroup 的大小
int specSize_Widht = MeasureSpec.getSize(widthMeasureSpec); // 获取实际的宽度
int specSize_Heigth = MeasureSpec.getSize(heightMeasureSpec); // 获取实际的高度
setMeasuredDimension(specSize_Widht,specSize_Heigth); //设置本ViewGroup的宽高
for(int i=0 ;i<childCount ; i++){
View child = getChildAt(i) ; //获得每个对象的引用
child.measure(50, 50) ; //简单的设置每个子View对象的宽高为 50px , 50px
//或者可以调用ViewGroup父类方法measureChild()或者measureChildWithMargins()方法
this.measureChild(child, widthMeasureSpec, heightMeasureSpec) ;
}
}
/**
* 对每个子View视图进行布局
* 接收四个参数,分别代表着左、上、右、下的坐标
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount() ;
int startLeft = 0 ;//设置每个子View的起始横坐标
int startTop = 10 ; //每个子View距离父视图的位置 , 简单设置为10px吧 。 可以理解为 android:margin=10px ;
// 一次绘制一个子视图
for(int i=0 ;i<childCount ; i++){
View child = getChildAt(i) ; //获得每个对象的引用
child.layout(startLeft, startTop,
startLeft+child.getMeasuredWidth(), startTop+child.getMeasuredHeight()) ;
startLeft = startLeft+child.getMeasuredWidth() + 10; //校准startLeft值,View之间的间距设为10px ;
}
}
/**
* 绘图过程Android已经为我们封装好了 ,这儿只为了观察方法调用线程
*/
protected void dispatchDraw(Canvas canvas){
Log.i(TAG, "**** dispatchDraw start ****") ;
super.dispatchDraw(canvas) ;
}
protected boolean drawChild(Canvas canvas , View child, long drawingTime){
Log.i(TAG, "**** drawChild start ****") ;
return super.drawChild(canvas, child, drawingTime) ;
}
}
// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20px"
android:text="点击我查看Log绘制流程" >
</Button>
<com.yline.layoutinflatertwo.View.MyViewGroup
android:id="@+id/custemViewGroup"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</com.yline.layoutinflatertwo.View.MyViewGroup>
</LinearLayout>
运行图:
可运行代码下载链接:
http://pan.baidu.com/s/1sjI2wRN
参考网址:
http://blog.csdn.net/guolin_blog/article/details/16330267