2016-04-10 3 views
1

Wenn ich den Ripple-Effekt in API < 21 möchte, verwende ich normalerweise eine Vordergrundansicht - die unten ist eine foregroundtextview, die ich für Textansichten verwende. Wenn es ein Bild gibt es eine foregroundimageview ist und der Code ist auch überall im Internet zum Download bereit:Wie zeichne ich kreisförmige Wellen um ein Symbol in API <21?

/* 
* Copyright 2014 DogmaLabs 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 


import android.annotation.TargetApi; 
import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.Rect; 
import android.graphics.drawable.Drawable; 
import android.graphics.drawable.NinePatchDrawable; 
import android.os.Build; 
import android.support.annotation.NonNull; 
import android.util.AttributeSet; 
import android.widget.TextView; 

import com.bekwaai.activities.R; 

public class ForegroundTextView extends TextView { 

    private Drawable mForegroundSelector; 
    private Rect mRectPadding; 
    private boolean mUseBackgroundPadding = false; 


    public ForegroundTextView (Context context) { 
     super(context); 
    } 


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


    public ForegroundTextView (Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 

     final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundTextViewLayout, defStyle, 0); 

     final Drawable d = a.getDrawable(R.styleable.ForegroundTextViewLayout_android_foreground); 

     if (d != null) { 
      setForeground(d); 
     } 


     a.recycle(); 


     if (this.getBackground() instanceof NinePatchDrawable) { 
      final NinePatchDrawable npd = (NinePatchDrawable) this.getBackground(); 
      mRectPadding = new Rect(); 
      if (npd.getPadding(mRectPadding)) { 
       mUseBackgroundPadding = true; 
      } 
     } 
    } 


    @Override 
    protected void drawableStateChanged() { 
     super.drawableStateChanged(); 


     if (mForegroundSelector != null && mForegroundSelector.isStateful()) { 
      mForegroundSelector.setState(getDrawableState()); 
     } 
    } 


    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 


     if (mForegroundSelector != null) { 
      if (mUseBackgroundPadding) { 
       mForegroundSelector.setBounds(mRectPadding.left, mRectPadding.top, w - mRectPadding.right, h - mRectPadding.bottom); 
      } else { 
       mForegroundSelector.setBounds(0, 0, w, h); 
      } 
     } 
    } 


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


     if (mForegroundSelector != null) { 
      mForegroundSelector.draw(canvas); 
     } 
    } 


    @Override 
    protected boolean verifyDrawable(Drawable who) { 
     return super.verifyDrawable(who) || (who == mForegroundSelector); 
    } 


    @Override 
    public void jumpDrawablesToCurrentState() { 
     super.jumpDrawablesToCurrentState(); 
     if (mForegroundSelector != null) mForegroundSelector.jumpToCurrentState(); 
    } 


    public void setForeground(Drawable drawable) { 
     if (mForegroundSelector != drawable) { 
      if (mForegroundSelector != null) { 
       mForegroundSelector.setCallback(null); 
       unscheduleDrawable(mForegroundSelector); 
      } 


      mForegroundSelector = drawable; 


      if (drawable != null) { 
       setWillNotDraw(false); 
       drawable.setCallback(this); 
       if (drawable.isStateful()) { 
        drawable.setState(getDrawableState()); 
       } 
      } else { 
       setWillNotDraw(true); 
      } 
      requestLayout(); 
      invalidate(); 
     } 
    } 


    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    @Override 
    public void drawableHotspotChanged(float x, float y) { 
     super.drawableHotspotChanged(x, y); 
     if (mForegroundSelector != null) { 
      mForegroundSelector.setHotspot(x, y); 
     } 
    } 
} 

Es funktioniert wie ein Charme, sehen gif unter:

ripples

Jetzt, ich habe ein Symbol in einem cardview:

icon

Sie, dass die b sehen Grenzen der Ikone ist ein Quadrat im Android-Studio visuellen Editor. Wenn ich einen Vordergrund-Bildausschnitt darauf anwende, werden die Wellen bis zu den Grenzen des Quadrats reichen, so dass der endgültige Effekt ein weißer quadratischer Block unter dem Kamerasymbol sein wird.

Ich will das wirklich nicht. Ich würde eine kreisförmige weiße Welligkeit mag schließlich unter der Kamera, ähnlich wie wenn Symbole in der Werkzeugleiste angeklickt wird angezeigt werden:

enter image description here

Gibt es eine Möglichkeit, diese < 21 für API zu tun?

Antwort

1

Ich habe eine Lösung auf der Instama-App gefunden, aber es ist nicht genau das, was ich will, aber es wird tun müssen.

Alles, was sie tat, war sie einen Selektor als Hintergrund eines Image verbunden:

<?xml version="1.0" encoding="utf-8"?> 
<!--drawable/btn_feed_action.xml--> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="200" android:exitFadeDuration="200"> 
    <item android:state_pressed="false"> 
     <shape android:shape="oval"> 
      <solid android:color="@android:color/transparent" /> 
     </shape> 
    </item> 
    <item android:state_pressed="true"> 
     <shape android:shape="oval"> 
      <solid android:color="@color/white45" /> 
     </shape> 
    </item> 
</selector> 

jedes Mal dann das Bild gedrückt wird, wird der 45% transparent weiße Kreis eingeben und als Hintergrund des Bildes gegossen . Sobald dein Finger entfernt ist, verschwindet der Kreis.

Die Lösung ist kein "Ripple" -Effekt, eher ein Ein- und Ausblendeffekt. Kann jemand eine bessere Lösung finden?