2016-06-22 2 views

Antwort

1

Die Verwendung der Bibliothek scheint nicht möglich zu sein, jedoch besteht eine Lösung darin, eine View oder ViewGroup über dem Diagramm zu zeigen, das einen Button enthält. Sie müssen ein leeres Layout für die MarkerView einrichten und Ihr Diagramm in eine ViewGroup wie beispielsweise RelativeLayout einbinden.

Definieren Sie einen Zuhörer wie dies in Ihrem CustomMarkerView:

public interface Listener { 
    /** 
    * A callback with the x,y position of the marker 
    * @param x the x in pixels 
    * @param y the y in pixels 
    */ 
    void onMarkerViewLayout(int x, int y); 
} 

einige Membervariablen ein:

private Listener mListener; 
private int mLayoutX; 
private int mLayoutY; 
private int mMarkerVisibility; 

In Ihrem Konstruktor einen Zuhörer benötigen:

/** 
    * Constructor. Sets up the MarkerView with a custom layout resource. 
    * @param context a context 
    * @param layoutResource the layout resource to use for the MarkerView 
    * @param listener listens for the bid now click 
    */ 
    public SQUChartMarkerView(Context context, int layoutResource, Listener listener) { 
     super(context, layoutResource); 
     mListener = listener; 
    } 

Store, um die Ort der Marker sollte sein, wenn die Werte eingestellt sind:

@Override public int getXOffset(float xpos) { 
    mLayoutX = (int) (xpos - (getWidth()/2)); 
    return -getWidth()/2; 
} 


@Override public int getYOffset(float ypos) { 
    mLayoutY = (int) (ypos - getWidth()); 
    return -getHeight(); 
} 

Dann OnDraw außer Kraft setzen, um zu bestimmen, wenn Sie Ihr Layout ziehen sollten:

@Override protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    if(mMarkerVisibility == View.VISIBLE) mListener.onMarkerViewLayout(mLayoutX, mLayoutY); 
} 

Ich habe eine Option, um den Zustand der Markierung zu ändern:

public void setMarkerVisibility(int markerVisibility) { 
    mMarkerVisibility = markerVisibility; 
} 

Wo Sie für Marker Wesen hören angelegt, erhalten Sie Ihr Layout (z. B. blasen Sie es auf oder Sie können es als eine Mitgliedsvariable haben), stellen Sie sicher, dass Sie es messen, und stellen Sie dann die Ränder ein. In diesem Fall verwende ich getParent(), da das Diagramm und das Layout für den Marker dasselbe Elternelement verwenden. Ich habe ein BarChart, so dass meine Margen möglicherweise anders sind als bei Ihnen.

@Override public void onMarkerViewLayout(int x, int y) { 
    if(getParent() == null || mChartListener.getAmount() == null) return; 
    // remove the marker 
    ((ViewGroup) getParent()).removeView(mMarkerLayout); 
    ((ViewGroup) getParent()).addView(mMarkerLayout); 

    // measure the layout 
    // if this is not done, the first calculation of the layout parameter margins 
    // will be incorrect as the layout at this point has no height or width 
    int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(((ViewGroup) getParent()).getWidth(), View.MeasureSpec.UNSPECIFIED); 
    int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(((ViewGroup) getParent()).getHeight(), View.MeasureSpec.UNSPECIFIED); 
    mMarkerLayout.measure(widthMeasureSpec, heightMeasureSpec); 

    // set up layout parameters so our marker is in the same position as the mpchart marker would be (based no the x and y) 
    RelativeLayout.LayoutParams lps = (RelativeLayout.LayoutParams) mMarkerLayout.getLayoutParams(); 
    lps.height = FrameLayout.LayoutParams.WRAP_CONTENT; 
    lps.width = FrameLayout.LayoutParams.WRAP_CONTENT; 
    lps.leftMargin = x - mMarkerLayout.getMeasuredWidth()/2; 
    lps.topMargin = y - mMarkerLayout.getMeasuredHeight(); 
} 

Hoffe, das hilft.

+0

Mit der neuesten Bibliothek 3.0.2 sehe ich nicht getXOffset() oder getYOffset() vorhanden. –

+0

Und hier hören Sie, wenn der Marker onDraw() ausführt, nicht wirklich, wenn der Benutzer auf die markerView klickt. Ich denke, es gibt einen Unterschied. –

0

Ich habe meine App mit anklickbarer Marker-Ansicht beendet. Meine Lösung ist, dass wir eine Unterklasse von LineChart (oder einem anderen Diagramm) erstellen, dann onTouchEvent überschreiben und den Touch-Speicherort erkennen.

public class MyChart extends LineChart { 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     boolean handled = true; 
     // if there is no marker view or drawing marker is disabled 
     if (isShowingMarker() && this.getMarker() instanceof ChartInfoMarkerView){ 
      ChartInfoMarkerView markerView = (ChartInfoMarkerView) this.getMarker(); 
      Rect rect = new Rect((int)markerView.drawingPosX,(int)markerView.drawingPosY,(int)markerView.drawingPosX + markerView.getWidth(), (int)markerView.drawingPosY + markerView.getHeight()); 
      if (rect.contains((int) event.getX(),(int) event.getY())) { 
       // touch on marker -> dispatch touch event in to marker 
       markerView.dispatchTouchEvent(event); 
      }else{ 
       handled = super.onTouchEvent(event); 
      } 
     }else{ 
      handled = super.onTouchEvent(event); 
     } 
     return handled; 
    } 

    private boolean isShowingMarker(){ 
     return mMarker != null && isDrawMarkersEnabled() && valuesToHighlight(); 
    } 
} 

public class ChartInfoMarkerView extends MarkerView { 
    @BindView(R.id.markerContainerView) 
    LinearLayout markerContainerView; 

    protected float drawingPosX; 
    protected float drawingPosY; 
    private static final int MAX_CLICK_DURATION = 500; 
    private long startClickTime; 

    /** 
    * The constructor 
    * 
    * @param context 
    * @param layoutResource 
    */ 
    public ChartInfoMarkerView(Context context, int layoutResource) { 
     super(context, layoutResource); 
     ButterKnife.bind(this); 
     markerContainerView.setClickable(true); 
     markerContainerView.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Log.d("MARKER","click"); 
      } 
     }); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: { 
       startClickTime = Calendar.getInstance().getTimeInMillis(); 
       break; 
      } 
      case MotionEvent.ACTION_UP: { 
       long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime; 
       if(clickDuration < MAX_CLICK_DURATION) { 
        markerContainerView.performClick(); 
       } 
      } 
     } 
     return super.onTouchEvent(event); 
    } 

    @Override 
    public void draw(Canvas canvas, float posX, float posY) { 
     super.draw(canvas, posX, posY); 
     MPPointF offset = getOffsetForDrawingAtPoint(posX, posY); 
     this.drawingPosX = posX + offset.x; 
     this.drawingPosY = posY + offset.y; 
    } 
}