首页 > 技术文章 > 自定义view

hexihexi 2016-12-08 17:16 原文

这两篇文章不可错过,是最靠谱的基础文献。总的来说,如果想完全定制,就继承与于View类;如果只是在原有控件基础上拓展,那就继承TextView、Button或者LinearLayout等。接下来,就以实例的形式,逐步掌握这方面的技能。

    下面就自定义一个类,用来画一个圆圈:

 

  1. <pre class="html" name="code" snippet_file_name="blog_20140110_1_5174710" code_snippet_id="150430">import android.content.Context;  
  2. import android.graphics.Canvas;  
  3. import android.graphics.Color;  
  4. import android.graphics.Paint;  
  5. import android.graphics.Path;  
  6. import android.graphics.Path.Direction;  
  7. import android.util.AttributeSet;  
  8. import android.view.View;  
  9.   
  10. public class GraphicsView extends View {  
  11.     //用于画路径、线条等  
  12.     private Path circle;  
  13.     //画笔  
  14.     private Paint cPaint;  
  15.   
  16.     public GraphicsView(Context context) {  
  17.         super(context);  
  18.           
  19.         initView();  
  20.     }  
  21.   
  22.     public GraphicsView(Context context, AttributeSet attrs) {  
  23.         super(context, attrs);  
  24.         // TODO Auto-generated constructor stub  
  25.         initView();  
  26.     }  
  27.   
  28.     public GraphicsView(Context context, AttributeSet attrs, int defStyleAttr) {  
  29.         super(context, attrs, defStyleAttr);  
  30.         // TODO Auto-generated constructor stub  
  31.         initView();  
  32.     }  
  33.   
  34.     private void initView(){  
  35.         circle = new Path();  
  36.         //画一个轮廓  
  37.         circle.addCircle(150, 150, 100, Direction.CW);  
  38.         //设置画笔  
  39.         cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  40.         cPaint.setStyle(Paint.Style.STROKE);  
  41.         cPaint.setColor(Color.LTGRAY);  
  42.         cPaint.setStrokeWidth(3);  
  43.         //设置背景  
  44.         setBackgroundResource(R.drawable.ic_launcher);  
  45.     }  
  46.       
  47.     @Override  
  48.     public void draw(Canvas canvas) {  
  49.         // TODO Auto-generated method stub  
  50.         super.draw(canvas);  
  51.         canvas.drawPath(circle, cPaint);  
  52.     }  
  53.   
  54. }  
  55. </pre><br>  
  1. import android.content.Context;  
  2. import android.graphics.Canvas;  
  3. import android.graphics.Color;  
  4. import android.graphics.Paint;  
  5. import android.graphics.Path;  
  6. import android.graphics.Path.Direction;  
  7. import android.util.AttributeSet;  
  8. import android.view.View;  
  9.   
  10. public class GraphicsView extends View {  
  11.     //用于画路径、线条等  
  12.     private Path circle;  
  13.     //画笔  
  14.     private Paint cPaint;  
  15.   
  16.     public GraphicsView(Context context) {  
  17.         super(context);  
  18.           
  19.         initView();  
  20.     }  
  21.   
  22.     public GraphicsView(Context context, AttributeSet attrs) {  
  23.         super(context, attrs);  
  24.         // TODO Auto-generated constructor stub  
  25.         initView();  
  26.     }  
  27.   
  28.     public GraphicsView(Context context, AttributeSet attrs, int defStyleAttr) {  
  29.         super(context, attrs, defStyleAttr);  
  30.         // TODO Auto-generated constructor stub  
  31.         initView();  
  32.     }  
  33.   
  34.     private void initView(){  
  35.         circle = new Path();  
  36.         //画一个轮廓  
  37.         circle.addCircle(150, 150, 100, Direction.CW);  
  38.         //设置画笔  
  39.         cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  40.         cPaint.setStyle(Paint.Style.STROKE);  
  41.         cPaint.setColor(Color.LTGRAY);  
  42.         cPaint.setStrokeWidth(3);  
  43.         //设置背景  
  44.         setBackgroundResource(R.drawable.ic_launcher);  
  45.     }  
  46.       
  47.     @Override  
  48.     public void draw(Canvas canvas) {  
  49.         // TODO Auto-generated method stub  
  50.         super.draw(canvas);  
  51.         canvas.drawPath(circle, cPaint);  
  52.     }  
  53.   
  54. }  
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.util.AttributeSet;
import android.view.View;

public class GraphicsView extends View {
    //用于画路径、线条等
	private Path circle;
	//画笔
	private Paint cPaint;

	public GraphicsView(Context context) {
		super(context);
		
		initView();
	}

	public GraphicsView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		initView();
	}

	public GraphicsView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
		initView();
	}

	private void initView(){
		circle = new Path();
		//画一个轮廓
		circle.addCircle(150, 150, 100, Direction.CW);
        //设置画笔
		cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		cPaint.setStyle(Paint.Style.STROKE);
		cPaint.setColor(Color.LTGRAY);
		cPaint.setStrokeWidth(3);
        //设置背景
		setBackgroundResource(R.drawable.ic_launcher);
	}
	
	@Override
	public void draw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.draw(canvas);
		canvas.drawPath(circle, cPaint);
	}

}

    我们是继承了View,并且实现了全部三个构造方法。在这个地方需要注意一下,如果你的view不是在xml中,而且也不打算使用什么样式,那么就无需实现带有AttributeSet attrs, int defStyleAttr这样的构造方法,因为用不到样式什么的。比如在activity中就可以这样使用:

 

 

  1. import android.os.Bundle;  
  2. import android.view.Menu;  
  3. import android.app.Activity;  
  4.   
  5. public class MainActivity extends Activity {  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(new GraphicsView(context));  
  11.     }  
  12.   
  13.       
  14.   
  15.     @Override  
  16.     public boolean onCreateOptionsMenu(Menu menu) {  
  17.           
  18.         getMenuInflater().inflate(R.menu.main, menu);  
  19.         return true;  
  20.     }  
  21.   
  22. }  
import android.os.Bundle;
import android.view.Menu;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(new GraphicsView(context));
	}

	

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

    但是,上面这个类已经实现了所有构造方法,那么就可以在布局文件里使用了,如下:

 

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.      
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <com.example.apptest.GraphicsView  
  9.         android:id="@+id/graphics"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent" />  
  12.   
  13. </LinearLayout>  
<?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"
    android:orientation="vertical" >

    <com.example.apptest.GraphicsView
        android:id="@+id/graphics"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

    对应的activity就是这样:

 

 

  1. import android.os.Bundle;  
  2. import android.view.Menu;  
  3. import android.app.Activity;  
  4.   
  5. public class MainActivity extends Activity {  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.activity_main);  
  11.     }  
  12.   
  13.       
  14.   
  15.     @Override  
  16.     public boolean onCreateOptionsMenu(Menu menu) {  
  17.           
  18.         getMenuInflater().inflate(R.menu.main, menu);  
  19.         return true;  
  20.     }  
  21.   
  22. }  
import android.os.Bundle;
import android.view.Menu;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

    
    效果看起来就是这样的:

 

 

推荐阅读