4

I have a CardScrollView with multiple cards. Swiping left and right moves between the cards.

Some of the cards have a lot of content on them. I used a ScrollView so the user can scroll through the card to see the content.

Glass doesn't know whether it should scroll to a different card or scroll on the card it is on when the user swipes their finger for obvious reasons. It chooses to scroll to a different card.

To differentiate, I want to use the GestureDetector to make a one finger scroll scroll cards, and a two finger scroll scroll on the selected card. Seems easy enough, so I made the createGestureDetector() method and put if statements for each case.

Now I have a problem...I do not know how to tell the CardScrollView to advance or go back a card, and I dont know how to make the ScrollBody scroll based on the gesture.

I looked through all of the available methods and nothing stuck out to me as particularly helpful. Does anyone have any idea how to do this?

Bonus question: I saw a lot of "dispatch" commands, like dispatchGenericMotionEvent. What do dispatch methods do?

EDIT:

Here is my code after Jean Vacca's suggestion:

private GestureDetector createGestureDetector(Context context) {
        GestureDetector gestureDetector = new GestureDetector(context);

        gestureDetector.setFingerListener(new GestureDetector.FingerListener() {
            @Override
            public void onFingerCountChanged(int previousCount, int currentCount) {
                if(currentCount == 2){
                    mCardScrollView.deactivate();
                }else{

                    mCardScrollView.activate();
                }
            }
        });
            return gestureDetector;
    }

and the xml for my views is:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ScrollView 
        android:id="@+id/scrollBody"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="false">

        <LinearLayout
            android:id="@+id/scrollLinearLayout"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">           
        </LinearLayout>
    </ScrollView>

</RelativeLayout>

Which is filled with TextViews in this code segment located in the CardScrollAdapter:

public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        int nextID = 3;

        if (convertView == null) {
            convertView = View.inflate(context, R.layout.my_card, null);
            holder = new ViewHolder();

            MyClass mine = mMyList.get(position);

            LinearLayout ll = (LinearLayout)convertView.findViewById(R.id.scrollLinearLayout);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

            holder.name = new TextView(this.context);
            holder.name.setId(nextID);
            nextID++;
            holder.name.setTextSize(50);
            holder.name.setText(mine.getName());
            holder.name.setLayoutParams(lp);
            holder.name.setGravity(Gravity.CENTER);
            ll.addView(holder.name);

            holder.infoTextViews = new ArrayList<TextView>(mine.getInfo().size());
            for(int i = 0; i < mine.getInfo().size(); i++)
            {
                holder.infoTextViews.add(new TextView(this.context));
                TextView tv = holder.infoTextViews.get(i);
                tv.setId(nextID);
                nextID++;
                tv.setTextSize(24);
                tv.setText(mine.getInfo().get(i));
                tv.setLayoutParams(lp);
                tv.setGravity(Gravity.CENTER);
                ll.addView(tv);
            }
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        return convertView;
    }

I hope these edits help!

RoboCop87
  • 825
  • 1
  • 8
  • 21
  • You saved me thank you for this edit! Your adapter works great for xml cards and works great with XE16. All other solutions point towards deprecated solution. Thank you! – Clocker May 28 '14 at 12:48

2 Answers2

3

I had a similar problem on my project. To resolve it, I had to handle the "onFingerCountChanged" in the GestureDetector and desactivate the CardScrollView when i have 2 fingers count. So when I use one finger the cardscrollview scroll normaly and when I use two finger on can scroll in my card using the gestureDetector.

You code should look something like this :

    gestureDetector.setFingerListener(new GestureDetector.FingerListener() {
        @Override
        public void onFingerCountChanged(int previousCount, int currentCount) {
            if(currentCount == 2){
                yourCardScrollView.deactivate();
            }else{

                yourCardScrollView.activate();
            }

        }
        ....
    }
Jean Vacca
  • 46
  • 2
  • This looks like it will work, I'll test it out asap. Thanks for your answer! – RoboCop87 Mar 05 '14 at 10:29
  • I tried it out and while it did stop the cardscrollview from scrolling my scroll view still did not move. I can see the bar indicating that it has room to scroll, it just doesn't. I will edit my question to include my code and the code you provided. – RoboCop87 Mar 05 '14 at 16:43
  • Your problem is now to handle the scroll behavior in the scrollview. I'm not really sure how to handle it but you can use the setTwoFingerScrollListener of the gestureDetector to achieve this. – Jean Vacca Mar 06 '14 at 14:14
0

EDIT: I notice that my first answer is not work. I have another one. You can use following code in your Activity.

@Override
public boolean dispatchGenericMotionEvent(MotionEvent ev) {
    if (ev.getPointerCount() > 1) {
        return true;
    }
    return super.dispatchGenericMotionEvent(ev);
}

When dispatchGenericMotionEvent actives, detect if pointer is greater than one (muit-touch), return true and consume it.

I tested, but still have bug. https://code.google.com/p/google-glass-api/issues/detail?id=632
Reply me if it works.

Johnny
  • 1,824
  • 23
  • 16
  • Thanks for your answer Johnny! The code segment you provided doesn't seem to address what to do when the two finger swipe is detected, it just lets you know one of the or'ed events happened. How would you handle scrolling through the scrollview when a two finger swipe gesture is detected? – RoboCop87 Nov 11 '14 at 04:05