Android 사용자 정의 View 등급 슬라이더 구현 인 스 턴 스
구현 효과 도:
생각:
먼저 직선 을 그리고 등분 직선 으로 점 을 그립 니 다.
점 을 그 릴 때 X 값 을 집합 에 저장 합 니 다.
그리고 배경 그림 과 그림 의 숫자 를 그립 니 다.
이벤트 다운 을 클릭 할 때 작은 그림 을 큰 그림 으로 바 꿉 니 다.이동 할 때 손가락 을 따라 이동 합 니 다.
up 은 이때 X 에 따라 가장 가 까 운 집합 점 을 계산 한 후 자동 으로 흡착 합 니 다.
1,사용자 정의 속성
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="BeautySeekBarView">
<attr name="valueCountent" format="integer"/>
<attr name="padding" format="dimension"/>
<attr name="pointColor" format="color"/>
<attr name="lineColor" format="color"/>
<attr name="smallPic" format="reference"/>
<attr name="bigPic" format="reference"/>
</declare-styleable>
</resources>
그리고 속성 획득:
/**
*
*/
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(
TypedValue.COMPLEX_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<valueCountent;i++){
PointX=i*averageLength+getPaddingLeft();
canvas.drawPoint(PointX, PointY, pointPaint);//
if(pointList!=null && pointList.size()<valueCountent){
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<Float> pointList;// point
private HashMap<Float, Float> 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(
TypedValue.COMPLEX_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<Float>();
mHashMap=new HashMap<Float, Float>();
}
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<valueCountent;i++){
PointX=i*averageLength+getPaddingLeft();
canvas.drawPoint(PointX, PointY, pointPaint);//
if(pointList!=null && pointList.size()<valueCountent){
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:
<com.example.hello.BeautySeekBarView
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);
}
});
}
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.