大家好,谢谢你的时间。我希望,有人能够帮助解决我的问题。我被困了。
目标: 我试图用两个ListViews进行布局,它们一起滚动(下面的代码) - 如果用户首先滚动ListView,第二个也滚动,如果用户滚动第二个ListView,首先也是滚动。与他们同步是没有问题的。这是我使用的syncer代码。
class ListScrollSyncer implements OnScrollListener, OnTouchListener {
private Set<ListView> listSet = new HashSet<ListView>();
private ListView currentTouchSource;
private int currentOffset = 0;
private int currentPosition = 0;
public void addList(ListView list) {
listSet.add(list);
list.setOnTouchListener(this);
list.setSelectionFromTop(currentPosition, currentOffset);
}
public void removeList(ListView list) {
listSet.remove(list);
}
public boolean onTouch(View view, MotionEvent event) {
ListView list = (ListView) view;
if (currentTouchSource != null) {
currentTouchSource.setOnScrollListener(null);
}
currentTouchSource = list;
currentTouchSource.setOnScrollListener(this);
return false;
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
scrollToPosition();
}
private void scrollToPosition() {
if (currentTouchSource.getChildCount() > 0) {
currentPosition = currentTouchSource.getFirstVisiblePosition();
currentOffset = currentTouchSource.getChildAt(0).getTop();
}
Iterator<ListView> it = listSet.iterator();
while (it.hasNext()) {
ListView list = it.next();
if (list == currentTouchSource) {
continue;
}
list.setSelectionFromTop(currentPosition, currentOffset);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE && currentTouchSource != null) {
scrollToPosition();
currentTouchSource.setOnScrollListener(null);
currentTouchSource = null;
}
}
}
问题: ListView之一位于HorizontalScrollView中。两个方向都可以正常工作,但是当我为此ListView调用方法setSelection()或setSelectionFromTop()时,在每个setSelection *()方法之后调用位置为0的getView(),这会导致实际的性能问题。
问题:在调用setSelection *()之后,如何避免在HorizontalScrollView中重复测量ListView?
我发现了什么
如果将ListView放在FrameLayout中,一切正常。问题仅在于它在HorizontalScrollView中。我想,reuqestLayout()可能有问题,所以我使用了HorizontalScrollView并使用了父亲的requestLayout() - HorizontalScrollView的父亲是FrameLayout,但这也没有用,我没有更多的想法,可能在哪里问题
我知道,或者至少我认为,在requestLayout之后从HorizontalScrollView请求ListView的大小存在问题,但我不知道。
为layout_width和layout_height设置的wrap_content / match_parent / fixed_size_in_dp无效。
感谢您的时间和帮助。
更新1 添加了布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- First cell -->
<FrameLayout
android:id="@+id/first_cell"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<View
android:id="@+id/first_col_divider"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_toRightOf="@id/first_cell"
/>
<View
android:id="@+id/header_divider"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="@id/first_cell"
/>
<!-- Header -->
<com.peterbucko.android.example.fixedheaderstable.SyncedHorizontalScrollView
android:id="@+id/header_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/first_col_divider"
>
<LinearLayout
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
/>
</com.peterbucko.android.example.fixedheaderstable.SyncedHorizontalScrollView>
<ListView
android:id="@+id/first_col"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/header_divider"
android:layout_alignRight="@id/first_cell"
/>
<com.peterbucko.android.example.fixedheaderstable.SyncedHorizontalScrollView
android:id="@+id/content_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/header_divider"
android:layout_toRightOf="@id/first_col_divider"
android:fillViewport="true"
>
<ListView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</com.peterbucko.android.example.fixedheaderstable.SyncedHorizontalScrollView>
</RelativeLayout>
注意:SyncedHorizontalScrollView是HorizontalScrollView,带有用于滚动的侦听器,因此我可以同步两个HorizontalScrollView的水平滚动。
更新2 我尝试使用此布局创建简约项目
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<ListView
android:id="@+id/list1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<ListView
android:id="@+id/list2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FF00ff00"
/>
</LinearLayout>
使用此布局时,两个ListView都存在问题 - 两者都在setSelection *()之后重新测量。但是布局
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="@+id/list1"
android:layout_width="100dp"
android:layout_height="match_parent"
/>
<ListView
android:id="@+id/list2"
android:layout_width="110dp"
android:layout_height="match_parent"
android:layout_marginLeft="100dp"
android:background="#FF00ff00"
/>
</FrameLayout>
没有问题,并且在需要时调用getView - 应该显示新项目。
我可以想象,有一些机制可以为每个布局视图重新测量整个布局。所以这是一个问题。布局应该如何以及哪些视图应该用于我需要的结果?可能我可以创建一个自定义的FrameLayout,它的行为类似于HorizontalScrollView,但HorizontalScrollView已经是FrameLayout的后代。