Android-如何判断ListView滚动是由手指滑动触发的还是代码触发的
巴扎黑
巴扎黑 2017-04-17 15:00:26
0
4
313

我当前有个需求是做类似于饿了么外卖App的选择商品页面的两个ListView联动的效果:

1.左边的分类ListView点击后,右边的商品ListView能滚动到指定的分类板块。
2.滑动右边的商品ListView,左边的分类ListView能切换选中标记。

我的做法是:

private boolean mIsClickTrigger;
....
mCategoryListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        int productPos = ...;
        isClickTrigger = true;
        mProductListView.setSelection(productPos);
    }
});
mProductListView.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {}

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (isClickTrigger) {
            // 消耗掉点击触发
            isClickTrigger = false;
        } else {
            int categoryPos = ...;
            mCategoryListView.setItemChecked(categoryPos, true);
        }
    }
});

isClickTrigger这个标志位的作用是:当点击左边的分类ListView的某一项时,使滚动监听里的代码不执行。只有当用手指滑动右边的商品ListView时,才执行滚动监听里的代码。

但这样有个问题,当我使用listview.setSection(10)后发现滚动很突兀,为了让它能平滑地滚动,我用了listview.smoothScrollToPosition(10),滚动是很平滑了,但是由于滚动监听被多次回调了,标志位就没效果了。

所以想请问大家有没有什么好的办法,先谢谢了!!!

巴扎黑
巴扎黑

reply all(4)
伊谢尔伦

So you should want to solve:
When the sliding of mProductListView ends, based on the flag, it is judged that the user manually slid, and the check status of the corresponding entry of mCategoryListView is changed.
Because if mCategoryListView.onItemClick() causes mProductListView to slide, there is no need to do this.

onScroll(...) will be called continuously during the scrolling process, so the flag cannot be processed. What should be done is: "How to judge that ListView scrolling has ended?" 』
onScrollStateChanged(...) parameter scrollState, which has 3 states: one of them is SCROLL_STATE_IDLE, which can be used to indicate the "scrolling end" state. So the flag should be judged in onScrollStateChanged(), not in onScroll:

listView.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        Log.d(TAG, "Scroll state " + scrollState);
        //  所以应该在这里判断标志位,而不是在onScroll中:
        if (scrollState == SCROLL_STATE_IDLE) {
            if (isClickTrigger == true) {
                isClickTrigger = false;
            } else {
                //...
                mCategoryListView.setItemChecked(categoryPos, true);
            }
        }
    }
});

But after testing more than a dozen times, a problem was discovered. In half of the tests, SCROLL_STATE_IDLE appeared once, and in the other half of the tests, it appeared twice, as shown in the log below:

11-30 14:29:16.092: D/CrimeListFragment(9638): setSelection(18)
11-30 14:29:16.095: D/CrimeListFragment(9638): onScroll: 5, 13, 18

11-30 14:29:16.819: D/CrimeListFragment(9638): smoothScrollToPosition(1)
11-30 14:29:16.824: D/CrimeListFragment(9638): onScrollStateChanged: 2
11-30 14:29:16.841: D/CrimeListFragment(9638): onScroll: 5, 13, 18
11-30 14:29:16.860: D/CrimeListFragment(9638): onScroll: 4, 14, 18
11-30 14:29:16.875: D/CrimeListFragment(9638): onScroll: 4, 13, 18
......省略若干onScroll
11-30 14:29:16.943: D/CrimeListFragment(9638): onScroll: 2, 14, 18
11-30 14:29:16.944: D/CrimeListFragment(9638): onScroll: 2, 14, 18
11-30 14:29:16.944: D/CrimeListFragment(9638): onScrollStateChanged: 0
11-30 14:29:16.944: D/CrimeListFragment(9638): onScrollStateChanged: 2
11-30 14:29:16.959: D/CrimeListFragment(9638): onScroll: 2, 13, 18
11-30 14:29:16.977: D/CrimeListFragment(9638): onScroll: 1, 14, 18
......省略若干onScroll
11-30 14:29:17.028: D/CrimeListFragment(9638): onScroll: 0, 14, 18
11-30 14:29:17.028: D/CrimeListFragment(9638): onScroll: 0, 14, 18
11-30 14:29:17.028: D/CrimeListFragment(9638): onScrollStateChanged: 0

You should first see how this works. If it doesn’t work, you still need to find a workaround to determine "ListView scrolling ends". . .

左手右手慢动作

Implement the monitoring of View.OnTouchListener on the Adapter and implement the onTouch() method.
@Override

public boolean onTouch(View v, MotionEvent event) {
    Log.i("Tag","被触摸了");
    return false;
}
Ty80

Why does the questioner have this need? Is it anti-machine script?

迷茫

If you consider this, it means you haven’t thought about the problem yet.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!