1

我有两个片段,每个片段都包含一个列表视图。左侧片段中的列表视图附加了一个很长的标题视图。右侧的片段列表视图具有不同高度的列表元素(通常只有一个元素可以长于显示的高度)。保证右片段的列表视图总是比左片段列表视图的长度(以像素为单位)短得多。

我想做的是,如果我触摸并拖动/甩动左侧,右侧在与拖动/甩动操作相同的方向上移动大致相同的距离。如果右片段的列表视图到达列表的末尾(或开头),它应该停留在那里。如果我操作正确的列表视图,它应该像往常一样工作。

根据 sabadow 的要求,这里有一些代码。首先,左片段:

public class LeftFragment extends SherlockFragment {
    private LeftFragmentListener listener;

    // The Activity must implement this interface.
    public interface LeftFragmentListener {
        public void syncScroll(int diffY);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            listener = (LeftFragmentListener)activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement LeftFragment.LeftFragmentListener");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment.
        final ListView lv = (ListView)inflater.inflate(R.layout.main_left_fragment, container, false);
        final View header = inflater.inflate(R.layout.main_left_fragment_header, null);
        lv.addHeaderView(header);

        ... calls setAdapter, etc. ...

        lv.setOnScrollListener(new OnScrollListener() {
            private int lastY;

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                View c = view.getChildAt(0);
                if (c != null)
                {
                    int currY = c.getTop();
                    int diffY = currY - lastY;

                    lastY = currY;

                    listener.syncScroll(diffY);
                }
            }

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (scrollState != SCROLL_STATE_IDLE)
                {
                    View c = view.getChildAt(0);
                    if (c != null)  lastY = c.getTop();
                }
            }
        });

        return lv;
    }
}

现在,活动:

public class MainActivity extends MySlidingActivity implements LeftFragment.LeftFragmentListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Two list views.
            setContentView(R.layout.main_two_frags);
    }

    @Override
    public void syncScroll(int diffY) {
        RightFragment f = (RightFragment)getSupportFragmentManager().findFragmentById(R.id.main_right_fragment);
        if (f != null)  f.execSyncScroll(diffY);
    }
}

现在是正确的片段:

public class RightFragment extends SherlockFragment {
    private ListView lv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment.
        lv = (ListView)inflater.inflate(R.layout.main_right_fragment, container, false);
        ... calls setAdapter, etc. ...

        return lv;
    }

    // Event sync across fragments - only used when the two views are showing.
    public void execSyncScroll(int diffY)
    {
        Log.e("setSelection", "lastY + diffY = " + (lastY + diffY));
//      lv.setSelectionFromTop(0, lastY + diffY);
//      lv.scrollBy(0, -diffY);
// Nothing I've tried works.
    }
}

上面我说“我没有尝试过任何东西”的评论是我卡住的地方。我不知道该怎么做才能让 ListView 滚动。

scrollBy() 无法正常工作。它不会将滚动绑定到滚动条,也不会显示 ListView 中的所有项目。setSelectionFromTop() 根本不做任何事情。使用 OnTouchListener 并传递 MotionEvent(而不是“int”)会导致应用程序在尝试调用 lv.dispatchTouchEvent() 时崩溃。

4

2 回答 2

2

经过更多的搜索、挠头和脑细胞,我想出了:

        lv.smoothScrollBy(-diffY, 0);

这会立即在我想要的方向上滚动差异。我仍然有一个崩溃错误,其中“lv”对象变得无效(例如将横向旋转到纵向)并且另一个列表视图的 OnScrollListener() 调用侦听器,Activity 将它传递给正确的视图,但它已经变得无效或消失了离开,所以引发了异常。但我现在可以弄清楚了。

于 2012-11-07T22:34:58.323 回答
0

这在同一个活动中对我有用,也许你可以将它应用于你的片段?

如何同步两个 Listview 位置

于 2013-04-23T12:01:07.057 回答