Синхронизировать весь 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);