gpt4 book ai didi

android - 多个viewpager的滚动效果

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:23:30 25 4
gpt4 key购买 nike

我有一个 View 的概念。请指导我如何实现它。请检查线框。 enter image description here

我已经看过 FadingActionBar,但它似乎没有帮助。问题是我在屏幕上有多个 viewpager,我不会去任何地方试图达到预期的结果。如果我能够实现很酷的过渡/视差效果,那将是非常棒的。

任何输入将不胜感激。

编辑1:

选项卡放在 PagerTabStrip 上,并与其下方的 Viewpager 相连。此处的尝试是 ScrollView 并将 PagerTabStrip 停靠到 ActionBar,然后向下滚动将其向下显示以显示 ImageViewPager。

最佳答案

所以,这可以很容易地实现,但它需要一些小技巧,实际上更像是一种幻觉。此外,我将使用 ListView 而不是 ScrollView 作为我的“可滚动内容”,主要是因为在这种情况下和我的选项卡更容易使用我将使用 this open sourced library.

首先,您需要一个可以存储给定索引的 y 坐标的 View。此自定义 View 将放置在底部 ViewPager 的顶部,并显示为每个 ListView 的“真实”标题。您需要记住 ViewPager 中每个页面的标题的 y 坐标,以便稍后当用户在它们之间滑动时恢复它们。稍后我将对此进行扩展,但目前 View 应该是这样的:

协调 header

public class CoordinatedHeader extends FrameLayout {

/** The float array used to store each y-coordinate */
private final float[] mCoordinates = new float[5];

/** True if the header is currently animating, false otherwise */
public boolean mAnimating;

/**
* Constructor for <code>CoordinatedHeader</code>
*
* @param context The {@link Context} to use
* @param attrs The attributes of the XML tag that is inflating the view
*/
public CoordinatedHeader(Context context, AttributeSet attrs) {
super(context, attrs);
}

/**
* Animates the header to the stored y-coordinate at the given index
*
* @param index The index used to retrieve the stored y-coordinate
* @param duration Sets the duration for the underlying {@link Animator}
*/
public void restoreCoordinate(int index, int duration) {
// Find the stored value for the index
final float y = mCoordinates[index];
// Animate the header to the y-coordinate
animate().y(y).setDuration(duration).setListener(mAnimatorListener).start();
}

/**
* Saves the given y-coordinate at the specified index, the animates the
* header to the requested value
*
* @param index The index used to store the given y-coordinate
* @param y The y-coordinate to save
*/
public void storeCoordinate(int index, float y) {
if (mAnimating) {
// Don't store any coordinates while the header is animating
return;
}
// Save the current y-coordinate
mCoordinates[index] = y;
// Animate the header to the y-coordinate
restoreCoordinate(index, 0);
}

private final AnimatorListener mAnimatorListener = new AnimatorListener() {

/**
* {@inheritDoc}
*/
@Override
public void onAnimationCancel(Animator animation) {
mAnimating = false;
}

/**
* {@inheritDoc}
*/
@Override
public void onAnimationEnd(Animator animation) {
mAnimating = false;
}

/**
* {@inheritDoc}
*/
@Override
public void onAnimationRepeat(Animator animation) {
mAnimating = true;
}

/**
* {@inheritDoc}
*/
@Override
public void onAnimationStart(Animator animation) {
mAnimating = true;
}
};

}

现在您可以为您的ActivityFragment 创建主布局。布局包含底部的 ViewPagerCoordinatedHeader;它由底部的 ViewPager 和选项卡组成。

主要布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v4.view.ViewPager
android:id="@+id/activity_home_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<org.seeingpixels.example.widget.CoordinatedHeader
android:id="@+id/activity_home_header"
android:layout_width="match_parent"
android:layout_height="250dp" >

<android.support.v4.view.ViewPager
android:id="@+id/activity_home_header_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<com.astuetz.viewpager.extensions.PagerSlidingTabStrip
android:id="@+id/activity_home_tabstrip"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom"
android:background="@android:color/white" />
</org.seeingpixels.example.widget.CoordinatedHeader>

</FrameLayout>

您唯一需要的其他布局是“假”标题。此布局将添加到每个 ListView,给人以主布局中的 CoordinatedHeader 是真实布局的错觉。

注意 此布局的高度与主布局中的 CoordinatedHeader 相同很重要,对于此示例,我使用的是 250dp

假 header

<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="250dp" />

现在您需要准备每个将显示在底部 ViewPager 中的 Fragment,通过附加一个 AbsListView 来控制 CoordinatedHeader .OnScrollListener 到您的 ListView。此 Fragment 还应在使用 Fragment.setArguments 创建时传递唯一索引。此索引应表示其在 ViewPager 中的位置。

注意 我在这个例子中使用了一个ListFragment

可滚动内容 fragment

/**
* {@inheritDoc}
*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final Activity a = getActivity();

final ListView list = getListView();
// Add the fake header
list.addHeaderView(LayoutInflater.from(a).inflate(R.layout.view_fake_header, list, false));

// Retrieve the index used to save the y-coordinate for this Fragment
final int index = getArguments().getInt("index");

// Find the CoordinatedHeader and tab strip (or anchor point) from the main Activity layout
final CoordinatedHeader header = (CoordinatedHeader) a.findViewById(R.id.activity_home_header);
final View anchor = a.findViewById(R.id.activity_home_tabstrip);

// Attach a custom OnScrollListener used to control the CoordinatedHeader
list.setOnScrollListener(new OnScrollListener() {

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {

// Determine the maximum allowed scroll height
final int maxScrollHeight = header.getHeight() - anchor.getHeight();

// If the first item has scrolled off screen, anchor the header
if (firstVisibleItem != 0) {
header.storeCoordinate(index, -maxScrollHeight);
return;
}

final View firstChild = view.getChildAt(firstVisibleItem);
if (firstChild == null) {
return;
}

// Determine the offset to scroll the header
final float offset = Math.min(-firstChild.getY(), maxScrollHeight);
header.storeCoordinate(index, -offset);
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Nothing to do
}

});
}

最后,您需要设置 Coordinated header ,以便在用户使用 ViewPager.OnPageChangeListener 在页面之间滑动时恢复其 y 坐标。

注意 当将您的 PagerAdapter 附加到您的底部 ViewPager 时,调用 ViewPager.setOffscreenPageLimit 并设置是很重要的这相当于您的 PagerAdapter 中的页面总数。这样 CoordinatedHeader 就可以立即存储每个 Fragment 的 y 坐标,否则您会遇到不同步的麻烦。

主要 Activity

/**
* {@inheritDoc}
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);

// Setup the top PagerAdapter
final PagerAdapter topAdapter = new PagerAdapter(getFragmentManager());
topAdapter.buildData(DummyColorFragment.newInstance(Color.RED));
topAdapter.buildData(DummyColorFragment.newInstance(Color.WHITE));
topAdapter.buildData(DummyColorFragment.newInstance(Color.BLUE));

// Setup the top pager
final ViewPager topPager = (ViewPager) findViewById(R.id.activity_home_header_pager);
topPager.setAdapter(topAdapter);

// Setup the bottom PagerAdapter
final PagerAdapter bottomAdapter = new PagerAdapter(getFragmentManager());
bottomAdapter.buildData(DummyListFragment.newInstance(0));
bottomAdapter.buildData(DummyListFragment.newInstance(1));
bottomAdapter.buildData(DummyListFragment.newInstance(2));
bottomAdapter.buildData(DummyListFragment.newInstance(3));
bottomAdapter.buildData(DummyListFragment.newInstance(4));

// Setup the bottom pager
final ViewPager bottomPager = (ViewPager) findViewById(R.id.activity_home_pager);
bottomPager.setOffscreenPageLimit(bottomAdapter.getCount());
bottomPager.setAdapter(bottomAdapter);

// Setup the CoordinatedHeader and tab strip
final CoordinatedHeader header = (CoordinatedHeader) findViewById(R.id.activity_home_header);
final PagerSlidingTabStrip psts = (PagerSlidingTabStrip) findViewById(R.id.activity_home_tabstrip);
psts.setViewPager(bottomPager);
psts.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageScrollStateChanged(int state) {
if (state != ViewPager.SCROLL_STATE_IDLE) {
// Wait until the pager is idle to animate the header
return;
}
header.restoreCoordinate(bottomPager.getCurrentItem(), 250);
}
});
}

关于android - 多个viewpager的滚动效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21445296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com