2014-02-05 17 views

Antwort

1

Es gibt derzeit kein native GDK UI-Element zum Scrollen einer Liste mit Sensoren (in der Tat, nach this issue scheint die Verwendung von ListView überhaupt nicht angezeigt zu werden).

Allerdings konnte ich folgendes erreichen, um in my app einigermaßen gut zu funktionieren. Meine Liste ist auf 4 Elemente festgelegt (was hilft zu bestimmen, wie viel Scrollen stattfindet), so dass Sie dies entsprechend anpassen können (siehe Kommentare).

import com.google.android.glass.media.Sounds; 
import com.google.android.glass.touchpad.Gesture; 
import com.google.android.glass.touchpad.GestureDetector; 

import android.content.Context; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.media.AudioManager; 
import android.view.MotionEvent; 
import android.widget.ListView; 

/** 
* Implements sensor-based scrolling of a ListView 
*/ 
public class SensorListController implements SensorEventListener, GestureDetector.BaseListener { 

    static final String TAG = "SensorListController"; 

    Context mContext; 

    ListView mList; 

    SensorManager mSensorManager; 

    private float[] mRotationMatrix = new float[16]; 

    private float[] mOrientation = new float[9]; 

    private float[] history = new float[2]; 

    private float mHeading; 

    private float mPitch; 

    boolean mActive = true; 

    GestureDetector mGestureDetector; 

    public SensorListController(Context context, ListView list) { 
     this.mContext = context; 
     this.mList = list; 
     history[0] = 10; 
     history[1] = 10; 
     mGestureDetector = new GestureDetector(mContext); 
     mGestureDetector.setBaseListener(this); 
    } 

    /** 
    * Receive pass-through of event from View 
    */ 
    public boolean onMotionEvent(MotionEvent event) { 
     return mGestureDetector.onMotionEvent(event); 
    } 

    @Override 
    public boolean onGesture(Gesture gesture) { 
     switch (gesture) { 
      case TWO_LONG_PRESS: 
       // Toggle on and off accelerometer control of the list by long press 
       playSuccessSound(); 
       toggleActive(); 
       return true; 
      case TWO_TAP: 
       // Go to top of the list 
       playSuccessSound(); 
       scrollToTop(); 
       return true; 
     } 
     return false; 
    } 

    /** 
    * Should be called from the onResume() of Activity 
    */ 
    public void onResume() { 
     mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); 
     mSensorManager.registerListener(this, 
      mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), 
      SensorManager.SENSOR_DELAY_UI); 
    } 

    /** 
    * Should be called from the onPause() of Activity 
    */ 
    public void onPause() { 
     mSensorManager.unregisterListener(this); 
    } 

    /** 
    * Toggles whether the controller modifies the view 
    */ 
    public void toggleActive() { 
     mActive = !mActive; 
    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     if (mList == null || !mActive) { 
      return; 
     } 

     if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 
      SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values); 
      SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, 
       SensorManager.AXIS_Z, mRotationMatrix); 
      SensorManager.getOrientation(mRotationMatrix, mOrientation); 

      mHeading = (float) Math.toDegrees(mOrientation[0]); 
      mPitch = (float) Math.toDegrees(mOrientation[1]); 

      float xDelta = history[0] - mHeading; // Currently unused 
      float yDelta = history[1] - mPitch; 

      history[0] = mHeading; 
      history[1] = mPitch; 

      float Y_DELTA_THRESHOLD = 0.13f; 

//   Log.d(TAG, "Y Delta = " + yDelta); 

      int scrollHeight = mList.getHeight() 
       /19; // 4 items per page, scroll almost 1/5 an item 

//   Log.d(TAG, "ScrollHeight = " + scrollHeight); 

      if (yDelta > Y_DELTA_THRESHOLD) { 
//    Log.d(TAG, "Detected change in pitch up..."); 
       mList.smoothScrollBy(-scrollHeight, 0); 
      } else if (yDelta < -Y_DELTA_THRESHOLD) { 
//    Log.d(TAG, "Detected change in pitch down..."); 
       mList.smoothScrollBy(scrollHeight, 0); 
      } 
     } 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
    } 

    private void scrollToTop() { 
     mList.smoothScrollToPosition(0); 
    } 

    private void playSuccessSound() { 
     // Play sound to acknowledge action 
     AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 
     audio.playSoundEffect(Sounds.SUCCESS); 
    } 
} 

Ich habe das oben in einer ListActivity verwendet. Ich initialisieren es in onCreate(), und hier ist die Methode, die es initialisiert:

private void initListController() { 
    mListView = getListView(); 
    mListView.setChoiceMode(ListView.CHOICE_MODE_NONE); 
    mListView.setSelector(android.R.color.transparent); 
    mListView.setClickable(true); 

    mListController = new SensorListController(this, mListView); 
} 

es transparent, indem sie diese auch entfernt den Auswahlindikatoren aus dem Blickfeld.

Der obige Controller verwendet auch zwei Finger drücken, um das Scrollen anzuhalten/fortzusetzen, und zwei Finger tippen, um zum Anfang der Liste zu blättern (und bestätigt diese beiden Aktionen mit einem Ton). Beachten Sie, dass für diese Gesten zu arbeiten, müssen Sie onGenericMotionEvent() in Ihrer Aktivität außer Kraft zu setzen und den Fall passieren, wie:

@Override 
public boolean onGenericMotionEvent(MotionEvent event) { 
    // We need to pass events through to the list controller 
    if (mListController != null) { 
     return mListController.onMotionEvent(event); 
    } 
    return false; 
} 

Der vollständige Quellcode für diese Lösung on Github zu sehen ist, und die APK kann here heruntergeladen werden .

Verwandte Themen