无法点击自定义视图并识别它

时间:2016-12-15 00:58:13

标签: android onclicklistener ontouchevent custom-view

我制作了一个自定义视图,表示具有其他属性的drawable。

我在FrameLayout内容中添加了更多自定义视图到activity xml。

所以,我在屏幕上有很多自定义视图。这些自定义视图使用包含在db中的数据进行定位,因此是以dinamically方式创建的。

我的目标是点击屏幕上显示的其中一个自定义视图,识别点击的自定义视图并修改drawable。

实际上onClick仅在自定义视图之一上工作,并且点击在所有屏幕中执行,而不仅仅是在自定义视图上。

我测试了更多方法,但这些都没有用。

我的自定义视图:

public class NodeView extends View {

private static final String TAG_LOG = NodeView.class.getName();

private String _nodeId;
private int _x;
private int _y;
private float _weight;
private int _type;
private Drawable _nodeDrawable;

private int _usingMode;

private boolean touched;
private boolean mDownTouch;

private OnClickListener _onClickListener;

public void set_onClickListener(OnClickListener _onClickListener) {
    this._onClickListener = _onClickListener;
}

public String get_nodeId() {
    return _nodeId;
}

public void set_nodeId(String _nodeId) {
    this._nodeId = _nodeId;
    invalidate();
    requestLayout();
}

public int get_x() {
    return _x;
}

public void set_x(int _x) {
    this._x = _x;
    invalidate();
    requestLayout();
}

public int get_y() {
    return _y;
}

public void set_y(int _y) {
    this._y = _y;
    invalidate();
    requestLayout();
}

public float get_weight() {
    return _weight;
}

public void set_weight(float _weight) {
    this._weight = _weight;
    invalidate();
    requestLayout();
}

public int get_type() {
    return _type;
}

public void set_type(int _type) {
    this._type = _type;
    invalidate();
    requestLayout();
}

public Drawable get_nodeDrawable() {
    return _nodeDrawable;
}

public void set_nodeDrawable(Drawable _nodeDrawable) {
    this._nodeDrawable = _nodeDrawable;
    invalidate();
    requestLayout();
}

public int get_usingMode() {
    return _usingMode;
}

public void set_usingMode(int _usingMode) {
    this._usingMode = _usingMode;
}

public NodeView(Context context, Node node, int usingMode) {
    super(context);
    init(node, usingMode);
}

private void init(Node node, int usingMode) {
    _nodeId = node.getNodeId();
    Log.d(TAG_LOG, node.toString());
    _x = node.getPosition()[0];
    _y = node.getPosition()[1];
    _weight = node.getWidth();
    _type = node.getType();
    set_usingMode(usingMode);

    // Set the _nodeDrawable depending on node type and using mode
    switch (get_usingMode()) {
        case 0:
            switch (_type) {
                case 0:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_node_unselected);
                    _nodeDrawable.setBounds(0, 0, 80, 80);
                    break;
                case 1:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_lift_unselected);
                    _nodeDrawable.setBounds(0, 0, 140, 140);
                    break;
                case 2:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_wc_unselected);
                    _nodeDrawable.setBounds(0, 0, 115, 115);
                    break;
                case 3:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_exit_unselected);
                    _nodeDrawable.setBounds(0, 0, 125, 125);
                    break;
            }
            break;
        case 1:
            switch (_type) {
                case 0:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_node_unselected_nav);
                    _nodeDrawable.setBounds(0, 0, 80, 80);
                    break;
                case 1:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_lift_unselected_nav);
                    _nodeDrawable.setBounds(0, 0, 140, 140);
                    break;
                case 2:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_wc_unselected_nav);
                    _nodeDrawable.setBounds(0, 0, 115, 115);
                    break;
                case 3:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_exit_unselected_nav);
                    _nodeDrawable.setBounds(0, 0, 125, 125);
                    break;
            }
            break;
        case 2:
            switch (_type) {
                case 0:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_node_unselected_em);
                    _nodeDrawable.setBounds(0, 0, 80, 80);
                    break;
                case 1:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_lift_unselected_em);
                    _nodeDrawable.setBounds(0, 0, 140, 140);
                    break;
                case 2:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_wc_unselected_em);
                    _nodeDrawable.setBounds(0, 0, 115, 115);
                    break;
                case 3:
                    _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_exit_unselected_em);
                    _nodeDrawable.setBounds(0, 0, 125, 125);
                    break;
            }
            break;
    }

    touched = false;

    Log.d(TAG_LOG, "Type: " + _type + ", Using Mode: " + String.valueOf(_usingMode));
    invalidate();
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    Log.d(TAG_LOG, "Canvas in");

    switch (_type) {
        case 0:
            canvas.translate((float) _x - 2, (float) _y + 10);
            break;
        case 1:
            canvas.translate((float) _x - 29, (float) _y - 18);
            break;
        case 2:
            canvas.translate((float) _x - 18, (float) _y - 18);
            break;
        case 3:
            canvas.translate((float) _x - 18, (float) _y - 40);
            break;
    }


    Log.d(TAG_LOG, " x short: " + _x + " y short: " + _y);
    Log.d(TAG_LOG, " x float: " + (float) _x + " y float: " + (float) _y);
    if (touched) {
        _nodeDrawable = getResources().getDrawable(R.drawable.ic_node_selected);
        _nodeDrawable.setBounds(0, 0, 140, 140);
        _nodeDrawable.draw(canvas);
    } else {
        // Set the _nodeDrawable depending on node type and using mode
        switch (get_usingMode()) {
            case 0:
                switch (_type) {
                    case 0:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_node_unselected);
                        _nodeDrawable.setBounds(0, 0, 80, 80);
                        break;
                    case 1:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_lift_unselected);
                        _nodeDrawable.setBounds(0, 0, 140, 140);
                        break;
                    case 2:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_wc_unselected);
                        _nodeDrawable.setBounds(0, 0, 115, 115);
                        break;
                    case 3:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_exit_unselected);
                        _nodeDrawable.setBounds(0, 0, 125, 125);
                        break;
                }
                break;
            case 1:
                switch (_type) {
                    case 0:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_node_unselected_nav);
                        _nodeDrawable.setBounds(0, 0, 80, 80);
                        break;
                    case 1:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_lift_unselected_nav);
                        _nodeDrawable.setBounds(0, 0, 140, 140);
                        break;
                    case 2:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_wc_unselected_nav);
                        _nodeDrawable.setBounds(0, 0, 115, 115);
                        break;
                    case 3:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_exit_unselected_nav);
                        _nodeDrawable.setBounds(0, 0, 125, 125);
                        break;
                }
                break;
            case 2:
                switch (_type) {
                    case 0:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_node_unselected_em);
                        _nodeDrawable.setBounds(0, 0, 80, 80);
                        break;
                    case 1:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_lift_unselected_em);
                        _nodeDrawable.setBounds(0, 0, 140, 140);
                        break;
                    case 2:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_wc_unselected_em);
                        _nodeDrawable.setBounds(0, 0, 115, 115);
                        break;
                    case 3:
                        _nodeDrawable = getResources().getDrawable(it.univpm.idstid.ui.R.drawable.ic_exit_unselected_em);
                        _nodeDrawable.setBounds(0, 0, 125, 125);
                        break;
                }
                break;
        }
        _nodeDrawable.draw(canvas);

    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:

            touched = !touched;
            invalidate();

            mDownTouch = true;
            //Toast.makeText(getContext(), String.valueOf(event.getX()) + " " + String.valueOf(event.getY()), Toast.LENGTH_SHORT).show();
            return true;

        case MotionEvent.ACTION_UP:
            if (mDownTouch) {
                mDownTouch = false;
                //performClick(); // Call this method to handle the response, and
                // thereby enable accessibility services to
                // perform this action for a user who cannot
                // click the touchscreen.
                return true;
            }
    }
    performClick();
    return false; // Return false for other touch events
}

@Override
public boolean performClick() {
    Toast.makeText(getContext(), get_nodeId(), Toast.LENGTH_SHORT).show();
    return true;
}

我的活动:

    public class MapActivity extends AppCompatActivity {

    private static final String TAG_LOG = it.univpm.idstid.iot4en.MapActivity.class.getName();

    ImageView mapImage;
    public static MenuItem forward;
    public static MenuItem firstPage;

    private String nodeSelected;

    private int _usingMode = 0;

    // _usingMode = 0 indica un utilizzo dell'applicazione non ancora definito, cioè non si sa ancora se verrà utilizzata
    // in modalità navigazione o emergenza

    int initFloorExtra;

    Graph graphFloor;

    private NodeView[] nodeViews;

    ViewGroup nodesContainer;

    public Graph getGraphFloor() {
        return graphFloor;
    }

    public int get_usingMode() {
        return _usingMode;
    }

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


        ActionBar ab = getSupportActionBar();
        ab.setDisplayHomeAsUpEnabled(true);

        Intent inputIntent = getIntent();
        initFloorExtra = inputIntent.getIntExtra("initFloor", 0);
        String floorString = Integer.toString(initFloorExtra);

        mapImage = (ImageView) findViewById(R.id.mapFloor);

        nodesContainer = (ViewGroup) findViewById(R.id.nodesContenitore);

        graphFloor = Graph.Builder.create(this, floorString)
                .build();

        nodeViews = new NodeView[graphFloor.getNodes().size()];
        int i = 0;

        for (Node n : graphFloor.getNodes()) {
            nodeViews[i] = new NodeView(this, n, get_usingMode());
            nodeViews[i].setId(i);
            nodeViews[i].setTag(n.getNodeId());
            FrameLayout.LayoutParams nodeLp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
            nodeViews[i].setLayoutParams(nodeLp);
            Log.d(TAG_LOG, nodeLp.toString());
            nodesContainer.addView(nodeViews[i]);

            i++;
        }

        if (initFloorExtra != 0) {
            getSupportActionBar().setTitle(getResources().getString(R.string.floor_pos) + " " + floorString);
        }
        switch (initFloorExtra) {
            case 145:
                mapImage.setImageResource(R.drawable.q145);
                break;
            case 150:
                mapImage.setImageResource(R.drawable.q150);
                break;
            case 155:
                mapImage.setImageResource(R.drawable.q155);
                break;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_home, menu);
        firstPage = menu.findItem(R.id.firstPage);
        forward = menu.findItem(R.id.forward);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        switch (itemId) {
            case R.id.firstPage:
                Intent intent = new Intent(this, InitPositionActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                MapActivity.this.finish();
                break;
            case R.id.forward:
                Intent nextPage = new Intent(this, ModActivity.class);
                nextPage.putExtra("initPos", nodeSelected); //TODO: invece degli intent scrivere su db
                nextPage.putExtra("initFloor", initFloorExtra);
                startActivity(nextPage);
                break;
            case android.R.id.home: // Id relativo alla freccia in alto a sinistra, per tornare alla schermata precedente
                NavUtils.navigateUpFromSameTask(this);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

活动xml:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mapactivity"
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:background="@drawable/background_sfumato"
tools:context="it.univpm.idstid.iot4en.MapActivity">

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/mapFloor"
    android:layout_gravity="center_horizontal"/>

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/nodesContenitore">
</FrameLayout>

1 个答案:

答案 0 :(得分:0)

NodeView是一个视图,因此它有View.OnClickListener。您可以为每个View.OnClickListener实施NodeView,例如

...
for (Node n : graphFloor.getNodes()) {
    nodeViews[i] = new NodeView(this, n, get_usingMode());
    ...
    nodeViews[i].setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            // Perform nodeview on click   
            // as your requirement, modify the drawable here          
        }
    });
    ...
}