以编程方式禁用ScrollView?

时间:2011-04-23 09:03:23

标签: android android-scrollview

我想启用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(已消失)因为这也会隐藏Gallery,我想要的是隐藏ScrollView的效果。当有ScrollView时,Gallery中的图像变为scrollabale并且不适合屏幕,所以你必须滚动才能看到整个图像,我不想在按钮点击时禁用/启用它。

我试过了:

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

但是图库中的图像仍然是可滚动的,不适合屏幕..这是解决方案吗?

18 个答案:

答案 0 :(得分:174)

首先要点几点:

  1. 您无法禁用滚动浏览ScrollView。您需要扩展到ScrollView并覆盖onTouchEvent方法,以便在匹配某些条件时返回false
  2. 无论是否在ScrollView中,Gallery组件都会水平滚动 - ScrollView仅提供垂直滚动(水平滚动需要Horizo​​ntalScrollView)
  3. 您似乎表示图像拉伸本身存在问题 - 这与ScrollView无关,您可以更改ImageView与android:scaleType属性(XML)或{{1方法 - 例如setScaleType不会拉伸您的图片并将其置于原始尺寸的中心
  4. 您可以按如下方式修改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);
        }
    
    }
    

    在您的XML文件中(只是将<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> 更改为您的特殊ScrollView)。

    然后致电

    LockableScrollView

    禁用视图滚动。

    我认为你不仅仅是为了实现你想要的结果而禁用滚动的问题(例如,使用上面的代码,画廊将保持可滚动状态) - 我建议对这三个组件中的每个组件进行更多的研究(Gallery,ScrollView,ImageView)查看每个属性具有的属性及其行为。

答案 1 :(得分:69)

我走了这条路:

        scrollView.setOnTouchListener(new View.OnTouchListener() {

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

答案 2 :(得分:9)

发现这个简单的解决方案只需设置

ScrollView.requestDisallowInterceptTouchEvent(true);

答案 3 :(得分:5)

禁用ScrollView

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

答案 4 :(得分:4)

开始,我使用了第一条评论中发布的代码,但我改变了它:

    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 未定义

我希望这会对你有所帮助

答案 5 :(得分:3)

我没有足够的分数来评论答案,但我想说mikec的答案对我有用,除了我必须改变它以返回!isScrollable如此:

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

答案 6 :(得分:2)

这是一个更简单的解决方案。覆盖onTouch() ScrollView的{​​{1}},如果您想通过触摸绕过滚动,则返回false。程序化滚动仍然有效,无需扩展OnTouchListener类。

ScrollView

答案 7 :(得分: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);
    }
}

答案 8 :(得分: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);      
            }
    }

答案 9 :(得分: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作为父级添加到要在其中添加另一个Scrollview作为子视图的屏幕,并且整个屏幕可滚动。我用它作为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>

它适用于我的情况。

答案 10 :(得分:1)

@JosephEarl +1他在这里有一个很好的解决方案,对我来说非常有效,并且可以通过编程方式进行一些小修改。


以下是我所做的小改动:

LockableScrollView类:

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

答案 11 :(得分:1)

我在NestedScrollView上有一个布局,消耗了触摸事件并禁用了滚动:

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

并启用:

progressBarLayout.setOnTouchListener(null);

答案 12 :(得分:0)

科特林:


scrollView.setOnTouchListener { _, _ -> true }

附注。 Vel_daN:爱​​你所做的?。

答案 13 :(得分:0)

我可能迟到了,但仍然...

此答案基于动态删除和添加视图

要禁用滚动:

View child = scoll.getChildAt(0);// since scrollView can only have one direct child
ViewGroup parent = (ViewGroup) scroll.getParent();
scroll.removeView(child); // remove child from scrollview
parent.addView(child,parent.indexOfChild(scroll));// add scroll child at the position of scrollview
parent.removeView(scroll);// remove scrollView from parent

要启用ScrollView,只需逆转该过程

答案 14 :(得分: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;
}
}

答案 15 :(得分:0)

这有帮助吗?

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

答案 16 :(得分:-2)

正如您在documentation中所看到的,您无法将可见性设置为false。在你的情况下你应该使用:

scrollview.setVisibility(Visibility.GONE);

答案 17 :(得分:-5)

按钮点击监听器上的

只需

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

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

以便按钮单击时不启用滚动条