Scrollview vertical et horizontal sur android
je suis vraiment fatigué à la recherche d'une solution pour le Scrollview vertical et horizontal.
j'ai lu qu'il n'y a pas de vues/layouts dans le cadre qui implémentent cette fonctionnalité, mais j'ai besoin de quelque chose comme ceci:
je dois définir un layout dans un autre, le layout enfant doit mettre en œuvre défilement vertical/horizontal pour se déplacer.
initialement mis en œuvre un code qui a déplacé la disposition pixel par pixel, mais je pense que n'est pas de la bonne façon. Je l'ai essayé avec ScrollView et ScrollView Horizontal mais rien ne fonctionne comme je le veux, parce qu'il ne met en œuvre que le défilement vertical ou horizontal.
Toile N'est pas ma solution parce que j'ai besoin d'attacher des écouteurs dans certains éléments enfants.
Que puis-je faire?
10 réponses
mélangeant quelques-unes des suggestions ci-dessus, et a pu obtenir une bonne solution:
Custom ScrollView:
package com.scrollable.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;
public class VScroll extends ScrollView {
public VScroll(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VScroll(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VScroll(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}
Custom HorizontalScrollView:
package com.scrollable.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;
public class HScroll extends HorizontalScrollView {
public HScroll(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public HScroll(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HScroll(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}
the Scrollbleimageactivity:
package com.scrollable.view;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
public class ScrollableImageActivity extends Activity {
private float mx, my;
private float curX, curY;
private ScrollView vScroll;
private HorizontalScrollView hScroll;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
vScroll = (ScrollView) findViewById(R.id.vScroll);
hScroll = (HorizontalScrollView) findViewById(R.id.hScroll);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float curX, curY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mx = event.getX();
my = event.getY();
break;
case MotionEvent.ACTION_MOVE:
curX = event.getX();
curY = event.getY();
vScroll.scrollBy((int) (mx - curX), (int) (my - curY));
hScroll.scrollBy((int) (mx - curX), (int) (my - curY));
mx = curX;
my = curY;
break;
case MotionEvent.ACTION_UP:
curX = event.getX();
curY = event.getY();
vScroll.scrollBy((int) (mx - curX), (int) (my - curY));
hScroll.scrollBy((int) (mx - curX), (int) (my - curY));
break;
}
return true;
}
}
la mise en page:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.scrollable.view.VScroll android:layout_height="fill_parent"
android:layout_width="fill_parent" android:id="@+id/vScroll">
<com.scrollable.view.HScroll android:id="@+id/hScroll"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/bg"></ImageView>
</com.scrollable.view.HScroll>
</com.scrollable.view.VScroll>
</LinearLayout>
comme cela semble être le premier résultat de recherche dans Google pour" Android vertical+ScrollView horizontal", j'ai pensé que je devrais ajouter ceci ici. Matt Clark a construit une vue personnalisée basée sur la source Android, et il semble fonctionner parfaitement: two Dimensional ScrollView
attention, la classe de cette page a un bug qui calcule la largeur horizontale de la vue. Une correction de Manuel Hilty est dans les commentaires:
Solution: remplacer l'énoncé à la ligne 808 par le suivant:
final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
modifier: le lien ne fonctionne plus mais voici un lien vers une ancienne version du blogpost .
j'ai trouvé une meilleure solution.
XML: (de la conception.xml)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:layout_width="90px" android:layout_height="90px">
<RelativeLayout android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent">
</RelativeLayout>
</FrameLayout>
</FrameLayout>
Code Java:
public class Example extends Activity {
private RelativeLayout container;
private int currentX;
private int currentY;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.design);
container = (RelativeLayout)findViewById(R.id.container);
int top = 0;
int left = 0;
ImageView image1 = ...
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(left, top, 0, 0);
container.addView(image1, layoutParams);
ImageView image2 = ...
left+= 100;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(left, top, 0, 0);
container.addView(image2, layoutParams);
ImageView image3 = ...
left= 0;
top+= 100;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(left, top, 0, 0);
container.addView(image3, layoutParams);
ImageView image4 = ...
left+= 100;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(left, top, 0, 0);
container.addView(image4, layoutParams);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
currentX = (int) event.getRawX();
currentY = (int) event.getRawY();
break;
}
case MotionEvent.ACTION_MOVE: {
int x2 = (int) event.getRawX();
int y2 = (int) event.getRawY();
container.scrollBy(currentX - x2 , currentY - y2);
currentX = x2;
currentY = y2;
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
return true;
}
}
ça marche!!!
si vous voulez charger d'autres dispositions ou de contrôle, la structure est la même.
Je l'utilise et fonctionne très bien:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="@+id/ScrollView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView android:id="@+id/HorizontalScrollView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="@+id/ImageView01"
android:src="@drawable/pic"
android:isScrollContainer="true"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:adjustViewBounds="true">
</ImageView>
</HorizontalScrollView>
</ScrollView>
le lien source est ici: Android-spa
Ma solution basée sur Mahdi Hijazi réponse , mais sans toutes les vues personnalisées:
Modèle:
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:id="@+id/scrollVertical"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<WateverViewYouWant/>
</ScrollView>
</HorizontalScrollView>
Code (onCreate / onCreateView):
final HorizontalScrollView hScroll = (HorizontalScrollView) value.findViewById(R.id.scrollHorizontal);
final ScrollView vScroll = (ScrollView) value.findViewById(R.id.scrollVertical);
vScroll.setOnTouchListener(new View.OnTouchListener() { //inner scroll listener
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
hScroll.setOnTouchListener(new View.OnTouchListener() { //outer scroll listener
private float mx, my, curX, curY;
private boolean started = false;
@Override
public boolean onTouch(View v, MotionEvent event) {
curX = event.getX();
curY = event.getY();
int dx = (int) (mx - curX);
int dy = (int) (my - curY);
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (started) {
vScroll.scrollBy(0, dy);
hScroll.scrollBy(dx, 0);
} else {
started = true;
}
mx = curX;
my = curY;
break;
case MotionEvent.ACTION_UP:
vScroll.scrollBy(0, dy);
hScroll.scrollBy(dx, 0);
started = false;
break;
}
return true;
}
});
vous pouvez changer l'ordre des scrollviews. Il suffit de changer leur ordre dans la mise en page et dans le code. Et évidemment au lieu de WateverViewYouWant vous mettez la mise en page/Vues que vous voulez faire défiler les deux directions.
Option # 1: vous pouvez proposer un nouveau design D'interface utilisateur qui ne nécessite pas de défilement horizontal et vertical simultané.
Option #2: Vous pouvez obtenir le code source de ScrollView
et HorizontalScrollView
, apprendre comment le noyau de L'équipe Android mis en œuvre ces, et de créer votre propre BiDirectionalScrollView
mise en œuvre.
Option #3: vous pouvez vous débarrasser des dépendances qui vous obligent à utiliser le système de widget et dessiner directement sur la toile.
Option #4: Si vous tombez sur une application open source qui semble implémenter ce que vous recherchez, regardez comment ils l'ont fait.
Essayez cette
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="@+id/Sview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView
android:id="@+id/hview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView .......
[here xml code for image]
</ImageView>
</HorizontalScrollView>
</ScrollView>
puisque le lien En deux dimensions de Scrollview est mort, je n'ai pas pu l'obtenir et j'ai donc créé mon propre composant. Il gère jetant et fonctionne correctement pour moi. La seule restriction est que wrap_content pourrait ne pas fonctionner correctement pour ce composant.
j'ai une solution pour votre problème. Vous pouvez vérifier le code ScrollView il ne gère que le défilement vertical et ignore le défilement horizontal et le modifier. Je voulais une vue comme une webview, donc ScrollView modifié et il a bien fonctionné pour moi. Mais cela pourrait ne pas convenir à vos besoins.
dites-moi quel type D'UI vous ciblez.
Cordialement,
Ravi Pandit
en jouant avec le code, vous pouvez mettre un ScrollView horizontal dans un ScrollView. Ainsi, vous pouvez avoir les deux de défilement dans la même vue.
Source: http://androiddevblog.blogspot.com/2009/12/creating-two-dimensions-scroll-view.html
j'espère que cela pourra vous aider.