web-dev-qa-db-ja.com

onScrollは、listView.onScrollListener(this)を設定したときに呼び出されますが、タッチしません

onScrollListenerListViewを設定すると、onScrollが呼び出されます。特定のものが初期化されていないため、これによりクラッシュが発生します。

これは正常ですか?注:これは私が電話に触れなくても起きています。

public class MainActivity1 extends Activity implements OnClickListener, OnScrollListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout1);

    ListView lv = (ListView)findViewById(R.id.listview1);
    lv.setOnScrollListener(this);
    ...
}
...
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount){
    if( firstVisibleItem+visibleItemCount == totalItemCount ){
        pullContactList();
    }
}
33
Siavash

setOnScrollListenerAbsListViewのソースコード(ListViewのスーパークラス)がこれを行うので、これは正常です。

 public void setOnScrollListener(OnScrollListener l) {
        mOnScrollListener = l;
        invokeOnItemScrollListener();
    }

invokeOnItemScrollListenerはこれを行います:

/**
     * Notify our scroll listener (if there is one) of a change in scroll state
*/
    void invokeOnItemScrollListener() {
        if (mFastScroller != null) {
            mFastScroller.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
        }
        if (mOnScrollListener != null) {
            mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
        }
        onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
    }

何をしようとしているかに応じて、この問題を回避する方法はいくつかあります。

編集:

ユーザーが実際にスクロールした場合にのみこれを実行したいので、次のようなことができると思います。

    lv.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    if(view == lv && motionEvent.getAction() == MotionEvent.ACTION_SCROLL) {
                      userScrolled = true;
    }
return false;
                }
            });

それから.

lv.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount){
        if(userScrolled && firstVisibleItem+visibleItemCount == totalItemCount ){
            pullContactList();
        }
    }

});
23
LuxuryMode

のjavadocによると、単なるリマインダー

MotionEvent.ACTION_SCROLL

このアクションは常にポインターの下のウィンドウまたはビューに配信されますが、現在タッチされているウィンドウまたはビューとは異なる場合があります。

このアクションはタッチイベントではないため、onTouchEvent(MotionEvent)ではなくonGenericMotionEvent(MotionEvent)に配信されます。

したがって、motionEvent.getAction()はSCROLLイベントを取得しません。 MOVEを確認してください

onScrollStateChangedOnScrollListenerメソッドでも同様のことができます

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
        if(scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
            userScrolled = true;
        }   
}
59
CrazyGreenHand

私はこのソリューションを使用し、それは私にとってはうまくいきます:

public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                canScroll = false;
            } else if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING ||
                    scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                canScroll = true;

            }
        }
3

私のために働いたソリューション!!!上記の答えの組み合わせで解決策を作りました!! @LuxuryModeと@CrazyGreenHandに感謝

My TouchListener: MotionEvent.ACTION_SCROLLがトリガーされなかったため、MOVEアクションを使用しました

 expandableListView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if(view == expandableListView && motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
                userScrolled = true;
            }
            return false;
        }
    });

My Scroll Listener:

  expandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {

        }

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (firstVisibleItem == 0){
                swipeRefreshLayout.setEnabled(true);
            }else {
                swipeRefreshLayout.setEnabled(false);
            }
            int lastVisibleItem = absListView.getLastVisiblePosition();
            if (userScrolled&&!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                onLoadMore();
                isLoading = true;
            }
            Log.d(TAG, "onScroll: firstVisibleItem=>"+firstVisibleItem+"==>visibleItemCount=>"+visibleItemCount+"==>totalItemCount==>"+totalItemCount+"==>lastVisibleItem==>"+lastVisibleItem);
        }
    });
0
prasanthMurugan

VisibleItemCount> 0の場合にのみ、必要なタスクを実行できます。

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount){
    if (visibleItemCount > 0 ){
        //perform the task to be done
    }
}
0
Varun Bhatia