我有两个片段,每个片段都包含一个列表视图。左侧片段中的列表视图附加了一个很长的标题视图。右侧的片段列表视图具有不同高度的列表元素(通常只有一个元素可以长于显示的高度)。保证右片段的列表视图总是比左片段列表视图的长度(以像素为单位)短得多。
我想做的是,如果我触摸并拖动/甩动左侧,右侧在与拖动/甩动操作相同的方向上移动大致相同的距离。如果右片段的列表视图到达列表的末尾(或开头),它应该停留在那里。如果我操作正确的列表视图,它应该像往常一样工作。
根据 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() 时崩溃。