2015-07-03 10 views
8

Długo zauważyłem, że android.support.v4.widget.CircleImageView. Za każdym razem, gdy chcę użyć kształtu okrągłego, pojawi się w moim umyśle CircleImageView. Próbowałem go używać wiele razy, ale za każdym razem zawodziłem. Ponieważ zezwolenie dostępu android.support.v4.widget.CircleImageView jest domyślne, co oznacza, że ​​tylko klasy w tym samym pakiecie z CircleImageView, a mianowicie android.support.v4.widget, są w stanie uzyskać do niego dostęp.Dlaczego opcja CircleImageView biblioteki android v4 nie jest publiczna?

Nie mogę zrozumieć, że teraz okrągły ImageView jest w powszechnym użyciu, dlaczego nie ustawisz CircleImageView do publicznej wiadomości tak, że deweloperzy nie muszą przesłaniać ImageView w okrągłym ImageView? Czy nie jest tak, że zespół Google Android zmusza nas do wymyślić koła?

Czy też nie znam tego CircleImageView dobrze?

Wszelkie wskazówki zostaną docenione. Z góry dziękuję.

+0

(nie downvoter), ale odpowiedź brzmi: kto wie? Obejrzyj @ http://stackoverflow.com/questions/28616578/inflate-android-support-v4widget-circleimageview-inflateexception + http://grepcode.com/file/repository.grepcode.com/java/ext/ com.google.android/android/5.0.2_r1/android/support/v4/widget/CircleImageView.java + http://code.google.com/p/android/issues/detail?id=85049. Wydaje się, że nikt nie ma odpowiedzi, ale istnieje wiele bibliotek oprogramowania open source innych firm, które można zaimportować, co daje takie samo zachowanie (i więcej). – kha

+0

@ChrisBanes działa na Androidzie. Ale nie wiem jak to zrobić. – SilentKnight

+0

Wystarczająco uczciwe. Nie wiem, jak @ ludzie, których nie ma w rozmowie Obawiam się :( – kha

Odpowiedz

8

próbowałem na kopiowanie i wklejanie kodów źródłowych z android.support.v4.widget.CircleImageView aby publicznie tak:

package me.danielpan.youtubelike.view; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.RadialGradient; 
import android.graphics.Shader; 
import android.graphics.drawable.ShapeDrawable; 
import android.graphics.drawable.shapes.OvalShape; 
import android.support.v4.view.ViewCompat; 
import android.view.animation.Animation; 
import android.widget.ImageView; 

/** 
* Private class created to work around issues with AnimationListeners being 
* called before the animation is actually complete and support shadows on older 
* platforms. 
* 
* @hide 
*/ 
public class CircleImageView extends ImageView { 

    private static final int KEY_SHADOW_COLOR = 0x1E000000; 
    private static final int FILL_SHADOW_COLOR = 0x3D000000; 
    // PX 
    private static final float X_OFFSET = 0f; 
    private static final float Y_OFFSET = 1.75f; 
    private static final float SHADOW_RADIUS = 3.5f; 
    private static final int SHADOW_ELEVATION = 4; 

    private Animation.AnimationListener mListener; 
    private int mShadowRadius; 

    public CircleImageView(Context context, int color, final float radius) { 
     super(context); 
     final float density = getContext().getResources().getDisplayMetrics().density; 
     final int diameter = (int) (radius * density * 2); 
     final int shadowYOffset = (int) (density * Y_OFFSET); 
     final int shadowXOffset = (int) (density * X_OFFSET); 

     mShadowRadius = (int) (density * SHADOW_RADIUS); 

     ShapeDrawable circle; 
     if (elevationSupported()) { 
      circle = new ShapeDrawable(new OvalShape()); 
      ViewCompat.setElevation(this, SHADOW_ELEVATION * density); 
     } else { 
      OvalShape oval = new OvalShadow(mShadowRadius, diameter); 
      circle = new ShapeDrawable(oval); 
      ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint()); 
      circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset, 
        KEY_SHADOW_COLOR); 
      final int padding = mShadowRadius; 
      // set padding so the inner image sits correctly within the shadow. 
      setPadding(padding, padding, padding, padding); 
     } 
     circle.getPaint().setColor(color); 
     setBackgroundDrawable(circle); 
    } 

    private boolean elevationSupported() { 
     return android.os.Build.VERSION.SDK_INT >= 21; 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     if (!elevationSupported()) { 
      setMeasuredDimension(getMeasuredWidth() + mShadowRadius*2, getMeasuredHeight() 
        + mShadowRadius*2); 
     } 
    } 

    public void setAnimationListener(Animation.AnimationListener listener) { 
     mListener = listener; 
    } 

    @Override 
    public void onAnimationStart() { 
     super.onAnimationStart(); 
     if (mListener != null) { 
      mListener.onAnimationStart(getAnimation()); 
     } 
    } 

    @Override 
    public void onAnimationEnd() { 
     super.onAnimationEnd(); 
     if (mListener != null) { 
      mListener.onAnimationEnd(getAnimation()); 
     } 
    } 

    /** 
    * Update the background color of the circle image view. 
    * 
    * @param colorRes Id of a color resource. 
    */ 
    public void setBackgroundColorRes(int colorRes) { 
     setBackgroundColor(getContext().getResources().getColor(colorRes)); 
    } 

    @Override 
    public void setBackgroundColor(int color) { 
     if (getBackground() instanceof ShapeDrawable) { 
      ((ShapeDrawable) getBackground()).getPaint().setColor(color); 
     } 
    } 

    private class OvalShadow extends OvalShape { 
     private RadialGradient mRadialGradient; 
     private Paint mShadowPaint; 
     private int mCircleDiameter; 

     public OvalShadow(int shadowRadius, int circleDiameter) { 
      super(); 
      mShadowPaint = new Paint(); 
      mShadowRadius = shadowRadius; 
      mCircleDiameter = circleDiameter; 
      mRadialGradient = new RadialGradient(mCircleDiameter/2, mCircleDiameter/2, 
        mShadowRadius, new int[] { 
        FILL_SHADOW_COLOR, Color.TRANSPARENT 
      }, null, Shader.TileMode.CLAMP); 
      mShadowPaint.setShader(mRadialGradient); 
     } 

     @Override 
     public void draw(Canvas canvas, Paint paint) { 
      final int viewWidth = CircleImageView.this.getWidth(); 
      final int viewHeight = CircleImageView.this.getHeight(); 
      canvas.drawCircle(viewWidth/2, viewHeight/2, (mCircleDiameter/2 + mShadowRadius), 
        mShadowPaint); 
      canvas.drawCircle(viewWidth/2, viewHeight/2, (mCircleDiameter/2), paint); 
     } 
    } 
} 

Wygląda dobrze, dobrze? Nie ma dostosowanych atrybutów i wygląda na to, że można go normalnie używać jako standardowego ImageView.

Ale jeśli spróbowałeś tego, dowiesz się, że został zgłoszony NoSuchMethodException. Ten wyjątek oznacza, że ​​konieczne konstruktory nie są zastępowane. Tak, że nie można nawet utworzyć instancji jako normalnego View.

Po przeczytaniu tych kodów źródłowych, zdaję sobie sprawę, że CircleImageView dodaje tylko cień za ImageView, którego wynik nie jest RoundCornerImageView lub RoundImageView. Więc jeśli chcę RoundImageView, muszę zapomnieć o tej klasie i zaimplementować ten efekt przez przesłonięcie ImageView.

W końcu, nie jest komentarz pliku, który zwraca uwagę na wykorzystanie android.support.v4.widget.CircleImageView:

prywatna klasa stworzony, aby obejść problemy z AnimationListeners miano przed animacja jest faktycznie kompletne i wsparcia cienie na starsze platformy.

I mam nadzieję, że nikt nie zapyta ponownie taką głupie pytanie i niech kończy się tutaj,^_ ^, Haha ~

3

Zgodnie z dokumentacją ta klasa jest klasą prywatną używaną do pracy i nie możemy jej utworzyć. Być może ta klasa zostanie usunięta wcześniej, niż podejrzewam.

Istnieją sposoby tworzenia okrągłego tła dla widoku.

file: odkształcalne/contact_badge_round.xml

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> 

    <size android:width="32dp" android:height="32dp"/> 

    <gradient android:centerColor="#123456" <!--Put your custom color for bg --> 
       android:startColor="#123456" 
       android:endColor="#123456" 
     /> 

</shape> 

następnie w układzie utworzyć przycisk i ustawić tło jako contact_badge_round

<ImageView 
     android:id="@+id/roundContact" 
     android:layout_width="32dp" 
     android:layout_height="32dp" 
     android:src="@drawalbe/your_image" 
     android:gravity="center" 
     android:background="@drawable/background_new_entity_symbol" 
     /> 
+0

To jest sposób na wdrożenie efektu cienia – SilentKnight

+0

To nie doda cienia, utworzy widok kołowy! –

+0

To doda cień na API21 +, ale musisz dodać 'android: outlineProvider =" background "'. – WindRider

Powiązane problemy