我在使用背景着色器作为背景图片时遇到了一些令人讨厌的事情:即使纠正了position offset,也存在宽度不匹配。
此处提供了一个最小项目:http://ge.tt/6UonbQ42/v/0
以下是结果的屏幕截图:
红线应与背景同步。对于渐变的第一站,它是可以的,但最后,有一个偏移。有没有办法以编程方式知道这个偏移量,还是我必须硬编码一个适用于我的设备的猜测值?
这是主要代码:
package com.example.androidplottest;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.os.Bundle;
import android.view.View;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYSeries;
public class MainActivity extends Activity {
public class Tuple<E> {
public E x, y;
public Tuple(E x, E y) {
this.x = x;
this.y = y;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void drawPlot(View view) {
XYPlot plot = (XYPlot) findViewById(R.id.plot);
// Test data
ArrayList<Tuple<Float>> data = new ArrayList<MainActivity.Tuple<Float>>();
data.add(new Tuple<Float>(5f, 10f));
data.add(new Tuple<Float>(5.1f, 150f));
data.add(new Tuple<Float>(5.2f, 10f));
data.add(new Tuple<Float>(5.3f, 150f));
data.add(new Tuple<Float>(5.4f, 10f));
data.add(new Tuple<Float>(9f, 150f));
data.add(new Tuple<Float>(9.1f, 10f));
data.add(new Tuple<Float>(9.2f, 150f));
data.add(new Tuple<Float>(9.3f, 10f));
data.add(new Tuple<Float>(9.4f, 150f));
data.add(new Tuple<Float>(9.5f, 10f));
data.add(new Tuple<Float>(9.6f, 150f));
data.add(new Tuple<Float>(9.7f, 10f));
data.add(new Tuple<Float>(9.8f, 150f));
data.add(new Tuple<Float>(9.9f, 10f));
data.add(new Tuple<Float>(10f, 150f));
// Create series
plot.addSeries(tupleArrayToXYSeries(data, "Data set"), new LineAndPointFormatter(Color.RED, null, null, null));
// Find the dynamic range
float max = data.get(0).y;
float min = data.get(0).y;
for(Tuple<Float> hb : data) {
if(hb.y > max) max = hb.y;
if(hb.y < min) min = hb.y;
}
// Color bounds
float minSat=0, maxSat=1;
float minVal=0f, maxVal=1;
// Target color
int[] gradientColors = new int[data.size()];
for(int i=0; i<data.size(); i++) {
float hue = 120;
float sat = Math.max(0, Math.min(1, (data.get(i).y-min)/(max-min)*(maxSat-minSat)+minSat));
float val = Math.max(0, Math.min(1, (data.get(i).y-min)/(max-min)*(maxVal-minVal)+minVal));
int color = Color.HSVToColor(new float[] {hue, sat, val});
gradientColors[i] = color;
}
// Get times
float[] timesArray = new float[data.size()];
int i = 0;
for (Tuple<Float> f : data) {
timesArray[i++] = (f != null ? (f.x-data.get(0).x)/(data.get(data.size()-1).x-data.get(0).x) : Float.NaN);
}
// Set the plot background (shader translation due to this bug:
// https://stackoverflow.com/questions/24738800/androidplot-background-image-shift)
plot.getGraphWidget().setGridPadding(0, 0, 0, 0);
plot.getGraphWidget().getGridRect();
RectF rect = plot.getGraphWidget().getGridRect();
Shader colorShader = new LinearGradient(0, 0, rect.width(), 0, gradientColors, timesArray, TileMode.CLAMP);
Matrix m = new Matrix();
m.setTranslate(rect.left, rect.top);
colorShader.setLocalMatrix(m);
plot.getGraphWidget().getGridBackgroundPaint().setColor(Color.WHITE);
plot.getGraphWidget().getGridBackgroundPaint().setShader(colorShader);
plot.redraw();
}
private XYSeries tupleArrayToXYSeries(ArrayList<Tuple<Float>> tuplesArray, String title) {
ArrayList<Float> xList = new ArrayList<Float>();
ArrayList<Float> yList = new ArrayList<Float>();
for(Tuple<Float> tuple : tuplesArray) {
xList.add(tuple.x);
yList.add(tuple.y);
}
return new SimpleXYSeries(xList, yList, title);
}
}