2014-02-19 27 views
0

我有一個ViewPager的片段,其中包含GridViews。我想保存當前的滾動位置和偏移量GridView,並在滑動尋呼機時將這些參數賦予出現的GridView。我這樣做:立即滾動GridView到給定的偏移量

  1. 在GridView的onScroll事件我只保存這個參數值的活動。
  2. 當頁面將要改變時(onPageScrollStateChangedstate == 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給定偏移量?

在此先感謝!

回答

3

幸運的是,我找到了解決方案。正如我之前所說,setSelection方法GridView是非常有用和正確的工作,所以我用它來滾動到給定的位置。然後理論上我應該調用smoothScrollToPositionFromTop,但它不能正常工作 - 在某些情況下,它只是停止在中間滾動。此處的解決方案是將此調用包裝到Runnable中,並將其傳遞到View.postDelayed(action, delay),延遲時間爲1 ms。我對這個解決方案非常滿意。 代碼:

public void setMarksGridScrolling(final int position, final int offset) { 
    mMarksGrid.setSelection(position); 
    mMarksGrid.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      mMarksGrid.smoothScrollToPositionFromTop(position, offset, 1); 
     } 
    }, 1); 
} 
+0

感謝分享結果 – BzH

相關問題