Android - горизонтальная прокрутка нескольких видимых предметов - PullRequest
48 голосов
/ 08 октября 2011

РЕДАКТИРОВАТЬ: см. Мой собственный ответ для простого решения

ВАЖНО : Щедрость предлагается для ясного способа изменить ViewPager для удовлетворения сценария, описанного ниже.Пожалуйста, не предлагайте HorizontalScrollView - мне нужен полный сценарий жизненного цикла фрагмента

Мне нужно реализовать горизонтальную прокрутку представлений на основе Fragments, в которых один элемент находится в центре, а элементы вправо / влевочастично или полностью видны.ViewPager плохо подходит для этой задачи, поскольку фокусируется на отображении одного элемента за раз.

Чтобы упростить понимание ниже, приведен быстрый набросок, на котором элементы 1, 5 и 6 находятся за пределами видимой области.,И я хочу сделать этот видимый номер настраиваемым, чтобы, например, в книжной ориентации я показывал только 2 (или, возможно, только один) элемента.

Я не пытаюсь разместить, например, 3 элемента на экране, покакак показано на рисунке, можно обрезать другие элементыНа маленьком экране нормально иметь 1 центральный элемент, и по мере того, как экран увеличивается в размере, нужно показывать несколько элементов (обрезка - это нормально)

Я понимаю, что это похоже на галерею, но опять же, элементы не являются простыми изображениями, ноFragments с вертикально прокручиваемым списком в каждом фрагменте

PS Нашел этот пост @Commonsware, который перечислил 3 различных подхода .Для моих нужд мне нравится # 3

enter image description here

Ответы [ 7 ]

24 голосов
/ 24 ноября 2012

У этого есть удивительно легкий ответ, я даже не уверен, почему это не было отправлено сразу. Все, что мне нужно было сделать, чтобы получить точный эффект, это переопределить метод PagerAdapter#getPageWidth. По умолчанию он возвращает 1, но если вы установите его на 0,5, вы получите 2 страницы, 0,33 - 3 и т. Д. В зависимости от ширины разделителя между элементами пейджера вам может понадобиться немного уменьшить значение.

См. Следующий фрагмент:

    @Override
    public float getPageWidth(final int position) {
        // this will have 3 pages in a single view
        return 0.32f;
    }
2 голосов
/ 28 декабря 2011

Однажды я написал что-то похожее на шаблон. В моем примере я могу прокручивать с помощью кнопок вверх и вниз и вбок. Вы можете изменить его немного, чтобы удовлетворить ваши требования. В моем примере у меня есть 4 вида, расположенные так:

1 2
3 4

Похоже на это. На картинке прокручиваю от просмотра 1 вправо до просмотра 2:

Android View Scrolling

Код состоит из этого 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;
//          }
//      });
    }
}

Большие цифры на каждом экране - это черные фоновые изображения с нарисованными на них цифрами. (Я не разместил его здесь, потому что вы, вероятно, все равно измените код).

1 голос
/ 19 апреля 2012

Мы делаем что-то в точности так, как вы описываете, используя Gallery с Fragments и адаптер галереи, расширяющий BaseAdapter.Я бы порекомендовал пойти с галереей для достижения вашей цели (мы также используем ViewPager для представления, где нам не нужно видеть другие фрагменты).

0 голосов
/ 29 декабря 2011

Если вы хотите расширить ViewPager, просто переопределите метод draw и setOffscreenPageLimit (int limit). Но я рекомендую использовать FragmentPageAdapter, если сами ваши фрагменты довольно сложны.

Вы можете проверить исходный код здесь или если вы хотите проверить тот код в пакете поддержки, вы можете сделать это здесь .

0 голосов
/ 28 декабря 2011

Прочтите этот пост в блоге о том, как написать собственное представление горизонтальной прокрутки для достижения чего-то похожего. В примере за один раз виден только один экран, но вы можете легко изменить его для своих нужд.

0 голосов
/ 28 декабря 2011

В дополнение ко второму ответу мистера Зандера, посмотрите на это https://stackoverflow.com/a/2655740/935075

0 голосов
/ 08 декабря 2011

Я могу придумать два способа реализовать это.

  1. По ViewSwitcher . Вот отличное видео YouTube , показывающее, как оно работает с onGestureListener . Однако я не уверен, будет ли это работать с несколькими видами, как показано на вашей картинке.

  2. В качестве альтернативы вы можете использовать HorizontalScrollView . Тем не менее, это часто вызывает проблемы, если у вас есть один ScrollView внутри другого, но это может стоить того!

Дайте мне знать, как это происходит, Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...