Synchronize all the ListView in a ViewPager

前端 未结 3 493
情书的邮戳
情书的邮戳 2020-12-14 05:01

In my application I have a ViewPager with each one a custom ListView in it linked toghether like row in a table. The problem is that when I scroll a ListView in the first pa

相关标签:
3条回答
  • 2020-12-14 05:35

    What you are trying to do is synchronize the listviews. There is a library that already implements this for two listviews here. I will try to explain the part of the source code relevant to you which is located in the activity here.

    Suppose if you have access to all your listviews through variables:

    listViewOne = (ListView) findViewById(R.id.list_view_one);
    listViewTwo = (ListView) findViewById(R.id.list_view_two);
    listViewThree = (ListView) findViewById(R.id.list_view_three);
    listViewFour = (ListView) findViewById(R.id.list_view_four);
    

    Set the same touch listeners on them:

    listViewOne.setOnTouchListener(touchListener);
    listViewTwo.setOnTouchListener(touchListener);
    // similarly for listViewThree & listViewFour
    

    The basic idea of the touch listener is to dispatch events to the other views so that they also scroll synchronously with the listview being touched.

    // Passing the touch event to the opposite list
    OnTouchListener touchListener = new OnTouchListener() {                                        
        boolean dispatched = false;
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (v.equals(listViewOne) && !dispatched) {
                dispatched = true;
                listViewTwo.dispatchTouchEvent(event);
                listViewThree.dispatchTouchEvent(event);
                listViewFour.dispatchTouchEvent(event);
            } else if (v.equals(listViewTwo) && !dispatched) {
                dispatched = true;
                listViewOne.dispatchTouchEvent(event);
                listViewThree.dispatchTouchEvent(event);
                listViewFour.dispatchTouchEvent(event);
             } // similarly for listViewThree & listViewFour 
             dispatched = false;
             return false;
        }
    };
    

    The library also has set a scroll listener, which I believe is used because the views may be of differing heights, which you don't have. Try and let me know if this works.

    0 讨论(0)
  • 2020-12-14 05:40

    Are the listview item heights equal? if so, you could pass the position of the top visible element to the other listview adapters.

     int curTop=listview.getFirstVisiblePosition();
    
     listview2.setSelection(curTop);
    
    0 讨论(0)
  • 2020-12-14 05:41

    The problem you are having is similar to this one Update ViewPager dynamically?. It has nothing to do with setting onTouchListener because you don't have access to all ListViews inside ViewPager.

    Following is a working and tested code. Key point is getItemPosition() method in PagerAdapter.

    import java.util.ArrayList;
    import java.util.List;
    
    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.support.v4.app.ListFragment;
    import android.support.v4.view.ViewPager;
    import android.widget.AbsListView;
    import android.widget.AbsListView.OnScrollListener;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    
    public class MainActivity extends FragmentActivity implements ScrollListener {
    private MyPagerAdapter mPagerAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyPagerAdapter pagerAdapter = mPagerAdapter = new MyPagerAdapter(
                getSupportFragmentManager(), this);
        pagerAdapter.addFragmentInfo(DummyFragment.class.getName(), "First",
                new Bundle());
        pagerAdapter.addFragmentInfo(DummyFragment.class.getName(), "Second",
                new Bundle());
        pagerAdapter.addFragmentInfo(DummyFragment.class.getName(), "Third",
                new Bundle());
    
        final ViewPager pager = (ViewPager) findViewById(R.id.pager);
        pager.setOffscreenPageLimit(2);
        pager.setAdapter(pagerAdapter);
    }
    
    @Override
    public void onScrollChanged(int index) {
        mPagerAdapter.setIndex(index);
    }
    
    @Override
    public int getCurrentScrollIndex() {
        return mPagerAdapter == null ? 0 : mPagerAdapter
                .getCurrentScrollIndex();
    }
    
    public static class MyPagerAdapter extends FragmentStatePagerAdapter {
    
        public static class FragmentInfo {
    
            public FragmentInfo(String fragmentName, String title, Bundle args) {
                super();
                this.fragmentName = fragmentName;
                this.title = title;
                this.args = args;
            }
    
            String fragmentName;
            String title;
            Bundle args;
        }
    
        private List<FragmentInfo> mFragmentInfos = new ArrayList<FragmentInfo>();
        private final Context mContext;
        private int mIndex;
    
        public MyPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
    
            mContext = context;
        }
    
        @Override
        public Fragment getItem(int position) {
            FragmentInfo info = mFragmentInfos.get(position);
            Fragment fragment = Fragment.instantiate(mContext,
                    info.fragmentName, info.args);
            return fragment;
        }
    
        @Override
        public int getCount() {
            return mFragmentInfos.size();
        }
    
        @Override
        public int getItemPosition(Object object) {
            if (object instanceof ScrollRefreshable) {
                ((ScrollRefreshable) object).refreshScroll(mIndex);
            }
            return super.getItemPosition(object);
        }
    
        public void addFragmentInfo(String fragmentName, String title,
                Bundle args) {
            mFragmentInfos.add(new FragmentInfo(fragmentName, title, args));
        }
    
        public void setIndex(int index) {
            mIndex = index;
            notifyDataSetChanged();
        }
    
        public int getCurrentScrollIndex() {
            return mIndex;
        }
    }
    
    
    public static class DummyFragment extends ListFragment implements
            ScrollRefreshable {
        private ScrollListener mRefreshListener;
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            if (activity instanceof ScrollListener) {
                mRefreshListener = (ScrollListener) activity;
            }
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            String[] values = new String[] { "Android", "iPhone",
                    "WindowsMobile", "Blackberry", "WebOS", "Ubuntu",
                    "Windows7", "Max OS X", "Linux", "OS/2", "Android2",
                    "iPhone2", "WindowsMobile2", "Blackberry2", "WebOS2",
                    "Ubuntu2", "Windows72", "Max OS X2", "Linux2", "OS/22" };
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    getActivity(), android.R.layout.simple_list_item_1, values);
            setListAdapter(adapter);
            getListView().setOnScrollListener(new OnScrollListener() {
    
                @Override
                public void onScrollStateChanged(AbsListView view,
                        int scrollState) {
                    if (scrollState == SCROLL_STATE_IDLE) {
                        if (mRefreshListener != null) {
                            mRefreshListener.onScrollChanged(view
                                    .getFirstVisiblePosition());
                        }
                    }
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem,
                        int visibleItemCount, int totalItemCount) {
                }
            });
            // update scroll position at start
            if (mRefreshListener != null) {
                int index = mRefreshListener.getCurrentScrollIndex();
                scrollListViewTo(index);
            }
        }
    
        @Override
        public void refreshScroll(int index) {
            scrollListViewTo(index);
        }
    
        private void scrollListViewTo(int index) {
            ListView lv = getListView();
            if (lv != null) {
                lv.setSelection(index);
            }
        }
    }
    }
    
    interface ScrollRefreshable {
    public void refreshScroll(int index);
    }
    
    interface ScrollListener {
    public void onScrollChanged(int index);
    
    public int getCurrentScrollIndex();
    }
    
    0 讨论(0)
提交回复
热议问题