Вимкнути програму ScrollView програмно?


108

Я б хотів увімкнути ScrollView і відключити його натисканням кнопки.
Вимкнути засоби, наприклад, якщо ScrollView там не було .., і включити його повертає ScrollView.

Я хочу цього, тому що у мене є галерея з текстовими зображеннями, і на кнопку натисніть, щоб орієнтація екрана змінювалася, тож у Landscape текст стає більшим. І я хочу, щоб ScrollView, щоб зображення не розтягувалося, а текст став нечитабельним.

scrollview.Enabled=false / setVisibility(false) не робить нічого.

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>

Дякую

Edit1: Я не можу використовувати видимість (пішла), оскільки це також приховало б Галерею, що я хочу приховати ефект ScrollView. Коли є ScrollView, зображення в Галереї стають прокручуваними та не вміщуються на екрані, тому вам доведеться прокручувати, щоб побачити все зображення, я не хочу відключати / вмикати це при натисканні кнопки.

Я спробував це:

((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);

Але все ж зображення в Галереї можна прокручувати і не підходити до екрану .. яке рішення для цього?

Відповіді:


187

Кілька пунктів для початку:

  1. Не можна вимкнути прокрутку ScrollView. Вам потрібно буде поширитись на ScrollView і замінити onTouchEventметод повернення, falseколи деяка умова збігається.
  2. Компонент Галерея прокручується горизонтально незалежно від того, перебуває він у ScrollView чи ні - ScrollView надає лише вертикальну прокрутку (для горизонтальної прокрутки вам потрібен HorizontalScrollView)
  3. Ви начебто говорите, що у вас є проблема з самим розтягуванням зображення - це не має нічого спільного з ScrollView, ви можете змінити, як ImageView масштабує android:scaleTypeвластивість (XML) або setScaleTypeметод - наприклад ScaleType.CENTER, не розтягне ваше зображення і буде централізуйте його в оригінальному розмірі

Ви можете змінити ScrollViewтак, щоб відключити прокрутку

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);
    }

}

Тоді ви б використали

<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>

у вашому XML-файлі (щойно змінив ScrollViewспеціальний LockableScrollView).

Тоді дзвоніть

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

щоб вимкнути прокручування подання.

Я думаю, що у вас є більше, ніж проблема вимкнення прокрутки, хоча для досягнення бажаного результату (наприклад, галерея залишатиметься для прокрутки разом із наведеним вище кодом) - рекомендую зробити ще кілька досліджень щодо кожного з трьох компонентів (Галерея, ScrollView, ImageView), щоб побачити, які властивості має кожен і як він веде себе.


Ось як виглядає клас: pastebin.com/dsWSWR4x Але я отримую помилку 'Метод onTouch (View, MotionEvent) типу LockableScrollView повинен перекрити або реалізувати метод супертипу'
Омар

Вибачте, виправив помилки в моєму коді - мав бутиonTouchEvent(MotionEvent ev)
Джозеф граф

1
Гаразд, код відповідає, хоча коли я запускаю додаток, він виходить з ладу ... і коли я видаляю цей клас і повертаю <ScrollView замість вашого класу, програма працює добре!
Омар

Привіт Омаре, ви можете опублікувати помилку, яку ви отримали? Переконайтесь, що змініть ім'я com.mypackagege в <com.mypackagename.LockableScrollView> на своє власне
Джозеф Граф

1
Хороша відповідь. Якщо ви зміните регістр MotionEvent.ACTION_DOWN: до регістру MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_DOWN: ви також зможете відключити прокрутку також під час перетягування. Але, звичайно, у кожного, як йому потрібно ним користуватися.
луки

70

Я пішов таким шляхом:

        scrollView.setOnTouchListener(new View.OnTouchListener() {

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

3
Простий і чудово працює. Ключовим моментом є використання змінної (наприклад, isBlockedScrollView) для управління, коли потрібно включити прокрутку. Встановіть його як істинне, коли прокрутка повинна бути дозволена, а в іншому помилковою.
PeteH

5
@ PeteH, я не маю поняття, чому, але мої ListViewроботи працюють навпаки: правда, коли прокрутка вимкнена, а помилкова, коли вона включена.
Мачадо

@Holmes: ти маєш рацію, правда, коли хочеш заблокувати прокрутку
лілія

1
Крім того, у мене в режимі прокрутки є дитячі подання (кнопки), і я все ще можу взаємодіяти з ними, незважаючи на те, що не переважає OnInterceptTouchEvent ()! Елегантне рішення.
Коді

1
@Machado Причина, яку потрібно повернути true, щоб заблокувати прокрутку, полягає в тому, що слухач дотику приймає булеве значення, повернене для того, щоб визначити, чи слід споживачу події вживати чи ні. Якщо ви повернете помилкове, подання прокрутки перейде до передачі сенсорної події слухачеві прокрутки.
Вінс

11

Знайшли це просте рішення просто встановити

ScrollView.requestDisallowInterceptTouchEvent(true);

5
requestDisallowInterceptTouchEventпрацює лише для того, щоб дитина заблокована. Так було б якmLinearLayout.requestDisallowInterceptTouchEvent(true);
Муз

6

Вимкнути ScrollView

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

5

для початку я використав Код, розміщений у першому коментарі, але я змінив його так:

    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);      
            }
    }

}

тоді я закликав це таким чином

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

тому що я намагався

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

але він сказав, що setIsScrollable не визначено

Я сподіваюся, що це допоможе тобі


Примітка: перші два конструктори потрібні, якщо ваш ScrollView- основний контейнер компонування вашого класу компонування.
актарам

Якщо ви натиснете кнопку або щось інше, що спочатку перехоплює дотики, перегляд прокрутки все ще прокручується
Крісті Балуша

3

Ось більш просте рішення. Замініть значення onTouch()" ScrollView OnTouchListenerі" поверніть на помилкове, якщо ви хочете обійти прокрутку на дотик. Програмна прокрутка все ще працює і не потрібно розширювати ScrollViewклас.

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

1
! isScrollable, оскільки справжнє значення повернення означає, що подія була перехоплена.
goRGon

3

У мене недостатньо балів, щоб коментувати відповідь, але я хотів сказати, що відповідь mikec працювала на мене, за винятком того, що мені довелося змінити її, щоб повернутися!

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

1
@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

@JosephEarl +1 У нього є чудове рішення, яке прекрасно працювало для мене з незначними модифікаціями для програмного забезпечення.


Ось незначні зміни, які я внесла:

LockableScrollView клас:

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

Основна активність:

LockableScrollView sv;

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

1

У мене був макет над NestedScrollView, який споживає сенсорну подію та вимикає прокрутку:

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

і включити:

progressBarLayout.setOnTouchListener(null);

1

Можна створити CustomScrollView, для якого ви можете відключити його втручання в інші представлення. Хоча це може часом дратувати кінцевого споживача. Використовуйте його обережно.

Це код:

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;
    }
}

Як користуватися CustomScrollView?

Ви можете додати CustomScrollView в якості батьків до екрана, у який потрібно додати ще один перегляд прокрутки як дочірнього перегляду, і весь екран можна прокручувати. Я використовував це для відносного макета.

<?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>

Це працювало для моєї справи.


1
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);
    }
}

0

Чи допомагає це?

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

1
Я не думаю, що це мало якусь різницю, у мене все ще є те саме питання
Омар

0

Ви можете розширити галерею та використовувати прапор, щоб відключити прокрутку, коли потрібно:

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;
}
}

-3

Як ви бачите в документації , ви не можете встановити видимість на хибну. У вашому випадку ви, ймовірно, повинні використовувати:

scrollview.setVisibility(Visibility.GONE);

2
Це також приховає Галерею, щоб її не було рішення, я відредагував публікацію з більш детальною інформацією
Омар,

-6

слухач натискання кнопки просто робити

ScrollView sView = (ScrollView)findViewById(R.id.ScrollView01);

sView.setVerticalScrollBarEnabled(false);
sView.setHorizontalScrollBarEnabled(false);

щоб панель прокрутки не була включена при натисканні кнопки


2
Це приховує лише бари, я думаю .. але не ефект прокрутки
Омар

1
це не дозволить вам прокручувати, також не приховатиме перегляд галереї
Sumant
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.