2

これは私の EndLessScrollListener.java です。上にスクロールすると、リストの一番上までスクロールし続けるというこの問題に直面した人はいますか。チャットメッセージのハングアウトに似たアプリを構築しています。したがって、古いチャット メッセージを表示するには、ユーザーは上にスクロールし、一番上までスクロールし続けます。助けてください。参考までに、listView で次の 2 つの属性を使用しています: android:stackFromBottom="true" android:transcriptMode="normal"

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>
4

1 に答える 1

1

このコードを使用してこの問題を解決しました

    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);
     }
于 2015-01-29T13:44:30.377 に答える