java - Android:在 ListView 中使用 EndlessScrollListener 只是在向上滚动时继续加载数据

标签 java android endlessscroll

这是我的 EndLessScrollListener.java。有没有人遇到过这个问题,你向上滚动并且它一直滚动到列表的顶部。我正在构建一个类似于聊天消息的环聊的应用程序,其中最新消息就在底部。因此,要查看较旧的聊天消息,用户向上滚动并继续向右滚动到顶部。请帮忙。仅供引用,我在我的 listView 中使用了这两个属性: 机器人:stackFromBottom =“真” android:transcriptMode="正常"

import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;

/*
 * https://github.com/thecodepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews
 */
public abstract class EndlessScrollListener implements OnScrollListener {
    // The minimum amount of items to have below your current scroll position
    // before loading more.
    private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
private boolean reverse = false;

public EndlessScrollListener() {
}

public EndlessScrollListener(int visibleThreshold) {
    this.visibleThreshold = visibleThreshold;
}

public EndlessScrollListener(int visibleThreshold, boolean reverse) {
    this.visibleThreshold = visibleThreshold;
    this.reverse = reverse;
}

public EndlessScrollListener(int visibleThreshold, int startPage) {
    this.visibleThreshold = visibleThreshold;
    this.startingPageIndex = startPage;
    this.currentPage = startPage;
}

// This happens many times a second during a scroll, so be wary of the code you place        here.
// We are given a few useful parameters to help us work out if we need to load some more    data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int   totalItemCount) {
    // If the total item count is zero and the previous isn't, assume the
    // list is invalidated and should be reset back to initial state
    if (totalItemCount < previousTotalItemCount) {
        this.currentPage = this.startingPageIndex;
        this.previousTotalItemCount = totalItemCount;
        if (totalItemCount == 0) { this.loading = true; } 
    }

    // If it's still loading, we check to see if the dataset count has
    // changed, if so we conclude it has finished loading and update the current page
    // number and total item count.
    if (loading && (totalItemCount > previousTotalItemCount)) {
        loading = false;
        previousTotalItemCount = totalItemCount;
        currentPage++;
    }

    // If reverse then the firstVisibleItem is calculated wrong
    if (reverse) {
        firstVisibleItem = totalItemCount - firstVisibleItem;
    }
    // If it isn't currently loading, we check to see if we have breached
    // the visibleThreshold and need to reload more data.
    // If we do need to reload some more data, we execute onLoadMore to fetch the data.
    if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) {
        onLoadMore(currentPage + 1, totalItemCount);
        loading = true;
    }
}

// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    // Don't take any action on changed
}

public void reset() {
    currentPage = 0;
    previousTotalItemCount = 0;
    loading = true;
    startingPageIndex = 0;
}
}

This is my xml file.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<RelativeLayout
    android:id="@+id/sendMessageLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:minHeight="48dp" >

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/image"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="8dp" />

    <ImageView
        android:id="@+id/sendMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="4dp"
        android:background="?android:attr/selectableItemBackground"
        android:padding="8dp"
        android:src="@drawable/convo_send" />

    <EditText
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="48dp"
        android:layout_toLeftOf="@+id/sendMessage"
        android:background="@android:color/transparent"
        android:hint="New message"
        android:inputType="textMultiLine|textCapSentences"
        android:textColor="@android:color/black"
        android:textColorHint="@color/g3"
        android:textSize="@dimen/sp_17" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_alignParentTop="true"
        android:background="#DBDCDC" />
</RelativeLayout>

    <ListView
        android:id="@+id/conversation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/sendMessageLayout"
        android:cacheColorHint="@android:color/transparent"
        android:choiceMode="multipleChoice"
        android:descendantFocusability="afterDescendants"
        android:divider="@android:color/transparent"
        android:dividerHeight="3dp"
        android:paddingBottom="6dp"
        android:scrollbars="none"
        android:stackFromBottom="true"
        android:transcriptMode="normal"
        tools:listitem="@layout/conversation_text" />

</RelativeLayout>

最佳答案

我已经用这段代码解决了这个问题

    if (view.isStackFromBottom()) {
        if (!loading && firstVisibleItem == 0 ) {
            onLoadMore(currentPage + 1, totalItemCount);
            loading = true;
        }
    }

    else if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) {
        onLoadMore(currentPage + 1, totalItemCount);
        loading = true;
    }

当 onLoadMore 成功处理新数据时,我滚动到前一个第一项以防止 onScroll 被 firstVisibleItem = 0 调用

    ListItemObject firstObject = mAdapter.getItem(0);
    mAdapter.addAll(0, resultsObject);

    int index = mAdapter.indexOf(firstObject);
                    // Scroll to the previous first item position to avoid
                    // Calling onLoadMore again
     if (index != -1) {
              mMessagesListView.setSelection(index);
     }

关于java - Android:在 ListView 中使用 EndlessScrollListener 只是在向上滚动时继续加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25707803/

相关文章:

java - 仅替换未替换的字符

android - 当一个 View 以编程方式与底部对齐时,在 2 个 View 之间添加一个 View

android - 在 Android 中,如何获取套接字以连接到指定的 servlet?

java - android AlarmManager setRepating延时问题

macos - NSScrollView 并在滚动时手动设置内容偏移量

android - 带页面指示器的无尽自动 ScrollView 寻呼机

android - 实现无尽滚动(分页)后,图像未在回收站 View 中显示(加载)

java - Eclipse Java Maven 项目禁用 dafault 项目方面

java - Log4j2:向每个记录行添加特定字符串

java - 无法使用 JavaMail POP 获取 Gmail 收件箱