如何使一个 gridview 滚动与另一个 gridview 完全相同?
How to make a gridview scrolling exactly the same as another gridview?
要在 table 布局中显示数据并冻结第一列,其他列可以水平滚动,我使用了 2 个网格视图,如下所示 XML 文件内容:
<RelativeLayout 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"
tools:context="com.example.gridviews.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<GridView
android:id="@+id/gridViewID"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:columnWidth="50dp"
android:horizontalSpacing="1dp"
android:numColumns="1"
android:paddingTop="5dp"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<GridView
android:id="@+id/gridViewDays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="5"
android:paddingTop="5dp"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</RelativeLayout>
和我的代码:
...
BaseAdapter adapterId = new BaseAdapter() {
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
textView.setText(String.valueOf(dataList.get(position).Id));
textView.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, 70));
return textView;
}
};
BaseAdapter adapterDays = new BaseAdapter() {
@Override
public int getCount() {
return dataList.size() * 5;
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
int mod = position % 5;
int idx = position / 5;
switch (mod) {
case 0:
textView.setText(String.valueOf(dataList.get(idx).Mon));
break;
case 1:
textView.setText(String.valueOf(dataList.get(idx).Tue));
break;
case 2:
textView.setText(String.valueOf(dataList.get(idx).Wed));
break;
case 3:
textView.setText(String.valueOf(dataList.get(idx).Thu));
break;
case 4:
textView.setText(String.valueOf(dataList.get(idx).Fri));
break;
}
textView.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, 70));
return textView;
}
};
gridViewID.setAdapter(adapterId);
gridViewDays.setAdapter(adapterDays);
// Horizontal scrolling of gridViewDays
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) gridViewDays.getLayoutParams();
linearParams.width = 300;
gridViewDays.setLayoutParams(linearParams);
// Vertical scrolling...
gridViewID.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int firstVisibleItem = view.getFirstVisiblePosition();
gridViewID.setSelection(firstVisibleItem);
gridViewDays.setSelection(firstVisibleItem * 5);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
...
使用这些代码,当然当我将手移出屏幕时,gridViewDays
gridview 将与 gridViewID
具有相同的选择,如下图所示:
但是,当我用手触摸屏幕滚动 gridViewID
时,gridViewDays
将如下图所示(在 gridViewID
滚动时它不滚动)
那么,如何使 gridViewDays
gridview 垂直滚动与 gridViewID
相同?我也尝试了一些方法,例如 smoothScrollToPosition
、smoothScrollByOffset
、smoothScrollToPositionFromTop
... 在 onScroll
中,但它们不起作用
更新: 虽然下面的答案(@vrundpurohit 和我的)有效,但是,我发现该应用程序在处理大数据时性能不佳(我的意思是当数据列表有太多项目时)。
感谢@vrundpurohit 的评论,我在 S.O 中搜索了更多并找到了
@dennisdrew 的回答是
How to put GridView inside ScrollView
从那里开始,我使用@tacone 的 ExpandableHeightGridView
class
Gridview height gets cut
解决我的问题。
我修改的代码:
...
final ExpandableHeightGridView gridViewID = (ExpandableHeightGridView) findViewById(R.id.gridViewID);
final ExpandableHeightGridView gridViewDays = (ExpandableHeightGridView) findViewById(R.id.gridViewDays);
gridViewID.setExpanded(true);
gridViewDays.setExpanded(true);
...
布局文件:
<ScrollView 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"
tools:context="com.example.gridviews.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.example.gridviews.ExpandableHeightGridView
android:id="@+id/gridViewID"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:columnWidth="50dp"
android:horizontalSpacing="1dp"
android:numColumns="1"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
<HorizontalScrollView
android:id="@+id/horizontalScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.example.gridviews.ExpandableHeightGridView
android:id="@+id/gridViewDays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="5"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</ScrollView>
谢谢大家!
使用NonScrollGridView
。并将两者包装在单个 ScrollView
中
这是 NonScrollGridView
..
的代码
public class NonScrollGridView extends GridView {
public NonScrollGridView(Context context) {
super(context);
}
public NonScrollGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollGridView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
编辑:
这是您可以执行此操作的方法。
<ScrollView android:id="@+id/scroll" ... >
<NonScrollGridView />
<RelativeLayout android:id="@+id/head1" ... >
<!-- header for 1st GridView -->
</RelativeLayout>
<HorizontalScrollView ... >
<HorizontalScrollView ... >
<NonScrollGridView />
<RelativeLayout android:id="@+id/head2" ... >
<!-- header for 1st GridView -->
</RelativeLayout>
</HorizontalScrollView>
</HorizontalScrollView>
</ScrollView>
现在让两者都变得 headers 粘性.. 执行以下操作。
scroll.getViewTreeObserver().addOnScrollChangedListener(
new ViewTreeObserver.OnScrollChangedListener() {
public void onScrollChanged() {
ViewCompat.setTranslationY(head1, who.getScrollY());
ViewCompat.setTranslationY(head2, who.getScrollY());
}
});
快乐编码..
要在 table 布局中显示数据并冻结第一列,其他列可以水平滚动,我使用了 2 个网格视图,如下所示 XML 文件内容:
<RelativeLayout 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"
tools:context="com.example.gridviews.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<GridView
android:id="@+id/gridViewID"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:columnWidth="50dp"
android:horizontalSpacing="1dp"
android:numColumns="1"
android:paddingTop="5dp"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<GridView
android:id="@+id/gridViewDays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="5"
android:paddingTop="5dp"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</RelativeLayout>
和我的代码:
...
BaseAdapter adapterId = new BaseAdapter() {
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
textView.setText(String.valueOf(dataList.get(position).Id));
textView.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, 70));
return textView;
}
};
BaseAdapter adapterDays = new BaseAdapter() {
@Override
public int getCount() {
return dataList.size() * 5;
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
int mod = position % 5;
int idx = position / 5;
switch (mod) {
case 0:
textView.setText(String.valueOf(dataList.get(idx).Mon));
break;
case 1:
textView.setText(String.valueOf(dataList.get(idx).Tue));
break;
case 2:
textView.setText(String.valueOf(dataList.get(idx).Wed));
break;
case 3:
textView.setText(String.valueOf(dataList.get(idx).Thu));
break;
case 4:
textView.setText(String.valueOf(dataList.get(idx).Fri));
break;
}
textView.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, 70));
return textView;
}
};
gridViewID.setAdapter(adapterId);
gridViewDays.setAdapter(adapterDays);
// Horizontal scrolling of gridViewDays
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) gridViewDays.getLayoutParams();
linearParams.width = 300;
gridViewDays.setLayoutParams(linearParams);
// Vertical scrolling...
gridViewID.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int firstVisibleItem = view.getFirstVisiblePosition();
gridViewID.setSelection(firstVisibleItem);
gridViewDays.setSelection(firstVisibleItem * 5);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
...
使用这些代码,当然当我将手移出屏幕时,gridViewDays
gridview 将与 gridViewID
具有相同的选择,如下图所示:
但是,当我用手触摸屏幕滚动 gridViewID
时,gridViewDays
将如下图所示(在 gridViewID
滚动时它不滚动)
那么,如何使 gridViewDays
gridview 垂直滚动与 gridViewID
相同?我也尝试了一些方法,例如 smoothScrollToPosition
、smoothScrollByOffset
、smoothScrollToPositionFromTop
... 在 onScroll
中,但它们不起作用
更新: 虽然下面的答案(@vrundpurohit 和我的)有效,但是,我发现该应用程序在处理大数据时性能不佳(我的意思是当数据列表有太多项目时)。
感谢@vrundpurohit 的评论,我在 S.O 中搜索了更多并找到了 @dennisdrew 的回答是 How to put GridView inside ScrollView
从那里开始,我使用@tacone 的 ExpandableHeightGridView
class
Gridview height gets cut
解决我的问题。
我修改的代码:
...
final ExpandableHeightGridView gridViewID = (ExpandableHeightGridView) findViewById(R.id.gridViewID);
final ExpandableHeightGridView gridViewDays = (ExpandableHeightGridView) findViewById(R.id.gridViewDays);
gridViewID.setExpanded(true);
gridViewDays.setExpanded(true);
...
布局文件:
<ScrollView 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"
tools:context="com.example.gridviews.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.example.gridviews.ExpandableHeightGridView
android:id="@+id/gridViewID"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:columnWidth="50dp"
android:horizontalSpacing="1dp"
android:numColumns="1"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
<HorizontalScrollView
android:id="@+id/horizontalScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.example.gridviews.ExpandableHeightGridView
android:id="@+id/gridViewDays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="5"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</ScrollView>
谢谢大家!
使用NonScrollGridView
。并将两者包装在单个 ScrollView
这是 NonScrollGridView
..
public class NonScrollGridView extends GridView {
public NonScrollGridView(Context context) {
super(context);
}
public NonScrollGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollGridView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
编辑: 这是您可以执行此操作的方法。
<ScrollView android:id="@+id/scroll" ... >
<NonScrollGridView />
<RelativeLayout android:id="@+id/head1" ... >
<!-- header for 1st GridView -->
</RelativeLayout>
<HorizontalScrollView ... >
<HorizontalScrollView ... >
<NonScrollGridView />
<RelativeLayout android:id="@+id/head2" ... >
<!-- header for 1st GridView -->
</RelativeLayout>
</HorizontalScrollView>
</HorizontalScrollView>
</ScrollView>
现在让两者都变得 headers 粘性.. 执行以下操作。
scroll.getViewTreeObserver().addOnScrollChangedListener(
new ViewTreeObserver.OnScrollChangedListener() {
public void onScrollChanged() {
ViewCompat.setTranslationY(head1, who.getScrollY());
ViewCompat.setTranslationY(head2, who.getScrollY());
}
});
快乐编码..