防蘋果小米日期時間控件

網上想找個類似的控件,好像不是那麼好找。找到一個是繼承view實現的,看的眼花繚亂,然後自己就繼承listview實現一下。

一共實現了DatePicker, TimePicker, DateTimePcker三個控件,其實就是組裝了一下。
先上效果圖
這裏寫圖片描述

先說下思路:
1.先畫出可以上下滑動並可以自動歸位的滑動條目WheelView,上圖就是由五個這樣的條目組成。
2.組裝視圖, 利用RelativieLayout定位,把放置上下兩個線條級年月日等文字。
3. 實現自定義組合控件的DateTimePikder。

遇到的問題
1. listview的顏色控制
2. listview平滑,smoothScrollBy post到主線程後纔會生效。
3. 連接滑動線程阻塞
4. datePicker日的變換比較麻煩

WheelView主要分三部分
1. onMeasure中設置高度爲5個item的高度
2. 設置onScrollChangeListener控件滑動
3. onScroll方法中控制item的顏色變化
4. onScrollStateChanged方法中實現滑動鬆開後的平滑歸位

下面是WheelView的主要代碼,後邊會給 同完整代碼

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (getChildCount() > 0) { //設置listview高度爲五個item
            itemHeight = getChildAt(0).getMeasuredHeight();
            setMeasuredDimension(widthMeasureSpec, (itemHeight + getDividerHeight()) * MAX_ITEM_COUNT);
            setDividerHeight(0);

            if (isFirst) { //只在第一次設值
                currentValue = Integer.parseInt(((TextView) getChildAt(2)).getText().toString());
                isFirst = false;
            }
        }
    }

    /**
     * 自動滑動到頂部位置
     */
    public void doScroll() {
        final int offsetY = getChildAt(0).getBottom();
        final int distance;
        if (offsetY < itemHeight / 2) { //向上
            distance = offsetY;
            currentValue = Integer.parseInt(((TextView) getChildAt(3)).getText().toString()); //上滑時取下邊一個
        } else {
            distance = offsetY - itemHeight;
            currentValue = Integer.parseInt(((TextView) getChildAt(2)).getText().toString());
        }

        postDelayed(new Runnable() { //這裏要post到主線程度纔會有平滑的效果, delay 100ms解決連續滾動時的阻塞
            @Override
            public void run() {
                if (isIdle && distance != 0) {
                    smoothScrollBy(distance, 400 * Math.abs(distance) / itemHeight); //下滑時取下邊一個,可能是滑動方法是異步的
                }
            }
        }, 100);
        if (onItemChangedListener != null) {
            onItemChangedListener.onItemSelected(currentValue);
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
            isIdle = true;
            doScroll();
        } else {
            isIdle = false;
        }
    }


    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (visibleItemCount > 0) {
            int offsetY = getChildAt(0).getBottom() + getDividerHeight();
            if (offsetY > itemHeight / 2) {// 控制滑過一半改變顏色
                ((TextView) getChildAt(2)).setTextColor(0xffE75A3E);

                ((TextView) getChildAt(1)).setTextColor(0xff989898);
                ((TextView) getChildAt(3)).setTextColor(0xff989898);

                ((TextView) getChildAt(0)).setTextColor(0xffCBCBCB);
                ((TextView) getChildAt(4)).setTextColor(0xffCBCBCB);
                if (getChildCount() > 5)
                    ((TextView) getChildAt(5)).setTextColor(0xffCBCBCB);
            } else {
                ((TextView) getChildAt(3)).setTextColor(0xffE75A3E);

                ((TextView) getChildAt(2)).setTextColor(0xff989898);
                ((TextView) getChildAt(4)).setTextColor(0xff989898);

                ((TextView) getChildAt(1)).setTextColor(0xffCBCBCB);
                ((TextView) getChildAt(0)).setTextColor(0xffCBCBCB);
                if (getChildCount() > 5)
                    ((TextView) getChildAt(5)).setTextColor(0xffCBCBCB);
            }
        }

    }

這裏只說下TimePicker,這個組裝起來最簡單,其它的讀者自己看代碼。
主要就是在構造方法中初始個控件佈局和並監聽條目的變化

private void initView(final Context context) {
        LayoutInflater.from(context).inflate(R.layout.my_timepicker_layout, this,
                true);

        mCalendar = Calendar.getInstance();
        int hour = mCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = mCalendar.get(Calendar.MINUTE);

        txtTime = (TextView) findViewById(R.id.txtTime);
        txtTime.setText(formatDate(hour, minute));

        wvHour = (WheelView) findViewById(R.id.wvHour);
        WheelViewAdapter adapterHour = new WheelViewAdapter(0, 23, context);
        wvHour.setAdapter(adapterHour);
        Log.d("dd", ""+ hour);
        wvHour.setCurrentItem(hour + 24 * 5); //設置到中間位置實現循環滑動

        wvMinute = (WheelView) findViewById(R.id.wvMinute);
        WheelViewAdapter adapterMinute = new WheelViewAdapter(0, 60, context);
        wvMinute.setAdapter(adapterMinute);
        wvMinute.setCurrentItem(minute + 12 * 5);  //設置到中間位置實現循環滑動



        wvHour.setOnItemChangedListener(new WheelView.OnItemChangedListener() {
            @Override
            public void onItemSelected(int value) {
                //月份是從0開始, 格式化時要減一
                txtTime.setText(formatDate(value, wvMinute.getCurrentValue()));
                if (onTimeSetListener != null) {
                    onTimeSetListener.onTimeSet(value, wvMinute.getCurrentValue());
                }
            }
        });

        wvMinute.setOnItemChangedListener(new WheelView.OnItemChangedListener() {
            @Override
            public void onItemSelected(int value) {

                txtTime.setText(formatDate(wvHour.getCurrentValue(), value));
                if (onTimeSetListener != null) {
                    onTimeSetListener.onTimeSet(wvHour.getCurrentValue(), value);
                }
            }
        });

    }

看看佈局文件, 用RelativieLayout便於固定文字和線條,

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/txtTime"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:gravity="center"
        android:padding="10dp"
        android:text="10:30"
        android:textColor="#626262"
        android:textSize="18dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtTime"
        android:orientation="horizontal">

        <wei.jiang.datepicker.view.WheelView
            android:id="@+id/wvHour"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1">

        </wei.jiang.datepicker.view.WheelView>

        <wei.jiang.datepicker.view.WheelView
            android:id="@+id/wvMinute"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1">

        </wei.jiang.datepicker.view.WheelView>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_below="@+id/txtTime"
        android:layout_marginTop="70dp"
        android:background="#E1E1E1" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtTime"
        android:layout_marginTop="76dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:paddingLeft="42dp"
            android:text="時"
            android:textColor="#E75A3E"
            android:textSize="16dp" />

        <TextView
            android:layout_width="0px"
            android:layout_height="wrap_content"

            android:layout_weight="1"
            android:gravity="center"
            android:paddingLeft="40dp"
            android:text="分"
            android:textColor="#E75A3E"
            android:textSize="16dp" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_below="@+id/txtTime"
        android:layout_marginTop="105dp"
        android:background="#E1E1E1" />


</RelativeLayout>

之前有不少bug,github更新了下,csdn傳資源系統抽風。
github地址 https://github.com/jw1352/myDatetimePicker/
csdn下載地址:http://download.csdn.net/detail/u012325403/9381756

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章