MultiTouching - Horizo​​ntalScrollView中的触摸按钮 - Android

时间:2012-12-18 21:49:00

标签: android button multi-touch horizontalscrollview

我尝试使用多重触控创建应用,并使用此代码:

Multitouchng code

它有效,但我有问题,因为在我的应用程序中我有Horizo​​ntalScrollView(HSV),当我从HSV开始按下按钮时我在“downTouchedViewsIndex”中有按钮Id(View.getId()) “,但是当我滚动我的HSV并按下任何按钮时,我只有布局的ID - 没有关于按钮的信息。

我的触控代码:

package com.lacrima.pianoo;

public class MainActivity extends Activity implements SeekBar.OnSeekBarChangeListener, OnTouchListener {

    static private String TAG = "MainActivity";

    public View parent;

    private final ArrayList[] recentTouchedViewsIndex = new ArrayList[10];

    private final ArrayList[] downTouchedViewsIndex = new ArrayList[10];

    private final ArrayList<View> moveOutsideEnabledViews = new ArrayList<View>();

    private List<Integer> list = new ArrayList<Integer>();

    private final int mTouchSlop = 24;

    AssetFileDescriptor des; // deskryptor do opisu wczytywanego pliku muzycznego (miejsce gdzie jesta zapisany dlugość i inne takie)
    MediaPlayer[] mp = new MediaPlayer[36];// = new MediaPlayer();

    //Pierwsza oktawa
    Button button1, button2, button3, button4, button5, button6, button7;
    Button button1_5, button2_5, button4_5, button5_5, button6_5;
    //Druga oktawa
    Button button8, button9, button10, button11, button12, button13, button14;
    Button button8_5, button9_5, button11_5, button12_5, button13_5; 
    //Trzecia oktawa
    Button button15, button16, button17, button18, button19, button20, button21; 
    Button button15_5, button16_5, button18_5, button19_5, button20_5;

    SamplePlayer sound;
    Integer[] soundIDs = new Integer[36];

    private boolean[] whitePlays = new boolean[21];
    private boolean[] blackPlays = new boolean[15];

    private View[] whiteViews = new View[21];
    private View[] blackViews = new View[15];

    private int lastButton;

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

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //Ustawienie ekranu horuzontalnie na sztywno
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

        parent = findViewById(android.R.id.content).getRootView();
        parent.setOnTouchListener(this);


        SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
        final LockedHorizontalScrollView hsv = (LockedHorizontalScrollView)findViewById(R.id.hsv);

        seek.setMax(948);
        seek.setProgress(474);
        seek.setOnSeekBarChangeListener(this);
        hsv.post(new Runnable() {
            @Override
            public void run() {
                hsv.scrollTo(474, 0);
            }
        });

        sound = new SamplePlayer(this);

        falsePlays();
        buttonListeners();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

        LockedHorizontalScrollView hsv = (LockedHorizontalScrollView)findViewById(R.id.hsv);
        hsv.scrollTo(progress, 0);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        //uruchamiane w momencie kliknięcia na suwak
        Log.d(TAG, "Tracking on");
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        //uruchamiane w momencie odkliknięcia suwaka
        Log.d(TAG, "Tracking off");

    }


    @Override
    protected void onDestroy() {
        sound.release();
        super.onDestroy();
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {


        // index of the pointer which starts this Event
        final int actionPointerIndex = event.getActionIndex();

        // resolve the action as a basic type (up, down or move)
        int actionResolved = event.getAction() & MotionEvent.ACTION_MASK;
        if (actionResolved < 7 && actionResolved > 4) {
            actionResolved = actionResolved - 5;
        }

        if (actionResolved == MotionEvent.ACTION_DOWN || actionResolved == MotionEvent.ACTION_UP
                || actionResolved == MotionEvent.ACTION_CANCEL) {
            dealEvent(actionPointerIndex, event, v, actionResolved);
        }

        return true;
    }


    private void dealEvent(final int actionPointerIndex, final MotionEvent event, final View eventView,
            final int actionResolved) {

        int rawX, rawY;
        final int location[] = { 0, 0 };
        eventView.getLocationOnScreen(location);
        // Log.v("tag", location + "");
        rawX = (int) event.getX(actionPointerIndex) + location[0];
        rawY = (int) event.getY(actionPointerIndex) + location[1];

        final int actionPointerID = event.getPointerId(actionPointerIndex);
        ArrayList<View> hoverViews = getTouchedViews(rawX, rawY);

        if (actionResolved == MotionEvent.ACTION_DOWN) {
            downTouchedViewsIndex[actionPointerID] = (ArrayList<View>) hoverViews.clone();

            lastButton = hoverViews.get(k-1).getId();

        }

        if(actionResolved == MotionEvent.ACTION_UP){
            int k = hoverViews.size();
            Log.d("klop", "Odklijniecie: " + hoverViews.get(k-1).getId());
            lastButton = eventView.getId();
        }
        // deletes all views which where not clicked on ActionDown
        if (downTouchedViewsIndex[actionPointerID] != null) {
            final ArrayList<View> tempViews = (ArrayList<View>) hoverViews.clone();
            tempViews.removeAll(downTouchedViewsIndex[actionPointerID]);
            hoverViews.removeAll(tempViews);
        }

        if (recentTouchedViewsIndex[actionPointerID] != null) {
            final ArrayList<View> recentTouchedViews = recentTouchedViewsIndex[actionPointerID];

            final ArrayList<View> shouldTouchViews = (ArrayList<View>) hoverViews.clone();
            if (!shouldTouchViews.containsAll(recentTouchedViews)) {
                shouldTouchViews.removeAll(recentTouchedViews);
                shouldTouchViews.addAll(recentTouchedViews);

                final ArrayList<View> outsideTouchedViews = (ArrayList<View>) shouldTouchViews.clone();
                outsideTouchedViews.removeAll(hoverViews);
            }

            recentTouchedViewsIndex[actionPointerID] = hoverViews;
            hoverViews = shouldTouchViews;
        } else {
            recentTouchedViewsIndex[actionPointerID] = hoverViews;
        }

        if (actionResolved == MotionEvent.ACTION_UP) {
            recentTouchedViewsIndex[actionPointerID] = null;
            downTouchedViewsIndex[actionPointerID] = null;
        }
        for (final View view : hoverViews) {
            int x, y;
            view.getLocationOnScreen(location);
            x = rawX - location[0];
            y = rawY - location[1];

            // View does not recognize that the Pointer is
            // outside if the Pointer is not far away (>mTouchSlop)
            if (recentTouchedViewsIndex[actionPointerID] != null) {
                if (pointInView(x, y, mTouchSlop, view.getWidth(), view.getHeight())) {


                    if (!recentTouchedViewsIndex[actionPointerID].contains(view)) {
                        recentTouchedViewsIndex[actionPointerID].add(view);
                    }
                } else if (moveOutsideEnabledViews.contains(view)) {
                    Log.v("tag", "outside but gets event");
                    recentTouchedViewsIndex[actionPointerID].add(view);
                }
            }
            final MotionEvent me = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), actionResolved, x, y,
                    event.getPressure(actionPointerIndex), event.getPressure(actionPointerIndex), event.getMetaState(),
                    event.getXPrecision(), event.getYPrecision(), event.getDeviceId(), event.getEdgeFlags());
            me.setLocation(x, y);

            if (!me.equals(event)) {
                // deals the Event
                view.onTouchEvent(me);
            }

            // debug
            if (actionResolved == MotionEvent.ACTION_MOVE) {
                Log.v("tag", "#" + actionPointerIndex + " Rawx:" + rawX + " rawy:" + rawY + " x:" + x + " y:" + y + " "
                        + view.toString());
            }
        }
    }

    private ArrayList<View> getTouchedViews(final int x, final int y) {

        final ArrayList<View> touchedViews = new ArrayList<View>();
        final ArrayList<View> possibleViews = new ArrayList<View>();

        if (parent instanceof ViewGroup) {
            possibleViews.add(parent);
            for (int i = 0; i < possibleViews.size(); i++) {
                final View view = possibleViews.get(i);

                final int location[] = { 0, 0 };
                view.getLocationOnScreen(location);

                if (((view.getHeight() + location[1] >= y) & (view.getWidth() + location[0] >= x) & (view.getLeft() <= x) & (view
                        .getTop() <= y)) || view instanceof FrameLayout) {
                    touchedViews.add(view);
                    possibleViews.addAll(getChildViews(view));
                }

            }
        }

        return touchedViews;

    }

    private ArrayList<View> getChildViews(final View view) {
        final ArrayList<View> views = new ArrayList<View>();
        if (view instanceof ViewGroup) {
            final ViewGroup v = ((ViewGroup) view);
            if (v.getChildCount() > 0) {
                for (int i = 0; i < v.getChildCount(); i++) {
                    views.add(v.getChildAt(i));
                }

            }
        }
        return views;
    }


    private boolean pointInView(final float localX, final float localY, final float slop, final float width,
            final float height) {
        return localX >= -slop && localY >= -slop && localX < ((width) + slop) && localY < ((height) + slop);
    }

    public void addMoveOutsideEnabledViews(final View view) {
        moveOutsideEnabledViews.add(view);
    }

和xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#0A0A0A"
    android:orientation="vertical" >

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="fill_parent"
        android:layout_height="53dp" />

    <com.lacrima.pianoo.LockedHorizontalScrollView
        android:id="@+id/hsv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scrollbars="none" >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="horizontal" >

            <Button...

</RelativeLayout>
    </com.lacrima.pianoo.LockedHorizontalScrollView>

</LinearLayout>

我的代码很长,所以我把它放在dropbox(整个项目)上,你可以看到发生了什么

Project

2 个答案:

答案 0 :(得分:0)

我认为如果移动滚动条,则会失去第一个单击按钮的焦点。两个原因: - Scrollview重写onTouchEvent并返回true。 - &GT;触摸消耗殆尽 - 你失去了第一个按钮的焦点。尝试使用addMoveOutsideEnabledViews Methode添加按钮,看看会发生什么。

答案 1 :(得分:0)

我解决了我的问题。

您无需寻找触摸按钮。您必须获取触摸位置的X和Y,并从scrollView添加值。然后你必须检查,有任何按钮和启动方法:

rawX = (int) event.getX(actionPointerIndex) + location[0];
rawY = (int) event.getY(actionPointerIndex) + location[1];

    scrollX = seek.getProgress() + rawX;

    if (actionResolved == MotionEvent.ACTION_DOWN) {
        findButton(scrollX, rawY, true);
    }

    if(actionResolved == MotionEvent.ACTION_UP || actionResolved == MotionEvent.ACTION_CANCEL) {
        findButton(scrollX, rawY, false);
    }