如何结合的设定点(自定义形状)和触摸事件就可以了Android系统 [英] how to bound set of points (custom shape) and touch event on it android

查看:163
本文介绍了如何结合的设定点(自定义形状)和触摸事件就可以了Android系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够得到我的位点的集合(如数组)使用的这个链接 现在我的问题是我怎么能约束这些点的形状/地区。也就是说当用户谈到了我的界分区域,我想根据该移动的对象(​​形状)。以上彩色位图的链接返回点(它去除透明部分),仅彩色部分点是回报的数组。 这是我的code:

1)CustomSahpe.java

 公共类CustomShape {
私人最终上下文的背景下;

点阵位图;
INT宽度,高度;
INT []像素;
私人最终的ArrayList<点>分=新的ArrayList<点>();
公共CustomShape(上下文的背景下){
    // TODO自动生成构造函数存根
    //超(上下文);
    this.context =背景;
    位= BitmapFactory.de codeResource(context.getResources()
            R.drawable.ic_menu_balloon);
    宽度= bitmap.getWidth();
    身高= bitmap.getHeight();
    像素=新INT [宽*高]。
    bitmap.getPixels(像素,0,宽度,0,0,宽度,高度);
    getActualBitmap();
}

公众的ArrayList<点> getPoints(){
    返回点;
}

公共无效getActualBitmap(){
    为(中间体X = 0 X  - 其中;宽度; X + = 2){
        INT firstY = -1,lastY = -1;
        对于(INT Y = 0; Y<高度; Y + = 2){
            布尔透明=(像素[Y *宽+ X] == Color.TRANSPARENT);
            如果(!透明){
                如果(firstY == -1){
                    firstY = Y;
                }
                lastY = Y;
            }
        }
        如果(firstY!= -1){
            points.add(新的点(x,firstY));
            points.add(新的点(x,lastY));
        }
    }
}
 

}

2)MySha pre.java

  MyShape的类{
    CustomShape customShape;
    点分[];
    私人诠释的x,y;
    路径path =新路径();
    MyShape的公众(上下文的背景下){
        customShape =新CustomShape(ScaleTestActivity.this);
        点=新点[customShape.getPoints()的大小()];
        的for(int i = 0; I< customShape.getPoints()的大小();我++){
            点[i] =新的点();
            点[I] = customShape.getPoints()得到(一)。
        }
    }
    公共路径getPath(){
        返回路径;
    }

    公共无效的OnDraw(帆布油画){
        // TODO自动生成方法存根
        涂料粉刷=新的油漆();
        paint.setColor(Color.WHITE);
        的for(int i = 0; I< points.length;我++){
            点对点=新的点(点[I] .X +的getX(),点[I] .Y + getY()以);
            path.lineTo(分[I] .X,点[I] .Y);
            canvas.drawPoint(point.x,point.y,油漆);
        }
    }
    公共无效setX的(INT X){
        this.x = X;
    }
    公众诠释的getX(){
        返回X;
    }
    公共无效塞蒂(int y)对{
        this.y = Y;
    }
    公众诠释getY()以{
        返回是;
    }
}
 

}

3)MainPanel.java

 类的mainPanel扩展视图{
        上下文语境;
        MyShape的MyShape的;
        布尔标志= FALSE;
        公共mainPanel中(上下文的背景下){
            超(上下文);
            this.context =背景;
            = MyShape的MyShape的新(上下文);
        }

        @覆盖
        保护无效的OnDraw(帆布油画){
            super.onDraw(画布);
            canvas.drawColor(Color.RED);
            myShape.onDraw(画布);
        }

        @覆盖
        公共布尔的onTouchEvent(MotionEvent事件){
            // TODO自动生成方法存根
            INT X,Y;
            X =(int)的event.getX();
            Y =(INT)event.getY();
            点对点=新的点(X,Y);

            开关(event.getAction()){
            案例MotionEvent.ACTION_DOWN:
                myShape.setX(X);
                myShape.setY(Y);
                RectF rectF =新RectF();
                路径path = myShape.getPath();
                path.computeBounds(rectF,真正的);
                地区地区=新区域();

                region.setPath(路径,新的区域((INT)rectF.left,(INT)rectF.top,(INT)rectF.right,(INT)rectF.bottom));

                如果(region.contains(X,Y)){
                    标志=真正的;
                    Log.i(系统了,onDown);
                }
                打破;
            案例MotionEvent.ACTION_MOVE:
                Log.i(系统了,onMove:+标志);
                如果(旗){
                    myShape.setX(X);
                    myShape.setY(Y);
                    Log.i(系统了,onMove);
                }
                打破;
            案例MotionEvent.ACTION_UP:
// myShape.setX(X);
// myShape.setY(Y);
                标志= FALSE;
                Log.i(系统了,onUp);
                打破;
            默认:
                打破;
            }
            无效();
            返回true;
        }
    }
 

4)ScaleTestActivity.java

  @覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(新的mainPanel(本));
}
 

解决方案

我用一个多边形类来检测旋转的位图触摸。它的主要依据是从本网站 http://alienryderflex.com/polygon/ 信息和code。这应该与你的code。

 公共类多边形{

//多边形coodinates。
私人最终诠释[] polyY,polyX;

//在多边形的边数。
私人最终诠释polySides;

/ **
 *默认构造函数。
 *参数像素多边形ÿcoods。
 *参数PY多边形x coods。
 *参数PS多边形的边数。
 * /
公共多边形(最终诠释[] PX,最终诠释[]吡啶,最终诠释PS){
    polyX = PX;
    polyY = PY;
    polySides = PS;
}

/ **
 *如果Polygon包含一个点检查。
 * @seehttp://alienryderflex.com/polygon/
 *参数X坐标点水平的POS机。
 *参数ÿ点垂直POS机。
 * @返回点是保利的标志。
 * /
公共布尔包含(最终浮动X,最终浮动Y){

    布尔oddTransitions = FALSE;
    的for(int i = 0,J = polySides -1; I< polySides; J = ++){
        如果((polyY [1]  - ; Y&安培;&放大器; polyY [J]≥= Y)||(polyY [J] LT; Y&安培;&放大器; polyY [I]> = Y)){
            如果(polyX [I] +(Y  -  polyY [I])/(polyY [J]  -  polyY [I])*(polyX [J]  -  polyX [I])其中,X){
                !oddTransitions = oddTransitions;
            }
        }
    }
    返回oddTransitions;
}


}
 

您可以添加此构造函数来帮助你将一个点阵多边形对象。

 公共多边形(点[]点){
    polySides = points.length;
    polyY =新INT [polySides]
    polyX =新INT [polySides]

    的for(int i = 0; I< polySides;我++){
        polyY [i] =点[I] .Y;
        polyX [i] =点[I] .X;
    }
}
 

您也许可以使用它在你的类MyShape的使用这个方法。

 公共布尔isTouched(最终浮动X,最终浮动Y){
   最后的多边形P =新的多边形(点);
      返回p.contains(X,Y);
}
 

现在,如果你有一个奇怪的形状,你应该能够准确地检测出是否使用接触它。我用这个方法很多次了。

i am able to get my bitmap set of points (as an array) using this link now my question is how can i bound these points as shape/region. Means when user touched on area of my bounded points, i want to move objects(shape) according to that. Above link return points of colored bitmap (it remove transparent part), only colored part points are return as an array. This is what my code :

1) CustomSahpe.java

public class CustomShape {
private final Context context;

Bitmap bitmap;
int width, height;
int[] pixels;
private final ArrayList<Point> points = new ArrayList<Point>();
public CustomShape(Context context) {
    // TODO Auto-generated constructor stub
    // super(context);
    this.context = context;
    bitmap = BitmapFactory.decodeResource(context.getResources(),
            R.drawable.ic_menu_balloon);
    width = bitmap.getWidth();
    height = bitmap.getHeight();
    pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);        
    getActualBitmap();
}

public ArrayList<Point> getPoints(){
    return points;
}

public void getActualBitmap() {
    for (int x = 0; x < width; x+=2) {
        int firstY = -1, lastY = -1;
        for (int y = 0; y < height; y+=2) {
            boolean transparent = (pixels[y * width + x] == Color.TRANSPARENT);
            if (!transparent) {
                if (firstY == -1) {
                    firstY = y;
                }
                lastY = y;
            }
        }
        if (firstY != -1) {
            points.add(new Point(x, firstY));
            points.add(new Point(x, lastY));
        }
    }
}

}

2) MyShapre.java

class MyShape{
    CustomShape customShape ;
    Point points[];
    private int x, y;
    Path path = new Path();
    public MyShape(Context context) {           
        customShape = new CustomShape(ScaleTestActivity.this);
        points = new Point[customShape.getPoints().size()];
        for(int i=0;i<customShape.getPoints().size();i++){
            points[i] = new Point();
            points[i] = customShape.getPoints().get(i); 
        }
    }
    public Path getPath(){
        return path;
    }

    public void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
        for(int i =0 ;i<points.length;i++){             
            Point point = new Point(points[i].x + getX(), points[i].y + getY());
            path.lineTo(points[i].x, points[i].y);
            canvas.drawPoint(point.x,point.y,paint);
        }
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getX() {
        return x;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getY() {
        return y;
    }       
}

}

3) MainPanel.java

    class MainPanel extends View{
        Context context;
        MyShape myShape;
        boolean flag = false;
        public MainPanel(Context context) {         
            super(context);
            this.context = context;
            myShape = new MyShape(context);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.RED);
            myShape.onDraw(canvas);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub          
            int x,y;
            x = (int)event.getX();
            y = (int)event.getY();
            Point point = new Point(x, y);

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                myShape.setX(x);
                myShape.setY(y);
                RectF rectF = new RectF();
                Path path = myShape.getPath();
                path.computeBounds(rectF, true);
                Region region = new Region();

                region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));

                if(region.contains(x,y)){
                    flag = true;
                    Log.i("System out","onDown");
                }
                break;
            case MotionEvent.ACTION_MOVE:               
                Log.i("System out","onMove : "+flag);
                if(flag){
                    myShape.setX(x);
                    myShape.setY(y);
                    Log.i("System out","onMove");
                }
                break;
            case MotionEvent.ACTION_UP:
//              myShape.setX(x);
//              myShape.setY(y);
                flag = false;
                Log.i("System out","onUp");
                break;
            default:
                break;
            }
            invalidate();
            return true;
        }
    }

4) ScaleTestActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);      
    setContentView(new MainPanel(this));
}

解决方案

I use a Polygon class to detect touches on rotated bitmaps. It's based mostly on information and code from this site http://alienryderflex.com/polygon/. This should work with your code.

public class Polygon {

// Polygon coodinates.
private final int[] polyY, polyX;

// Number of sides in the polygon.
private final int polySides;

/**
 * Default constructor.
 * @param px Polygon y coods.
 * @param py Polygon x coods.
 * @param ps Polygon sides count.
 */
public Polygon( final int[] px, final int[] py, final int ps ) {
    polyX = px;
    polyY = py;
    polySides = ps;
}

/**
 * Checks if the Polygon contains a point.
 * @see "http://alienryderflex.com/polygon/"
 * @param x Point horizontal pos.
 * @param y Point vertical pos.
 * @return Point is in Poly flag.
 */
public boolean contains( final float x, final float y ) {

    boolean oddTransitions = false;
    for( int i = 0, j = polySides -1; i < polySides; j = i++ ) {
        if( ( polyY[ i ] < y && polyY[ j ] >= y ) || ( polyY[ j ] < y && polyY[ i ] >= y ) ) {
            if( polyX[ i ] + ( y - polyY[ i ] ) / ( polyY[ j ] - polyY[ i ] ) * ( polyX[ j ] - polyX[ i ] ) < x ) {
                oddTransitions = !oddTransitions;          
            }
        }
    }
    return oddTransitions;
}


}

You could add this constructor to help you convert a Point array to a Polygon object.

public Polygon(Point[] points){
    polySides = points.length;
    polyY = new int[polySides];
    polyX = new int[polySides];

    for(int i = 0; i < polySides; i++){
        polyY[i] = points[i].y;
        polyX[i] = points[i].x;
    }
}

You might be able to use it in your MyShape class with this method.

 public boolean isTouched(final float X, final float Y){
   final Polygon p = new Polygon(points);
      return p.contains(X, Y);
}

Now if you have an odd shape you should be able to detect exactly if the use touches it. I have used this method many times.

这篇关于如何结合的设定点(自定义形状)和触摸事件就可以了Android系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆