Android – 多个可视项目的水平滚动

编辑:看到我自己的答案,简单的解决scheme

重要提示赏金提供了清晰的方式来修改ViewPager,以满足下面描述的情况。 请不要提供Horizo​​ntalScrollView – 我需要全面的Fragment生命周期scheme

我需要实现基于Fragments的视图的水平滚动,其中一个项目位于中心,而右侧/左侧的项目部分或完全可见。 ViewPager专注于每次显示一个项目,因此ViewPager不适合执行此任务。

为了便于理解,下面是一个快速的草图,其中项目1,5和6在可视区域之外。 而且,想要使这个可视数字可configuration,例如在纵向视图中,我将只显示2(或可能只是一个)项目。

我并不是想在屏幕上显示3个项目,只要显示中央项目,其他人可以裁剪。 在小屏幕上可以有1个中央项目,并且随着屏幕长大(裁剪是OK)项目应显示

我明白,这看起来像一个画廊,但再次项目不是简单的图像,但每个片段中垂直滚动列表片段

PS通过@Commonsware发现这篇博文列出了3种不同的方法 。 为了我的需要,我喜欢#3

在这里输入图像说明

这个答案非常简单,我甚至不知道为什么不马上发布。 所有我需要做的,以获得确切的效果是重写PagerAdapter#getPageWidth方法。 默认情况下,它返回1,但是如果你设置为0.5,你将得到2页,0.33会给你3等等。根据分页器项目之间的分隔符的宽度,你可能不得不稍微减less值。

请参阅以下代码片段:

  @Override public float getPageWidth(final int position) { // this will have 3 pages in a single view return 0.32f; } 

一旦我写了类似的模板。 在我的例子中,我可以上下左右滚动button。 你可以修改一下,以满足你的要求。 在我的例子中,我有4个视图排列如下:

1 2
3 4

看起来像这样 在图片上,从视图1滚动到右边查看2:

Android视图滚动

代码由这个xml组成:

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_height="350sp" android:layout_width="320sp"> <LinearLayout android:id="@+id/viewContainer" android:background="#CCCCCC" android:layout_width="640sp" android:layout_height="700sp"> </LinearLayout> </LinearLayout> <TableLayout android:id="@+id/tableLayout" android:layout_width="320sp" android:layout_height="fill_parent" android:stretchColumns="1" android:gravity="bottom" android:layout_alignParentBottom="true"> <TableRow android:background="#333333" android:gravity="bottom"> <Button android:id="@+id/btnUp" android:layout_width="60sp" android:layout_height="50sp" android:text="Lift U" /> <Button android:layout_width="60sp" android:layout_height="50sp" android:visibility="invisible" /> <Button android:layout_width="60sp" android:layout_height="50sp" android:visibility="invisible" /> <Button android:id="@+id/btnScreenUp" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn U" /> </TableRow> <TableRow android:background="#444444" android:layout_gravity="right"> <Button android:id="@+id/btnDown" android:layout_width="60sp" android:layout_height="50sp" android:text="Lift D" /> <Button android:id="@+id/btnEnter" android:layout_width="60sp" android:layout_height="50sp" android:text="Enter" /> <Button android:id="@+id/btnScreenLeft" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn L" /> <Button android:id="@+id/btnScreenDown" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn D" /> <Button android:id="@+id/btnScreenRight" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn R" /> </TableRow> </TableLayout> </FrameLayout> 

和这个Java代码:

 import android.app.Activity; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class ViewSwitcherTest extends Activity { private TextView view1, view2, view3, view4; private Button btnUp, btnEnter, btnDown, btnScreenDown, btnScreenUp, btnScreenLeft, btnScreenRight; private LinearLayout viewContainer; // private TableLayout tableLayout; private LinearLayout.LayoutParams layoutParams; private DisplayMetrics metrics = new DisplayMetrics(); private int top = 0, left = 0; private float density = 1.0f; // private ViewSwitcher switcher; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindowManager().getDefaultDisplay().getMetrics(metrics); density = metrics.density; setContentView(R.layout.main); // Buttons btnEnter = (Button)findViewById(R.id.btnEnter); btnUp = (Button)findViewById(R.id.btnUp); btnDown = (Button)findViewById(R.id.btnDown); btnScreenDown = (Button)findViewById(R.id.btnScreenDown); btnScreenUp = (Button)findViewById(R.id.btnScreenUp); btnScreenLeft = (Button)findViewById(R.id.btnScreenLeft); btnScreenRight = (Button)findViewById(R.id.btnScreenRight); // -------- // tableLayout = (TableLayout)findViewById(R.id.tableLayout); view1 = new TextView(this); view1.setBackgroundResource(R.drawable.view1); view1.setHeight((int)(350*density)); view1.setWidth((int)(320*density)); view1.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer = (LinearLayout)findViewById(R.id.viewContainer); viewContainer.addView(view1, layoutParams); //Add 2nd view view2 = new TextView(this); view2.setBackgroundResource(R.drawable.view2); view2.setHeight((int)(350*density)); view2.setWidth((int)(320*density)); view2.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer.addView(view2, layoutParams); //Add 3rd view view3 = new TextView(this); view3.setBackgroundResource(R.drawable.view3); view3.setHeight((int)(350*density)); view3.setWidth((int)(320*density)); view3.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); top += 350*density; left += 640*density*(-1); layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer.addView(view3, layoutParams); //add 4th view view4 = new TextView(this); view4.setBackgroundResource(R.drawable.view4); view4.setHeight((int)(350*density)); view4.setWidth((int)(320*density)); view4.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); top += 0; left += 640*density; layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer.addView(view4, layoutParams); btnEnter.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // Quit the application for now finish(); } }); btnScreenLeft.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(-10,0); } }); btnScreenRight.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(10,0); } }); btnScreenUp.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(0,-10); } }); btnScreenDown.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(0,10); } }); // view1.setOnKeyListener(new OnKeyListener() { // @Override // public boolean onKey(View v, int keyCode, KeyEvent event) { // if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) // viewContainer.scrollBy(0,10); // return true; // } // }); } } 

每个屏幕上的大数字都是黑色的背景图像,上面印着这些数字。 (我没有在这里发布,因为你可能会修改代码)。

我们正在做一些与使用带Fragments的图库以及扩展BaseAdapter的图库适配器完全相同的描述。 我会build议去一个画廊实现你的目标(我们也使用ViewPager的视图,我们不需要看到其他片段)。

我可以想到两种可能的实现方法。

  1. 通过ViewSwitcher 。 这是一个很棒的YouTubevideo,展示了它如何与onGestureListener一起工作 。 但是,我不确定这是否会与您的图片显示多个视图。

  2. 作为替代,您可以使用Horizo​​ntalScrollView 。 但是,如果您在另一个ScrollView中放置一个滚动视图,通常会导致问题,但这可能是值得的!

让我知道如何,祝你好运!

除了MrZander的第二个答案看看这个https://stackoverflow.com/a/2655740/935075

看看这个博客文章如何编写自定义水平滚动视图来实现类似的东西。 该示例一次只能显示一个屏幕,但您应该可以根据需要轻松修改它。

如果要扩展ViewPager,只需重写draw方法和setOffscreenPageLimit(int limit)即可。 但是,我build议使用FragmentPageAdapter如果你的片段本身是复杂的。

你可以在这里检查源代码或者如果你想检查在支持包中的一个,你可以在这里做。