Вимкнути програму 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.