155

垂直および水平 Scrollview のソリューションを探すのに本当に疲れました。

この機能を実装するフレームワークにはビュー/レイアウトがないことを読みましたが、次のようなものが必要です:

他のレイアウトを定義する必要があります。子レイアウトは、移動のために垂直/水平スクロールを実装する必要があります。

最初はレイアウトをピクセル単位で移動するコードを実装しましたが、それは正しい方法ではないと思います。ScrollView と Horizo​​ntal ScrollView で試してみましたが、垂直または水平スクロールのみを実装しているため、思いどおりに動作しません。

誰かの子要素にリスナーをアタッチする必要があるため、キャンバスは私のソリューションではありません。

私に何ができる?

4

12 に答える 12

43

「Android縦+横ScrollView」のGoogle検索結果はこれが初めてらしいので、ここに追加しようと思いました。Matt Clarkは、Android ソースに基づいてカスタム ビューを構築しました。これは完全に機能しているようです:

そのページのクラスには、ビューの水平幅を計算するバグがあることに注意してください。Manuel Hilty による修正がコメントにあります。

解決策: 行 808 のステートメントを次のように置き換えます。

final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);


編集:リンクはもう機能しませんが、ここにブログ投稿の古いバージョンへのリンクがあります

于 2011-03-07T19:14:49.717 に答える
28

より良い解決策を見つけました。

XML: (design.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>

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; 
  }
}

それはうまくいきます!!!

他のレイアウトまたはコントロールをロードする場合、構造は同じです。

于 2010-01-13T15:35:06.533 に答える
25

私はそれを使用し、正常に動作します:

<?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>

ソース リンクは次のとおりです: Android-spa

于 2011-06-04T09:06:31.743 に答える
21

Mahdi Hijazi answerに基づく私のソリューションですが、カスタムビューはありません:

レイアウト:

<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>

コード (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;
        }
    });

スクロールビューの順序を変更できます。レイアウトとコードで順序を変更するだけです。そして明らかに、WateverViewYouWant の代わりに、両方向にスクロールしたいレイアウト/ビューを配置します。

于 2013-01-10T10:54:26.667 に答える
6

これを試して

<?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>
于 2012-06-13T11:16:59.603 に答える
6

オプション #1: 水平方向と垂直方向の同時スクロールを必要としない新しい UI デザインを考え出すことができます。

ScrollViewオプション #2:およびのソースコードを入手しHorizontalScrollView、コア Android チームがそれらをどのように実装したかを学び、独自のBiDirectionalScrollView実装を作成することができます。

オプション #3: ウィジェット システムを使用してキャンバスに直接描画する必要がある依存関係を取り除くことができます。

オプション 4: 探しているものを実装しているように見えるオープン ソース アプリケーションを見つけたら、そのアプリケーションがどのように実装されているかを確認してください。

于 2010-01-11T20:58:46.627 に答える
6

Two Dimensional Scrollview リンクが無効になっているため、取得できなかったため、独自のコンポーネントを作成しました。それは投げ飛ばしを処理し、私にとっては適切に機能します。唯一の制限は、wrap_content がそのコンポーネントに対して適切に機能しない可能性があることです。

https://gist.github.com/androidseb/9902093

于 2014-03-31T21:11:05.667 に答える
2

あなたの問題の解決策があります。垂直スクロールのみを処理し、水平スクロールを無視してこれを変更する ScrollView コードを確認できます。WebView のようなビューが欲しかったので、ScrollView を変更するとうまくいきました。しかし、これはあなたのニーズに合わないかもしれません。

対象となるUIの種類を教えてください。

よろしく、

ラヴィ・パンディット

于 2011-05-13T13:28:47.813 に答える
1

コードをいじってみると、Horizo​​ntalScrollView を ScrollView に入れることができます。これにより、同じビューで 2 つのスクロール方法を使用できます。

ソース: http://androiddevblog.blogspot.com/2009/12/creating-two-dimensions-scroll-view.html

これがお役に立てば幸いです。

于 2011-04-07T08:59:57.723 に答える