2010-03-03 5 views
29

J'ai chargé quelques images dans une galerie. Maintenant, je suis capable de faire défiler mais une fois commencé à défiler, le défilement ne s'arrêtera pas. Je voudrais que la galerie défile juste à l'image suivante et puis arrête jusqu'à ce que l'utilisateur fasse à nouveau le geste de défilement.Comment arrêter le défilement dans un widget Galerie?

ceci est mon code

import android.widget.ImageView; 
import android.widget.Toast; 
import android.widget.AdapterView.OnItemClickListener; 

public class GalleryExample extends Activity { 

private Gallery gallery; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    gallery = (Gallery) findViewById(R.id.examplegallery); 
    gallery.setAdapter(new AddImgAdp(this)); 

    gallery.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView parent, View v, int position, long id) { 

      Toast.makeText(GalleryExample.this, "Position=" + position, Toast.LENGTH_SHORT).show(); 
     } 
    }); 

} 

public class AddImgAdp extends BaseAdapter { 
    int GalItemBg; 
    private Context cont; 


    private Integer[] Imgid = { 
      R.drawable.a_1, R.drawable.a_2, R.drawable.a_3, R.drawable.a_4, R.drawable.a_5, R.drawable.a_6, R.drawable.a_7 
    }; 

    public AddImgAdp(Context c) { 
     cont = c; 
     TypedArray typArray = obtainStyledAttributes(R.styleable.GalleryTheme); 
     GalItemBg = typArray.getResourceId(R.styleable.GalleryTheme_android_galleryItemBackground, 0); 
     typArray.recycle(); 
    } 

    public int getCount() { 
     return Imgid.length; 
    } 

    public Object getItem(int position) { 
     return position; 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imgView = new ImageView(cont); 

     imgView.setImageResource(Imgid[position]); 

     i.setScaleType(ImageView.ScaleType.FIT_CENTER); 
     imgView.setBackgroundResource(GalItemBg); 

     return imgView; 
    } 
} 

}

et le fichier XMLLayout

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout android:id="@+id/LinearLayout01" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
xmlns:android="http://schemas.android.com/apk/res/android" > 
<Gallery xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/examplegallery" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" /> 
</LinearLayout> 
+0

Vous devez fournir un peu plus d'informations sur votre problème pour obtenir une réponse – Janusz

+0

OK J'ai plusieurs images Chargé dans une galerie, lorsque je fais défiler vers la droite, il ne s'arrête jamais, je veux un arrêt dans chaque image. –

+0

Janusz Je suis sûr que vous savez comment résoudre ce problème! : D –

Répondre

2

La meilleure façon que j'ai trouvé d'y arriver est en redéfinissant la Galerie onFling méthode, et fournissant ma propre valeur velocityX:

@Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 
     return super.onFling(e1, e2, 10, velocityY); 
    } 

Ce n'est pas parfait, mais cela fait l'affaire. Idéalement, vous écririez probablement quelque chose de personnalisé pour onFling pour le faire fonctionner exactement comme vous le souhaitez.

49

Je pense que j'ai trouvé un moyen de réaliser à la fois seulement le défilement 1 vue à la fois dans la galerie et être capable d'avoir une longueur de balayage minimale pour déclencher l'animation.

Remplacer la méthode de onFling du widget galerie et au lieu d'appeler super.onFling, vérifiez si le coup était de gauche à droite ou de droite à gauche et appeler l'événement dpad approprié comme indiqué ci-dessous:

private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){ 
    return e2.getX() > e1.getX(); 
} 

@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){ 
    int kEvent; 
    if(isScrollingLeft(e1, e2)){ //Check if scrolling left 
    kEvent = KeyEvent.KEYCODE_DPAD_LEFT; 
    } 
    else{ //Otherwise scrolling right 
    kEvent = KeyEvent.KEYCODE_DPAD_RIGHT; 
    } 
    onKeyDown(kEvent, null); 
    return true; 
} 
+3

Vous, monsieur, êtes un renard intelligent. Merci pour cette solution élégante - exactement ce dont j'avais besoin pour rendre ma galerie utilisable. – sniurkst

+3

Exactement ce que je cherchais. Juste pour clarifier cette solution, je n'ai pas réussi à comprendre comment définir onFling() inline et ai dû recourir à la création d'une galerie personnalisée à la place. Cette solution m'a aidé à la fin: http://stackoverflow.com/questions/4582123/creating-a-custom-gallery-overriding-onfling –

+0

+1 pour la simplicité, cela a fonctionné pour moi! –

2

Je trouve la dérogation suivante sur onFling fonctionnait assez bien pour les petits grands coups et la pagination d'une seule page:

@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
{ 
    boolean leftScroll = isScrollingLeft(e1, e2); 

    float velX; 
    if(leftScroll) 
    { 
     velX=500; 
    } 
    else 
    { 
     velX=-500; 
    } 

    return super.onFling(e1, e2, velX, velocityY); 
} 

la valeur Velx + -500 semble fournir un assez bon résultat, mais il pourrait être ajusté en fonction de votre préférences.

(Note: ce utilise la méthode présentée dans isScrollingLeft@Nadewad's answer)

12

Ceci est le code qui a fonctionné pour moi.

solution de Nadewad + quelques réglages de vitesse d'animation:

Créer classe qui étend la Galerie, et passer outre cette metods:

@Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
    setAnimationDuration(600); 
    return super.onScroll(e1, e2, distanceX, distanceY); 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
    float velMax = 2500f; 
    float velMin = 1000f; 
    float velX = Math.abs(velocityX); 
    if (velX > velMax) { 
     velX = velMax; 
    } else if (velX < velMin) { 
     velX = velMin; 
    } 
    velX -= 600; 
    int k = 500000; 
    int speed = (int) Math.floor(1f/velX * k); 
    setAnimationDuration(speed); 

    int kEvent; 
    if (isScrollingLeft(e1, e2)) { 
     // Check if scrolling left 
     kEvent = KeyEvent.KEYCODE_DPAD_LEFT; 
    } else { 
     // Otherwise scrolling right 
     kEvent = KeyEvent.KEYCODE_DPAD_RIGHT; 
    } 
    onKeyDown(kEvent, null); 

    return true; 
    } 

Amusez-vous!

3

La façon facile suit:

@Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 
     return super.onFling(e1, e2, 0, velocityY); 
    } 

Vous pouvez également vérifier ici: Android Infinite Loop Gallery

+0

Celui-ci fonctionne le mieux pour moi, car il fait défiler la galerie seulement un à la fois, peu importe à quelle vitesse vous balayez. J'ai essayé la solution KeyEvent et si vous avez balayé trop vite, il va sauter comme deux ou trois. –

1

DIEU !!! MERCI OMG, j'ai littéralement branché cela dans du code et ça a marché! hgh, 48 h directement et de penser que je devais seulement faire la recherche google parfaite pour ma réponse. Littéralement, branchez et jouez. Merci beaucoup.

nouveau code

public class CustomGallery extends Gallery { 

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

public CustomGallery(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

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

private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){ 
    return e2.getX() > e1.getX(); 
} 

@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){ 
    int kEvent; 
    if(isScrollingLeft(e1, e2)){ //Check if scrolling left 
    kEvent = KeyEvent.KEYCODE_DPAD_LEFT; 
    } 
    else{ //Otherwise scrolling right 
    kEvent = KeyEvent.KEYCODE_DPAD_RIGHT; 
    } 
    onKeyDown(kEvent, null); 
    return true; 
} 
} 

ancien code: seulement à des fins de comparaison

public class CustomGallery extends Gallery { 

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

public CustomGallery(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

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

@Override 
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 
     float distanceY) { 
    //Do something specific here. 
    return super.onScroll(e1, e2, distanceX, distanceY); 
} 
} 
+0

Je suis content que cela vous a aidé. En fait, Google a publié la classe ViewPager qui atteint le même objectif, mais fait en réalité une animation de défilement intermédiaire pendant que vous glissez votre doigt plutôt que de défiler une fois le mouvement de balayage terminé. – Nadewad

2

pas besoin de faire quelque chose retourner tout simplement faux

private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){ 
    return e2.getX() > e1.getX(); 
} 

@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){ 
    return false; 
} 

il a travaillé pour moi

Questions connexes