Beginning in Android 3.0 (API level 11), you have more control on how and when to use layers with the View.setLayerType() method. This API takes two parameters: the type of layer you want to use and an optional Paint object that describes how the layer should be composited... ... ... A view can use one of three layer types:
- LAYER_TYPE_NONE: The view is rendered normally and is not backed by an off-screen buffer. This is the default behavior.
- LAYER_TYPE_HARDWARE: The view is rendered in hardware into a hardware texture if the application is hardware accelerated. If the application is not hardware accelerated, this layer type behaves the same as LAYER_TYPE_SOFTWARE.
- LAYER_TYPE_SOFTWARE: The view is rendered in software into a bitmap.
You can disable hardware acceleration for an individual view at runtime with the following code:
Note: You currently cannot enable hardware acceleration at the view level. View layers have other functions besides disabling hardware acceleration.
reference: http://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Note: You currently cannot enable hardware acceleration at the view level. View layers have other functions besides disabling hardware acceleration.
reference: http://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling
To varify if a View is Hardware Accelerated, we can call myView.isHardwareAccelerated() and/or Canvas.isHardwareAccelerated().
- View.isHardwareAccelerated() returns true if the View is attached to a hardware accelerated window.
- Canvas.isHardwareAccelerated() returns true if the Canvas is hardware accelerated
reference: http://developer.android.com/guide/topics/graphics/hardware-accel.html#determining
Also have to be noticed is when hardware accelerated, some operation is unsupported, depends on API levels. That's why we have to disable Hardware Acceleration.
reference: http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
MainActivity.java
package com.example.androiddrawpath;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MainActivity extends Activity {
	SeekBar radiusBar;
	MyView myView;
	
	SeekBar ptBar;
	TextView textPt;
	final static int MIN_PT = 3;
	
	RadioButton optLayerTypeNone, optLayerTypeSoftware, optLayerTypeHardware;
	TextView textLayerInfo;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		radiusBar = (SeekBar) findViewById(R.id.radiusbar);
		myView = (MyView) findViewById(R.id.myview);
		float defaultRatio = (float) (radiusBar.getProgress())
				/ (float) (radiusBar.getMax());
		myView.setShapeRadiusRatio(defaultRatio);
		radiusBar.setOnSeekBarChangeListener(radiusBarOnSeekBarChangeListener);
		
		textPt = (TextView)findViewById(R.id.pttext);
		ptBar = (SeekBar)findViewById(R.id.ptbar);
		ptBar.setOnSeekBarChangeListener(ptBarOnSeekBarChangeListener);
		
		optLayerTypeNone = (RadioButton)findViewById(R.id.typeNone);
		optLayerTypeSoftware = (RadioButton)findViewById(R.id.typeSoftware);
		optLayerTypeHardware = (RadioButton)findViewById(R.id.typeHardware);
		textLayerInfo = (TextView)findViewById(R.id.typeinfo);
		
		myView.passElements(textLayerInfo);
		myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
		optLayerTypeNone.setOnCheckedChangeListener(optLayerTypeOnCheckedChangeListener);
		optLayerTypeSoftware.setOnCheckedChangeListener(optLayerTypeOnCheckedChangeListener);
		optLayerTypeHardware.setOnCheckedChangeListener(optLayerTypeOnCheckedChangeListener);
	};
	
	OnCheckedChangeListener optLayerTypeOnCheckedChangeListener = 
		new OnCheckedChangeListener(){
			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if(optLayerTypeNone.isChecked()){
					myView.setLayerType(View.LAYER_TYPE_NONE, null);
				}else if(optLayerTypeSoftware.isChecked()){
					myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
				}else{
					myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
				}
				
				myView.invalidate();
			}};
	OnSeekBarChangeListener radiusBarOnSeekBarChangeListener = 
		new OnSeekBarChangeListener() {
		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			float ratio = (float) (radiusBar.getProgress())
					/ (float) (radiusBar.getMax());
			myView.setShapeRadiusRatio(ratio);
			myView.invalidate();
		}
		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {}
		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {}
	};
	
	OnSeekBarChangeListener ptBarOnSeekBarChangeListener = 
		new OnSeekBarChangeListener() {
		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			int pt = progress + MIN_PT;
			textPt.setText("number of point in polygon: " + String.valueOf(pt));
			myView.setNumberOfPoint(pt);
			myView.invalidate();
		}
		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {}
		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {}
	};
}
MyView.java
package com.example.androiddrawpath;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
public class MyView extends View {
	
	MyShape myShape;
	float ratioRadius;
	int numberOfPoint = 3;	//default
	
	//corresponding to UI element
	TextView textLayerInfo;
	public MyView(Context context) {
		super(context);
		initMyView();
	}
	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initMyView();
	}
	public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initMyView();
	}
	
	public void initMyView(){
		myShape = new MyShape();
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		long starting = System.nanoTime();
		
		int w = getWidth();
		int h = getHeight();
		
		if((w==0) || (h==0)){
			return;
		}
		
		float x = (float)w/2.0f;
		float y = (float)h/2.0f;
		float radius;
		if(w > h){
			radius = h * ratioRadius;
		}else{
			radius = w * ratioRadius;
		}
		
		myShape.setPolygon(x, y, radius, numberOfPoint);
		canvas.drawPath(myShape.getPath(), myShape.getPaint());
		
		long end = System.nanoTime();
		
		String info = "myView.isHardwareAccelerated() = " + isHardwareAccelerated() + "\n"
				+ "canvas.isHardwareAccelerated() = " + canvas.isHardwareAccelerated() + "\n"
				+ "processing time (reference only) : " + String.valueOf(end - starting) + " (ns)";
		textLayerInfo.setText(info);
		
	}
	
	public void setShapeRadiusRatio(float ratio){
		ratioRadius = ratio;
	}
	
	public void setNumberOfPoint(int pt){
		numberOfPoint = pt;
	}
	
	public void passElements(TextView textLayerInfo){
		this.textLayerInfo = textLayerInfo;
	}
}
MyShape.java
package com.example.androiddrawpath;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
public class MyShape {
	private Paint paint;
	private Path path;
	public MyShape() {
		paint = new Paint();
		paint.setColor(Color.BLUE);
		paint.setStrokeWidth(3);
		paint.setStyle(Paint.Style.STROKE);
		
		path = new Path();
	}
	public void setCircle(float x, float y, float radius, Path.Direction dir){
		path.reset();
		path.addCircle(x, y, radius, dir);
	}
	
	public void setPolygon(float x, float y, float radius, int numOfPt){
		
		double section = 2.0 * Math.PI/numOfPt;
		
		path.reset();
		path.moveTo(
			(float)(x + radius * Math.cos(0)), 
			(float)(y + radius * Math.sin(0)));
		
		for(int i=1; i<numOfPt; i++){
			path.lineTo(
				(float)(x + radius * Math.cos(section * i)), 
				(float)(y + radius * Math.sin(section * i)));
		}
		
		path.close();
		
	}
	
	public Path getPath(){
		return path;
	}
	
	public Paint getPaint(){
		return paint;
	}
	
}
/res/layout/activity_main.xml
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.androiddrawpath.MainActivity" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="radius(%)"/>
    <SeekBar 
        android:id="@+id/radiusbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="50" />
    <TextView 
        android:id="@+id/pttext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="number of point in polygon: 3"/>
    <SeekBar 
        android:id="@+id/ptbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="10"
        android:progress="0" />
    
    <RadioGroup
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    	<RadioButton android:id="@+id/typeNone"
        	android:layout_width="0dp"
	        android:layout_weight="1"
    	    android:layout_height="wrap_content"
        	android:text="LAYER_TYPE_NONE"/>
	    <RadioButton android:id="@+id/typeSoftware"
    	    android:layout_width="0dp"
        	android:layout_weight="1"
	        android:layout_height="wrap_content"
    	    android:text="LAYER_TYPE_SOFTWARE"/>
	    <RadioButton android:id="@+id/typeHardware"
    	    android:layout_width="0dp"
        	android:layout_weight="1"
	        android:layout_height="wrap_content"
    	    android:text="LAYER_TYPE_HARDWARE"/>
    </RadioGroup>
    
    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
	    <TextView 
	        android:id="@+id/typeinfo"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:layout_alignParentBottom="true" />
	    <com.example.androiddrawpath.MyView 
	        android:id="@+id/myview"
	        android:layout_width="match_parent"
	        android:layout_height="match_parent" />
    </RelativeLayout>
</LinearLayout>
In order to call setLayerType(int layerType, Paint paint), View.isHardwareAccelerated() and Canvas.isHardwareAccelerated (), android:minSdkVersion in AndroidManifest.xml have to be set ="11" in .
 Download the files.
Download the files.More examples of Draw Path on canvas of custom View.

 
No comments:
Post a Comment