34 votes

Comment puis-je changer la couleur OverScroll dans Android 2.3.1?

Depuis Android 2.3.1, il existe une nouvelle fonctionnalité pour OverScroll, appelée ScrollViews and Lists. Avec

 android:overScrollMode="never"
 

Je peux l'éteindre, mais si je ne veux pas l'éteindre, comment puis-je en changer la couleur?

21voto

Graeme Points 9167

Autant que je sache, il n'existe aucun moyen pour ce faire. J'ai donc créé un, de présenter:

Graeme est Incroyable Liste Personnalisée de la Vue v2

J'ai créé une vue personnalisée qui effectue overscroll pour les ListViews et pour GridViews (XML de l'exemple est un peu plus impliqué GridView mais vue fonctionne pour les deux):

<CustomGlowListView     android:id="@+id/searches"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:background="@android:color/black"
                        android:layout_margin="10dp"
                        android:tag="GridView"
                        android:numColumns="3"  
                        android:horizontalSpacing="8dp" 
                        android:verticalSpacing="8dp">
</CustomGlowListView>   

Le CustomGlowListView ressemble à ceci:

public class CustomGlowListView extends RelativeLayout{

private ImageView underscrollEdge; 
private ImageView underscrollGlow; 
private ImageView overscrollGlow;
private ImageView overscrollEdge;
private AbsListView listView;

private final   static float    MAX_EDGE_SIZE   = 11f;
private final   static float    MAX_GLOW_SIZE   = 93f;  
private         float   scrollDistanceSinceBoundary     = 0;

private Rect paddingRectangle = new Rect();

GestureDetector listViewGestureDetector;    

// Gives the option of short circuiting the overscroll glow fade (Such as by scrolling away from the overscrolled edge)
boolean interruptFade = false;

public CustomGlowListView(Context context, AttributeSet attrs) 
{ 
    super(context, attrs);

    listViewGestureDetector = new GestureDetector(new ListViewGestureDetector());

    if( getTag() == null ||
        getTag().toString().equalsIgnoreCase("ListView"))       {   listView = new ListView(context);   }
    else if(getTag().toString().equalsIgnoreCase("GridView"))   
    {   
        listView = new GridView(context, attrs);
        ((GridView)listView).getSelector().getPadding(paddingRectangle);
    }
    listView.setId(android.R.id.list);
    listView.setOverScrollMode(OVER_SCROLL_NEVER);
    addView(listView, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));


    underscrollEdge = new ImageView(context);
    underscrollEdge.setImageResource(R.drawable.underscroll_edge);
    underscrollEdge.setScaleType(ScaleType.FIT_XY);
    underscrollGlow = new ImageView(context);
    underscrollGlow.setImageResource(R.drawable.underscroll_glow);
    underscrollGlow.setScaleType(ScaleType.FIT_XY);
    overscrollGlow = new ImageView(context);
    overscrollGlow.setImageResource(R.drawable.overscroll_glow);
    overscrollGlow.setScaleType(ScaleType.FIT_XY);
    overscrollEdge = new ImageView(context);
    overscrollEdge.setImageResource(R.drawable.overscroll_edge);
    overscrollEdge.setScaleType(ScaleType.FIT_XY);

    addView(underscrollGlow, getWideLayout(ALIGN_PARENT_TOP));      
    addView(underscrollEdge, getWideLayout(ALIGN_PARENT_TOP));  

    addView(overscrollGlow, getWideLayout(ALIGN_PARENT_BOTTOM));        
    addView(overscrollEdge, getWideLayout(ALIGN_PARENT_BOTTOM));    
}   

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if(ev.getAction() == MotionEvent.ACTION_DOWN) interruptFade = true;
    listViewGestureDetector.onTouchEvent(ev);

    if(ev.getAction() == MotionEvent.ACTION_UP) reset();
    return super.dispatchTouchEvent(ev);
}

private RelativeLayout.LayoutParams getWideLayout(int alignment)
{
    RelativeLayout.LayoutParams returnLayout = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0);
    returnLayout.addRule(alignment);
    return returnLayout;
}

public void reset()
{
    interruptFade = false;
    new GlowShrinker().execute(scrollDistanceSinceBoundary);    
    scrollDistanceSinceBoundary = 0;
}   

private class ListViewGestureDetector extends SimpleOnGestureListener
{       
    @Override
    public boolean onScroll(MotionEvent downMotionEvent, MotionEvent currentMotionEvent, float distanceX, float distanceY) 
    {
        float distanceTraveled = downMotionEvent.getY() - currentMotionEvent.getY();
        if(listIsAtTop() && distanceTraveled < 0) // At top and finger moving down
        {
            scrollDistanceSinceBoundary -= distanceY;
            scaleEdges(underscrollEdge, underscrollGlow, scrollDistanceSinceBoundary);
        }
        else if(listIsAtTop() && distanceTraveled > 0 && scrollDistanceSinceBoundary > 0) // At top and finger moving up while in overscroll
        {
            scrollDistanceSinceBoundary -= distanceY;
            scaleEdges(underscrollEdge, underscrollGlow, scrollDistanceSinceBoundary);
        }           
        else if(listIsAtBottom() && distanceTraveled > 0) // At bottom and finger moving up
        {
            scrollDistanceSinceBoundary += distanceY;
            scaleEdges(overscrollEdge, overscrollGlow, scrollDistanceSinceBoundary);
        }
        else if(listIsAtBottom() && distanceTraveled < 0 && scrollDistanceSinceBoundary > 0) // At bottom and finger moving up while in overscroll
        {
            scrollDistanceSinceBoundary += distanceY;
            scaleEdges(overscrollEdge, overscrollGlow, scrollDistanceSinceBoundary);
        }           
        else if(scrollDistanceSinceBoundary != 0) // Neither over scrolling or under scrolling but was at last check. Reset both graphics. 
        {
            reset();
        }           

        Log.v(CustomGlowListView.class.getSimpleName(), "boundaryDistance = " + scrollDistanceSinceBoundary);

        return false;
    }

    private boolean listIsAtTop()   {   return listView.getChildAt(0).getTop() - paddingRectangle.top == 0;     }
    private boolean listIsAtBottom(){ return listView.getChildAt(listView.getChildCount()-1).getBottom() + paddingRectangle.bottom == listView.getHeight(); } 
}

private class GlowShrinker extends AsyncTask<Float, Integer, Void>
{
    ImageView glow;
    ImageView edge;

    private final int SHRINK_SPEED = 4;
    private final int SHRINK_INCREMENT = 50;

    @Override
    protected void onPreExecute() {         
        if(underscrollGlow.getHeight() > 0)
        {
            glow = underscrollGlow;
            edge = underscrollEdge;
        }
        else if (overscrollGlow.getHeight() > 0)
        {
            glow = overscrollGlow;
            edge = overscrollEdge;
        }
        else
        {
            return;
        }
    }

    @Override
    protected Void doInBackground(Float... scrollDistanceSinceBoundary) {
        if(glow != null && edge != null)
        {
            int currentSize = (int) scrollDistanceSinceBoundary[0].floatValue();
            int shrinkRate  = (int) currentSize / SHRINK_INCREMENT;

            for(int i=0; i < SHRINK_INCREMENT; i++)
            {
                if(interruptFade) 
                {                       
                    publishProgress(0);
                    return null;
                }
                currentSize -= shrinkRate;
                publishProgress(currentSize);

                try {       Thread.sleep(SHRINK_SPEED);     } catch (InterruptedException e) {  }
            }               
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        if(glow != null && edge != null)
            CustomGlowListView.scaleEdges(edge, glow, 0);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        CustomGlowListView.scaleEdges(edge, glow, values[0]);
    }   
}

private static void scaleEdges(ImageView scrollEdge, ImageView scrollGlow, float scrollBy)
{
    float edgeSize = scrollBy / 20;
    float glowSize = scrollBy / 2;
    if(edgeSize > MAX_EDGE_SIZE) edgeSize = MAX_EDGE_SIZE;
    if(glowSize > MAX_GLOW_SIZE) glowSize = MAX_GLOW_SIZE;
    setHeight(scrollEdge, edgeSize);
    setHeight(scrollGlow, glowSize);
}

private static void setHeight(ImageView viewIn, float height)
{
    ViewGroup.LayoutParams params = viewIn.getLayoutParams();
    params.height = (int) height;
    viewIn.setLayoutParams(params);
}   

public AbsListView getListView()
{
    return listView;
}
}

Le overscroll images, vous pouvez les saisir à partir de plates-formes\android-10\data\res\drawable-mdpi\ et ensuite modifier la Teinte et la Saturation à changer de couleur.

J'espère que cela peut être un point de départ utile pour d'autres ListView personnalisation - Être intéressant d'écouter de tout.

6voto

Menny Points 168

En fait, au lieu d'utiliser un ListView personnalisé, vous pouvez simplement "bidouiller" votre façon de changer la couleur. L'effet de rayonnement est en fait un dessin incorporable dans les ressources du système d'exploitation, vous pouvez appliquer un filtre de couleur sur ce qui suit:

 int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.MULTIPLY);
 

En savoir plus à ce sujet ici: http://evendanan.net/android/branding/2013/12/09/branding-edge-effect/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X