我必须创建一个产品热图,其外观与图片完全相同(但附件)。但产品数量可能会因要求而异。
到目前为止我尝试了什么: 1.尝试使用动态布局创建相同的地图,但是当产品数量在奇数中变化而不是我有一些空白时有问题。 2.尝试了一些类似的文件:AChartEngine,http://androidplot.com/
但仍然没有运气..
答案 0 :(得分:0)
这可以通过这种方式实现,但您应该自己实施分区策略,因为我还没有完成:
public class RectDrawable extends Drawable {
public static final int DEFAULT_SIZE = 100;
public static final int DEFAULT_COLOR = Color.BLUE;
private Point mSize = new Point(100, 100), mOffset = new Point(0, 0);
private Dimension mDimension = new Dimension();
private Paint mPaint = new Paint();
private void setSizeAndOffset(int width, int height, int offsetX, int offsetY) {
mSize.x = width;
mSize.y = height;
mOffset.x = offsetX;
mOffset.y = offsetY;
}
public RectDrawable(int color) {
mPaint.setColor(color);
}
public RectDrawable(int width, int height, int offsetX, int offsetY, int color) {
this(color);
mDimension.size.x = width;
mDimension.size.y = height;
mDimension.offset.x = offsetX;
mDimension.offset.y = offsetY;
}
public RectDrawable(Point size, Point offset, int color) {
this(color);
mDimension.size.x = size.x;
mDimension.size.y = size.y;
mDimension.offset.x = offset.x;
mDimension.offset.y = offset.y;
}
public void setStyle(Paint.Style style) {
mPaint.setStyle(style);
}
public void setColor(int color) {
mPaint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
canvas.drawRect(mDimension.offset.x, mDimension.offset.y, mDimension.offset.x + mDimension.size.x, mDimension.offset.y + mDimension.size.y, mPaint);
}
@Override
public void setAlpha(int i) {
mPaint.setAlpha(i);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 0;
}
}
public static abstract class DrawInstructionHolder {
protected float weight;
protected int color;
}
public static class Product extends DrawInstructionHolder {
private int color;
private String name;
private int volume;
public Product(int color, String name, int volume, float weight) {
this.color = color;
this.name = name;
this.volume = volume;
if (weight > 1f)
throw new IllegalArgumentException("The weight has to be in between the range of 0f to 1f!");
this.weight = weight;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
public static List<Product> getDemoCollection() {
List<Product> products = new ArrayList<Product>();
products.add(new Product(Color.YELLOW, "Coragen", 190, 0.2f));
products.add(new Product(Color.RED, "Record", 126, 0.5f));
products.add(new Product(Color.GREEN, "Furzate", 316, 0.1f));
products.add(new Product(Color.BLUE, "Ferterra", 190, 0.2f));
return products;
}
}
public class Dimension {
public Point size, offset;
public Dimension() {
size = new Point();
offset = new Point();
}
public Dimension(Point size, Point offset) {
this.size = size;
this.offset = offset;
}
}
public class HeatMapView extends View {
public DimensionResolveStrategy randomRecDimensionResolveStrategy = new DimensionResolveStrategy() {
@Override
public List<Dimension> calculateDimensions(Canvas canvas, List<? extends DrawInstructionHolder> items, int columns) {
final List<Dimension> dimensions = new ArrayList<Dimension>();
final int width = canvas.getWidth(), height = canvas.getHeight();
final Point size = new Point(width, height), offset = new Point();
final Random random = new Random(System.currentTimeMillis());
final float totalSpace = width * height;
float currentSpace = totalSpace;
//Trivial cases
if (items.size() <= 1) {
dimensions.add(new Dimension(size, offset));
return dimensions;
}
//Randomily evaluate the dimensions of the first item
currentSpace = (int) (items.get(0).weight * totalSpace);
size.x = random.nextInt((int) (width % currentSpace)) + 1;
size.y = (int) (currentSpace / size.x);
dimensions.add(new Dimension(size, offset));
for (int i = 1; i < items.size(); i++) {
//Do your magic here
}
return dimensions;
}
};
public List<Product> mProducts = Product.getDemoCollection();
public DimensionResolveStrategy mDimResolver;
public List<Dimension> mDimensions;
private int mColumns = 2;
private RectDrawable rectDrawable = new RectDrawable(Color.GREEN);
public HeatMapView(Context context, List dimensions, DimensionResolveStrategy dimensionResolveStrategy) {
super(context);
mDimensions = dimensions;
mDimResolver = dimensionResolveStrategy;
}
public HeatMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HeatMapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
Dimension dimension;
mDimensions = mDimResolver.calculateDimensions(canvas, mProducts, mColumns);
if (mProducts.size() != mDimensions.size())
throw new IllegalStateException("Arraylengths of drawing instructions and dimensions are not matching, " +
"look into your calculateDimensions(..) function of your DimensionResolveStrategy instance! ");
for (int i = 0; i < mProducts.size(); i++) {
dimension = mDimensions.get(1);
rectDrawable.setSizeAndOffset(dimension.size.x, dimension.size.y, dimension.offset.x, dimension.offset.y);
rectDrawable.setColor(mProducts.get(i).color);
rectDrawable.draw(canvas);
}
}
}
public interface DimensionResolveStrategy {
public List<Dimension> calculateDimensions(Canvas canvas, List<? extends DrawInstructionHolder> items, int columns);
}