Android - horizontal scrolling of multiple viewable items

大城市里の小女人 提交于 2019-11-29 18:45:10

This one has surprisingly easy answer, I'm not even sure why it wasn't posted right away. All that I needed to do to get the exact effect was to override PagerAdapter#getPageWidth method. By default it returns 1 but if you set it to 0.5 you will get 2 pages, 0.33 will give you 3, etc. Depending on width of the separator between pager items you may have to slightly decrease the value.

See the following snippet:

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

Once I wrote something similar as template. In my example I can scroll with the buttons up and down and sidewise. You could modify it a little bit to fulfill your requirements. In my example I have 4 Views arranged like this:

1 2
3 4

It looks like this. On the picture I scroll from view 1 to the right to view 2:

The code consist of this 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>

and this Java code:

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

The big numbers on every screen are black background images with those numbers painted on it. (I didn't post it here because you will probably modify the code anyway).

Wryday

We are doing something pretty much exactly like you are describing using a Gallery with Fragments, and a gallery adapter extending the BaseAdapter. I would recommend going with a gallery to achieve your goal (we also use a ViewPager for the view where we do not need to see the other fragments).

I can think of two ways to possibly implement this.

  1. By a ViewSwitcher. Here is an excellent YouTube video showing how it works with an onGestureListener. However, I am not sure if this will work with multiple views like your picture shows.

  2. As an alternative, you could use a HorizontalScrollView. However, this often causes issues if you have one ScrollView inside of a another, but it may be worth a shot!

Let me know how it goes, Good luck!

sebataz

In addition to MrZander's second answer take a look at this https://stackoverflow.com/a/2655740/935075

Check out this blog post on how to write a custom horizontal scroll view to achieve something similar. The example has only one screen visible at a time, but you should be able to easily modify it for your needs.

Cris Stringfellow

If you want to extend ViewPager just override the draw method, and setOffscreenPageLimit(int limit). But, I recommend using FragmentPageAdapter if your fragments themselves are kind of complex.

You can check the source code here or if you want to check the one in the support package you can do it here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!