ตรวจสอบว่า ListView ถูกเลื่อนไปที่ด้านล่างหรือไม่?


105

ฉันจะทราบได้หรือไม่ว่า ListView ของฉันถูกเลื่อนไปที่ด้านล่าง? โดยที่ฉันหมายความว่ารายการสุดท้ายสามารถมองเห็นได้อย่างสมบูรณ์

คำตอบ:


171

แก้ไขแล้ว :

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

ดำเนินการOnScrollListenerตั้งค่าของคุณListView'sonScrollListenerแล้วคุณควรจะสามารถที่จะจัดการกับสิ่งที่ถูกต้อง

ตัวอย่างเช่น:

private int preLast;
// Initialization stuff.
yourListView.setOnScrollListener(this);

// ... ... ...

@Override
public void onScroll(AbsListView lw, final int firstVisibleItem,
        final int visibleItemCount, final int totalItemCount)
{

    switch(lw.getId()) 
    {
        case R.id.your_list_id:     

            // Make your calculation stuff here. You have all your
            // needed info from the parameters of this function.

            // Sample calculation to determine if the last 
            // item is fully visible.
            final int lastItem = firstVisibleItem + visibleItemCount;

            if(lastItem == totalItemCount)
            {
                if(preLast!=lastItem)
                {
                    //to avoid multiple calls for last item
                    Log.d("Last", "Last");
                    preLast = lastItem;
                }
            }
    }
}

26
ซึ่งจะตรวจไม่พบว่ารายการสุดท้ายสามารถมองเห็นได้ทั้งหมดหรือไม่
fhucho

1
หากคุณมีส่วนหัวหรือส่วนท้ายในมุมมองรายการคุณต้องคำนึงถึงสิ่งนั้นด้วย
Martin Marconcini

5
@Wroclai สิ่งนี้จะตรวจไม่พบว่ารายการสุดท้ายสามารถมองเห็นได้ทั้งหมดหรือไม่
Gaurav Arora

ฉันกำลังมองหารหัสการทำงานที่คล้ายกัน .. มันได้ผล !! ขอบคุณมาก!!
Suraj Dubey

ฉันไม่ต้องการเริ่มคำถามใหม่ แต่ฉันจะทำอย่างไรถ้าlistviewเป็นstackFromBottom? ฉันพยายามif (0 == firstVisibleItem){//listviewtop}แต่มันถูกเรียกซ้ำ
ร่มรื่นด้านใน

68

คำตอบที่ล่าช้า แต่หากคุณต้องการตรวจสอบว่า ListView ของคุณเลื่อนลงจนสุดหรือไม่โดยไม่ต้องสร้างตัวฟังเหตุการณ์คุณสามารถใช้คำสั่ง if นี้:

if (yourListView.getLastVisiblePosition() == yourListView.getAdapter().getCount() -1 &&
    yourListView.getChildAt(yourListView.getChildCount() - 1).getBottom() <= yourListView.getHeight())
{
    //It is scrolled all the way down here

}

ขั้นแรกให้ตรวจสอบว่าตำแหน่งสุดท้ายที่เป็นไปได้อยู่ในมุมมองหรือไม่ จากนั้นจะตรวจสอบว่าด้านล่างของปุ่มสุดท้ายตรงกับด้านล่างของ ListView หรือไม่ คุณสามารถทำสิ่งที่คล้ายกันเพื่อดูว่ามันอยู่ด้านบนสุดหรือไม่:

if (yourListView.getFirstVisiblePosition() == 0 &&
    yourListView.getChildAt(0).getTop() >= 0)
{
    //It is scrolled all the way up here

}

4
ขอบคุณ. แค่ต้องเปลี่ยน ... getChildAt (yourListView.getCount () -1) ... เป็น ... getChildAt (yourListView.getChildCount () -1) ...
OferR

@OferR ไม่แน่ใจ แต่ฉันคิดว่าgetChildCount()ส่งคืนมุมมองใน viewgroup ซึ่งด้วยการรีไซเคิลมุมมองไม่เหมือนกับจำนวนรายการในอะแด็ปเตอร์ อย่างไรก็ตามเนื่องจาก ListView มาจาก AdapterView คุณสามารถใช้getCount()โดยตรงบน ListView
William T. Mallard

@ William T. Mallard ประโยคแรกของคุณถูกต้องและนี่คือสิ่งที่เราต้องการ: มุมมองสุดท้ายที่แสดงในกลุ่ม นี่เป็นการตรวจสอบว่าสามารถมองเห็นได้อย่างสมบูรณ์ (พิจารณา ListView ที่มี 20 บรรทัด แต่แสดงเพียง 8 รายการสุดท้ายเราต้องการได้มุมมองที่ 8 ใน ViewGroup ไม่ใช่ครั้งที่ 20 ซึ่งไม่มีอยู่)
OferR

โปรดทราบว่าโซลูชันนี้จะไม่ทำงานหากคุณกำลังอัปเดตมุมมองรายการอย่างรวดเร็ว
กระรอก

19

วิธีที่ฉันทำ:

listView.setOnScrollListener(new AbsListView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE 
            && (listView.getLastVisiblePosition() - listView.getHeaderViewsCount() -
            listView.getFooterViewsCount()) >= (adapter.getCount() - 1)) {

        // Now your listview has hit the bottom
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }
});

1
มันเจ๋งมาก! ขอบคุณ
Shariful islam


6
public void onScrollStateChanged(AbsListView view, int scrollState)        
{
    if (!view.canScrollList(View.SCROLL_AXIS_VERTICAL) && scrollState == SCROLL_STATE_IDLE)    
    {
        //When List reaches bottom and the list isn't moving (is idle)
    }
}

สิ่งนี้ได้ผลสำหรับฉัน


1
view.canScrollList method คือ API 19+ เท่านั้นน่าเสียดาย
ozmank

ใช้งานได้เหมือนมีเสน่ห์
pavaniiitn

4

นี้สามารถ

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub

                if (scrollState == 2)
                    flag = true;
                Log.i("Scroll State", "" + scrollState);
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub
                if ((visibleItemCount == (totalItemCount - firstVisibleItem))
                        && flag) {
                    flag = false;



                    Log.i("Scroll", "Ended");
                }
            }

3

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

หมายเหตุ: ฉันต้องย้ายรหัสที่เกี่ยวข้องกับอะแดปเตอร์ของฉันไปที่ onViewCreated แทนที่จะเป็น onCreate และตรวจจับการเลื่อนเป็นหลักดังนี้:

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (getListView().getLastVisiblePosition() == (adapter.getCount() - 1))
        if (RideListSimpleCursorAdapter.REACHED_THE_END) {
            Log.v(TAG, "Loading more data");
            RideListSimpleCursorAdapter.REACHED_THE_END = false;
            Intent intent = new Intent(getActivity().getApplicationContext(), FindRideService.class);
            getActivity().getApplicationContext().startService(intent);
        }
}

ที่นี่ RideListSimpleCursorAdapter.REACHED_THE_END เป็นตัวแปรเพิ่มเติมใน SimpleCustomAdapter ของฉันซึ่งตั้งค่าดังนี้:

if (position == getCount() - 1) {
      REACHED_THE_END = true;
    } else {
      REACHED_THE_END = false;
    }

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


ฉันกำจัดสิ่งอื่นออกไปเพราะมันทำให้ฉันมีปัญหา แต่โดยรวมแล้วเป็นคำตอบที่ดี
Mike Baglio Jr.

3

canScrollVertically(int direction)ใช้ได้กับทุก Views และดูเหมือนว่าจะทำตามที่คุณถามโดยมีโค้ดน้อยกว่าคำตอบอื่น ๆ เกือบทั้งหมด เสียบจำนวนบวกและหากผลลัพธ์เป็นเท็จแสดงว่าคุณอยู่ที่ด้านล่างสุด

กล่าวคือ:

if (!yourView.canScrollVertically(1)) { //you've reached bottom }


2

เพื่อขยายความเกี่ยวกับหนึ่งในคำตอบข้างต้นนี่คือสิ่งที่ฉันต้องทำเพื่อให้มันทำงานได้อย่างสมบูรณ์ ดูเหมือนว่าจะมีช่องว่างภายในภายในของ ListViews ประมาณ 6dp และ onScroll () ถูกเรียกเมื่อรายการว่างเปล่า สิ่งนี้จัดการทั้งสองสิ่งนั้น อาจได้รับการปรับให้เหมาะสมเล็กน้อย แต่เขียนเพิ่มเติมเพื่อความชัดเจน

หมายเหตุด้านข้าง: ฉันได้ลองใช้เทคนิคการแปลง dp เป็นพิกเซลหลายแบบและ dp2px () นี้ดีที่สุด

myListView.setOnScrollListener(new OnScrollListener() {
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (visibleItemCount > 0) {
            boolean atStart = true;
            boolean atEnd = true;

            View firstView = view.getChildAt(0);
            if ((firstVisibleItem > 0) ||
                    ((firstVisibleItem == 0) && (firstView.getTop() < (dp2px(6) - 1)))) {
                // not at start
                atStart = false;
            }

            int lastVisibleItem = firstVisibleItem + visibleItemCount;
            View lastView = view.getChildAt(visibleItemCount - 1);
            if ((lastVisibleItem < totalItemCount) ||
                    ((lastVisibleItem == totalItemCount) &&
                            ((view.getHeight() - (dp2px(6) - 1)) < lastView.getBottom()))
                    ) {
                        // not at end
                    atEnd = false;
                }

            // now use atStart and atEnd to do whatever you need to do
            // ...
        }
    }
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
});

private int dp2px(int dp) {
    return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}

2

ฉันยังไม่สามารถแสดงความคิดเห็นได้เพราะฉันมีชื่อเสียงไม่เพียงพอ แต่ในคำตอบของ @Ali Imran และ @Wroclai ฉันคิดว่ามีบางอย่างขาดหายไป ด้วยรหัสชิ้นนั้นเมื่อคุณอัปเดต preLast แล้วจะไม่เรียกใช้งานบันทึกอีก ในปัญหาเฉพาะของฉันฉันต้องการดำเนินการบางอย่างทุกครั้งที่เลื่อนไปด้านล่าง แต่เมื่ออัปเดต preLast เป็น LastItem แล้วการดำเนินการนั้นจะไม่ถูกดำเนินการอีก

private int preLast;
// Initialization stuff.
yourListView.setOnScrollListener(this);

// ... ... ...

@Override
public void onScroll(AbsListView lw, final int firstVisibleItem,
                 final int visibleItemCount, final int totalItemCount) {

switch(lw.getId()) {
    case android.R.id.list:     

        // Make your calculation stuff here. You have all your
        // needed info from the parameters of this function.

        // Sample calculation to determine if the last 
        // item is fully visible.
         final int lastItem = firstVisibleItem + visibleItemCount;
       if(lastItem == totalItemCount) {
          if(preLast!=lastItem){ //to avoid multiple calls for last item
            Log.d("Last", "Last");
            preLast = lastItem;
          }
       } else {
            preLast = lastItem;
}

}

ด้วยคำว่า "else" ตอนนี้คุณสามารถรันโค้ดของคุณได้แล้ว (Log ในกรณีนี้) ทุกครั้งที่คุณเลื่อนลงไปด้านล่าง


2
public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        int lastindex = view.getLastVisiblePosition() + 1;

        if (lastindex == totalItemCount) { //showing last row
            if ((view.getChildAt(visibleItemCount - 1)).getTop() == view.getHeight()) {
                //Last row fully visible
            }
        }
    }

1

สำหรับรายชื่อของคุณไปยังสายเมื่อเข้าถึงรายการสุดท้ายและหากมีข้อผิดพลาดเกิดขึ้นแล้วนี้จะไม่เรียก endoflistview อีกครั้ง รหัสนี้จะช่วยสถานการณ์นี้เช่นกัน

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    final int lastPosition = firstVisibleItem + visibleItemCount;
    if (lastPosition == totalItemCount) {
        if (previousLastPosition != lastPosition) { 

            //APPLY YOUR LOGIC HERE
        }
        previousLastPosition = lastPosition;
    }
    else if(lastPosition < previousLastPosition - LIST_UP_THRESHOLD_VALUE){
        resetLastIndex();
    }
}

public void resetLastIndex(){
    previousLastPosition = 0;
}

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


1

ฉันพบวิธีที่ดีมากในการโหลดชุดหน้าถัดไปโดยอัตโนมัติในแบบที่ไม่ต้องใช้ของคุณเองScrollView(เช่นคำตอบที่ยอมรับต้องการ)

ในParseQueryAdapterมีวิธีการที่เรียกgetNextPageViewว่าเพื่อให้คุณสามารถจัดหามุมมองที่กำหนดเองของคุณเองซึ่งจะปรากฏที่ส่วนท้ายของรายการเมื่อมีข้อมูลให้โหลดมากขึ้นดังนั้นมันจะทริกเกอร์เมื่อคุณถึงจุดสิ้นสุดของชุดหน้าปัจจุบันของคุณเท่านั้น (เป็นมุมมอง "โหลดเพิ่มเติม .. " ตามค่าเริ่มต้น) วิธีนี้จะเรียกเฉพาะเมื่อมีข้อมูลให้โหลดมากขึ้นดังนั้นจึงเป็นสถานที่ที่ดีในการเรียกloadNextPage(); วิธีนี้อะแดปเตอร์จะทำงานหนักทั้งหมดให้คุณในการกำหนดเวลาที่ควรโหลดข้อมูลใหม่และจะไม่ถูกเรียกเลยหากคุณมี ถึงจุดสิ้นสุดของชุดข้อมูล

public class YourAdapter extends ParseQueryAdapter<ParseObject> {

..

@Override
public View getNextPageView(View v, ViewGroup parent) {
   loadNextPage();
   return super.getNextPageView(v, parent);
  }

}

จากนั้นภายในกิจกรรม / ส่วนของคุณคุณต้องตั้งค่าอะแดปเตอร์และข้อมูลใหม่จะได้รับการอัปเดตโดยอัตโนมัติสำหรับคุณเหมือนเวทมนตร์

adapter = new YourAdapter(getActivity().getApplicationContext());
adapter.setObjectsPerPage(15);
adapter.setPaginationEnabled(true);
yourList.setAdapter(adapter);

1

ในการตรวจสอบว่ารายการสุดท้ายสามารถมองเห็นได้อย่างสมบูรณ์หรือไม่คุณสามารถเพิ่มการคำนวณที่ด้านล่างของรายการที่มองเห็นได้ล่าสุดโดยlastItem.getBottom()ง่าย

yourListView.setOnScrollListener(this);   

@Override
public void onScroll(AbsListView view, final int firstVisibleItem,
                 final int visibleItemCount, final int totalItemCount) {

    int vH = view.getHeight();
    int topPos = view.getChildAt(0).getTop();
    int bottomPos = view.getChildAt(visibleItemCount - 1).getBottom();

    switch(view.getId()) {
        case R.id.your_list_view_id:
            if(firstVisibleItem == 0 && topPos == 0) {
                //TODO things to do when the list view scroll to the top
            }

            if(firstVisibleItem + visibleItemCount == totalItemCount 
                && vH >= bottomPos) {
                //TODO things to do when the list view scroll to the bottom
            }
            break;
    }
}

1

ฉันไปกับ:

@Override
public void onScroll(AbsListView listView, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
    if(totalItemCount - 1 == favoriteContactsListView.getLastVisiblePosition())
    {
        int pos = totalItemCount - favoriteContactsListView.getFirstVisiblePosition() - 1;
        View last_item = favoriteContactsListView.getChildAt(pos);

        //do stuff
    }
}

1

ในวิธีการgetView()(ของBaseAdapterคลาส -derived) เราสามารถตรวจสอบว่าตำแหน่งของมุมมองปัจจุบันเท่ากับรายการของรายการในไฟล์Adapter. หากเป็นเช่นนั้นแสดงว่าเรามาถึงจุดสิ้นสุด / ด้านล่างของรายการ:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // ...

    // detect if the adapter (of the ListView/GridView) has reached the end
    if (position == getCount() - 1) {
        // ... end of list reached
    }
}

0

ฉันพบวิธีที่ดีกว่าในการตรวจจับการเลื่อนรายการมุมมองที่ด้านล่างก่อนอื่นให้ตรวจหาจุดสิ้นสุดของ scoll โดย
การใช้ onScrollListener นี้เพื่อตรวจจับจุดสิ้นสุดของการเลื่อนใน ListView

 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.currentFirstVisibleItem = firstVisibleItem;
    this.currentVisibleItemCount = visibleItemCount;
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    this.currentScrollState = scrollState;
    this.isScrollCompleted();
 }

private void isScrollCompleted() {
    if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
        /*** In this way I detect if there's been a scroll which has completed ***/
        /*** do the work! ***/
    }
}

ในที่สุดก็รวมคำตอบของ Martijn

OnScrollListener onScrollListener_listview = new OnScrollListener() {       

        private int currentScrollState;
        private int currentVisibleItemCount;

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // TODO Auto-generated method stub

            this.currentScrollState = scrollState;
            this.isScrollCompleted();
        }

        @Override
        public void onScroll(AbsListView lw, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // TODO Auto-generated method stub
            this.currentVisibleItemCount = visibleItemCount;

        }

        private void isScrollCompleted() {
            if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
                /*** In this way I detect if there's been a scroll which has completed ***/
                /*** do the work! ***/

                if (listview.getLastVisiblePosition() == listview.getAdapter().getCount() - 1
                        && listview.getChildAt(listview.getChildCount() - 1).getBottom() <= listview.getHeight()) {
                    // It is scrolled all the way down here
                    Log.d("henrytest", "hit bottom");
                }


            }
        }

    };

0

ขอบคุณมากสำหรับโปสเตอร์ใน stackoverflow! ฉันรวมแนวคิดบางอย่างและสร้างผู้ฟังในชั้นเรียนสำหรับกิจกรรมและส่วนย่อย ๆ (ดังนั้นรหัสนี้จึงสามารถนำกลับมาใช้ใหม่ได้มากขึ้นทำให้เขียนโค้ดได้เร็วขึ้นและสะอาดขึ้นมาก)

สิ่งที่คุณต้องทำเมื่อคุณมีคลาสของฉันคือการใช้อินเทอร์เฟซ (และแน่นอนว่าสร้างวิธีการสำหรับมัน) ซึ่งประกาศในคลาสของฉันและสร้างอ็อบเจ็กต์ของคลาสนี้ที่ส่งผ่านอาร์กิวเมนต์

/**
* Listener for getting call when ListView gets scrolled to bottom
*/
public class ListViewScrolledToBottomListener implements AbsListView.OnScrollListener {

ListViewScrolledToBottomCallback scrolledToBottomCallback;

private int currentFirstVisibleItem;
private int currentVisibleItemCount;
private int totalItemCount;
private int currentScrollState;

public interface ListViewScrolledToBottomCallback {
    public void onScrolledToBottom();
}

public ListViewScrolledToBottomListener(Fragment fragment, ListView listView) {
    try {
        scrolledToBottomCallback = (ListViewScrolledToBottomCallback) fragment;
        listView.setOnScrollListener(this);
    } catch (ClassCastException e) {
        throw new ClassCastException(fragment.toString()
                + " must implement ListViewScrolledToBottomCallback");
    }
}

public ListViewScrolledToBottomListener(Activity activity, ListView listView) {
    try {
        scrolledToBottomCallback = (ListViewScrolledToBottomCallback) activity;
        listView.setOnScrollListener(this);
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement ListViewScrolledToBottomCallback");
    }
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.currentFirstVisibleItem = firstVisibleItem;
    this.currentVisibleItemCount = visibleItemCount;
    this.totalItemCount = totalItemCount;
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    this.currentScrollState = scrollState;
    if (isScrollCompleted()) {
        if (isScrolledToBottom()) {
            scrolledToBottomCallback.onScrolledToBottom();
        }
    }
}

private boolean isScrollCompleted() {
    if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
        return true;
    } else {
        return false;
    }
}

private boolean isScrolledToBottom() {
    System.out.println("First:" + currentFirstVisibleItem);
    System.out.println("Current count:" + currentVisibleItemCount);
    System.out.println("Total count:" + totalItemCount);
    int lastItem = currentFirstVisibleItem + currentVisibleItemCount;
    if (lastItem == totalItemCount) {
        return true;
    } else {
        return false;
    }
}
}

0

คุณต้องเพิ่มทรัพยากรส่วนท้าย xml ที่ว่างเปล่าลงใน listView ของคุณและตรวจสอบว่าส่วนท้ายนี้มองเห็นได้หรือไม่

    private View listViewFooter;
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_newsfeed, container, false);

        listView = (CardListView) rootView.findViewById(R.id.newsfeed_list);
        footer = inflater.inflate(R.layout.newsfeed_listview_footer, null);
        listView.addFooterView(footer);

        return rootView;
    }

จากนั้นใน listView scroll ฟังคุณทำสิ่งนี้

@
Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  if (firstVisibleItem == 0) {
    mSwipyRefreshLayout.setDirection(SwipyRefreshLayoutDirection.TOP);
    mSwipyRefreshLayout.setEnabled(true);
  } else if (firstVisibleItem + visibleItemCount == totalItemCount) //If last row is visible. In this case, the last row is the footer.
  {
    if (footer != null) //footer is a variable referencing the footer view of the ListView. You need to initialize this onCreate
    {
      if (listView.getHeight() == footer.getBottom()) { //Check if the whole footer is visible.
        mSwipyRefreshLayout.setDirection(SwipyRefreshLayoutDirection.BOTTOM);
        mSwipyRefreshLayout.setEnabled(true);
      }
    }
  } else
    mSwipyRefreshLayout.setEnabled(false);
}


0

หากคุณตั้งค่าแท็กในมุมมองของรายการสุดท้ายของ listview คุณสามารถดึงข้อมูลมุมมองด้วยแท็กได้ในภายหลังหากมุมมองเป็นโมฆะนั่นเป็นเพราะมุมมองไม่ได้โหลดอีกต่อไป แบบนี้:

private class YourAdapter extends CursorAdapter {
    public void bindView(View view, Context context, Cursor cursor) {

         if (cursor.isLast()) {
            viewInYourList.setTag("last");
         }
         else{
            viewInYourList.setTag("notLast");
         }

    }
}

ถ้าคุณต้องการทราบว่ามีการโหลดรายการสุดท้ายหรือไม่

View last = yourListView.findViewWithTag("last");
if (last != null) {               
   // do what you want to do
}

0

Janwilx72 ถูกต้อง แต่ min sdk คือ 21 ดังนั้นฉันจึงสร้างวิธีนี้:

private boolean canScrollList(@ScrollOrientation int direction, AbsListView listView) {
    final int childCount = listView.getChildCount();
    if (childCount == 0) {
        return false;
    }

    final int firstPos = listView.getFirstVisiblePosition();
    final int paddingBottom = listView.getListPaddingBottom();
    final int paddingTop = listView.getListPaddingTop();
    if (direction > 0) {
        final int lastBottom = listView.getChildAt(childCount - 1).getBottom();
        final int lastPos    = firstPos + childCount;
        return lastPos < listView.getChildCount() || lastBottom > listView.getHeight() - paddingBottom;
    } else {
        final int firstTop = listView.getChildAt(0).getTop();
        return firstPos > 0 || firstTop < paddingTop;
    }
}

สำหรับ ScrollOrientation:

protected static final int SCROLL_UP = -1;
protected static final int SCROLL_DOWN = 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({SCROLL_UP, SCROLL_DOWN})
protected @interface Scroll_Orientation{}

อาจจะสายไปสำหรับผู้มาสายเท่านั้น。


0

หากคุณใช้อะแดปเตอร์แบบกำหนดเองกับมุมมองรายการของคุณ (คนส่วนใหญ่ทำ!) โซลูชันที่สวยงามจะได้รับที่นี่!

https://stackoverflow.com/a/55350409/1845404

เมธอด getView ของอะแด็ปเตอร์จะตรวจจับเมื่อรายการถูกเลื่อนไปยังรายการสุดท้าย นอกจากนี้ยังเพิ่มการแก้ไขสำหรับช่วงเวลาที่หายากเมื่อมีการเรียกตำแหน่งก่อนหน้านี้แม้ว่าอะแด็ปเตอร์จะแสดงผลมุมมองสุดท้ายแล้วก็ตาม


0

ฉันทำอย่างนั้นและทำงานให้ฉัน:

private void YourListView_Scrolled(object sender, ScrolledEventArgs e)
        {
                double itemheight = YourListView.RowHeight;
                double fullHeight = YourListView.Count * itemheight;
                double ViewHeight = YourListView.Height;

                if ((fullHeight - e.ScrollY) < ViewHeight )
                {
                    DisplayAlert("Reached", "We got to the end", "OK");
                }
}

-5

เพื่อเลื่อนลงไปที่รายการสุดท้าย

ListView listView = new ListView(this);
listView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView.setStackFromBottom(true);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.