วิธีปิดการใช้งาน RecyclerView scrolling


221

RecyclerViewฉันไม่สามารถปิดการใช้งานในการเลื่อน ฉันพยายามโทรออกrv.setEnabled(false)แต่ฉันยังสามารถเลื่อนได้

ฉันจะปิดการใช้งานการเลื่อนได้อย่างไร


1
อะไรคือจุดใช้RecyclerViewหากคุณไม่ต้องการเลื่อน?
CommonsWare

16
@CommonsWare ฉันต้องการปิดการใช้งานชั่วคราวเช่นในขณะที่ฉันทำแอนิเมชั่นที่กำหนดเองกับลูก ๆ ของมัน
Zsolt Safrany

1
อ่านั่นมันสมเหตุสมผลแล้ว ฉันอาจจะวางตัวโปร่งใสViewเหนือสิ่งRecyclerViewอื่นใดสลับไปมาระหว่างVISIBLEและGONEตามที่จำเป็น แต่ปิดข้อมือของคุณดูเหมือนจะสมเหตุสมผล
CommonsWare

หวังว่านี่จะช่วยหาทางออกที่ดีกว่า
Saiteja Parsi

1
@CommonsWare นี่คือสิ่งที่ฉันต้องการเช่น ฉันต้องแสดงภาพใน RecyclerView ทีละภาพโดยไม่มีภาพที่มองเห็นได้เพียงบางส่วนเท่านั้นหนึ่งภาพในวิวพอร์ตของฉัน และมีลูกศรอยู่ทางซ้ายและขวาซึ่งผู้ใช้สามารถนำทางด้วย ขึ้นอยู่กับรูปที่แสดงในปัจจุบัน (เป็นประเภทต่าง ๆ ) บางสิ่งที่อยู่นอก RecyclerView จะถูกเรียกใช้ มันคือการออกแบบที่ลูกค้าของเราต้องการ
Varvara Kalinina

คำตอบ:


368

คุณควรแทนที่ layoutmanager ของมุมมองรีไซเคิลสำหรับเรื่องนี้ วิธีนี้จะปิดใช้งานการเลื่อนเท่านั้นไม่มีฟังก์ชันอื่น ๆ คุณจะยังสามารถจัดการคลิกหรือกิจกรรมการสัมผัสอื่น ๆ ตัวอย่างเช่น:-

เดิม:

 public class CustomGridLayoutManager extends LinearLayoutManager {
 private boolean isScrollEnabled = true;

 public CustomGridLayoutManager(Context context) {
  super(context);
 }

 public void setScrollEnabled(boolean flag) {
  this.isScrollEnabled = flag;
 }

 @Override
 public boolean canScrollVertically() {
  //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
  return isScrollEnabled && super.canScrollVertically();
 }
}

ที่นี่โดยใช้แฟล็ก "isScrollEnabled" คุณสามารถเปิด / ปิดการใช้งานฟังก์ชั่นการเลื่อนของมุมมองรีไซเคิลของคุณชั่วคราว

นอกจากนี้:

ง่าย ๆ แทนที่การใช้งานปัจจุบันของคุณเพื่อปิดการเลื่อนและอนุญาตให้คลิก

 linearLayoutManager = new LinearLayoutManager(context) {
 @Override
 public boolean canScrollVertically() {
  return false;
 }
};

2
นี่ควรเป็นคำตอบที่ถูกต้องเนื่องจากมันปิดการเลื่อนขณะที่อนุญาตให้ฉันคลิก
Jared Burrows

10
การปิดใช้งานการเลื่อนบน LayoutManger เริ่มต้นควรมีอยู่แล้วผู้ใช้ API ไม่ควรทำเช่นนี้ ขอบคุณสำหรับคำตอบว่า!
Martin O'Shea

1
จะทำอย่างไรถ้าฉันต้องการปิดใช้งานการเลื่อนจากบางรายการเท่านั้น หมายความว่าคุณสามารถเลื่อนลง (หรือขึ้น) ไปที่มัน แต่จากนั้นถูกบล็อกจนกว่าฉันจะเปิดใช้งานอีกครั้ง?
นักพัฒนา android

2
นอกจากนี้ยังปิดใช้งาน smoothScrollToPosition
Mladen Rakonjac

4
คุณเพิ่มวัตถุเวอร์ชัน kotlin: LinearLayoutManager (นี่) {แทนที่ความสนุก canScrollVertically (): Boolean {return false}}
amorenew

149

คำตอบที่แท้จริงคือ

recyclerView.setNestedScrollingEnabled(false);

ข้อมูลเพิ่มเติมในเอกสาร


39
วิธีนี้จะปิดใช้งานการเลื่อนแบบซ้อนเท่านั้นไม่ใช่การเลื่อนทั้งหมด โดยเฉพาะอย่างยิ่งหาก RecyclerView ของคุณอยู่ใน ScrollView แต่ไม่เต็มหน้าจอ ScrollView จะไม่เลื่อน (เนื้อหาพอดีกับหน้าจอ) และคุณจะได้รับ UI การเลื่อนใน RecyclerView ของคุณ (เอฟเฟกต์ท้ายรายการเมื่อพยายามเลื่อนตัวอย่างเช่น ) แม้ว่ามันจะไม่เลื่อนเมื่อมันใหญ่ขึ้น การขยาย LayoutManager ทำงานได้จริง
personne3000

3
@ personne3000 ฉันเชื่อว่า recyclerView.setHasFixedSize (จริง) ทำงานเพื่อสิ่งนั้น แก้ไข: ฉันยังใช้สิ่งนี้ร่วมกับ setFillViewport (จริง) ดังนั้นฉันจึงไม่แน่ใจว่าหนึ่งในสองแก้ไขมัน
mDroidd

5
ใช้งานได้ดีสำหรับฉัน แต่ "RecyclerView" ของฉันอยู่ในโครงร่าง Fragment โดยใช้ "ScrollView" ดังนั้นฉันจึงต้องเปลี่ยน "ScrollView" โดย "NestedScrollView" ตามที่อธิบายไว้ที่นี่: stackoverflow.com/a/38088902/618464
educoutinho

1
อย่าลืมใช้ชื่อคลาสแบบเต็มสำหรับNestedScrollView: android.support.v4.widget.NestedScrollViewดังที่อธิบายไว้ที่นี่โดย chessdork: stackoverflow.com/questions/37846245/…
gustavoknz

หลังจากใช้เวลา 4 ชั่วโมงเพื่อลองคิดดูว่ามีอะไรผิดปกตินี้แก้ไขปัญหาของฉันได้ ในกรณีของฉันฉันใช้ recyclerview ภายใน MotionLayout และฉันเพิ่งเพิ่มพื้นที่การกวาดเพื่อลากขึ้นโดยเพิ่มการเคลื่อนไหว: touchAnchorId = "@ id / swipe_area" มันใช้งานได้ตามปกติ แต่ยังทำงานเมื่อสัมผัสกับพื้นที่ว่างของ recyclerview ใช้ความระมัดระวังเมื่อใช้ motionLayout กับองค์ประกอบแบบเลื่อนได้อื่น ๆ
O. Kumru

73

คำตอบที่แท้จริงคือ: สำหรับ API 21 และสูงกว่า:

ไม่จำเป็นต้องใช้รหัส java คุณสามารถตั้งค่าเป็น android:nestedScrollingEnabled="false" xml:

<android.support.v7.widget.RecyclerView
     android:id="@+id/recycler"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipToPadding="true"
     android:nestedScrollingEnabled="false"
     tools:listitem="@layout/adapter_favorite_place">

11
ฉันคิดว่านี่เป็นคำตอบที่ได้รับการยอมรับโดยไม่ต้องใช้ความพยายามใด ๆ ในชั้นเรียนคุณสามารถปิดการเลื่อนและยังอนุญาตให้มีการสัมผัสในเค้าโครง
VipiN Negi

อะไรสำหรับ APIs ที่ต่ำกว่า 21?
Mouaad Abdelghafour AITALI

@pic สำหรับ API ที่ต่ำกว่าคุณสามารถใช้: recyclerView.setNestedScrollingEnabled (false);
Milad Faridnia

1
คำตอบที่ยอมรับสำหรับฉัน
Fernando Torres

1
นี่เป็นคำตอบที่ดีที่สุดและตรงไปตรงมาที่สุดซึ่งช่วยหลีกเลี่ยงมลภาวะของโค้ดที่ไม่จำเป็นและรูปแบบการขยายชั้นเรียนที่ไม่มีที่สิ้นสุด
Raphael C

52

วิธีนี้ค่อนข้างเป็นการแก้ปัญหา แต่ก็ใช้งานได้; คุณสามารถเปิด / RecyclerViewปิดการใช้งานในการเลื่อน

นี้เป็นที่ว่างเปล่าขโมยเหตุการณ์ทุกสัมผัสจึงปิดการใช้งานเป้าหมายRecyclerView.OnItemTouchListenerRecyclerView

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return true;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

ใช้มัน:

RecyclerView rv = ...
RecyclerView.OnItemTouchListener disabler = new RecyclerViewDisabler();

rv.addOnItemTouchListener(disabler);        // disables scolling
// do stuff while scrolling is disabled
rv.removeOnItemTouchListener(disabler);     // scrolling is enabled again 

8
สิ่งนี้ปิดใช้งานการคลิกไอเท็มด้วยหรือไม่
Jahir Fiquitiva

@JahirFiquitiva ใช่ "นี่เป็น RecyclerViewOnItemTouchListener ที่ว่างเปล่าขโมยกิจกรรมการสัมผัสทุกครั้ง"
สูงสุด

1
นอกจากนี้ยังปิดใช้งานการเลื่อนมุมมองพาเรนต์ด้วย
Jemshit Iskenderov

รายการนี้จะปิดใช้งานการคลิกไอเท็มด้วย
Muhammad Riyaz

1
เหตุใดจึงต้องใช้วิธีแก้ปัญหาแฮ็ค (ที่มีผลข้างเคียง) เมื่อมีวิธีแก้ปัญหาที่สะอาด เพียงแค่แทนที่ LayoutManager (ดูคำตอบอื่น ๆ )
personne3000

37

สิ่งนี้ใช้ได้กับฉัน:

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

11
สิ่งนี้ปิดใช้งานการสัมผัสทั้งหมด
Jared Burrows

1
เคล็ดลับดี! หากต้องการเปิดใช้งานอีกครั้งเพียงตั้งค่า onTouchListener ของ onTouch อีกครั้งเพื่อส่งคืนค่าเท็จ
HendraWD

อืม แต่มีคำเตือนCustom view 'RecyclerView' has setOnTouchListener called on it but does not override performClick
HendraWD

หากคุณได้รับคำเตือนแบบเดียวกันกับที่ @HendraWD พูดถึงในความคิดเห็นด้านบนให้ดูที่คำตอบของคำถามนี้: stackoverflow.com/questions/46135249/ …
Nicolás Carrasco

1
แทนการกลับมาจริงและดังนั้นจึงปิดการใช้งานทุกประเภทของกิจกรรมสัมผัสเพียงreturn e.getAction() == MotionEvent.ACTION_MOVE;แทนreturn true;เท่านั้นดังนั้นเลื่อน / เหตุการณ์รูดได้รับการยกเลิก
Toufic Batache

15

คุณสามารถปิดการใช้งานการเลื่อนโดยการตรึง RecyclerView ของคุณ

ในการตรึง: recyclerView.setLayoutFrozen(true)

หากต้องการยกเลิกการตรึง: recyclerView.setLayoutFrozen(false)


1
รับทราบ: มุมมองเด็กไม่ได้รับการปรับปรุงเมื่อ RecyclerView ถูกตรึง ฉันต้องปิดการใช้งานการเลื่อนเมื่อมีที่ว่างเพียงพอบนหน้าจอเพื่อแสดงรายการทั้งหมด โอ้ ... API Android ที่ดีสำหรับงานนี้คืออะไร ...
Oleksandr Nos

1
เลิกใช้แล้วใน API 28
OhhhThatVarun

13

สร้างคลาสที่ขยายคลาสRecyclerView

public class NonScrollRecyclerView extends RecyclerView {

    public NonScrollRecyclerView(Context context) {
        super(context);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}

สิ่งนี้จะปิดการใช้งานเหตุการณ์การเลื่อน แต่ไม่ใช่การคลิกเหตุการณ์

ใช้สิ่งนี้ใน XML ของคุณทำสิ่งต่อไปนี้:

  <com.yourpackage.xyx.NonScrollRecyclerView 
     ...
     ... 
  />

ขอบคุณ! ทั้งหมดนี้เป็นสิ่งจำเป็นเมื่อเราต้องการอนุญาตให้มุมมองของนักรีไซเคิลให้มีความสูงเต็มตามเนื้อหาโดยไม่ต้องเลื่อนภายใน :)
Rahul Rastogi

แต่ถ้ามุมมองรีไซเลอร์นี้อยู่ในมุมมองการเลื่อน (เช่นScrollView) ดังนั้นตัวจัดการโครงร่างควรจะแทนที่ canScrollVertically () วิธีการคืนค่าเท็จจากมัน
ราหุล Rastogi

@RahulRastogi ใช้ NestedScrollView แทน ScrollView
Ashish

เฮ้ @AshishMangave โปรดบอกวิธีเปิดใช้งานอีกครั้งโดยทางโปรแกรม
Shruti

@Shutut เราไม่สามารถทำสิ่งนี้ได้ตามปกติ bcz เราจะแทนที่วิธี onMeasure ของ recyclerview โดยตรงคุณสามารถลองใช้ recyclerView.setNestedScrollingEnabled (false) นี้ได้ซึ่งจะช่วยคุณ
Ashish

11

หากคุณเพียงแค่ปิดการใช้งานฟังก์ชั่นเพียงเลื่อนของRecyclerViewแล้วคุณสามารถใช้วิธีการsetLayoutFrozen(true); RecyclerViewแต่มันไม่สามารถปิดการใช้งานเหตุการณ์สัมผัส

your_recyclerView.setLayoutFrozen(true);

วิธีนี้เลิกใช้แล้ว คุณช่วยแนะนำอีกอันได้ไหม
Aiyaz Parmar

เลิกใช้แล้วใน API 28
OhhhThatVarun

9
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            // Stop only scrolling.
            return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
        }
    });


วิธีนี้จะยกเลิกการเลื่อนของ smoothScrollToPosition () เมื่อแตะ
ypresto

นี่เป็นทางออกที่ดีที่สุดสำหรับฉันเพราะมันช่วยให้การเลื่อนโดยทางโปรแกรม
Miguel Sesma

7

มีคำตอบที่ง่ายจริงๆ

LinearLayoutManager lm = new LinearLayoutManager(getContext()) {
                @Override
                public boolean canScrollVertically() {
                    return false;
                }
            };

รหัสด้านบนปิดการใช้งาน RecyclerView เลื่อนแนวตั้ง



6

เขียนเวอร์ชัน kotlin:

class NoScrollLinearLayoutManager(context: Context?) : LinearLayoutManager(context) {
    private var scrollable = true

    fun enableScrolling() {
        scrollable = true
    }

    fun disableScrolling() {
        scrollable = false
    }

    override fun canScrollVertically() =
            super.canScrollVertically() && scrollable


    override fun canScrollHorizontally() =
            super.canScrollVertically()

 && scrollable
}

การใช้งาน:

recyclerView.layoutManager = NoScrollLinearLayoutManager(context)
(recyclerView.layoutManager as NoScrollLinearLayoutManager).disableScrolling()

5

ขยายLayoutManagerและแทนที่canScrollHorizontally()และcanScrollVertically()เพื่อปิดใช้งานการเลื่อน

โปรดทราบว่าการแทรกไอเท็มที่จุดเริ่มต้นจะไม่เลื่อนกลับไปที่จุดเริ่มต้นโดยอัตโนมัติเพื่อหลีกเลี่ยงสิ่งนี้:

  private void clampRecyclerViewScroll(final RecyclerView recyclerView)
  {
    recyclerView.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
    {
      @Override
      public void onItemRangeInserted(int positionStart, int itemCount)
      {
        super.onItemRangeInserted(positionStart, itemCount);
        // maintain scroll position at top
        if (positionStart == 0)
        {
          RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
          if (layoutManager instanceof GridLayoutManager)
          {
            ((GridLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }else if(layoutManager instanceof LinearLayoutManager)
          {
            ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }
        }
      }
    });
  }

1
ปิดการใช้งานนี้ยัง smoothScrollToPosition
Mladen Rakonjac

5

ฉันรู้ว่านี่มีคำตอบที่ยอมรับแล้ว แต่โซลูชันไม่ได้คำนึงถึงกรณีการใช้งานที่ฉันเจอ

ฉันต้องการรายการส่วนหัวที่ยังคงสามารถคลิกได้โดยเฉพาะ แต่ยังปิดการใช้งานกลไกการเลื่อนของ RecyclerView สามารถทำได้ด้วยรหัสต่อไปนี้:

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
                            @Override
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
         return e.getAction() == MotionEvent.ACTION_MOVE;
     }

     @Override
     public void onTouchEvent(RecyclerView rv, MotionEvent e) {

     }

     @Override
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
});

ด้วยเหตุผลบางอย่างคุณต้องคลิกขวาโดยไม่ต้องย้ายเพื่อให้ทำงานได้
Jared Burrows

จุดที่ดี @ JaredBurrows นี่เป็นเพราะเราไม่สนใจ ACTION_MOVE เพื่อสัมผัสที่เป็นธรรมชาติมีบางอย่างให้สัมผัสและการเคลื่อนไหวบนหน้าจอ น่าเสียดายที่ฉันไม่สามารถแก้ไขปัญหานี้ได้
Ryan Simon

ขอบคุณสิ่งที่ฉันต้องการ!
นักเรียน

5

ในฐานะที่setLayoutFrozenจะเลิกคุณสามารถปิดการใช้งานการเลื่อนโดยการแช่แข็ง RecyclerView suppressLayoutของคุณโดยใช้

ในการตรึง:

recyclerView.suppressLayout(true)

หากต้องการยกเลิกการตรึง:

recyclerView.suppressLayout(false)

4

ใน XML: -

คุณสามารถเพิ่ม

android:nestedScrollingEnabled="false"

ในไฟล์เด็ก XML โครงร่าง RecyclerView

หรือ

ใน Java: -

childRecyclerView.setNestedScrollingEnabled(false);

สู่ RecyclerView ของคุณในโค้ด Java

ใช้ ViewCompat (Java): -

childRecyclerView.setNestedScrollingEnabled(false);จะทำงานในandroid_version> 21อุปกรณ์เท่านั้น เพื่อทำงานในอุปกรณ์ทั้งหมดใช้ต่อไปนี้

ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);


ควรเพิ่มพลังให้กับ apis ทั้งหมด
Ricard

3

ด้วยเหตุผลบางอย่าง @Alejandro Gracia คำตอบจะเริ่มทำงานหลังจากไม่กี่วินาที ฉันพบวิธีแก้ปัญหาที่บล็อก RecyclerView ในทันที:

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                return true;
            }
            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            }
            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
            }
        });

3

แทนที่ onTouchEvent () และ onInterceptTouchEvent () และคืนค่า false ถ้าคุณไม่ต้องการ OnItemTouchListener เลย สิ่งนี้ไม่ได้ปิดใช้งาน OnClickListeners ของ ViewHolders

public class ScrollDisabledRecyclerView extends RecyclerView {
    public ScrollDisabledRecyclerView(Context context) {
        super(context);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return false;
    }
}

3

คุณสามารถเพิ่มบรรทัดนี้หลังจากตั้งค่าอะแดปเตอร์ของคุณ

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

ตอนนี้มุมมองรีไซเคิลของคุณจะทำงานได้อย่างราบรื่น


2

ฉันได้รับการดิ้นรนในเรื่องนี้มาหลายชั่วโมงดังนั้นฉันอยากจะแบ่งปันประสบการณ์ของฉันสำหรับการแก้ปัญหา layoutManager มันก็ดี แต่ถ้าคุณต้องการเลื่อนการเปิดใช้งานเครื่องรีไซเคิลจะกลับสู่ด้านบน

ทางออกที่ดีที่สุดจนถึงตอนนี้ (สำหรับฉันอย่างน้อย) กำลังใช้ @Zsolt Safrany methode แต่เพิ่ม getter และ setter ดังนั้นคุณไม่ต้องลบหรือเพิ่ม OnItemTouchListener

ดังต่อไปนี้

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    boolean isEnable = true;

    public RecyclerViewDisabler(boolean isEnable) {
        this.isEnable = isEnable;
    }

    public boolean isEnable() {
        return isEnable;
    }

    public void setEnable(boolean enable) {
        isEnable = enable;
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return !isEnable;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {}

   @Override
   public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept){}
 }

การใช้

RecyclerViewDisabler disabler = new RecyclerViewDisabler(true);
feedsRecycler.addOnItemTouchListener(disabler);

// TO ENABLE/DISABLE JUST USE THIS
disabler.setEnable(enable);

2

ใน Kotlin ถ้าคุณไม่ต้องการสร้างคลาสพิเศษเพียงเพื่อตั้งค่าหนึ่งค่าคุณสามารถสร้างคลาสที่ไม่ระบุชื่อได้จาก LayoutManager:

recyclerView.layoutManager = object : LinearLayoutManager(context) {
    override fun canScrollVertically(): Boolean = false
}

1

นี่คือวิธีที่ฉันทำกับการผูกข้อมูล:

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipChildren="false"
                android:onTouch="@{(v,e) -> true}"/>

ในสถานที่ของ "จริง" ฉันใช้ตัวแปรบูลีนที่เปลี่ยนไปตามเงื่อนไขเพื่อให้มุมมองรีไซเคิลจะสลับระหว่างการปิดการใช้งานและเปิดใช้งาน


1

มาพร้อมกับส่วนที่มีหลาย RecycleView ดังนั้นฉันต้องการเพียงหนึ่งเลื่อนแทนการเลื่อนในแต่ละ RecycleView

ดังนั้นฉันแค่ใส่ ScrollView ลงในคอนเทนเนอร์หลักที่มี 2 RecycleViews และใช้android:isScrollContainer="false"ใน RecycleView

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"
    android:isScrollContainer="false" />


1

มีวิธีที่ตรงไปตรงมามากขึ้นในการปิดใช้งานการเลื่อน (ในทางเทคนิคมันค่อนข้างมากกว่าการสกัดกั้นเหตุการณ์การเลื่อนและสิ้นสุดเมื่อมีเงื่อนไขตรง) โดยใช้ฟังก์ชันมาตรฐานเพียงอย่างเดียว RecyclerViewมีวิธีการที่เรียกว่าaddOnScrollListener(OnScrollListener listener)และใช้เพียงแค่นี้คุณสามารถหยุดมันจากการเลื่อนเพียงเพื่อ:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (viewModel.isItemSelected) {
            recyclerView.stopScroll();
        }
    }
});

กรณีการใช้งาน: สมมติว่าคุณต้องการปิดการใช้งานการเลื่อนเมื่อคุณคลิกที่รายการใดรายการหนึ่งภายในRecyclerViewเพื่อให้คุณสามารถดำเนินการบางอย่างได้โดยไม่ต้องวอกแวกโดยการเลื่อนไปที่รายการอื่นโดยไม่ตั้งใจและเมื่อคุณทำเสร็จแล้ว รายการอีกครั้งเพื่อเปิดใช้งานการเลื่อน เพื่อที่คุณจะต้องการที่จะแนบOnClickListenerไปทุกรายการภายในRecyclerViewดังนั้นเมื่อคุณคลิกที่รายการก็จะสลับisItemSelectedจากไปfalse trueวิธีนี้เมื่อคุณพยายามที่จะเลื่อนRecyclerViewจะเรียกวิธีการโดยอัตโนมัติonScrollStateChangedและตั้งแต่isItemSelectedตั้งเป็นtrueมันจะหยุดทันทีก่อนที่จะRecyclerViewมีโอกาสดี ... เพื่อเลื่อน

หมายเหตุ: เพื่อการใช้งานที่ดีขึ้นลองใช้GestureListenerแทนOnClickListenerการป้องกันaccidentalการคลิก


stopScroll()ไม่ใช่เพื่อหยุดการเลื่อนเพียงเพื่อหยุด / หยุดการเลื่อน recyclerview
ฟาริด

@FARID ใช่วิธีนี้เพียงแค่หยุดเลื่อนใด ๆ ในความคืบหน้าและในกรณีนี้โดยเฉพาะอย่างยิ่งไม่ว่าทุกครั้งเมื่อผู้ใช้พยายามเพื่อเลื่อนเนื้อหา RecyclerView กับชุดisItemSelected trueมิฉะนั้นคุณจะต้องใช้ RecyclerView แบบกำหนดเองเพื่อปิดการเลื่อนเพื่อความดีและฉันต้องการหลีกเลี่ยงเพราะฉันต้องการฟังก์ชั่นพิเศษเพิ่มเติมซึ่งโซลูชันนี้มีให้
Tim Jorjev

0

เพียงเพิ่มลงในมุมมองรีไซเคิลของคุณเป็น xml

 android:nestedScrollingEnabled="false"

แบบนี้

<android.support.v7.widget.RecyclerView
                    android:background="#ffffff"
                    android:id="@+id/myrecycle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:nestedScrollingEnabled="false">

0

สำหรับการหยุดการเลื่อนโดยการสัมผัส แต่ให้เลื่อนผ่านคำสั่ง:

if (appTopBarMessagesRV == null) {appTopBarMessagesRV = findViewById (R.id.mainBarScrollMessagesRV);

        appTopBarMessagesRV.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

                if ( rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING)
                {
                     // Stop  scrolling by touch

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