6

在我的应用程序中,我有一个 ViewPager,其中每个都有一个自定义 ListView,它像表格中的行一样链接在一起。问题是,当我在第一页滚动 ListView 然后滚动 ViewPager 时,第一页的 ListView 和第二页的 ListView 未对齐。listView 必须对齐,因为在第一个中我有一个带有描述的 TextView,然后是 4 个带有数据的列,而在接下来的 ListViews 中,有 6 个没有描述的列,所以如果它们未对齐,那将非常复杂。那么我怎样才能一次滚动所有的 listViews 呢?

编辑:

非常感谢Rahul Parsani ...我终于设法做到了...如果您在单独的片段中有listView并且片段的数量未定义,这就是答案:

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

3 回答 3

5

您要做的是同步列表视图。这里有一个库已经为两个列表视图实现了这一点。我将尝试解释位于此处活动中的与您相关的源代码部分。

假设您是否可以通过变量访问所有列表视图:

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

该库还设置了一个滚动侦听器,我相信会使用它,因为视图可能具有不同的高度,而您没有。尝试让我知道这是否有效。

于 2013-11-14T04:06:45.637 回答
4

您遇到的问题类似于动态更新 ViewPager?. 它与设置无关,onTouchListener因为您无权访问所有ListViews inside 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();
}
于 2013-11-20T06:38:44.177 回答
-1

列表视图项的高度是否相等?如果是这样,您可以将顶部可见元素的位置传递给其他列表视图适配器。

 int curTop=listview.getFirstVisiblePosition();

 listview2.setSelection(curTop);
于 2013-11-18T10:28:07.917 回答