700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android 自定义view滚动条 Android自定义View实现等级滑动条的实例

android 自定义view滚动条 Android自定义View实现等级滑动条的实例

时间:2019-03-21 05:57:58

相关推荐

android 自定义view滚动条 Android自定义View实现等级滑动条的实例

Android自定义View实现等级滑动条的实例

实现效果图:

思路:

首先绘制直线,然后等分直线绘制点;

绘制点的时候把X值存到集合中。

然后绘制背景图片,以及图片上的数字。

点击事件down的时候,换小图片为大图片。move的时候跟随手指移动。

up的时候根据此时的X计算最近的集合中的点,然后自动吸附回去。

1,自定义属性

然后获取属性:

/**

* 获得我们所定义的自定义样式属性

*/

TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BeautySeekBarView, defStyleAttr, 0);

//等级数量即点的个数

valueCountent=a.getInteger(R.styleable.BeautySeekBarView_valueCountent, 5);

//点的颜色

pointColor = a.getColor(R.styleable.BeautySeekBarView_pointColor, Color.WHITE);

//线的颜色

lineColor = a.getColor(R.styleable.BeautySeekBarView_lineColor, Color.WHITE);

//小图片

smallPic=a.getResourceId(R.styleable.BeautySeekBarView_smallPic, R.drawable.ic_launcher);

//滑动过程中的大图片

bigPic=a.getResourceId(R.styleable.BeautySeekBarView_bigPic, R.drawable.ic_launcher);

//控件的内边距

viewPadding=a.getDimensionPixelSize(R.styleable.BeautySeekBarView_padding, (int) TypedValue.applyDimension(

PLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

a.recycle();

2.绘制

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

float PointX = 0;

float PointY=getHeight()/2;

canvas.drawLine(0+getPaddingLeft(),PointY, getWidth()-getPaddingRight(), PointY, linePaint); //绘制直线

int averageLength =(getWidth()-getPaddingLeft()-getPaddingRight())/(valueCountent-1);

for(int i=0;i

PointX=i*averageLength+getPaddingLeft();

canvas.drawPoint(PointX, PointY, pointPaint);//绘制点

if(pointList!=null && pointList.size()

pointList.add(PointX);//把每个点都放入集合中;

}

}

sePoolTH.release();

canvas.drawBitmap(mBitmap, bitmapPointX-bitmapWidth/2, PointY-bitmapHeight/2, null);//绘制拖动的图片

canvas.drawText(""+index, bitmapPointX, (getHeight() - fontMetrics.ascent - fontMetrics.descent) / 2, textPaint); //绘制文字

}

全部代码如下

import java.util.ArrayList;

import java.util.HashMap;

import java.util.concurrent.Semaphore;

import android.R.integer;

import android.animation.ValueAnimator;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.FontMetricsInt;

import android.util.AttributeSet;

import android.util.Log;

import android.util.TypedValue;

import android.view.MotionEvent;

import android.view.View;

public class BeautySeekBarView extends View {

private Semaphore sePoolTH=new Semaphore(0);//信号量,解决并发问题

private int valueCountent;//等级点的数量

private int pointColor;

private int lineColor;

private Bitmap mBitmap;

private int bitmapWidth;

private int bitmapHeight;

private float bitmapPointX;

private ArrayList pointList;//储存画出的点的point值

private HashMap mHashMap;把差值和listX当做键值对保存起来,便于后期找出

private int index=1;//索引

private float mListX;//移动后最小的点

private int smallPic;

private int bigPic;

private int viewPadding;

private Paint pointPaint;

private Paint linePaint;

private Paint textPaint;

private FontMetricsInt fontMetrics;

public BeautySeekBarView(Context context) {

this(context,null);

}

public BeautySeekBarView(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public BeautySeekBarView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

/**

* 获得我们所定义的自定义样式属性

*/

TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BeautySeekBarView, defStyleAttr, 0);

//等级数量即点的个数

valueCountent=a.getInteger(R.styleable.BeautySeekBarView_valueCountent, 5);

//点的颜色

pointColor = a.getColor(R.styleable.BeautySeekBarView_pointColor, Color.WHITE);

//线的颜色

lineColor = a.getColor(R.styleable.BeautySeekBarView_lineColor, Color.WHITE);

//小图片

smallPic=a.getResourceId(R.styleable.BeautySeekBarView_smallPic, R.drawable.ic_launcher);

//滑动过程中的大图片

bigPic=a.getResourceId(R.styleable.BeautySeekBarView_bigPic, R.drawable.ic_launcher);

//控件的内边距

viewPadding=a.getDimensionPixelSize(R.styleable.BeautySeekBarView_padding, (int) TypedValue.applyDimension(

PLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

a.recycle();

initData();//初始化数据

initPaint();//初始化画笔

}

public void initData() {

// valueCountent=7;

// pointColor=Color.WHITE;

// lineColor=Color.WHITE;

// setBackgroundColor(Color.BLACK);

setPadding(viewPadding, viewPadding, viewPadding, viewPadding);

bitmapPointX=getPaddingLeft();

mBitmap=BitmapFactory.decodeResource(getResources(), smallPic);

bitmapWidth=mBitmap.getWidth();

bitmapHeight=mBitmap.getHeight();

pointList=new ArrayList();

mHashMap=new HashMap();

}

public void initPaint() {

pointPaint=new Paint();

pointPaint.setColor(pointColor);

pointPaint.setStyle(Paint.Style.FILL);

pointPaint.setStrokeWidth(10);

pointPaint.setStrokeJoin(Paint.Join.ROUND);

pointPaint.setStrokeCap(Paint.Cap.ROUND);

pointPaint.setAntiAlias(true);

linePaint=new Paint();

linePaint.setColor(lineColor);

linePaint.setStyle(Paint.Style.STROKE);

linePaint.setStrokeWidth(4);

linePaint.setAntiAlias(true);

textPaint=new Paint();

textPaint.setStrokeWidth(3);

textPaint.setTextSize(24);

textPaint.setColor(Color.WHITE);

textPaint.setTextAlign(Paint.Align.CENTER);

fontMetrics = textPaint.getFontMetricsInt();

textPaint.setAntiAlias(true);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

float PointX = 0;

float PointY=getHeight()/2;

canvas.drawLine(0+getPaddingLeft(),PointY, getWidth()-getPaddingRight(), PointY, linePaint); //绘制直线

int averageLength =(getWidth()-getPaddingLeft()-getPaddingRight())/(valueCountent-1);

for(int i=0;i

PointX=i*averageLength+getPaddingLeft();

canvas.drawPoint(PointX, PointY, pointPaint);//绘制点

if(pointList!=null && pointList.size()

pointList.add(PointX);//把每个点都放入集合中;

}

}

sePoolTH.release();

canvas.drawBitmap(mBitmap, bitmapPointX-bitmapWidth/2, PointY-bitmapHeight/2, null);//绘制拖动的图片

canvas.drawText(""+index, bitmapPointX, (getHeight() - fontMetrics.ascent - fontMetrics.descent) / 2, textPaint); //绘制文字

}

long startTime = 0;

@Override

public boolean onTouchEvent(MotionEvent event) {

//获取手指的操作--》按下、移动、松开

int action = event.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

startTime=System.currentTimeMillis();

mBitmap=BitmapFactory.decodeResource(getResources(), bigPic);

bitmapWidth=mBitmap.getWidth();

bitmapHeight=mBitmap.getHeight();

textPaint.setTextSize(30);

//invalidate();

break;

case MotionEvent.ACTION_MOVE:

long endTimeMove=System.currentTimeMillis();

if(endTimeMove-startTime>100){//如果按下,抬起时间过大才认为是拖动,要执行动画。

bitmapPointX=event.getX();

updateIndex(bitmapPointX);

invalidate();

}

break;

case MotionEvent.ACTION_UP:

long endTime=System.currentTimeMillis();

bitmapPointX=event.getX();

mBitmap=BitmapFactory.decodeResource(getResources(),smallPic);

bitmapWidth=mBitmap.getWidth();

bitmapHeight=mBitmap.getHeight();

textPaint.setTextSize(24);

if(endTime-startTime>200){//如果按下,抬起时间过大才认为是拖动,要执行动画。

updateBitmapUI(bitmapPointX);

}else{

bitmapPointX=updateIndex(bitmapPointX);

invalidate();

}

startTime = 0;

break;

}

return true;

}

//更新索引

public float updateIndex(float pointX){

float lastValue=100000;

float currentValue=0;

float minValue=0;

for(float listX:pointList){

currentValue= Math.abs(pointX-listX);

mHashMap.put(currentValue, listX);//把差值和listX当做键值对保存起来,便于后期找出

minValue=Math.min(lastValue,currentValue);

lastValue=minValue;

}

if(mHashMap.containsKey(minValue)){

mListX=mHashMap.get(minValue);

}else{

Log.e("BeautySeekBarView", "updateBitmapUI--->mHashMap.containsKey(minValue) is null");

return -1;

}

if(pointList.contains(mListX)){

index=pointList.indexOf(mListX)+1;

if(mListener!=null){

mListener.getIndex(index);

}

}else{

Log.e("BeautySeekBarView", "updateBitmapUI--->pointList.contains(mListX) is null");

return -1;

}

return mListX;

}

//当手指抬起后更新Bitmap的位置

private void updateBitmapUI(float PointX2) {

mListX=updateIndex(PointX2);

//执行动画

ValueAnimator anim = ValueAnimator.ofFloat(PointX2, mListX);

anim.setDuration(50);

anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

bitmapPointX =(Float) animation.getAnimatedValue();

invalidate();

}

});

anim.start();

}

//设置等级点的数量

public void pointValueCountent(int countent){

if(countent<2){

valueCountent=2;

}else{

valueCountent=countent;

}

invalidate();

}

//设置默认位置

public void setPointLocation(final int location){

new Thread(new Runnable() {

@Override

public void run() {

try {

sePoolTH.acquire();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

if(location>0&&pointList!=null&& !pointList.isEmpty()){

bitmapPointX=pointList.get(location-1);

postInvalidate();

}

}

}).start();

}

//提供接口回调,获取索引

private indexListener mListener=null;

public interface indexListener{

void getIndex(int index);

}

public void setIndexListener(indexListener listener){

mListener=listener;

}

}

外部调用:

XML:

android:id="@+id/myView"

android:layout_centerVertical="true"

android:layout_width="match_parent"

android:layout_height="100dp"

ws:padding="20dp"

ws:valueCountent="6"

ws:pointColor="#FFFFFF"

ws:lineColor="#FFFFFF"

ws:smallPic="@drawable/beauty_seekbar_point"

ws:bigPic="@drawable/beauty_seekbar_point_big"/>

Java:

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

beautySeekBarView.setPointLocation(2) ;

//

}

private void initView() {

mTextView=(TextView) findViewById(R.id.tv);

beautySeekBarView=(BeautySeekBarView) findViewById(R.id.myView);

beautySeekBarView.setIndexListener(new indexListener() {

@Override

public void getIndex(int index) {

mTextView.setText("index="+index);

}

});

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。