我有一個ViewPager
的片段,其中包含GridViews
。我想保存當前的滾動位置和偏移量GridView
,並在滑動尋呼機時將這些參數賦予出現的GridView。我這樣做:立即滾動GridView到給定的偏移量
- 在GridView的
onScroll
事件我只保存這個參數值的活動。 - 當頁面將要改變時(
onPageScrollStateChanged
:state == SCROLL_STATE_DRAGGING
)我將保存的位置和偏移量傳遞給相鄰的片段,這些片段將給定值應用於GridViews
。
Activity類
public class JournalActivity extends FragmentActivity implements JournalMarksFragment.OnMarksGridScrolledListener {
private ListView mGroupList;
private ViewPager mPager;
private JournalPagerAdapter mPagerAdapter;
private int mFragmentGridPosition;
private int mFragmentGridOffset;
private int mCurFragmentIndex;
public ListView getGroupList() {
return mGroupList;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_journal);
mGroupList = (ListView)findViewById(R.id.group_list_view);
mGroupList.setAdapter(new ArrayAdapter<String>(
this,
R.layout.journal_student_item,
new String[]{"Item 1","Item 2","Item 3","Item 4",
"Item 5","Item 6","Item 7","Item 8",
"Item 9","Item 10","Item 11","Item 12",
"Item 13","Item 14","Item 15","Item 16",
"Item 17","Item 18","Item 19","Item 20",
}));
mPager = (ViewPager)findViewById(R.id.journal_pager);
mPagerAdapter = new JournalPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(mPagerAdapter.getCount() - 1);
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
if(state == ViewPager.SCROLL_STATE_DRAGGING) {
List<Fragment> frags = getSupportFragmentManager().getFragments();
for (Fragment frag : frags) {
if (frag instanceof JournalMarksFragment) {
JournalMarksFragment fragment = (JournalMarksFragment) frag;
if(fragment.getIndex() != mPager.getCurrentItem()) {
fragment.setMarksGridScrolling(mFragmentGridPosition, mFragmentGridOffset);
}
}
}
}
}
});
}
@Override
public void onMarksGridScrolled(int scrolledPosition, int offset) {
mFragmentGridPosition = scrolledPosition;
mFragmentGridOffset = offset;
}
}
片段類
public class JournalMarksFragment extends Fragment implements AbsListView.OnScrollListener {
public static final String ARG_INDEX = "index";
private OnMarksGridScrolledListener mGridScrollListener;
private GridView mHeaderGrid;
private GridView mMarksGrid;
private ListView mLinkedGroupList;
private int mIndex;
private int mPrevGridScrollingState;
public JournalMarksFragment() {
super();
}
public int getIndex() {
return mIndex;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mGridScrollListener = (OnMarksGridScrolledListener) activity;
mLinkedGroupList = ((JournalActivity) activity).getGroupList();
}
@Override
public void onDetach() {
super.onDetach();
mGridScrollListener = null;
mLinkedGroupList = null;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mIndex = getArguments().getInt(ARG_INDEX);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_journal, container, false);
mHeaderGrid = (GridView)v.findViewById(R.id.journal_header_view);
mMarksGrid = (GridView)v.findViewById(R.id.journal_marks_view);
String[] headerData = new String[]{"Section 1", "Section2", "Section 3", "Section 4", "Section 5", "Section 6"};
String[] marksData = new String[120];
Random rand = new Random(System.currentTimeMillis());
for (int i = 0; i < marksData.length; i++) {
marksData[i] = String.valueOf(rand.nextInt(5));
}
mHeaderGrid.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.journal_mark_item, headerData));
mMarksGrid.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.journal_mark_item, marksData));
mMarksGrid.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mLinkedGroupList.dispatchTouchEvent(motionEvent);
return false;
}
});
mMarksGrid.setOnScrollListener(this);
return v;
}
//here is the problem
public void setMarksGridScrolling(int position, int offset) {
/*mMarksGrid.setSelection(position);
mMarksGrid.smoothScrollByOffset(-offset);*/
mMarksGrid.smoothScrollToPositionFromTop(position, -offset);
}
private int calculateGridOffset(GridView grid) {
int offset = (int)getActivity().getResources().getDisplayMetrics().density;
final View first = grid.getChildAt(0);
if (first != null) {
offset -= first.getTop() + 1;
}
return offset;
}
@Override
public void onScrollStateChanged(AbsListView absListView, int state) {}
@Override
public void onScroll(AbsListView absListView, int i, int i2, int i3) {
if (mGridScrollListener != null) {
int position = mMarksGrid.getFirstVisiblePosition();
int offset = calculateGridOffset(mMarksGrid);
mGridScrollListener.onMarksGridScrolled(position, offset);
}
}
public interface OnMarksGridScrolledListener {
public void onMarksGridScrolled(int scrolledPosition, int offset);
}
}
尋呼機適配器
public class JournalPagerAdapter extends FragmentStatePagerAdapter {
public JournalPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
JournalMarksFragment fragment = new JournalMarksFragment();
Bundle args = new Bundle();
args.putInt(JournalMarksFragment.ARG_INDEX, i);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return 20;
}
}
其實我的這個東西的實現在大多數情況下工作正常 - 我滾動GridView
然後滑動頁面並獲得相同的滾動位置和偏移相鄰GridView
。但是當我滾動我的GridView
到非常低的FIRST然後滑動頁面時,我得到應用滾動偏移的怪異行爲:出現的GridView
在每次新的滑動時都獲得非常隨機的滾動偏移。只有5-6次刷卡後GridView
才能得到正確的值。
我不確定,但我想這是我之前使用的GridView方法smoothScrollToPositionFromTop(position, offset, duration)
的問題,因爲setSelection(position)
方法正常工作 - 使用是我總是讓我的GridView滾動到正確的位置。我需要的是完成滾動到剩餘的偏移量。我嘗試使用smoothScrollByOffset(offset)
,但它不想正常工作。另外,我不需要平滑滾動。那麼,是否有任何方式執行即時(如setSelection方法)滾動的GridView給定偏移量?
在此先感謝!
感謝分享結果 – BzH