5

SOに関するこのトピックに関するいくつかの質問を読みましたが、それに対する確かな答えは実際には見つかりませんでした。

複数のカスタムビューをスタックするフレームレイアウトがありますが、onTouchイベントはトップビューでのみ機能します。(カスタムビューは、同じonTouchイベントを持つすべて同じビューであり、それらの複数だけです)

FrameLayout

  • customView [2] <---これは最後に追加されたビューであり、イベントを受信する唯一のビューです
  • customView [1]
  • customView [0]

私はAndroid2.2でテストしていますが、以下の他のビューでタッチが発生した場所を知る方法があるかどうか疑問に思っていますか?


編集(コードの追加)

問題が発生している場所を説明するのに役立つコードを追加しています。最初は、自動的にonTouchEventtrueが返されました。これにより、最後のビュー(私の場合はcustomerView [2])だけが値を生成するようになりました。

ただし、onTouchEventtrueまたはfalseを返すように設定するメソッドを追加すると、生成された値を返すビューはcustomView[0]のみになります。

これで私が求めていることが明らかになることを願っています。私はこれにかなり慣れていません、そしてそれを説明するために時間を割いてくれてありがとう(そしてもちろんあなたの忍耐に感謝します)。

また、TextViewが各touchEventの値で更新されないことを認識し、修正に取り組んでいます。

私の活動:

public class MyActivity extend Activity {

    CustomView[] customView;
    TextView[] textView;
    int numViews 3;
    //FrameLayout and Params created

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

        for(int i = 0; i < numViews; i++) {
            customView[i] = new CustomView(this, i);


            //Allows the onTouch to be handled by all Views - View[0] is the bottom view
            if(i == 0) {
                customView[i].setTouchBool(true);        //set view's onTouch to return true
            } else {
                customView[i].setTouchBool(false);       //set view's onTouch to return false
            }

            //Set TextView to display the number generated by the CustomView
            textView[i].setText(Double.toString(customView[i].getGeneratedNumber()));

            //Add views to main layout
            frame.addView(textView[i]);
            frame.addView(customView[i]);
        }
    }
}

私の見解:

public class CustomView extends View {

    boolean onTouchHandler = true;
    int xVal = 0, yVal = 0;
    int index;
    double generatedNum = 0;

    public CustomView(Context context) {
        this(context, 0);
        this.index = 0;
    }

    public CustomView(Context context, int index) {
        super(context);
        this.index = index;
    }


    @Override 
    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();

        switch(action) {
            case MotionEvent.ACTION_DOWN: {
                //do logic 
            }

            case MotionEvent.ACTION_MOVE: {
                //do logic
            }

            case MotionEvent.ACTION_UP: {
                xVal = (int) ev.getX();
                yVal = (int) ev.getY();

                generateNumber(xVal, yVal, index);

                break; 
            }
        }
         return onTouchHandler;    
    }  


    private void generateNumber(int x, int y, int index) {
        if(index == 0) {
            generatedNum = (x / 2) * (y / 2) + 64;
        } else {
            generatedNum = (x / 2) * (y / 2) + (index * 128);
        }
    }

    public double getGeneratedNumber() {
        return generatedNum;
    }

    public boolean setTouchBool(boolean b) {
        this.onTouchHandler = b;
    }
}
4

2 に答える 2

16

onTouchEventAndroidは、ビューの1つからを受け取るまで、各ビューを呼び出すビューをカスケードしtrueます。タッチイベントをそれらすべてで処理する場合は、最後のイベントに到達するまでfalseを返します。

編集:

Ok。私が正しく理解していれば、1つのレイヤーの深さの子ビューの束を含む単一のトップビューがあります。私の最初の答えは、ViewGroupの階層で互いに重なり合った3つのカスタムビューがあると想定していました(View3はView2の子です。View2はView1の子です。View1はParentViewの子です)。親ビューでのユーザーのタッチイベントを、そのすべての子に送信する必要があります。

その場合、AFAIK、それを可能にするAndroidのAPIにはビューがありません。したがって、それを行うカスタムビューを作成する必要があります。

OK、私はこれをテストしていませんので、それが機能するかどうか、そしてそれがあなたが試しているものであるかどうかを教えてください。オブジェクトが何であれ拡張するカスタムクラスを作成し、そのようにメソッドframeをオーバーライドします。onTouch

@Override 
public boolean onTouchEvent(MotionEvent ev) {
   for(int i = 0; i < this.getChildCount(); i++){
      this.getChildAt(i).dispatchTouchEvent(ev);
   } 
   return true;
} 

falseここで、カスタムビューと同じロジックを維持します。ただし、前の回答で述べたように受信しない限り、親ビューはonTouchイベントを受信しないため、すべて戻る必要があります。

注:この実装では、ロジックが子タッチイベントを発生させる->falseを返す->親タッチイベントを発生させる->子タッチイベントを再度発生させるため、ユーザーが実際にタッチする子ビューが2回発生します

于 2011-11-18T22:55:10.303 に答える