1. 程式人生 > >滾動選擇器PickerView

滾動選擇器PickerView

字型滾動選擇器,當滾動到某個字型時,直接改變對應的字型,首先看一下滾動選擇器

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import
android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; /** * * 滾動選擇器 */ public class PolaroidPickerView extends View { public
static final String TAG = "PolaroidPickerView"; /** * text之間間距和minTextSize之比 */ public static final float MARGIN_ALPHA = 2.0f; /** * 自動回滾到中間的速度 */ public static final float SPEED = 2; public static final String ABCDEFG_TEXT = "PickView"; private ArrayList<Typeface> mTypefaceList; /** * 選中的位置,這個位置是mTypefaceList的中心位置,一直不變 */
private int mCurrentSelected; private Paint mPaint; private float mMaxTextSize = 30; private float mMinTextSize = 20; 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) < SPEED) { mMoveLen = 0; if (mTask != null) { mTask.cancel(); mTask = null; performSelect(); } } else // // 這裡mMoveLen / Math.abs(mMoveLen)是為了保有mMoveLen的正負號,以實現上滾或下滾 mMoveLen = mMoveLen - mMoveLen / Math.abs(mMoveLen) * SPEED; invalidate(); } }; public PolaroidPickerView(Context context) { super(context); init(); } public PolaroidPickerView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public void setOnSelectListener(onSelectListener listener) { mSelectListener = listener; } private void performSelect() { if (mSelectListener != null) mSelectListener.onSelect(mTypefaceList.get(mCurrentSelected)); } public void setSelected(int selected) { mCurrentSelected = selected; } private void moveHeadToTail() { Typeface head = mTypefaceList.get(0); mTypefaceList.remove(0); mTypefaceList.add(head); } private void moveTailToHead() { Typeface tail = mTypefaceList.get(mTypefaceList.size() - 1); mTypefaceList.remove(mTypefaceList.size() - 1); mTypefaceList.add(0, tail); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mViewHeight = getMeasuredHeight(); mViewWidth = getMeasuredWidth(); // 按照View的高度計算字型大小 mMaxTextSize = mViewHeight / 5.0f; mMinTextSize = mMaxTextSize / 2f; isInit = true; invalidate(); } private void init() { timer = new Timer(); //初始化字型資料 這裡我們可以設定成String,從而設計文字滾動選擇器,文字選擇器mList = new mList<String>(); mTypefaceList = new ArrayList<Typeface>(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Style.FILL); mPaint.setTextAlign(Align.CENTER); mPaint.setColor(mColorText); // Typeface tf = Typeface.createFromAsset(this.getContext().getAssets(), // "fonts/FasterOne-Regular.ttf"); // mPaint.setTypeface(tf); } @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)); //設定畫筆字型 文字滾動選擇器不需要設定字型 // canvas.drawText(mList.get(mCurrentSelected),x,baseline,mPaint); mPaint.setTypeface(mTypefaceList.get(mCurrentSelected)); //設定selected顏色 // mPaint.setColor(getResources().getColor(R.color.edit_font_color)); mPaint.setColor(Color.RED); //畫內容, 文字選擇器只需要直接畫內容, canvas.drawText(PolaroidPickerView.ABCDEFG_TEXT, x, baseline, mPaint); //繪製上方data for (int i = 1; (mCurrentSelected - i) >= 0; i++) { drawOtherText(canvas, i, -1); } // 繪製下方data for (int i = 1; (mCurrentSelected + i) < mTypefaceList.size(); i++) { drawOtherText(canvas, i, 1); } } /** * @param canvas * @param position * 距離mCurrentSelected的差值 * @param type * 1表示向下繪製,-1表示向上繪製 */ private void drawOtherText(Canvas canvas, int position, int type) { float d = (float) (MARGIN_ALPHA * mMinTextSize * position + type * mMoveLen); float scale = parabola(mViewHeight / 4.0f, d); float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize; mPaint.setTextSize(size); mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha)); //設定normal顏色 // mPaint.setColor(getResources().getColor(R.color.black)); mPaint.setColor(Color.WHITE); float y = (float) (mViewHeight / 2.0 + type * d); FontMetricsInt fmi = mPaint.getFontMetricsInt(); float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0)); //設定其他的字型顯示並畫出來 mPaint.setTypeface(mTypefaceList.get(mCurrentSelected + type * position)); canvas.drawText(PolaroidPickerView.ABCDEFG_TEXT, (float) (mViewWidth / 2.0), baseline, mPaint); } /** * 拋物線 * * @param zero * 零點座標 * @param x * 偏移量 * @return scale */ private float parabola(float zero, float x) { float f = (float) (1 - Math.pow(x / zero, 2)); return f < 0 ? 0 : f; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: doDown(event); break; case MotionEvent.ACTION_MOVE: doMove(event); break; case MotionEvent.ACTION_UP: doUp(event); break; } return true; } private void doDown(MotionEvent event) { if (mTask != null) { mTask.cancel(); mTask = null; } mLastDownY = event.getY(); } private void doMove(MotionEvent event) { mMoveLen += (event.getY() - mLastDownY); if (mMoveLen > MARGIN_ALPHA * mMinTextSize / 2) { // 往下滑超過離開距離 moveTailToHead(); mMoveLen = mMoveLen - MARGIN_ALPHA * mMinTextSize; } else if (mMoveLen < -MARGIN_ALPHA * mMinTextSize / 2) { // 往上滑超過離開距離 moveHeadToTail(); mMoveLen = mMoveLen + MARGIN_ALPHA * mMinTextSize; } mLastDownY = event.getY(); invalidate(); } private void doUp(MotionEvent event) { // 擡起手後mCurrentSelected的位置由當前位置move到中間選中位置 if (Math.abs(mMoveLen) < 0.0001) { mMoveLen = 0; return; } if (mTask != null) { mTask.cancel(); mTask = null; } mTask = new MyTimerTask(updateHandler); timer.schedule(mTask, 0, 10); } public ArrayList<Typeface> getTypefaceList() { return mTypefaceList; } public void setTypefaceList(ArrayList<Typeface> mTypefaceList) { this.mTypefaceList = mTypefaceList; mCurrentSelected = mTypefaceList.size() / 2; invalidate(); } class MyTimerTask extends TimerTask { Handler handler; public MyTimerTask(Handler handler) { this.handler = handler; } @Override public void run() { handler.sendMessage(handler.obtainMessage()); } } public interface onSelectListener { void onSelect(Typeface typeface); } public int getCurSeleceted(){ return mCurrentSelected; } }

呼叫並設定字型給對應的文字

    /**
     * 初始化字型
     */
    private void initData() {
        mFonts.add(Typeface.DEFAULT);
        String[] listName;
        try {
            listName = mPolaroidActivity.getAssets().list("fonts");
            for (String fontname : listName) {
                mFonts.add(Typeface.createFromAsset(mPolaroidActivity.getAssets(), "fonts/"
                        + fontname));
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

  inflater.inflate(R.layout.polaroid_fragment_font_style, mFl);
            PolaroidPickerView pickerView = (PolaroidPickerView) mFl.findViewById(R.id.polaroid_fragment_font_style_pickerview);
            //給滾動選擇器設定字型,文字選擇器直接設定文字即可
        pickerView.setTypefaceList(mFonts);
        pickerView.setOnSelectListener(new PolaroidPickerView.onSelectListener() {
            @Override
            public void onSelect(Typeface typeface) {
                mPolaroidActivity.getEt().setTypeface(typeface);
            }
        });

相關推薦

Android自定義控制元件實戰——滾動選擇PickerView

  手機裡設定鬧鐘需要選擇時間,那個選擇時間的控制元件就是滾動選擇器,前幾天用手機刷了MIUI,發現自帶的那個時間選擇器效果挺好看的,於是就自己仿寫了一個,權當練手。先來看效果:                                              

滾動選擇PickerView

字型滾動選擇器,當滾動到某個字型時,直接改變對應的字型,首先看一下滾動選擇器 import android.content.Context; import android.graphics.Canvas; import android.graphics.C

微信小程式之滾動選擇(時間日期選擇)

微信小程式自己封裝了很多控制元件,用起來確實很方便,如果這是Android裡面,還需要自己去定義,不廢話,效果圖: 一起來看看怎麼實現的呢?看完你應該就該說,尼瑪,這就行啦…. 這個效果呢,要用到picker元件,動畫從底部彈起的滾動選擇器,現支援三種選擇器,通過mode來區

時間選擇 PickerView

//新增依賴 compile 'com.contrarywind:Android-PickerView:3.2.7' //程式碼 Calendar selectedDate = Calendar.getInstance(); Calendar startDate

Android-仿千度尺的橫向滾動選擇

先上一個效果圖 主要核心方法,這裡有一個問題ontouchEvent如果返回super,則move事件不會繼續執行,down事件則沒問題.所以這裡要返回true 其次,就是計算滾動距離的問題 @Override public boolean onTouchEvent(Mot

Android 時間選擇 PickerView,的詳細使用

private void initTimePicker1() {//選擇出生年月日 //控制時間範圍(如果不設定範圍,則使用預設時間1900-2100年,此段程式碼可註釋) //因為系統Calendar的月份是從0-11的,所以如果是呼叫Calendar的set方法來設定時

Android 仿 iphone 自定義滾動選擇

背景:其實我們都知道,在我們做開發的過程中,會遇到Android 自身所帶控制元件不夠的情況,那麼這個時候,就需要我們自定義控制元件,所以,也就造成了,在開發的過程中,我們一定要掌握好自定義控制元件,不然,當你去一家公司,產品萌妹子過來找你,這個效果很不錯,問你能不能實

微信小程式picker滾動選擇,級聯問題

小程式API提供的滾動選擇器是沒有級聯關係的,請求介面返回的資料是tree型別的 { "data": [{ "flid": "13541", "name": "阿斯蒂", "children": [{ "flid": "3c24dcad-2356-4ae

Android自定義半圓形圓盤滾動選擇View

前段時間公司專案要求做一個特效的滑動選擇器,效果如下圖的樣子: 功能要求:兩邊的半圓形轉盤可以轉動,轉盤上的圖示也一起滾動,藍紅色圖示指著的小圖示變成高亮選中狀態。 第一眼看到這個需求就想到這個必須要用自定義控制元件來做才

webApp滾動選擇-實踐與應用

最近更新時間:2017年7月21日15:05:35    前端開發不僅追求介面的華麗,而且要適應和熟悉使用者的互動方式,目前webApp介面中的選擇器大多數採用的方案是,底部彈出滾動選擇器,使用者可以進行自如的選擇,互動性非常好。1、開源H5選擇器picker.js    原

Android 自定義含有滾動選擇的對話方塊

1.概述 使用LIstView和Dialog實 自定義含有滾動選擇器的對話方塊,可以設定顯示字型的不同顏色,設定字型透明度,設定大小,設定顯示多少項。下面給兩個效果: 顯示7項,字型透明度和大小改變 顯示5項,字型顏色和大小改變

android圖片滾動選擇的實現

之前的一篇文章《Android自定義view——滾動選擇器》(沒看過的同學建議先去了解一下)介紹了滾動選擇器的原理,並實現了字串選擇器。現在要講講圖片選擇器的實現,以及通過選擇器實現老虎機效果。 圖片選擇器 跟字串選擇器(StringScroll

微信小程式—picker(滾動選擇)

從底部彈起的滾動選擇器,現支援五種選擇器,通過mode來區分,分別是普通選擇器(selector),多列選擇器(multiSelector),時間選擇器(time),日期選擇器(date),省市區選擇器(region),預設是普通選擇器。 效果圖如下,

時間選擇Android-PickerView的使用

GitHub Android-PickerView絕不僅僅只能實現時間選擇,還能實現省市區等聯動效果,更多使用請戳→GitHub 時間選擇器效果圖 先用起來 新增依賴 compile 'com.contrarywind:Android-PickerView:4.

PickerView的使用(時間選擇

前段時間,因業務整合,有個需求是把原來可以選擇年月日的彈窗改為僅選擇年月。 前期思路 重寫原生的DatePickerDialog,設定DatePickerDialog的樣式為年月日為滑動選擇,隱藏日的選擇,實現功能。 程式碼如下: import android.app

Android-PickerView 三級聯動選擇的標題和內容的字型大小、顏色設定

Android-PickerView這個開源專案已經轉交給我負責繼續維護,目前我已經更新優化一部分,填補了一些不足之處,推出了3.x新版本,使用起來更加靈活方便,定製性更強。歡迎提Issue ,Pull Request 更新時間:2017-2-24日

Android使用wheelView實現簡單類似ios PickerView選擇效果

在專案中匯入wheelView檔案 佈局檔案:wheel_view.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa

Android 開發 pickerview 自定義選擇

超好用的類:在專案直接寫入,可以自定義選擇器, package com.bestgo.callshow.custom_control; import android.content.Context; import android.content.res.TypedArra

Android實現一個選擇-recycleview滾動中第一個item位置的獲取

package com.example.administrator.testanima.ActivityTwo; import android.content.Context; import android.os.Bundle; import android.os.Handler;

使用Android-PickerView實現地址選擇時間選擇

這裡貢獻下我使用Android-PickerView實現地址選擇器遇到的坑,算是一個筆記。首先要吐槽下後臺介面,為了實現移動端和web端的統一(ps:可能他沒搞過後臺介面),修改地址的時候本來要用下拉框。。。我去,後面ios的大兄弟苦苦哀求,改成了他們io