我已经为此工作了大约两天,但仍然没有弄清楚如何使其工作。我有一个视差效果,该效果实现了ImageView并使用加速度计来移动图像(例如Virtual Reality类型的应用程序)。它的效果很好,并且可以根据加速度计进行相应的滚动。
我想做的是设置一种“无限背景”,用户可以继续浏览四周,并且当到达一组特定坐标时会显示不同的图像。我通过等到用户到达某个特定点,然后使用setImageResource()绘制新图像来完成此操作。它有效,但是我的视差图像视图始终以(0,0)为中心。我需要它以新图像的边缘为中心。在下面的代码中,我尝试在configureMatrix()中更改mXTranslation变量并触发setTranslate(),它可以移动图像,但稍后会恢复为(0,0)。我怀疑传感器提供的数据如此之快,以至于我的更改出现后,下一个传感器数据就会被输入并覆盖(最终将其捕捉回到中心位置(0.0),但是我不确定。) >
我真的只想加载一个新图像(相同尺寸),并给它一种“无限背景”的感觉。任何有用的代码将不胜感激:
public ParallaxImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mTranslationMatrix = new Matrix();
mSensorInterpreter = new ParallaxSensorInterpreter();
setScaleType(ScaleType.MATRIX);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
configureMatrix();
}
@Override
public void onSensorChanged(SensorEvent event) {
if (mSensorInterpreter == null) return;
final float[] vectors = mSensorInterpreter.interpretSensorEvent(getContext(), event);
if (vectors == null) return;
setTranslate(-vectors[2], -vectors[1]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
public void registerSensorManager() {
registerSensorManager(SensorManager.SENSOR_DELAY_FASTEST);
}
public void registerSensorManager(int samplingPeriodUs) {
if (getContext() == null || mSensorManager != null) return;
mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager != null) {
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
samplingPeriodUs);
}
}
public void unregisterSensorManager() {
if (mSensorManager == null || mSensorInterpreter == null) return;
mSensorManager.unregisterListener(this);
mSensorManager = null;
mSensorInterpreter.reset();
}
public void setParallaxIntensity(float parallaxIntensity) {
mParallaxIntensity = parallaxIntensity;
configureMatrix();
}
public void setTiltSensitivity(float sensitivity) {
mSensorInterpreter.setTiltSensitivity(sensitivity);
}
public void setScaledIntensities(boolean scaledIntensities) {
mScaledIntensities = scaledIntensities;
}
public void setMaximumJump(float maximumJump) {
mMaximumJump = maximumJump;
}
private void setTranslate(float x, float y) {
float xScale, yScale;
if (mScaledIntensities) {
xScale = mXOffset;
yScale = mYOffset;
} else {
xScale = Math.max(mXOffset, mYOffset);
yScale = Math.max(mXOffset, mYOffset);
}
if (mMaximumJump > 0) {
if (x - mXTranslation / xScale > mMaximumJump) {
x = mXTranslation / xScale + mMaximumJump;
} else if (x - mXTranslation / xScale < -mMaximumJump) {
x = mXTranslation / xScale - mMaximumJump;
}
if (y - mYTranslation / yScale > mMaximumJump) {
y = mYTranslation / yScale + mMaximumJump;
} else if (y - mYTranslation / yScale < -mMaximumJump) {
y = mYTranslation / yScale - mMaximumJump;
}
} else {
}
mXTranslation = x * xScale;
mYTranslation = y * yScale;
configureMatrix();
}
private void configureMatrix() {
if (getDrawable() == null || getWidth() == 0 || getHeight() == 0) return;
int dWidth = getDrawable().getIntrinsicWidth();
int dHeight = getDrawable().getIntrinsicHeight();
int vWidth = getWidth();
int vHeight = getHeight();
float scale;
float dx, dy;
if (dWidth * vHeight > vWidth * dHeight) {
scale = (float) vHeight / (float) dHeight;
mXOffset = (vWidth - dWidth * scale * mParallaxIntensity) * 0.5f;
mYOffset = (vHeight - dHeight * scale * mParallaxIntensity) * 0.5f;
} else {
scale = (float) vWidth / (float) dWidth;
mXOffset = (vWidth - dWidth * scale * mParallaxIntensity) * 0.5f;
mYOffset = (vHeight - dHeight * scale * mParallaxIntensity) * 0.5f;
}
dx = mXOffset + mXTranslation;
dy = mYOffset + mYTranslation;
mTranslationMatrix.set(getImageMatrix());
mTranslationMatrix.setScale(mParallaxIntensity * scale, mParallaxIntensity * scale);
mTranslationMatrix.postTranslate(dx, dy);
setImageMatrix(mTranslationMatrix);
}