Android仿iphone自定义滚动选择器

作者:袖梨 2022-06-25

本文实例为大家分享了Android仿iphone自定义滚动选择器的具体代码,供大家参考,具体内容如下

一、多的不说,效果图,先走起

二、实例源码

(1)自定义控件

package com.pickerscrollview.views; 
 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Timer; 
import java.util.TimerTask; 
 
import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Paint.Align; 
import android.graphics.Paint.FontMetricsInt; 
import android.graphics.Paint.Style; 
import android.os.Handler; 
import android.os.Message; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 
 
import com.pickerscrollview.bean.Pickers; 
 
/** 
 * 自定义滚动选择器 
 * 
 * @author zengtao 2015年5月20日 下午7:36:03 
 * 
 */ 
@SuppressLint({ "HandlerLeak", "ClickableViewAccessibility" }) 
public class PickerScrollView extends View { 
 
  public static final String TAG = "PickerView"; 
  /** 
   * text之间间距和minTextSize之比 
   */ 
  public static final float MARGIN_ALPHA = 2.8f; 
  /** 
   * 自动回滚到中间的速度 
   */ 
  public static final float SPEED = 2; 
 
  private List mDataList; 
  /** 
   * 选中的位置,这个位置是mDataList的中心位置,一直不变 
   */ 
  private int mCurrentSelected; 
  private Paint mPaint; 
 
  private float mMaxTextSize = 20; 
  private float mMinTextSize = 10; 
 
  private float mMaxTextAlpha = 255; 
  private float mMinTextAlpha = 120; 
 
  private int mColorText = 0x333333; 
 
  private int mViewHeight; 
  private int mViewWidth; 
 
  private float mLastDownY; 
  /** 
   * 滑动的距离 
   */ 
  private float mMoveLen = 0; 
  private boolean isInit = false; 
  private onSelectListener mSelectListener; 
  private Timer timer; 
  private MyTimerTask mTask; 
 
  Handler updateHandler = new Handler() { 
 
    @Override 
    public void handleMessage(Message msg) { 
      if (Math.abs(mMoveLen)  datas) { 
    mDataList = datas; 
    mCurrentSelected = datas.size() / 2; 
    invalidate(); 
  } 
 
  /** 
   * 选择选中的item的index 
   * 
   * @param selected 
   */ 
  public void setSelected(int selected) { 
    mCurrentSelected = selected; 
    int distance = mDataList.size() / 2 - mCurrentSelected; 
    if (distance  0) 
      for (int i = 0; i (); 
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setStyle(Style.FILL); 
    mPaint.setTextAlign(Align.CENTER); 
    mPaint.setColor(mColorText); 
  } 
 
  @Override 
  protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    // 根据index绘制view 
    if (isInit) 
      drawData(canvas); 
  } 
 
  private void drawData(Canvas canvas) { 
    // 先绘制选中的text再往上往下绘制其余的text 
    float scale = parabola(mViewHeight / 4.0f, mMoveLen); 
    float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize; 
    mPaint.setTextSize(size); 
    mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha)); 
    // text居中绘制,注意baseline的计算才能达到居中,y值是text中心坐标 
    float x = (float) (mViewWidth / 2.0); 
    float y = (float) (mViewHeight / 2.0 + mMoveLen); 
    FontMetricsInt fmi = mPaint.getFontMetricsInt(); 
    float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0)); 
 
    int indexs = mCurrentSelected; 
    String textData = mDataList.get(indexs).getShowConetnt(); 
    canvas.drawText(textData, x, baseline, mPaint); 
 
    // 绘制上方data 
    for (int i = 1; (mCurrentSelected - i) >= 0; i++) { 
      drawOtherText(canvas, i, -1); 
    } 
    // 绘制下方data 
    for (int i = 1; (mCurrentSelected + i)  MARGIN_ALPHA * mMinTextSize / 2) { 
      // 往下滑超过离开距离 
      moveTailToHead(); 
      mMoveLen = mMoveLen - MARGIN_ALPHA * mMinTextSize; 
    } else if (mMoveLen 

(2)实体类

package com.pickerscrollview.bean; 
 
import java.io.Serializable; 
 
/** 
 * 
 * @author zengtao 2015年5月20日下午7:18:14 
 * 
 */ 
public class Pickers implements Serializable { 
 
  private static final long serialVersionUID = 1L; 
 
  private String showConetnt; 
  private String showId; 
 
  public String getShowConetnt() { 
    return showConetnt; 
  } 
 
  public String getShowId() { 
    return showId; 
  } 
 
  public Pickers(String showConetnt, String showId) { 
    super(); 
    this.showConetnt = showConetnt; 
    this.showId = showId; 
  } 
 
  public Pickers() { 
    super(); 
  } 
 
} 

(3)主界面

package com.pickerscrollview.ui; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.RelativeLayout; 
 
import com.pickerscrollview.bean.Pickers; 
import com.pickerscrollview.views.PickerScrollView; 
import com.pickerscrollview.views.PickerScrollView.onSelectListener; 
 
/** 
 * 主界面 
 * 
 * @author zengtao 2015年5月20日 下午7:36:03 
 * 
 */ 
public class MainActivity extends Activity { 
 
  private Button bt_scrollchoose; // 滚动选择器按钮 
  private PickerScrollView pickerscrlllview; // 滚动选择器 
  private List list; // 滚动选择器数据 
  private String[] id; 
  private String[] name; 
 
  private Button bt_yes; // 确定按钮 
  private RelativeLayout picker_rel; // 选择器布局 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    initView(); 
    initLinstener(); 
    initData(); 
  } 
 
  /** 
   * 初始化 
   */ 
  private void initView() { 
    bt_scrollchoose = (Button) findViewById(R.id.bt_scrollchoose); 
    picker_rel = (RelativeLayout) findViewById(R.id.picker_rel); 
    pickerscrlllview = (PickerScrollView) findViewById(R.id.pickerscrlllview); 
    bt_yes = (Button) findViewById(R.id.picker_yes); 
  } 
 
  /** 
   * 设置监听事件 
   */ 
  private void initLinstener() { 
    bt_scrollchoose.setOnClickListener(onClickListener); 
    pickerscrlllview.setOnSelectListener(pickerListener); 
    bt_yes.setOnClickListener(onClickListener); 
  } 
 
  /** 
   * 初始化数据 
   */ 
  private void initData() { 
    list = new ArrayList(); 
    id = new String[] { "1", "2", "3", "4", "5", "6" }; 
    name = new String[] { "中国银行", "农业银行", "招商银行", "工商银行", "建设银行", "民生银行" }; 
    for (int i = 0; i 

三、总结

先做一下解析,在滑动手指的时候,有一个突出的点,就是有点像圆弧那个弧度一样的感觉,所以我们要用parabola这个方法去计算出来,画多大的字也是需要计算控件的高度,和宽度来绘制,首先我们先绘制中间的文体,在绘制上下两边的字,当然,我们也要设置一个手势监听,用于监听用户按下,滑动,抬起的时候,的一个操作,我们会根据手指往上移动和向下移动距离的多少来判断显示那个文字,选中了那个。

源码下载:

相关文章

精彩推荐