안드로메트릭 IOS 날짜 또는 시간 선택기 WheelPicker
8388 단어 android 기술android
프로젝트에서 IOS를 모방한 시간 날짜 선택기를 사용했어요. 응, 바로 그런 롤러 효과예요. 더 말할 것도 없고 효과부터 봐요!
블로그를 쓸 줄 모르는구나, 움짤을 만들 줄 모른다는 뜻이다.이 그림을 보면 알 수 있을 텐데, 바로 이 효과다.
아, 먼저 설명해 드릴게요. 이것은 다른 사람의 코드를 참고하여 이루어진 것입니다. 비록 변경이 있었지만 저도 오리지널은 말하지 않겠습니다. 그냥 전재로 하겠습니다.
이어서 코드를 올려라!
import java.util.ArrayList;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class WheelPicker extends View {
private Context mContext;
private int mViewHeight;
private int mViewWidth;
/** */
private int mCenterItemHeight;
private int mCenterY;
private float mLastDownY; //
private float mMoveDistanceY = 0;
/** */
private int mCurrentDataIndex = 0;
/** */
private Paint mTextPaint;
/** */
private Paint mLinePaint;
/** */
private int mMaxTextSize;
/** */
private float mGapRatio = 0;
/** */
private boolean mIsTouchEnable = true;
/** */
private boolean mIsTouchDownEnable = true;
/** */
private boolean mIsTouchUpEnable = true;
private ArrayList mDataList = new ArrayList();
private OnScrollItemIndexListener indexListener;
public void setOnScrollItemIndexListener(OnScrollItemIndexListener indexListener){
this.indexListener = indexListener;
}
public WheelPicker(Context context) {
super(context);
init(context);
}
public WheelPicker(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
this.mContext = context;
mTextPaint = new Paint();
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setColor(0xff1f1f1f);
mLinePaint = new Paint();
mLinePaint.setStyle(Paint.Style.FILL);
mLinePaint.setTextAlign(Paint.Align.CENTER);
mLinePaint.setColor(0xff1f1f1f);
}
public void setData(ArrayList mDataList, int index){
mCurrentDataIndex = index;
this.mDataList.clear();
this.mDataList.addAll(mDataList);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mViewHeight = getMeasuredHeight();
mViewWidth = getMeasuredWidth();
mCenterY = mViewHeight/2;
mMaxTextSize = mViewHeight/10;
mCenterItemHeight = mViewHeight/4;
mGapRatio = 0.7f;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(mIsTouchEnable) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
onActionDown(event);
break;
case MotionEvent.ACTION_MOVE:
onActionMove(event);
break;
case MotionEvent.ACTION_UP:
onActionUp(event);
break;
}
}
return true;
}
private void onActionDown(MotionEvent event){
mLastDownY = event.getY();
//mMoveDistanceY = 0;
}
private void onActionMove(MotionEvent event){
float currentY = event.getY();
float diff = currentY - mLastDownY;
if(mIsTouchUpEnable && mIsTouchDownEnable) {
mMoveDistanceY += diff;
}else if(!mIsTouchUpEnable && mIsTouchDownEnable){ //
if(diff > 0){
mMoveDistanceY += diff;
mIsTouchUpEnable = true;
}
}else if(mIsTouchUpEnable && !mIsTouchDownEnable){ //
if(diff < 0){
mMoveDistanceY += diff;
mIsTouchDownEnable = true;
}
}
mLastDownY = currentY;
invalidate();
}
private void onActionUp(MotionEvent event){
returnBack(mMoveDistanceY, 0);
}
private void drawText(Canvas canvas, int currentIndex, int position){
float length = mCenterY + mMoveDistanceY;
if(position == 0){//
float scale = getScale((int) mMoveDistanceY);
mTextPaint.setTextSize((float) (mMaxTextSize * scale));
mTextPaint.setColor(getAlphaTextColor(scale));
Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
int diff = (fontMetricsInt.bottom + fontMetricsInt.top)/2;
float baseY = length-diff;
canvas.drawText(mDataList.get(currentIndex), mViewWidth / 2, baseY, mTextPaint);
if(mMoveDistanceY > mCenterItemHeight/2){ // index
if(mCurrentDataIndex > 0) {
mCurrentDataIndex--;
}else{
mIsTouchDownEnable = false; //
}
mMoveDistanceY = 0;
}else if(mMoveDistanceY < -mCenterItemHeight/2){ // index
if(mCurrentDataIndex < mDataList.size()-1) {
mCurrentDataIndex++;
}else{
mIsTouchUpEnable = false; //
}
mMoveDistanceY = 0;
}
}else { //
int realIndex = currentIndex + position;
if(realIndex >= 0 && realIndex < mDataList.size()){
length = length + mCenterItemHeight * mGapRatio * position;
float scale = getScale((int) length - mCenterY);
mTextPaint.setTextSize((float) (mMaxTextSize * scale));
mTextPaint.setColor(getAlphaTextColor(scale));
Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
int diff = (fontMetricsInt.bottom + fontMetricsInt.top)/2;
canvas.drawText(mDataList.get(realIndex), mViewWidth/2 , length-diff, mTextPaint);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=-3; i<=3; i++){
drawText(canvas, mCurrentDataIndex, i);
}
canvas.drawLine(0, mCenterY-mCenterItemHeight/2, mViewWidth, mCenterY-mCenterItemHeight/2, mLinePaint);
canvas.drawLine(0, mCenterY + mCenterItemHeight / 2, mViewWidth, mCenterY + mCenterItemHeight / 2, mLinePaint);
}
private float getScale(int lengthToCenter){
float ret = (float) (1 - Math.pow(((float)lengthToCenter)/mCenterY, 2));
if(ret < 0){
ret = 0;
}
return ret;
}
private void returnBack(float start, float end){
mIsTouchEnable = false;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, end);
valueAnimator.setDuration(100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mMoveDistanceY = (Float) valueAnimator.getAnimatedValue();
if (Math.abs(mMoveDistanceY) <= 3) {
mMoveDistanceY = 0;
mIsTouchEnable = true;
}
invalidate();
}
});
valueAnimator.start();
if(indexListener!=null){
indexListener.ScrollItemIndex(this, mCurrentDataIndex);
}
}
/**
*
* @param scale
* @return
*/
private int getAlphaTextColor(float scale){
int data = (int) (255 * scale);
return (data << 24);
}
public int getTimeDataIndex(){
return mCurrentDataIndex;
}
public String getTimeData(){
return mDataList.get(mCurrentDataIndex);
}
public interface OnScrollItemIndexListener{
public void ScrollItemIndex(View view, int index);
}
}
그렇습니다. 설명은 그만두고 심사를 통해 편집을 하겠습니다.
블로그가 어떻게 보이는지 아직 모르겠어요.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Shirates에서 상대 선택기를 사용하는 방법 - 1부 -이것은 간단하고 강력한 표현입니다(참조). 오른쪽, 아래, 왼쪽, 위 방향으로 상대적으로 위젯을 얻을 수 있습니다. 올바른 방향의 위젯 올바른 방향으로 입력 라벨을 올바른 방향으로 올바른 방향으로 이미지 :오른쪽 버...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.