Синхронизировать весь ListView в ViewPager

В моем приложении у меня есть ViewPager с каждым из них - пользовательский ListView, связанный с ним как строка в таблице. Проблема в том, что когда я просматриваю ListView на первой странице, а затем прокручиваю ViewPager ListView первой страницы, а ListView второй страницы смещается. ListView должен быть выровнен, потому что в первом случае у меня есть TextView с описанием, а затем 4 coloumns с данными и в следующих Coloumns ListViews 6 без описания, поэтому, если они смещены, это очень сложно. Итак, как я могу прокрутить все listViews сразу?

EDIT:

Большое спасибо Рахулу Парсани... Я наконец-то справился, как это сделать... Если у вас есть listView в отдельном фрагменте, а число фрагмента undefined, это ответ:

final ArrayList<ListView> lvs = new ArrayList<ListView>();
        for (int j = 0; j < adapter.getCount(); j++) {
            YourFragment fragJ = (YourFragment) adapter.getItem(j);
            final ListView listViewJ = fragJ.lv;
            lvs.add(listViewJ);
        }

        for (int j = 0; j < lvs.size(); j++) {
            final int x = j;
            lvs.get(j).setOnTouchListener(new OnTouchListener() {

                boolean dispatched = false;
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (!dispatched) {
                        dispatched = true;
                        if (x != 0) {
                            lvs.get(x - 1).dispatchTouchEvent(event);
                        };
                        if (x != lvs.size() - 1) {
                            lvs.get(x + 1).dispatchTouchEvent(event);
                        }

                    }
                    dispatched = false;
                    return false;
                }
            });
        }

Ответ 1

То, что вы пытаетесь сделать, это синхронизировать списки. Существует библиотека, которая уже реализует это для двух списков здесь. Я попытаюсь объяснить часть исходного кода, относящуюся к вам, которая находится в действии здесь.

Предположим, что у вас есть доступ ко всем спискам с помощью переменных:

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);

Установите для них те же сенсорные прослушиватели:

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

Основная идея сенсорного прослушивателя состоит в том, чтобы отправлять события другим представлениям, чтобы они также прокручивались синхронно с касанием списка.

// 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;
    }
};

В библиотеке также установлен прослушиватель прокрутки, который, как мне кажется, используется, поскольку представления могут иметь разную высоту, чего у вас нет. Попробуйте и дайте мне знать, если это сработает.

Ответ 2

Проблема, с которой вы сталкиваетесь, похожа на эту Динамически обновлять ViewPager?. Это не имеет никакого отношения к настройке onTouchListener, потому что у вас нет доступа ко всем ListView внутри ViewPager.

Ниже приведен код рабочий и проверенный. Ключевой момент - это метод getItemPosition() в 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();
}

Ответ 3

Являются ли высоты элемента listview равными? Если это так, вы можете передать позицию верхнего видимого элемента другим адаптерам списка.

 int curTop=listview.getFirstVisiblePosition();

 listview2.setSelection(curTop);