web-dev-qa-db-fra.com

Désactiver ScrollView par programme?

Je voudrais activer ScrollView et le désactiver par un clic de bouton.
Désactiver signifie comme si ScrollView n’était pas là… et l’activer renvoie ScrollView.

Je le veux parce que j'ai une galerie avec des images de texte et que sur un bouton, l'orientation de l'écran change, de sorte que dans Paysage, le texte devient plus gros. Et je veux le ScrollView pour que l'image ne s'étire pas et que le texte ne soit plus lisible.

scrollview.Enabled=false / setVisibility(false) ne fait rien.

xml:

<ScrollView 
Android:id="@+id/QuranGalleryScrollView" 
Android:layout_height="fill_parent" 
Android:layout_width="fill_parent">
<Gallery Android:id="@+id/Gallery" 
Android:layout_width="fill_parent" 
Android:layout_height="fill_parent"
Android:scrollbars="horizontal"></Gallery>
</ScrollView>

Merci

Edit1: Je ne peux pas utiliser Visibility (disparu) car cela masquerait également la galerie. Ce que je veux, c'est masquer l'effet de ScrollView. Quand il y a ScrollView, les images dans Gallery deviennent scrollabale et ne rentrent pas dans l’écran, il faut donc faire défiler pour voir toute l’image, je ne veux pas l’activer/désactiver avec un clic de bouton.

J'ai essayé ceci:

((ScrollView)findViewById(R.id.QuranGalleryScrollView)).setOnTouchListener(null);
                        ((ScrollView)findViewById(R.id.QuranGalleryScrollView)).setHorizontalScrollBarEnabled(false);
                        ((ScrollView)findViewById(R.id.QuranGalleryScrollView)).setVerticalScrollBarEnabled(false);
                        ((ScrollView)findViewById(R.id.QuranGalleryScrollView)).setEnabled(false);

Mais toujours dans la galerie, les images défilent et ne s’adaptent pas à l’écran. Quelle est la solution à ce problème?

101
Omar

Plusieurs points pour commencer:

  1. Vous ne pouvez pas désactiver le défilement d'une ScrollView. Vous auriez besoin d'étendre ScrollView et de remplacer la méthode onTouchEvent pour renvoyer false lorsqu'une condition est remplie.
  2. Le composant Galerie défile horizontalement, que ce soit dans un ScrollView ou non - un ScrollView fournit uniquement le défilement vertical (vous avez besoin d'un HorizontalScrollView pour le défilement horizontal)
  3. Vous semblez dire que l'image s'agrandit d'elle-même; cela n'a rien à voir avec ScrollView, vous pouvez modifier la mise à l'échelle d'une ImageView avec le Android:scaleType propriété (XML) ou la méthode setScaleType - par exemple ScaleType.CENTER n'allongera pas votre image et la centrera à sa taille originale

Vous pouvez modifier ScrollView comme suit pour désactiver le défilement

class LockableScrollView extends ScrollView {

    ...

    // true if we can scroll (not locked)
    // false if we cannot scroll (locked)
    private boolean mScrollable = true;

    public void setScrollingEnabled(boolean enabled) {
        mScrollable = enabled;
    }

    public boolean isScrollable() {
        return mScrollable;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // if we can scroll pass the event to the superclass
                return mScrollable && super.onTouchEvent(ev);
            default:
                return super.onTouchEvent(ev);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // Don't do anything with intercepted touch events if
        // we are not scrollable
        return mScrollable && super.onInterceptTouchEvent(ev);
    }

}

Vous utiliseriez alors

<com.mypackagename.LockableScrollView 
    Android:id="@+id/QuranGalleryScrollView" 
    Android:layout_height="fill_parent" 
    Android:layout_width="fill_parent">

    <Gallery Android:id="@+id/Gallery" 
        Android:layout_width="fill_parent" 
        Android:layout_height="fill_parent"
        Android:scrollbars="horizontal">
    </Gallery>

</com.mypackagename.LockableScrollView>

dans votre fichier XML (vient de changer le ScrollView en votre spécial LockableScrollView).

Alors appelez

((LockableScrollView)findViewById(R.id.QuranGalleryScrollView)).setScrollingEnabled(false);

désactiver le défilement de la vue.

Je pense que vous avez bien plus qu’à désactiver le défilement pour obtenir le résultat souhaité (la galerie reste défilante avec le code ci-dessus, par exemple). Je vous conseillerais de faire davantage de recherche sur chacun des trois composants ScrollView, ImageView) pour voir les propriétés de chacun et son comportement.

176
Joseph Earl

J'étais allé de cette façon:

        scrollView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            return isBlockedScrollView;
        }
    });
69
lily

Trouvé cette solution simple vient de définir

ScrollView.requestDisallowInterceptTouchEvent(true);
9
JWqvist

Désactiver ScrollView

ScrollView sw = (ScrollView) findViewById(R.id.scrollView1);
sw.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});
5
BelaSzombathelyi

pour commencer, j'ai utilisé le code posté dans le premier commentaire, mais je l'ai changé comme suit:

    public class LockableScrollView extends ScrollView {

    public LockableScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }
    public LockableScrollView(Context context, AttributeSet attrs) 
    {
        super(context, attrs);
    }

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

    // true if we can scroll (not locked)
    // false if we cannot scroll (locked)
    private boolean mScrollable = true;

    public void setScrollingEnabled(boolean enabled) {
        mScrollable = enabled;
    }

    public boolean isScrollable() {
        return mScrollable;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // if we can scroll pass the event to the superclass
                if (mScrollable) return super.onTouchEvent(ev);
                // only continue to handle the touch event if scrolling enabled
                return mScrollable; // mScrollable is always false at this point
            default:
                return super.onTouchEvent(ev);
        }
    }



@Override  
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {     
    case MotionEvent.ACTION_DOWN:         
        // if we can scroll pass the event to the superclass      
        if (mScrollable) return super.onInterceptTouchEvent(ev);      
        // only continue to handle the touch event if scrolling enabled    
        return mScrollable; // mScrollable is always false at this point     
        default:          
            return super.onInterceptTouchEvent(ev);      
            }
    }

}

alors je l'ai appelé de cette façon

((LockableScrollView)findViewById(R.id.scrollV)).setScrollingEnabled(false);

parce que j'ai essayé

((LockableScrollView)findViewById(R.id.scrollV)).setIsScrollable(false);

mais il a dit que setIsScrollable n'est pas défini

j'espère que cela t'aidera

4
Souhaieb

Je n'ai pas assez de points pour commenter une réponse, mais je voulais dire que la réponse de mikec a fonctionné pour moi, sauf que je devais la changer pour y revenir!

mScroller.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return !isScrollable;
    }
});
3
Dave

Voici une solution plus simple. Remplacez onTouch() pour ScrollViewOnTouchListener et renvoyez la valeur false si vous souhaitez ignorer le défilement au toucher. Le défilement par programme fonctionne toujours et il n'est pas nécessaire d'étendre la classe ScrollView.

mScroller.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
  return isScrollable;
}
});
2
mikec

Vous pouvez créer un CustomScrollView, pour lequel vous pouvez désactiver son interférence avec d'autres vues. Bien que cela puisse être parfois irritant pour l'utilisateur final. Utilisez-le avec prudence.

C'est le code:

import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.MotionEvent;
import Android.view.ViewParent;

public class CustomScrollView extends Android.widget.ScrollView {

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

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        /* Prevent parent controls from stealing our events once we've gotten a touch down */
        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
        {
            ViewParent p = getParent();
            if (p != null)
                p.requestDisallowInterceptTouchEvent(true);
        }

        return false;
    }
}

Comment utiliser le CustomScrollView?

Vous pouvez ajouter CustomScrollView en tant que parent à l'écran dans lequel vous souhaitez ajouter une autre vue de défilement en tant que vue enfant, et l'écran entier peut défiler. Je l'ai utilisé pour un RelativeLayout.

<?xml version="1.0" encoding="utf-8"?>
<**package.**CustomScrollView 
xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/some_id"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    xmlns:tools="http://schemas.Android.com/tools">
    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">
    #**Inside this I had a TableLayout and TableRow. Inside the TableRow,**
    #**I had a TextView which I made scrollable from Java Code.**
    #**textView.setMovementMethod(new ScrollingMovementMethod());**
    </RelativeLayout>
</ankit.inventory.ankitarora.inventorymanagementsimple.CustomScrollView>

Cela a fonctionné pour mon cas.

1
Ankit Arora

J'avais une mise en page sur NestedScrollView consommant l'événement tactile et désactivant le défilement:

progressBarLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return true;
            }
        });

et pour permettre:

progressBarLayout.setOnTouchListener(null);
1
SpyZip
public class LockableScrollView extends ScrollView {

    private boolean mScrollable = true;

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

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

    public LockableScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.Lollipop)
    public LockableScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public void setScrollable(boolean enabled) {
        mScrollable = enabled;
    }

    public boolean isScrollable() {
        return mScrollable;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return mScrollable && super.onTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mScrollable && super.onInterceptTouchEvent(ev);
    }
}
1
Täg
@Override  
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {     
    case MotionEvent.ACTION_DOWN:         
        // if we can scroll pass the event to the superclass      
        if (mScrollable) return super.onInterceptTouchEvent(ev);      
        // only continue to handle the touch event if scrolling enabled    
        return mScrollable; // mScrollable is always false at this point     
        default:          
            return super.onInterceptTouchEvent(ev);      
            }
    }
1
mohammad

@JosephEarl +1 Il a une excellente solution ici qui a parfaitement fonctionné pour moi avec quelques modifications mineures pour le faire par programme.


Voici les modifications mineures que j'ai apportées:

LockableScrollView Class:

public boolean setScrollingEnabled(boolean enabled) {
    mScrollable = enabled;
    return mScrollable;
}

MainActivity:

LockableScrollView sv;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sv = new LockableScrollView(this);
    sv.setScrollingEnabled(false);
}
1
jnthnjns

Vous pouvez étendre la galerie et utiliser certains indicateurs pour désactiver le défilement lorsque vous le souhaitez:

public class MyGallery extends Gallery {

public boolean canScroll;

public MyGallery(Context context, AttributeSet attrs) {
    canScroll = true;
    super(context, attrs);
}

public void setCanScroll(boolean flag)
{
    canScroll = flag;
}

@Override
public boolean onScroll(Android.view.MotionEvent e1, Android.view.MotionEvent e2, float distanceX, float distanceY) {
    if (canScroll)
        return super.onScroll(e1,e2,distancex,distancey);
    else
        return false;
}

@Override
public boolean onSingleTapUp(MotionEvent e)
{
    if (canScroll)
        return super.onSingleTapUp(ey);
    else
        return false;
}

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

Est-ce que cela aide?

((ScrollView)findViewById(R.id.QuranGalleryScrollView)).setOnTouchListener(null);
0
rajath