Canvas提供了ClipPath, ClipRect, ClipRegion 等方法来裁剪,通过Path, Rect ,Region 的不同组合,Android几乎可以支持任意现状的裁剪区域。
android.graphics包中定义了Point, Rect, Path, Region 这几种几何形状,Path可以为有圆弧,椭圆,二次曲线,三次曲线,线段,矩形等基本几何图形或是由这些基本几何图形组合而成,Path可以为开放或是闭合曲线。Rect提供了定义矩形的简洁方法。Region则支持通过区域的“加”,“减”,“并”,“异或”等逻辑运算由多个Region组合而成。Region.Op定义了Region支持的区域间运算种类。
Clipping 介绍有Region运算来为Canvs定义剪裁区域后,同一幅图最后显示的效果。canvas.save();和canvas.restore();用于保存和恢复Canvas的状态属性。
drawScene定义了绘图的内容:一条红线,一个绿圆,和“Clipping”文字。
private void drawScene(Canvas canvas) { canvas.clipRect(0, 0, 100, 100); canvas.drawColor(Color.WHITE); mPaint.setColor(Color.RED); canvas.drawLine(0, 0, 100, 100, mPaint); mPaint.setColor(Color.GREEN); canvas.drawCircle(30, 70, 30, mPaint); mPaint.setColor(Color.BLUE); canvas.drawText("Clipping", 100, 30, mPaint); }
剪裁区域为两个矩形相减:
canvas.save(); canvas.translate(160, 10); canvas.clipRect(10, 10, 90, 90); canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE); drawScene(canvas); canvas.restore();
剪裁区域为一个圆:
canvas.save(); canvas.translate(10, 160); mPath.reset(); canvas.clipPath(mPath); // makes the clip empty mPath.addCircle(50, 50, 50, Path.Direction.CCW); canvas.clipPath(mPath, Region.Op.REPLACE); drawScene(canvas); canvas.restore();
剪裁区域为两个矩形的并集:
canvas.save(); canvas.translate(160, 160); canvas.clipRect(0, 0, 60, 60); canvas.clipRect(40, 40, 100, 100, Region.Op.UNION); drawScene(canvas); canvas.restore();
剪裁区域为两个矩形的异或集:
canvas.save(); canvas.translate(10, 310); canvas.clipRect(0, 0, 60, 60); canvas.clipRect(40, 40, 100, 100, Region.Op.XOR); drawScene(canvas); canvas.restore();
最后一个为两个矩形的逆向差集:
canvas.save(); canvas.translate(160, 310); canvas.clipRect(0, 0, 60, 60); canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE); drawScene(canvas); canvas.restore();
效果图片:
Region.Op 是对几个clip区域起作用的。几个例子都是,先定义一个裁剪区域,然后再定义一个裁剪区域以及Region.Op ,但是在drawScene又创建了一裁剪区域。我的问题是Region.Op 是对前两个前作用吗,还是说对3个都起作用。
Region.Op 是对几个clip区域起作用的。几个例子都是,先定义一个裁剪区域,然后再定义一个裁剪区域以及Region.Op ,但是在drawScene又创建了一裁剪区域。我的问题是Region.Op 是对前两个前作用吗,还是说对3个都起作用。
如果有三次操作分别是a,b,c,最后的结果是(a OP b) OP c。第三次会在前两次OP的结果上进行,你可以自己写一个例子验证一下。
xaml
<ScrollViewer
Width="400"
Height="500"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<Image
Source="/Image/1.jpg"
Width="600"
Height="800"
>
</Image>
</ScrollViewer>
拖拽图片效果
方法一:
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class DragSample01 extends Activity {
ImageView img;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drag_sample01);
img = (ImageView)findViewById(R.id.img_view);
img.setOnTouchListener(new OnTouchListener(){
private int mx, my;
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
mx = (int)(event.getRawX());
my = (int)(event.getRawY() - 50);
v.layout(mx - img.getWidth()/2, my - img.getHeight()/2, mx + img.getWidth()/2, my + img.getHeight()/2);
break;
}
return true;
}});
}
}
方法二:
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class DragSample01 extends Activity {
ImageView img;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drag_sample01);
img = (ImageView)findViewById(R.id.img_view);
img.setOnTouchListener(new OnTouchListener(){
private float x, y;
private int mx, my;
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
case MotionEvent.ACTION_MOVE:
mx = (int)(event.getRawX() - x);
my = (int)(event.getRawY() - 50 - y);
v.layout(mx, my, mx + v.getWidth(), my + v.getHeight());
break;
}
return true;
}});
}
}
//////////------------------
拖拽图片效果
方法一:
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class DragSample01 extends Activity {
ImageView img;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drag_sample01);
img = (ImageView)findViewById(R.id.img_view);
img.setOnTouchListener(new OnTouchListener(){
private int mx, my;
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
mx = (int)(event.getRawX());
my = (int)(event.getRawY() - 50);
v.layout(mx - img.getWidth()/2, my - img.getHeight()/2, mx + img.getWidth()/2, my + img.getHeight()/2);
break;
}
return true;
}});
}
}
方法二:
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class DragSample01 extends Activity {
ImageView img;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drag_sample01);
img = (ImageView)findViewById(R.id.img_view);
img.setOnTouchListener(new OnTouchListener(){
private float x, y;
private int mx, my;
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
case MotionEvent.ACTION_MOVE:
mx = (int)(event.getRawX() - x);
my = (int)(event.getRawY() - 50 - y);
v.layout(mx, my, mx + v.getWidth(), my + v.getHeight());
break;
}
return true;
}});
}
}
拖动按钮到处跑
1. 布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="@+id/btn" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="拖动看看~~" />
</LinearLayout>
2. 代码
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
public class DraftTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button btn = (Button) findViewById(R.id.btn);
btn.setOnTouchListener(new OnTouchListener() {
int[] temp = new int[] { 0, 0 };
public boolean onTouch(View v, MotionEvent event) {
int eventaction = event.getAction();
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN: // touch down so check if the
temp[0] = (int) event.getX();
temp[1] = y - v.getTop();
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
v.layout(x - temp[0], y - temp[1], x + v.getWidth()
- temp[0], y - temp[1] + v.getHeight());
// v.postInvalidate();
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
});
}
}
另一种:
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
public class DraftTest extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics dm = getResources().getDisplayMetrics();
final int screenWidth = dm.widthPixels;
final int screenHeight = dm.heightPixels - 50;
final Button b = (Button) findViewById(R.id.btn);
b.setOnTouchListener(new OnTouchListener() {
int lastX, lastY;
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
int left = v.getLeft() + dx;
int top = v.getTop() + dy;
int right = v.getRight() + dx;
int bottom = v.getBottom() + dy;
if (left < 0) {
left = 0;
right = left + v.getWidth();
}
if (right > screenWidth) {
right = screenWidth;
left = right - v.getWidth();
}
if (top < 0) {
top = 0;
bottom = top + v.getHeight();
}
if (bottom > screenHeight) {
bottom = screenHeight;
top = bottom - v.getHeight();
}
v.layout(left, top, right, bottom);
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
});
}
}