5

この投稿のアドバイスに従ってみました。ScrollViewのスクロール位置を同期します-androidです が、問題が発生しています。

背景-水平スクロールと垂直スクロールの両方を備えたテーブルレイアウトが必要ですが、最初の行と最初の列が常に存在する必要があります-Excelのフリーズペインのように。残念ながら、AndroidのJavaプログラミングでは不可能に近いようです...私にそのような頭痛の種を引き起こします。これらの2つの水平スクロールビューを同期できる場合は、テーブルが希望どおりに機能するように設定しました。

私は上記の投稿されたリンクからのアドバイスに従いました、そして私が持っている問題はこれです。実装するとアプリフォースが閉じます

scrollView1.setScrollViewListener(this);

問題は、ObservableScrollViewsを宣言する方法にあるのではないかと思います。私はXMLを使用していません-すべてのオブジェクトはプログラムで作成されます。使ってみました

private ObservableScrollView oScrollViewOne = new ObservableScrollView(this);

しかし、これは同様に力を閉じさせています。(通常のスクロールビューを作成し、それにIDを割り当ててから、

scrollView1 =(ObservableScrollView)findViewById(ID); ここで、IDはスクロールビューに指定した整数です。

以下のコメントをどうすればよいのか、XMLレイアウトを使用していない場合はどのように使用するのか疑問に思っています。

また、既存のScrollViewタグの代わりに、この新しいObservableScrollViewクラスをレイアウトで指定する必要があります。

com.test.ObservableScrollView android:id = "@ + id /scrollview1"..。

以前に見たように、コードを指定せずにOnTouchMotionEventまたは他のアイデアを使用するための提案だけでなく、明示的なコードを使用して2つの水平スクロールビューの同期を実装するためのその他の提案。

これがエラーコードです

10-23 23:33:08.631: ERROR/AndroidRuntime(18187): FATAL EXCEPTION: main
10-23 23:33:08.631: ERROR/AndroidRuntime(18187): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.glen.apps.TeacherAidePro/com.glen.apps.TeacherAidePro.TeacherAidePro}: java.lang.NullPointerException
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2709)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.ActivityThread.access$2300(ActivityThread.java:135)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.os.Looper.loop(Looper.java:144)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.ActivityThread.main(ActivityThread.java:4937)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at java.lang.reflect.Method.invokeNative(Native Method)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at java.lang.reflect.Method.invoke(Method.java:521)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at dalvik.system.NativeStart.main(Native Method)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187): Caused by: java.lang.NullPointerException
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.view.View.<init>(View.java:1810)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.view.View.<init>(View.java:1856)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.view.ViewGroup.<init>(ViewGroup.java:299)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.widget.FrameLayout.<init>(FrameLayout.java:83)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.widget.ScrollView.<init>(ScrollView.java:137)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.widget.ScrollView.<init>(ScrollView.java:133)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.widget.ScrollView.<init>(ScrollView.java:129)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at com.glen.apps.TeacherAidePro.ObservableScrollView.<init>(ObservableScrollView.java:12)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at com.glen.apps.TeacherAidePro.TeacherAidePro.<init>(TeacherAidePro.java:119)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at java.lang.Class.newInstanceImpl(Native Method)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at java.lang.Class.newInstance(Class.java:1429)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.Instrumentation.newActivity(Instrumentation.java:1036)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2701)
10-23 23:33:08.631: ERROR/AndroidRuntime(18187):     ... 11 more

これが12行目です

 1. package com.glen.apps.TeacherAidePro;
 2.
 3. import android.content.Context;
 4. import android.util.AttributeSet;
 5. import android.widget.ScrollView;
 6.
 7. public class ObservableScrollView extends ScrollView {
 8.
 9.   private IScrollListener listener = null;    
10.
11.   public ObservableScrollView(Context context) {
12.       super(context);
  }
4

2 に答える 2

6

このエラーは、ObservableScrollViewのコンストラクターのnullポインターを示しています。コンストラクターと12行目だけを投稿していただけますか?

XMLとカスタムスクロールビューが相互作用する方法で私が見ている考えられる問題の1つは、カスタムスクロールビューが内部クラスであるということです。XMLで内部クラスのカスタムコンポーネントを宣言する方法、または外部クラスに移動する方法については、このページを参照してください。私は通常それを外部クラスに入れますが、それを内部クラスとして保持したい場合は、次のようになります。

<view
    class="com.glen.apps.TeacherAidePro$ObservableScrollView"
.../>

ただし、これでnullポインター例外が説明されるとは思わないので、ObservableScrollViewクラスを投稿してください。

編集:

Javaですべてを実行することを主張する場合、以下に実際の例を示します。

private ObservableScrollView scrollView1 = null;
private ObservableScrollView scrollView2 = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LinearLayout parent = new LinearLayout(this);
    parent.setOrientation(LinearLayout.HORIZONTAL);
    parent.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.FILL_PARENT));
    parent.setWeightSum(2.0f);

    scrollView1 = new ObservableScrollView(this);
    scrollView1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.FILL_PARENT, 1.0f));
    scrollView2 = new ObservableScrollView(this);
    scrollView2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.FILL_PARENT, 1.0f));

    scrollView1.setScrollViewListener(new ScrollViewListener() {
        public void onScrollChanged(ObservableScrollView scrollView, int x,
                int y, int oldx, int oldy) {
            scrollView2.scrollTo(x, y);
        }
    });
    scrollView2.setScrollViewListener(new ScrollViewListener() {
        public void onScrollChanged(ObservableScrollView scrollView, int x,
                int y, int oldx, int oldy) {
            scrollView1.scrollTo(x, y);
        }
    });

    TextView tv1 = new TextView(this);
    tv1.setText("TEXT1TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT");
    tv1.setTextSize(36.0f);
    scrollView1.addView(tv1);

    TextView tv2 = new TextView(this);
    tv2.setText("TEXT2TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT");
    tv2.setTextSize(36.0f);
    scrollView2.addView(tv2);

    parent.addView(scrollView1);
    parent.addView(scrollView2);
    parent.invalidate();

    setContentView(parent);
}

基本的に、これにより、それぞれ1.0の重みで2つのスクロールビューが並べて作成され、2.0のレイアウトで合計の重みを持つLinearLayoutに配置されるため、それぞれの幅は半分になります。

ただし、(私の意見では)レイアウトを作成する方がはるかに簡単なので、XMLに慣れることを強くお勧めします。また、間違いを見つけるのも簡単です。また、ネストされた形式のXMLを使用すると、読みやすくなります。とにかく、これが物事をクリアすることを願っています。

于 2011-10-24T12:24:23.910 に答える
1

これは、コードでの私の解決策の詳細な説明です。

//This should be inside yout oncreate
syncScrolls(firstView, secondView;
        syncScrolls(secondView, firstView);




    //This method accept 2 horizontal scroll views, but you could improve it passing an array. 
        private void syncScrolls(final HorizontalScrollView currentView, final HorizontalScrollView otherView) {

//This create the Gesture Listener where we override the methods we need
                GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//Here onfling just return true, this way doesnt happens
                        return true;
                    }
                    @Override
                    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//On scroll we sync the movement of the both views
                        otherView.scrollTo(currentView.getScrollX(), 0);
                        return super.onScroll(e1, e2, distanceX, distanceY);
                    }
                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }
                };
        //This create the gesture detectors that implements the previous custom gesture listener
                final GestureDetector gestureDetector = new GestureDetector(this, gestureListener);
        //And finally we set everything to the views we need
                currentView.setOnTouchListener(new View.OnTouchListener() {
                    public boolean onTouch(View v, MotionEvent event) {
                        return gestureDetector.onTouchEvent(event);
                    }
                });

        }

これが完全に良い答えかどうかはわかりませんが、前に述べたように、配列を使用してこれを改善することができます。同期する各ビューのメソッドを呼び出すのではなく、この場合は2です。また、同期する代わりにonFlingが防止されます。スクロールビューが長すぎる場合、これはユーザーフレンドリーではありません。そして最後に、ユーザーが小さなフリングを行う場合、まだ小さな問題がありますが、それは非常にまれなケースです。

于 2015-11-13T18:33:59.207 に答える