말하기 "ok glass"라고 말하면 사용자의 머리 동작에 따라 자동으로 스크롤되는 명령 목록이 나타납니다.머리 움직임으로 스크롤하는 내장 ScrollView
이것을 구현하는 GDK에 기본 제공 UI 요소가 있습니까? 아니면 센서를 사용하는 자체 코드를 작성해야합니까?
말하기 "ok glass"라고 말하면 사용자의 머리 동작에 따라 자동으로 스크롤되는 명령 목록이 나타납니다.머리 움직임으로 스크롤하는 내장 ScrollView
이것을 구현하는 GDK에 기본 제공 UI 요소가 있습니까? 아니면 센서를 사용하는 자체 코드를 작성해야합니까?
내가 https://developers.google.com/glass/develop/gdk/reference/index에 https://developers.google.com/glass/develop/gdk/dev-guides 및 참조에 GDK의 개발자 가이드를 통해 가서 확실히있다 이러한 내장 GDK에서 UI 요소, 그래서 지금의 대답은
12월 2013 년에 발표 XE (12)로 네 없다 센서를 사용하여 구현해야합니다.
사실 (센서를 사용하여 목록을 스크롤에 대한 기본 GDK UI 요소가 현재 없습니다 : 그것은 구글의 하나처럼 반짝 아니지만, 그 시작점이 될 수 있습니다 , ListView
의 사용은 전혀 권장되지 않습니다.)
그러나 나는 my app에서 합리적으로 잘 작동하려면 다음을 얻을 수있었습니다. 내 목록은 4 가지 요소 (스크롤이 얼마나 발생하는지 결정하는 데 도움이 됨)로 고정되어 있으므로 이에 맞게 조정할 수 있습니다 (주석 참조).
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);
}
}
위의 내용은 ListActivity
에 사용되었습니다. 나는 onCreate()
에서 초기화하고, 여기를 초기화하는 방법입니다 :
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);
}
이 또한 투명하여보기에서 선택 표시를 제거는.
위의 컨트롤러는 두 손가락을 사용하여 스크롤을 일시 중지/다시 시작하고 두 손가락을 사용하여 목록의 맨 위로 스크롤하여 소리와 함께 두 동작을 모두 인식합니다.
이 솔루션에 대한 전체 소스 코드를 on Github 볼 수 있고, APK가 here을 다운로드 할 수 있습니다@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;
}
: 이러한 제스처가 작동하려면, 당신은 당신의 활동에 onGenericMotionEvent()
을 무시하고 같은 이벤트를 통과 할 필요가 있습니다 .