自己写的自定义View,M收音机频率view,85MHz-108MHz。写得比较复杂,采用缓存画图,有很多地方需要改善。
直接看代码:
package com.example.viewmodel;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class FrequencyView extends View
{
private int minFrequency=850; //85MHz
private int maxFrequency=1080; //108MHz
private int defaultWidth=0;
private int defaultHeight=0;
private int frequency=0;
private int span=0;
private int curX=0;
private int curY=0;
private int centerX=0;
private int centerY=0;
private int startX=0;
private int endX=0;
private Canvas cacheCanvas=null;
private Bitmap cacheBitmap=null;
private Paint mPaint=null;
private boolean isFirstInitial=true;
private FrequencyChangedListener mListener=null;
private List<Integer> freList=null;
private List<Integer> posList=null;
public FrequencyView(Context context)
{
super(context);
initView();
}
public FrequencyView(Context context,@Nullable AttributeSet attrs)
{
super(context,attrs);
initView();
}
public FrequencyView(Context context,@Nullable AttributeSet attrs,int defStyleAttr)
{
super(context,attrs,defStyleAttr);
initView();
}
public void initView()
{
cacheCanvas=new Canvas();
mPaint=new Paint(Paint.DITHER_FLAG);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
freList=new ArrayList<Integer>();
posList=new ArrayList<Integer>();
isFirstInitial=true;
frequency=(maxFrequency+minFrequency)/2;
}
@Override
public void onMeasure(int widthMeasureSpec,int heightMeasureSpec)
{
defaultWidth=View.MeasureSpec.getSize(widthMeasureSpec);
defaultHeight=View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(defaultWidth,defaultHeight);
cacheBitmap=Bitmap.createBitmap(defaultWidth,defaultHeight,Bitmap.Config.ARGB_8888);
cacheCanvas.setBitmap(cacheBitmap);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x=event.getX(),y=event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
mPaint.setColor(Color.WHITE);
RectF rf=new RectF(0,0,defaultWidth,defaultHeight);
cacheCanvas.drawRect(rf, mPaint);
drawBackground(cacheCanvas);
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
frequency=matchFrequency(x);
mPaint.setColor(Color.RED);
mPaint.setTextSize(50);
mPaint.setStrokeWidth(8);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
cacheCanvas.drawText(String.valueOf(frequency/10.0)+"MHz", centerX, centerY-40, mPaint);
mPaint.setStrokeWidth(2);
cacheCanvas.drawLine(curX, centerY+5, curX, defaultHeight, mPaint);
break;
}
invalidate();
return true;
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
drawBackground(canvas);
Paint paint=new Paint();
canvas.drawBitmap(cacheBitmap, 0,0, paint);
if(mListener!=null)
{
mListener.onFrequencyChanged(frequency);
}
}
public int matchFrequency(float x)
{
//double k=(maxFrequency-minFrequency)/(endX-startX);
//DecimalFormat dcmFmt=new DecimalFormat("0.000");
//double m=Double.parseDouble(dcmFmt.format(k));
double k=(double)(maxFrequency-minFrequency)/(double)(endX-startX);
double curFre=k*((int)(x-startX))+minFrequency;
int position=-1;
for(int i:freList)
{
position++;
if((curFre>=i) && (curFre<=(i+1)))
{
if(curFre>((double)(2*i+1)/2))
{
curFre=i+1;
curX=posList.get(position+1);
}
else
{
curFre=i;
curX=posList.get(position);
}
}
if(curFre>maxFrequency)
{
curFre=maxFrequency;
curX=posList.get(posList.size()-1);
}
if(curFre<minFrequency)
{
curFre=minFrequency;
curX=posList.get(0);
}
}
return (int)curFre;
}
public void drawBackground(Canvas canvas)
{
Paint paint=new Paint();
paint.setColor(Color.WHITE);
RectF rf=new RectF(0,0,defaultWidth,defaultHeight);
canvas.drawRect(rf, paint);
centerX=defaultWidth/2;
centerY=defaultHeight/2;
curX=centerX;
curY=centerY;
int centerFrequency=(maxFrequency+minFrequency)/2;
paint.setColor(Color.BLUE);
paint.setStrokeWidth(6);
int length=defaultWidth;
span=(length)/(maxFrequency-minFrequency+1);
startX=centerX;
for(int i=centerFrequency;i>=minFrequency;i--)
{
if(isFirstInitial)
{
freList.add(i);
posList.add(startX);
}
if(0==i%10)
{
paint.setStrokeWidth(6);
canvas.drawLine(startX, centerY+10, startX, defaultHeight-10, paint);
paint.setTextSize(20);
paint.setStyle(Paint.Style.FILL);
if(minFrequency==i)
{
paint.setTextAlign(Paint.Align.LEFT);
}
else
{
paint.setTextAlign(Paint.Align.CENTER);
}
canvas.drawText(String.valueOf(i/10.0)+"MHz",startX,centerY-5,paint);
startX-=span;
continue;
}
paint.setStrokeWidth(3);
canvas.drawLine(startX, centerY+40, startX, defaultHeight-10, paint);
startX-=span;
}
endX=centerX+span;
for(int i=centerFrequency+1;i<=maxFrequency;i++)
{
if(isFirstInitial)
{
freList.add(i);
posList.add(endX);
}
if(0==i%10)
{
paint.setStrokeWidth(6);
canvas.drawLine(endX, centerY+10, endX, defaultHeight-10, paint);
paint.setTextSize(20);
paint.setStyle(Paint.Style.FILL);
if(minFrequency==i)
{
paint.setTextAlign(Paint.Align.RIGHT);
}
else
{
paint.setTextAlign(Paint.Align.CENTER);
}
canvas.drawText(String.valueOf(i/10.0)+"MHz",endX,centerY-5,paint);
endX+=span;
continue;
}
paint.setStrokeWidth(3);
canvas.drawLine(endX, centerY+40, endX, defaultHeight-10, paint);
endX+=span;
}
Collections.sort(freList);
Collections.sort(posList);
paint.setStrokeWidth(3);
startX+=span;
endX-=span;
canvas.drawLine(startX, defaultHeight-10, endX, defaultHeight-10, paint);
if(isFirstInitial)
{
firstDraw(cacheCanvas);
}
isFirstInitial=false;
invalidate();
}
public void firstDraw(Canvas canvas)
{
Paint paint=new Paint();
paint.setColor(Color.RED);
paint.setTextSize(50);
paint.setStrokeWidth(8);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(String.valueOf(frequency/10.0)+"MHz", centerX, centerY-40, paint);
paint.setStrokeWidth(2);
canvas.drawLine(centerX, centerY+5, centerX, defaultHeight, paint);
}
//dip tranfer to px
public int dp2px(int dip)
{
return (int)(dip*(this.getResources().getDisplayMetrics().density)+0.5f);
}
public void setOnFrequencyChangedListener(FrequencyChangedListener listener)
{
this.mListener=listener;
}
public void setMinFrequency(int minf)
{
this.minFrequency=minf;
}
public int getMinFrequency()
{
return this.minFrequency;
}
public void setMaxFrequency(int maxf)
{
this.maxFrequency=maxf;
}
public int getMaxFrequency()
{
return this.maxFrequency;
}
//监听接口
interface FrequencyChangedListener
{
public void onFrequencyChanged(int frequency);
}
}