android 触摸人体图像检测 body 部分。我应该使用什么布局元素?

android on touch human image detect the body part. What layout element should I use?

在下图中,我想检测人体的哪一部分 body 发生了触摸事件。我的想法是拥有一个 GridView 并确定人类 body 发生触摸事件的位置。不过,GridView 似乎有点矫枉过正。使用不同的布局会是更好的方法吗?

 gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                BodyImage item = (BodyImage) parent.getItemAtPosition(position);
                switch (position) {
                    case 0:

                        // code for head

                        break;
                    case 1:
                        // code for nose 
                    case 2:
                        // code for n-human part

这是给观众一个想法的图片 enter image description here

创建自定义ImageView并覆盖onTouch事件,可以检测用户触摸的位置。

@Override
public boolean onTouchEvent(MotionEvent event) {
    event.getX();// X pos of touch 
    event.getY();// Y pos of touch
    return super.onTouchEvent(event);
}

我们公司在我们的 Android 诊断决策支持应用程序中正是这样做的。

我们从人形(称为矮人)的图像开始。我们的平面设计师还为每个突出显示的 body 部分创建了透明叠加层(以显示选择),并为每个可以通过触摸激活的区域绘制了复杂的多边形。换句话说,每个可触摸区域都由一组 (x,y) 坐标表示,大致勾勒出 body 部分。

对于布局,主容器是一个 FrameLayout,其中包含一个带有矮人图像的 ImageView,每个带有 visibility="gone" 的高亮图像覆盖 ImageViews。使用 OnTouchListener 而不是 OnClickListener 以便我们可以从 MotionEvent 参数中获取 (x,y) 坐标。

OnTouchListener中,我们遍历所有多边形并命中测试以查看多边形是否包含该点。如果是这样,那么我们有我们的部分。

我们有一个自定义 Polygon class 主要是做命中测试。实施了一个 contains(int x, int y) 方法来进行命中测试,并使用了基于此算法的代码:http://alienryderflex.com/polygon/

为了绘制高光,我们有一个 PolygonDrawable class 使用坐标创建一个 Path,从可以渲染到的路径创建一个 PathShape UI.

首先感谢 Kris Larson 的上述回答。这个想法是叠加这里看到的两个图像 Images to be superposed in the Fragment and hide the image that has the color. The image on the right was colored used the open source Gimp GIMP

然后在 FrameLayout 上我动态添加了两个图像:

/**
 * A Fragment that launches Draw
 */
public static class DrawSectionFragment extends Fragment {

    public static final String ARG_SECTION_NUMBER = "section_number";
    boolean touching = false;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ........

        View rootView = inflater.inflate(R.layout.image_superposed, container, false);
      //  View rootView = inflater.inflate(R.layout.image_superposed, container);
        final ImageView iv1 = (ImageView) rootView.findViewById(R.id.imgSecond);
        iv1.setImageDrawable(getResources().getDrawable(R.drawable.twocolor1));
        final Bitmap bitmap = ((BitmapDrawable)iv1.getDrawable()).getBitmap();

        iv1.setOnTouchListener(new View.OnTouchListener(){
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                CxMediaPlayer mxMediaPlayer;
                mxMediaPlayer = new CxMediaPlayer(getActivity().getBaseContext());
                switch (event.getAction()) {

                    case MotionEvent.ACTION_DOWN:
                        // TODO Auto-generated method stub
                        touching = true;
                        Matrix inverse = new Matrix();
                        iv1.getImageMatrix().invert(inverse);
                        float[] touchPoint = new float[]{event.getX(), event.getY()};
                        inverse.mapPoints(touchPoint);
                        int xCoord = Integer.valueOf((int) touchPoint[0]);
                        int yCoord = Integer.valueOf((int) touchPoint[1]);

                        int pixel = bitmap.getPixel(xCoord, yCoord);

                        int redValue = Color.red(pixel);
                        int blueValue = Color.blue(pixel);
                        int greenValue = Color.green(pixel);

                        if (pixel == Color.CYAN) {
                            //mxMediaPlayer = new CxMediaPlayer(getActivity().getBaseContext());
                            mxMediaPlayer.playShortResource(getActivity().getBaseContext(), 1) ;
                        }
                        if (pixel == Color.YELLOW) {

                            mxMediaPlayer.playShortResource(getActivity().getBaseContext(), 2) ;
                        }
                        if (pixel == Color.rgb(0,0,255)) {
                            CxMediaPlayer mxMediaPlayer1 = new CxMediaPlayer(getActivity().getBaseContext());
                            mxMediaPlayer1.playShortResource(getActivity().getBaseContext(), 2) ;
                        }

                        break;
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        touching = false;
                        //invalidate();
                        break;

                }
               // mxMediaPlayer.Release();
                return true;
            }
        });;


        return rootView;
    }