Android - Karussellartiges Widget, das einen Teil der linken und rechten Elemente anzeigt

Also habe ich hoch und niedrig gesucht, aber keine Antwort auf meine Frage gefunden. Was ich grundsätzlich brauche, ist das Verhalten von Android ViewFlipper oder ViewPager, aber ich möchte Teile der linken und rechten Ansicht anzeigen, um dem Benutzer anzuzeigen, dass Elemente gescrollt werden müssen, anstatt dass die ausgewählte Ansicht den gesamten Bildschirm einnimmt.

Ich möchte auch der linken und der Seitenansicht einige Effekte hinzufügen, wie z. B. Dimmen und Skalieren, und dann etwas verkleinern. Ist es möglich, dies mit dem stock ViewFlipper oder ViewPager zu tun, oder muss ich eine eigene Ansichtsgruppe ausrollen, à la cover flow (http://www.inter-fuser.com/2010/01/android-coverflow-widget.html)?

(PS: Ich möchte das Galerie-Widget nicht verwenden, diese Komponente ist zum Kotzen.)

Folgendes müssen wir anzeigen, sobald eine Ansicht ausgewählt wurde (linke und rechte Ansicht werden weiterhin angezeigt):

Wenn Sie nach links oder rechts schwenken, wird die Hauptansicht ausgeblendet, etwas gedimmt und verkleinert, und bei der nächsten oder vorherigen Ansicht wird das Gegenteil erreicht.

 AngraX04. Apr. 2012, 22:02
Schließen, außer dass die ausgewählte Ansicht nicht den gesamten Bildschirm einnehmen sollte. Siehe Bearbeiten oben mit einem Bild, das das Layout erklärt.
 adneal04. Apr. 2012, 02:11

Antworten auf die Frage(4)

Ich poste es hier, falls jemand interessiert ist.

Erstens sollte das Layout für jedes Fragment einige Lücken auf beiden Seiten zulassen. Der einfachste Weg, dies zu tun, ist die Verwendung von Gewichten:

<code><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" />
</code>

Dadurch bleibt auf beiden Seiten eine schöne Marge von 10%. Stellen Sie sicher, dass Sie keinen Hintergrund für diese Objekte festlegen, da dies die Fragmente der Nachbarn verdeckt. Nun zum Pager selbst: Sie müssen negative Ränder verwenden, wie AngraX erklärte, aber auch die nachfolgenden Fragmente vorladen, da sie sichtbar sind, bevor sie regelmäßig angezeigt werden. Ich habe damit gute Ergebnisse erzielt:

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

Der Wert -7 lässt den Rand des nächsten Fragments sichtbar. Spielen Sie mit Ihrer spezifischen Komposition. Ich empfehle auch, jedes Fragment zu rahmen.

er Fragmente und Ränder. Ich habe es getan und es funktioniert gut.

hier ist eine mögliche Antwort, die nah an dem liegt, wonach Sie suchen, aber nicht genau das, wonach Sie suchen: Es gibt ein Projekt mit dem NamenViewFlow dass ich denke, bietet die Möglichkeit, den Benutzer über Indikatoren auf dem Bildschirm zu benachrichtigen, dass es mehr Ansichten gibt. Es bietet auch die Möglichkeit, Ansichten links und rechts von Ihrer aktuellen Ansicht zu puffern, so dass Sie möglicherweise auf den Code klicken können, um kleine Teile davon zu rendern, indem Sie im Grunde das verkleinern, was er als verfügbare Bildschirmgröße anzeigt.

Edit: Dumme mich; Ich sollte die letzte Frage lesen, bevor ich antworte. :) Ich glaube nicht, dass Sie dies mit einem ViewFlipper oder ViewPager tun können, leider.

 AngraX04. Apr. 2012, 21:39
Trotzdem danke. Ich wollte es vermeiden, mein eigenes Widget zu entwickeln. Vielleicht ist der Quellcode für ViewFlipper oder ViewPager ein guter Anfang.
Lösung für das Problem

der das gleiche Feature haben möchte. Bisher wurden große Fortschritte bei der Implementierung dieser Funktion erzielt, und jetzt funktioniert die Ansicht genau so, wie wir es benötigen.

Der ViewPager verfügt über eine Methode namens setPageMargin (). Diese Methode kann einen negativen Wert erhalten, wodurch sich die Fragmente / Ansichten überlappen. Um das gewünschte Layout zu erhalten, haben wir zunächst den linken und rechten Rand dynamisch um einen Prozentsatz des Bildschirms berechnet. Dies kann auch statisch erfolgen. Da wir jedoch eine Reihe unterschiedlicher Bildschirmgrößen anstreben, scheint dies der beste Ansatz zu sein.

Später setzen wir den Seitenrand des ViewPagers auf das 2-fache der Seitenränder. Dadurch rasten die Ansichten wieder zusammen. Zu diesem Zeitpunkt werden jedoch mehr als eine Ansicht vom ViewPager angezeigt.

Sie müssen nur noch eine Transformation (Skalierung) auf die Ansichten links und rechts anwenden (Android 3.0+) oder weitere Ränder hinzufügen, um sie auf die richtige Größe zu verkleinern (vor 3.0).

Mit OnPageChangeListener.onPageScrolled () kann der Bildlauf des ViewPagers verfolgt werden. Eine reibungslose Transformation kann erreicht werden. Der Code sieht folgendermaßen aus:

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

Das ist es. Ich habe nicht die vollständige Lösung gepostet, aber ich hoffe, dass dies ausreicht, um jemanden zum Laufen zu bringen.

P.S. Aktivieren Sie ab Version 3.0 die Hardwarebeschleunigung. Ohne sie sah das Scrollen auf einem Samsung Galaxy Tab 10.1 abgehackt aus.

 AngraX21. Juli 2016, 20:23
@ user3586231 Sry. Ich habe keinen Zugriff mehr auf diesen Code.
 AngraX18. Sept. 2012, 18:31
@Jorge Aguilar kann ich wirklich nicht sagen, ohne auf den Quellcode zu schauen. Unsere App befindet sich im Querformat und funktioniert einwandfrei.
 Marche10125. Feb. 2013, 22:29
Könnten Sie den Code für ScaleableFragment veröffentlichen?
 user358623120. Juli 2016, 13:43
Hallo, kannst du bitte den Code für sampleFragment.scaleImage (scale) posten? Nach Verwendung dieses Codes sind die linken / rechten Vorschauen von ViewPager nicht sichtbar ...
 Jorge Aguilar06. Aug. 2012, 18:55
Ich verwende die setPageMargin-Methode, aber ohne Ergebnis im Querformat. Ich arbeite nur im Hochformat. Aus irgendeinem Grund kann ich dies noch nicht verstehen. Der Rest ist ziemlich einfach. Wenn ich es jedoch nicht zum Querformat bringen kann, dann ist mein Ansatz (das gleiche wie beim Anwenden eines Abstands / Randes auf die nicht aktiven Ansichten), dann ist dies nutzlos. Gibt es einige andere Dinge, die ich neben der setPageMargin-Methode berücksichtigen muss, damit dies funktioniert?

Ihre Antwort auf die Frage