13

Вопрос по android-layout, android-widget, android – Android - Карусель как виджет, который отображает часть левого и правого элементов

Поэтому я искал все выше и ниже, но не смог найти ответ на свой вопрос. Что мне в основном нужно, так это поведение, предоставляемое Android ViewFlipper или ViewPager, но я хочу отобразить части левого и правого видов, чтобы указать пользователю, что существуют элементы для прокрутки, вместо того, чтобы выбранный вид занимал весь экран.

Я также хотел бы добавить некоторые эффекты к левому и боковому видам, такие как затемнение и масштабирование, а затем немного уменьшить. Можно ли это сделать с помощью стандартного ViewFlipper или ViewPager или мне нужно развернуть собственную группу представлений, & # xE0; La Cover Flow (http://www.inter-fuser.com/2010/01/android-coverflow-widget.html)?

(P.S. Я не хочу использовать виджет Галерея, этот компонент - отстой).

Вот что нам нужно отобразить после выбора вида (левый и правый вид все еще отображаются):

view switcher

Перемещение влево или вправо приведет к смещению основного вида, его затемнению и уменьшению, а также обратному переходу к следующему или предыдущему виду.

  • @ user3586231 Sry. У меня больше нет доступа к этому коду.

    от AngraX
  • Сможете ли вы опубликовать код для ScaleableFragment?

    от
  • В любом случае спасибо. Я хотел избежать разработки моего собственного виджета. Может быть, исходный код для ViewFlipper или ViewPager - хорошее начало.

    от AngraX
  • Я использую метод setPageMargin, но без результата в альбомной ориентации, работаю только в портретном режиме, по какой-то причине я не могу понять в данный момент, остальное довольно просто, но если я не могу заставить его работать в альбомной ориентации, тогда мой подход (так же, как вы применяете отступы / поля к неактивным представлениям), тогда это бесполезно. Есть некоторые другие вещи, которые мне нужно учитывать, кроме метода setPageMargin, чтобы это работало?

    от
  • @ Jorge Aguilar Я действительно не могу сказать, не глядя на исходный код. Наше приложение работает в ландшафтном режиме и работает просто отлично.

    от AngraX
  • Здравствуйте, не могли бы вы опубликовать код для sampleFragment.scaleImage (scale); после использования этого кода превью ViewPager влево / вправо не видны ...

    от
  • Закрыть, за исключением того, что выбранный вид не должен занимать весь экран. Смотрите редактирование выше с изображением, поясняющим расположение.

    от AngraX
  • Are you describing this?

    от adneal
  • 1

    Просто используйте ViewPager и поиграйтесь с шириной фрагментов и поле

    й. Я так и сделал, и все работает отлично.

  • 3

    Я немного поиграл с этим

    и мое решение довольно простое. Я публикую его здесь, если кому-то это интересно.

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

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.1" />
    
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.8"
        android:orientation="vertical" >
    
        <!-- fragment contents go here -->
    
    </LinearLayout>
    
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.1" />
    

    Это оставит хороший 10% -ый запас с обеих сторон. Не устанавливайте фон для них, так как он будет охватывать соседние фрагменты. Теперь для самого пейджера: вам нужно использовать отрицательные поля, как объяснил AngraX, но также не забудьте предварительно загрузить последующие фрагменты, так как они видны до того, как они станут регулярными. Я получил хорошие результаты с этим:

        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
        mPager.setPageMargin(getResources().getDisplayMetrics().widthPixels / -7);
        mPager.setOffscreenPageLimit(2);
    

    значение -7 оставляет край следующего фрагмента видимым, поиграйте с вашей конкретной композицией. Я также рекомендую создать каждый фрагмент.

  • 2

    Ну

    вот потенциальный ответ, который может быть близок к тому, что вы ищете, но не совсем то, что вы ищете: это проект под названиемViewFlow что, я думаю, дает возможность уведомить пользователя о наличии большего количества просмотров с помощью индикаторов на экране. Он также предоставляет возможность буферизовать представления слева и справа от вашего текущего представления, так что вы можете иметь возможность тыкать в код, чтобы визуализировать их небольшие части, в основном уменьшая то, что он просматривает, до доступного размера экрана.

    Редактировать: Глупый я; Я должен прочитать последний вопрос, прежде чем ответить. :) Я не думаю, что вы можете сделать это с помощью ViewFlipper или Viewpager, к сожалению.

  • 16

    Я хотел бы дать обновление всем

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

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

    Позже мы устанавливаем поле страницы ViewPager в 2 раза больше боковых полей. Это заставляет взгляды соединяться. Однако в это время ViewPager будет отображать несколько видов.

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

    OnPageChangeListener.onPageScrolled () может использоваться для отслеживания прокрутки ViewPager. Гладкий преобразование может быть достигнуто. Код выглядит так:

    private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
    
        @Override
        public void onPageSelected(int position) {
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
            // positionOffset varies from 0 to 1 and indicates how far the view is
            // from the center of the ViewPager. When a view is selected (centered), this
            // value is 0.
    
            // Fades the text in an out while the ViewPager scrolls from one view to another.
            // On our final design the text views are fixed to the center of the screen and
            // do not scroll along with the views.
            if (positionOffset < 0.5) {
                setTextViewAlpha(1 - positionOffset * 2);
            } else {
                setTextViewAlpha((positionOffset - 0.5f) * 2);
            }
    
            // It's surprisingly complicated to get the current object being displayed by
            // a ViewPager (there's no getCurrentObject method). ScaleableFragment is just
            // a custom class to allow an adapter to cache it internally and also correctly
            // manage a fragment's lifecycle and restore from a saved state.
            ScaleableFragment sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager
                    .getAdapter()).getItem(position);
    
            // Calculates by how much the current view will be scaled down. The RATIO_SCALE
            // is 0.3 in our case, which makes the side views 70% of the size of the
            // center view. When centered, the scale will be 1. When
            // fully scrolled, the scale will be 0.7.
            float scale = 1 - (positionOffset * RATIO_SCALE);
    
            // Just a shortcut to findViewById(R.id.image).setScale(scale);
            sampleFragment.scaleImage(scale);
    
    
            // Now, if not in the last element, scale the next one up (in opposite direction).
            if (position + 1 < pager.getAdapter().getCount()) {
                sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
                        .getItem(position + 1);
                scale = positionOffset * RATIO_SCALE + (1 - RATIO_SCALE);
                sampleFragment.scaleImage(scale);
            }
        }
    
        // Once scrolling is done. Make sure the views are in the right scale (1 for center,
        // 0.7 for sides). Required as the onPageScrolled() method does not guarantee it
        // will interpolate to 1.0 precisely.
        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                setTextViewAlpha(1);
                ScaleableFragment sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager
                        .getAdapter()).getItem(pager.getCurrentItem());
                sampleFragment.scaleImage(1);
                sampleFragment.enableClicks();
    
                if (pager.getCurrentItem() > 0) {
                    sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
                            .getItem(pager.getCurrentItem() - 1);
                    sampleFragment.scaleImage(1 - RATIO_SCALE);
                    sampleFragment.disableClicks();
                }
    
                if (pager.getCurrentItem() + 1 < pager.getAdapter().getCount()) {
                    sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
                            .getItem(pager.getCurrentItem() + 1);
                    sampleFragment.scaleImage(1 - RATIO_SCALE);
                    sampleFragment.disableClicks();
                }
            }
        }
    };
    

    Это оно. Я не опубликовал полное решение, но надеюсь, что этого будет достаточно, чтобы кто-то еще начал.

    Постскриптум На 3.0+ включите аппаратное ускорение. Без этого прокрутка выглядела прерывисто на вкладке Samsung Galaxy 10.1.