2016-06-07 2 views
1

enter image description hereWie kann ich die Symbole auf dem runden Bild Android platzieren?

Ich will nur genau erreichen, was auf die oben image.Red ist meine Symbole sind, wo ich brauche, dass der Kreisbild auf der Oberseite zu platzieren borders.Each und alle rote Symbole ihre eigene function.Say haben seine Art von Bewertungsbuttons. Hier brauche ich Hilfe, die wie man einen XML-Entwurf macht, um dies zu erreichen. Ich habe keine Idee, wie man das tut. So kann ich Code mit dieser Frage nicht hinzufügen. Brauche Hilfe im Voraus.

+0

Sie haben relative Layout verwenden und Sie können versuchen, Constraint-Layout aswell –

+0

@AsifSb Werfen Sie einen Blick auf meine Lösung –

Antwort

1

Werfen Sie einen Blick auf diese Klasse. Es sollte funktioniert, wie Sie wollen:

public class CircleLayout extends ViewGroup { 

    private static final float DEFAULT_FROM_DEGREES = -90f; 

    private static final float DEFAULT_TO_DEGREES = 270f; 

    private static final int MIN_RADIUS_DP = 100; 

    private static final float DEFAULT_CHILD_PADDING_DP = 5f; 

    private final Rect tempChildFrame = new Rect(); 

    private final float fromDegrees; 

    private final float toDegrees; 

    private final int childPadding; 

    private final int minRadius; 

    private int radius; 


    private int childSize; 

    private boolean expanded; 

    public CircleLayout(Context context) { 
     this(context, null); 
    } 

    public CircleLayout(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public CircleLayout(Context context, AttributeSet attrs, int def) { 
     super(context, attrs); 
     final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CircleLayout, 0, 0); 
     try { 
      childSize = Math.max(a.getDimensionPixelSize(R.styleable.CircleLayout_childSize, 0), 0); 
      fromDegrees = a.getFloat(R.styleable.CircleLayout_fromDegrees, DEFAULT_FROM_DEGREES); 
      toDegrees = a.getFloat(R.styleable.CircleLayout_toDegrees, DEFAULT_TO_DEGREES); 
      final float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_CHILD_PADDING_DP, getResources().getDisplayMetrics()); 
      childPadding = (int) a.getDimension(R.styleable.CircleLayout_childPadding, px); 
      expanded = a.getBoolean(R.styleable.CircleLayout_expandedChild, true); 
      minRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, MIN_RADIUS_DP, getResources().getDisplayMetrics()); 
     } finally { 
      a.recycle(); 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     radius = computeRadius(Math.abs(toDegrees - fromDegrees), getChildCount(), childSize, childPadding, minRadius); 
     final int size = radius * 2 + childSize + childPadding; 

     setMeasuredDimension(size + getPaddingLeft() + getPaddingRight(), size + getPaddingTop() + getPaddingBottom()); 

     final int count = getChildCount(); 
     for (int i = 0; i < count; i++) { 
      getChildAt(i).measure(MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY)); 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     final int centerX = getWidth()/2; 
     final int centerY = getHeight()/2; 
     final int radius = expanded ? this.radius : 0; 

     final int childCount = getChildCount(); 
     final float perDegrees = (toDegrees - fromDegrees)/childCount; 

     float degrees = fromDegrees; 
     for (int i = 0; i < childCount; i++) { 
      computeChildFrame(centerX, centerY, radius, degrees, childSize, tempChildFrame); 
      degrees += perDegrees; 
      getChildAt(i).layout(tempChildFrame.left, tempChildFrame.top, tempChildFrame.right, tempChildFrame.bottom); 
     } 
    } 

    private int computeRadius(float arcDegrees, int childCount, int childSize, int childPadding, int minRadius) { 
     if (childCount < 2) { 
      return minRadius; 
     } 

     final float perDegrees = arcDegrees/childCount; 
     final float perHalfDegrees = perDegrees/2; 
     final int perSize = childSize + childPadding; 

     final int radius = (int) ((perSize/2)/Math.sin(Math.toRadians(perHalfDegrees))); 

     return Math.max(radius, minRadius); 
    } 

    private void computeChildFrame(int centerX, int centerY, int radius, float degrees, int size, Rect result) { 
     final double childCenterX = centerX + radius * Math.cos(Math.toRadians(degrees)); 
     final double childCenterY = centerY + radius * Math.sin(Math.toRadians(degrees)); 
     final float halfSize = size * .5f; 
     result.left = (int) (childCenterX - halfSize); 
     result.top = (int) (childCenterY - halfSize); 
     result.right = (int) (childCenterX + halfSize); 
     result.bottom = (int) (childCenterY + halfSize); 
    } 

    public void expand() { 
     expanded = true; 
     requestLayout(); 
    } 

    public void shrink() { 
     expanded = false; 
     requestLayout(); 
    } 

    public void setChildSize(int size) { 
     if (childSize == size || size < 0) { 
      return; 
     } 
     childSize = size; 
     requestLayout(); 
    } 

    public boolean isExpanded() { 
     return expanded; 
    } 

    @Override 
    protected Parcelable onSaveInstanceState() { 
     final Parcelable superState = super.onSaveInstanceState(); 
     final SavedState result = new SavedState(superState); 
     result.childSize = childSize; 
     result.expanded = expanded; 
     return result; 
    } 

    @Override 
    protected void onRestoreInstanceState(Parcelable state) { 
     if (!(state instanceof SavedState)) { 
      super.onRestoreInstanceState(state); 
      return; 
     } 

     final SavedState ss = (SavedState) state; 
     childSize = ss.childSize; 
     expanded = ss.expanded; 
     super.onRestoreInstanceState(ss.getSuperState()); 
    } 

    public static class SavedState extends BaseSavedState { 

     @SuppressWarnings("hiding") 
     public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { 
      public SavedState createFromParcel(Parcel in) { 
       return new SavedState(in); 
      } 

      public SavedState[] newArray(int size) { 
       return new SavedState[size]; 
      } 
     }; 

     private int childSize; 

     private boolean expanded; 

     SavedState(Parcelable superState) { 
      super(superState); 
     } 

     @Override 
     public void writeToParcel(Parcel out, int flags) { 
      super.writeToParcel(out, flags); 
      out.writeInt(childSize); 
      out.writeInt(expanded ? 1 : 0); 
     } 

     private SavedState(Parcel in) { 
      super(in); 
      childSize = in.readInt(); 
      expanded = in.readInt() != 0; 
     } 
    } 
} 

Sie haben auch Stil für diese Ansicht hinzufügen:

<declare-styleable name="CircleLayout"> 
    <attr name="childSize" format="dimension"/> 
    <attr name="childPadding" format="dimension"/> 
    <attr name="fromDegrees" format="integer"/> 
    <attr name="toDegrees" format="integer"/> 
    <attr name="expandedChild" format="boolean"/> 
</declare-styleable> 

Beispiel für die Verwendung:

 <your.package.CircleLayout 
       android:clipChildren="false" 
       android:id="@+id/test_circle_view" 
       android:layout_width="match_parent" 
       app:childSize="50dp" 
       app:childPadding="25dp" 
       app:expandedChild="true" 
       android:layout_height="match_parent"> 
      <ImageView 
        android:id="@+id/circle_item_1" 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:background="@drawable/some_circle"/> 
      <ImageView 
        android:id="@+id/circle_item_2" 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:background="@drawable/some_circle"/> 
      <ImageView 
        android:id="@+id/circle_item_3" 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:background="@drawable/some_circle"/> 
      <ImageView 
        android:id="@+id/circle_item_4" 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:background="@drawable/some_circle"/> 
      <ImageView 
        android:id="@+id/circle_item_5" 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:background="@drawable/some_circle"/> 
      <ImageView 
        android:id="@+id/circle_item_6" 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:background="@drawable/some_circle"/> 

     </your.package.CircleLayout> 
+0

Anstelle von Kreislayout werde ich normale Bildansicht verwenden, aber das src Bild wird im Kreis mit padding.Hope du bekommst was ich versuche g, um hier zu sagen –

+0

aber wie willst du Funktion für deine Ikonen ohne Ansicht implementieren? Ist meine Lösung hilfreich für Sie? –

Verwandte Themen