Ich habe eine 'Seite', die eine Reihe von Komponenten enthält und deren Inhalt länger als die Höhe des Geräts ist. Gut, setzen Sie einfach das gesamte Layout (die gesamte Seite) in ein ScrollView
, kein Problem.
Eine der Komponenten ist a ViewPager
. Dies wird korrekt gerendert, aber die Reaktion auf ein Wischen / Schleudern funktioniert nicht richtig, es ist nervös und funktioniert nicht immer. Es scheint mit dem 'verwechselt' zu werden ScrollView
, funktioniert also nur zu 100%, wenn Sie in einer exakten horizontalen Linie fliegen.
Wenn ich das entferne ScrollView
, reagiert der ViewPager perfekt.
Ich habe eine Suche durchgeführt und dies nicht als bekannten Defekt gefunden. Hat das noch jemand erlebt?
- Plattformversion: 1.6
- Kompatibilitätsbibliothek v4.
- Gerät: HTC Incredible S.
Im Folgenden finden Sie einen Beispielcode, mit dem Sie testen können. Kommentieren Sie ihn aus ScrollView
, damit er ordnungsgemäß funktioniert.
Aktivität:
package com.ss.activities;
import com.ss.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TextView;
public class PagerInsideScollViewActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewPager vp = (ViewPager) findViewById(R.id.viewpager);
vp.setAdapter(new MyPagerAdapter(this));
}
}
class MyPagerAdapter extends PagerAdapter {
private Context ctx;
public MyPagerAdapter(Context context) {
ctx = context;
}
@Override
public int getCount() {
return 2;
}
@Override
public Object instantiateItem(View collection, int position) {
TextView tv = new TextView(ctx);
tv.setTextSize(50);
tv.setTextColor(Color.WHITE);
tv.setText("SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, " +
"SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, " +
"SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, " +
"SMILE DUDE, SMILE DUDE, SMILE DUDE");
((ViewPager) collection).addView(tv);
return tv;
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public void startUpdate(View arg0) {
}
@Override
public void finishUpdate(View arg0) {
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="300dp" />
</LinearLayout>
</ScrollView>
quelle
Antworten:
Ich hatte das gleiche Problem. Meine Lösung bestand darin, aufzurufen,
requestDisallowInterceptTouchEvent
als der ViewPager-Bildlauf gestartet wurde.Hier ist mein Code:
quelle
Weitere Informationen haben ergeben, dass es Probleme mit Bildlaufkomponenten innerhalb von Bildlaufkomponenten gibt.
Eine Lösung besteht darin, das vertikale Scrollen der ScrollView im Bereich der enthaltenen scrollbaren Komponente, in meinem Fall eines ViewPagers, zu deaktivieren.
Der Code für diese Lösung ist hier detailliert (und einfach genial!)
quelle
Hier ist eine Lösung:
Grundsätzlich stellen Sie die X- und Y-Werte ein, wenn Sie nach unten drücken, und berechnen die Entfernung beim Ziehen, um zu bestimmen, in welche Richtung wir gehen möchten. Spielen Sie mit der Dragthreshold, um sie für Ihren Fall zu optimieren.
quelle
Mit einem ViewPager können Sie Seitenänderungsereignisse erfassen und verhindern, dass ScrollView das Berührungsereignis abfängt, das die Seitenänderung verursacht hat.
Dies ist sehr einfach zu bedienen
ViewGroup.requestDisallowInterceptTouchEvent(boolean)
. Der Benutzer kann die ScrollView auch dann ziehen, wenn er den ViewPager zieht. Das horizontale Ziehen des Pagers funktioniert jedoch weiterhin, ohne dass die ScrollView stört.Dies funktioniert bei mir mit der Android Support v4-Bibliothek unter Android 2.3.4 und 4.2.1.
quelle
Ich habe die Lösung von @Michael Herbig angepasst. Der Vorteil dabei ist, dass sie in jeder Ansicht funktioniert, die dies zulässt
setOnTouchListener
, nicht nur in einem ViewPager (z. B. ViewPagerIndicator), sondern in einer eigenständigen Klasse.Anwendungsbeispiel:
Und die Klasse:
quelle
}}
@Override public boolean onTouch (View v, MotionEvent-Ereignis) {
Verwenden Sie über zwei und es wird sehr gut funktionieren. Ich habe auch in meinem Code verwendet.
quelle
Bei diesem Ansatz lasse ich den
ViewPager
Bildlauf in dieX
Richtung, ohne dass ich mir Sorgen machen muss, dass derScrollView
(übergeordnete) Benutzer das Ereignis stiehlt und den aktuellen Bildlauf abbricht. Noch wichtiger ist, dass dadurch auch der Bereich, in demViewPager
sich der befindet, in derY
Richtung scrollbar bleibt .quelle
Keine der Lösungen hier hat für mich gut funktioniert, da es sich entweder um die Modifikation der
ViewPager
Berührungslogik oderScrollView
der Logik handelt. Ich musste beides implementieren, jetzt funktioniert es wie ein Zauber.quelle
Sie können die InstantiateItem-Methode in Ihrer PagerAdapter-Klasse überschreiben, indem Sie jeder Seite eine scrollView hinzufügen. Hier ist ein Code:
quelle