ปิดการใช้งาน ScrollView แบบเป็นโปรแกรมหรือไม่


108

ฉันต้องการเปิดใช้งาน 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>

ขอบคุณ

แก้ไข 1: ฉันไม่สามารถใช้การมองเห็นได้ (ไปแล้ว) เนื่องจากจะซ่อนแกลเลอรีด้วยสิ่งที่ฉันต้องการคือซ่อนเอฟเฟกต์ของ 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);

แต่ภาพในคลังภาพยังเลื่อนได้และไม่พอดีกับหน้าจอ .. วิธีแก้ปัญหานี้คืออะไร?

คำตอบ:


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 ต้องแทนที่หรือใช้เมธอด supertype'
Omar

ขอโทษแก้ไขข้อผิดพลาดในรหัสของฉัน - ควรจะเป็นonTouchEvent(MotionEvent ev)
โจเซฟเอิร์ล

1
ตกลงตอนนี้รหัสเป็นไปตามแม้ว่าเมื่อฉันเรียกใช้แอปมันจะขัดข้อง ... และเมื่อฉันลบคลาสนี้และส่งคืน <ScrollView แทนคลาสของคุณแอปก็ทำงานได้ดี!
Omar

สวัสดี Omar คุณสามารถโพสต์ข้อผิดพลาดที่คุณได้รับ? อย่าลืมเปลี่ยน com.mypackagename ใน <com.mypackagename.LockableScrollView> เป็นของคุณเอง
โจเซฟเอิร์ล

1
คำตอบที่ดี. หากคุณเปลี่ยน case MotionEvent.ACTION_DOWN: เป็น case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_DOWN: คุณจะสามารถปิดใช้งานการเลื่อนได้ในขณะที่ลาก แต่แน่นอนว่าทุกคนต้องใช้มันอย่างไร
luky

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ทำงานของฉันตรงกันข้าม: จริงเมื่อปิดการเลื่อนและเท็จเมื่อเปิดใช้งาน
Machado

@Holmes: คุณพูดถูกเมื่อคุณต้องการบล็อกการเลื่อน
ลิลลี่

1
ทำงานได้อย่างสวยงามนอกจากนี้ฉันยังมีมุมมองของเด็ก ๆ (ปุ่ม) ภายใน scrollview และฉันยังสามารถโต้ตอบกับพวกเขาได้แม้ว่าจะไม่ได้แทนที่ onInterceptTouchEvent ()! โซลูชันที่หรูหรา
Cody

1
@Machado เหตุผลที่คุณต้องคืนค่า true เพื่อบล็อกการเลื่อนเนื่องจาก touch Listener รับค่าบูลีนที่ส่งคืนเพื่อกำหนดว่าควรใช้เหตุการณ์การสัมผัสหรือไม่ หากคุณส่งคืนเท็จมุมมองการเลื่อนจะดำเนินต่อเพื่อส่งต่อเหตุการณ์สัมผัสไปยังตัวฟังการเลื่อน
Vince

11

พบวิธีง่ายๆเพียงแค่ตั้งค่า

ScrollView.requestDisallowInterceptTouchEvent(true);

5
requestDisallowInterceptTouchEventใช้ได้กับลูกของ View เท่านั้นที่จะล็อค ดังนั้นมันจะเป็นอย่างไรmLinearLayout.requestDisallowInterceptTouchEvent(true);
Muz

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เป็นคอนเทนเนอร์โครงร่างหลักของคลาสเลย์เอาต์ของคุณ
actaram

หากคุณแตะปุ่มหรือสิ่งอื่นที่ขัดขวางการสัมผัสก่อนมุมมองแบบเลื่อนจะยังคงเลื่อนอยู่
Cristi Băluță

3

นี่คือวิธีที่ง่ายกว่า แทนที่onTouch()สำหรับScrollView OnTouchListenerและส่งคืนเท็จหากคุณต้องการข้ามการเลื่อนโดยการสัมผัส การเลื่อนแบบเป็นโปรแกรมยังคงใช้งานได้และไม่จำเป็นต้องขยายScrollViewคลาส

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

1
! isScrollable เนื่องจากค่าที่ส่งคืนจริงหมายความว่าเหตุการณ์ถูกดักฟัง
goRGon

3

ฉันมีคะแนนไม่เพียงพอที่จะแสดงความคิดเห็นเกี่ยวกับคำตอบ แต่ฉันอยากจะบอกว่าคำตอบของ mikec ได้ผลสำหรับฉันยกเว้นว่าฉันต้องเปลี่ยนเพื่อส่งคืน! isScrollable ดังนี้:

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 เป็นพาเรนต์ไปยังหน้าจอที่คุณต้องการเพิ่ม 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>

มันใช้ได้กับกรณีของฉัน


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
ฉันไม่คิดว่ามันไม่ได้แตกต่าง แต่อย่างใดฉันยังคงมีปัญหาเดิม
Omar

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
สิ่งนี้จะซ่อนแกลเลอรีด้วยดังนั้นจึงไม่ใช่วิธีแก้ปัญหาฉันแก้ไขโพสต์พร้อมรายละเอียดเพิ่มเติม
Omar

-6

บนปุ่มคลิกฟังเพียงแค่ทำ

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

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

เพื่อไม่ให้แถบเลื่อนเปิดใช้งานเมื่อคลิกปุ่ม


2
นี่เป็นเพียงการซ่อนแถบที่ฉันเดา .. แต่ไม่ใช่ผลของ scrollview
Omar

1
ไม่อนุญาตให้คุณเลื่อนและจะไม่ซ่อนมุมมองแกลเลอรี
Sumant
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.