Отключить ScrollView программно? - PullRequest
100 голосов
/ 23 апреля 2011

Я хотел бы включить ScrollView и отключить его нажатием кнопки.
Отключить означает, что, если ScrollView там не было .. и включить его возвращает ScrollView.

Я хочу этого, потому что у меня есть галерея с текстовыми изображениями, и при нажатии кнопки ориентация экрана меняется, поэтому в альбомной ориентации текст становится больше. И я хочу 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: я не могу использовать Visibility (ушел), так как это также скрыло бы Галерею, а я хочу скрыть эффект 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);

Но все же изображения в Галерее прокручиваются и не помещаются на экране. Какое решение для этого?

Ответы [ 16 ]

175 голосов
/ 23 апреля 2011

Несколько пунктов для начала:

  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), чтобы увидеть, какие свойства у каждого из них и как он ведет себя.

69 голосов
/ 15 марта 2013

Я пошел по этому пути:

        scrollView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            return isBlockedScrollView;
        }
    });
9 голосов
/ 20 января 2014

Нашли это простое решение, просто установите

ScrollView.requestDisallowInterceptTouchEvent(true);
5 голосов
/ 11 сентября 2013

Отключить ScrollView

ScrollView sw = (ScrollView) findViewById(R.id.scrollView1);
sw.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});
4 голосов
/ 27 февраля 2014

для начала, я использовал код, опубликованный в первом комментарии, но изменил его так:

    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 не определено

Я надеюсь, что это поможет вам

3 голосов
/ 21 сентября 2012

У меня недостаточно баллов, чтобы комментировать ответ, но я хотел сказать, что ответ Майка сработал для меня, за исключением того, что мне пришлось изменить его, чтобы вернуть! IsScrollable примерно так:

mScroller.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return !isScrollable;
    }
});
2 голосов
/ 26 июня 2012

Вот более простое решение. Переопределите onTouch() для ScrollView OnTouchListener и верните false, если вы хотите обойти прокрутку касанием. Программная прокрутка все еще работает, и нет необходимости расширять класс ScrollView.

mScroller.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
  return isScrollable;
}
});
1 голос
/ 15 марта 2018
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 голос
/ 02 марта 2017

Вы можете создать 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 в качестве родительского для экрана, на котором выВы хотите добавить еще один вид прокрутки в качестве дочернего вида, и весь экран можно прокручивать.Я использовал это для 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>

Это сработало для моего случая.

1 голос
/ 19 декабря 2016

У меня был макет поверх NestedScrollView, использующий событие касания и отключающий прокрутку:

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

и для включения:

progressBarLayout.setOnTouchListener(null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...