精华内容
下载资源
问答
  • Android时间轴控件-WheelView

    千次阅读 2018-11-16 11:26:03
    因此,我们就需要重新自定义scrollview,,也就是移动端常用的时间轴控件:WheelView 实现方式直接上代码: public class WheelView extends ScrollView { public static final String TAG = WheelView.class.getSi....

    在做时间轴或者某些类型的选择时,有时候设计师会给我们出类似下面的效果:
    在这里插入图片描述
    因此,我们就需要重新自定义scrollview,,也就是移动端常用的时间轴控件:WheelView

    实现方式直接上代码:

    public class WheelView extends ScrollView {
        public static final String TAG = WheelView.class.getSimpleName();
    
        public static class OnWheelViewListener {
            public void onSelected(int selectedIndex, String item) {
            }
        }
    
    
        private Context context;
    //    private ScrollView scrollView;
    
        private LinearLayout views;
    
        public WheelView(Context context) {
            super(context);
            init(context);
        }
    
        public WheelView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        public WheelView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context);
        }
    
        //    String[] items;
        List<String> items;
    
        private List<String> getItems() {
            return items;
        }
    
        public void setItems(List<String> list) {
            if (null == items) {
                items = new ArrayList<String>();
            }
            items.clear();
            items.addAll(list);
    
            // 前面和后面补全
            for (int i = 0; i < offset; i++) {
                items.add(0, "");
                items.add("");
            }
            initData();
        }
    
    
        // 每页显示的数量
        public static final int OFF_SET_DEFAULT = 1;
        int offset = OFF_SET_DEFAULT; // 偏移量(需要在最前面和最后面补全)
    
        int displayItemCount;
        int selectedIndex = 1; //
        int itemHeight = 0;//每个条目的高度
        int textSize = 20;//每个条目的字体大小
    
        public int getOffset() {
            return offset;
        }
    
        public void setOffset(int offset) {
            this.offset = offset;
        }
    
        public void setTextSize(int textSize) {
            this.textSize = textSize;
        }
    
        private void init(Context context) {
            this.context = context;
    
    //        scrollView = ((ScrollView)this.getParent());
    //        Log.d(TAG, "scrollview: " + scrollView);
            Log.d(TAG, "parent: " + this.getParent());
    //        this.setOrientation(VERTICAL);
            this.setVerticalScrollBarEnabled(false);
    
            views = new LinearLayout(context);
            views.setOrientation(LinearLayout.VERTICAL);
            this.addView(views);
    
            scrollerTask = new Runnable() {
    
                public void run() {
    
                    int newY = getScrollY();
                    if (initialY - newY == 0) { // stopped
                        final int remainder = initialY % itemHeight;
                        final int divided = initialY / itemHeight;
    //                    Log.d(TAG, "initialY: " + initialY);
    //                    Log.d(TAG, "remainder: " + remainder + ", divided: " + divided);
                        if (remainder == 0) {
                            selectedIndex = divided + offset;
    
                            onSeletedCallBack();
                        } else {
                            if (remainder > itemHeight / 2) {
                                WheelView.this.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);
                                        selectedIndex = divided + offset + 1;
                                        onSeletedCallBack();
                                    }
                                });
                            } else {
                                WheelView.this.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        WheelView.this.smoothScrollTo(0, initialY - remainder);
                                        selectedIndex = divided + offset;
                                        onSeletedCallBack();
                                    }
                                });
                            }
    
    
                        }
    
    
                    } else {
                        initialY = getScrollY();
                        WheelView.this.postDelayed(scrollerTask, newCheck);
                    }
                }
            };
    
    
        }
    
        int initialY;
    
        Runnable scrollerTask;
        int newCheck = 50;
    
        public void startScrollerTask() {
    
            initialY = getScrollY();
            this.postDelayed(scrollerTask, newCheck);
        }
    
        private void initData() {
            displayItemCount = offset * 2 + 1;
    
            for (String item : items) {
                views.addView(createView(item));
            }
    
            refreshItemView(0);
        }
    
        private TextView createView(String item) {
            TextView tv = new TextView(context);
            tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            tv.setSingleLine(true);
            tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
            tv.setText(item);
            tv.setGravity(Gravity.CENTER);
            int padding = dip2px(15);
            tv.setPadding(padding, padding, padding, padding);
            if (0 == itemHeight) {
                itemHeight = getViewMeasuredHeight(tv);
                Log.d(TAG, "itemHeight: " + itemHeight);
                views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight * displayItemCount));
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
                this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight * displayItemCount));
            }
            return tv;
        }
    
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
    
    //        Log.d(TAG, "l: " + l + ", t: " + t + ", oldl: " + oldl + ", oldt: " + oldt);
    
    //        try {
    //            Field field = ScrollView.class.getDeclaredField("mScroller");
    //            field.setAccessible(true);
    //            OverScroller mScroller = (OverScroller) field.get(this);
    //
    //
    //            if(mScroller.isFinished()){
    //                Log.d(TAG, "isFinished...");
    //            }
    //
    //        } catch (Exception e) {
    //            e.printStackTrace();
    //        }
    
    
            refreshItemView(t);
    
            if (t > oldt) {
    //            Log.d(TAG, "向下滚动");
                scrollDirection = SCROLL_DIRECTION_DOWN;
            } else {
    //            Log.d(TAG, "向上滚动");
                scrollDirection = SCROLL_DIRECTION_UP;
    
            }
        }
    
        private void refreshItemView(int y) {
            int position = y / itemHeight + offset;
            int remainder = y % itemHeight;
            int divided = y / itemHeight;
    
            if (remainder == 0) {
                position = divided + offset;
            } else {
                if (remainder > itemHeight / 2) {
                    position = divided + offset + 1;
                }
    
    //            if(remainder > itemHeight / 2){
    //                if(scrollDirection == SCROLL_DIRECTION_DOWN){
    //                    position = divided + offset;
    //                    Log.d(TAG, ">down...position: " + position);
    //                }else if(scrollDirection == SCROLL_DIRECTION_UP){
    //                    position = divided + offset + 1;
    //                    Log.d(TAG, ">up...position: " + position);
    //                }
    //            }else{
                    position = y / itemHeight + offset;
    //                if(scrollDirection == SCROLL_DIRECTION_DOWN){
    //                    position = divided + offset;
    //                    Log.d(TAG, "<down...position: " + position);
    //                }else if(scrollDirection == SCROLL_DIRECTION_UP){
    //                    position = divided + offset + 1;
    //                    Log.d(TAG, "<up...position: " + position);
    //                }
    //            }
    //        }
    
    //        if(scrollDirection == SCROLL_DIRECTION_DOWN){
    //            position = divided + offset;
    //        }else if(scrollDirection == SCROLL_DIRECTION_UP){
    //            position = divided + offset + 1;
            }
    
            int childSize = views.getChildCount();
            for (int i = 0; i < childSize; i++) {
                TextView itemView = (TextView) views.getChildAt(i);
                if (null == itemView) {
                    return;
                }
                if (position == i) {
                    itemView.setTextColor(checkTextColor);
                } else {
                    itemView.setTextColor(nocheckTextColor);
                }
            }
        }
    
        int checkTextColor = Color.parseColor("#0288ce");
        int nocheckTextColor = Color.parseColor("#bbbbbb");
    
        //设置选中的字体颜色
        public void setCheckTextColor(String checkTextColor) {
            this.checkTextColor = Color.parseColor(checkTextColor);
        }
    
        public void setCheckTextColor(int checkTextColor) {
            this.checkTextColor = checkTextColor;
        }
    
        //设置未选中的字体颜色
        public void setNocheckTextColor(String nocheckTextColor) {
            this.nocheckTextColor = Color.parseColor(nocheckTextColor);
        }
    
        public void setNocheckTextColor(int nocheckTextColor) {
            this.nocheckTextColor = nocheckTextColor;
        }
    
        /**
         * 获取选中区域的边界
         */
        int[] selectedAreaBorder;
    
        private int[] obtainSelectedAreaBorder() {
            if (null == selectedAreaBorder) {
                selectedAreaBorder = new int[2];
                selectedAreaBorder[0] = itemHeight * offset;
                selectedAreaBorder[1] = itemHeight * (offset + 1);
            }
            return selectedAreaBorder;
        }
    
    
        private int scrollDirection = -1;
        private static final int SCROLL_DIRECTION_UP = 0;
        private static final int SCROLL_DIRECTION_DOWN = 1;
    
        Paint paint;
        int viewWidth;
    
        @Override
        public void setBackgroundDrawable(Drawable background) {
    
            if (viewWidth == 0) {
                viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
                Log.d(TAG, "viewWidth: " + viewWidth);
            }
    
            if (null == paint) {
                paint = new Paint();
                paint.setColor(Color.parseColor("#83cde6"));
                paint.setStrokeWidth(dip2px(1f));
            }
    
            background = new Drawable() {
                @Override
                public void draw(Canvas canvas) {
                    canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[0], viewWidth * 5 / 6, obtainSelectedAreaBorder()[0], paint);
                    canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[1], viewWidth * 5 / 6, obtainSelectedAreaBorder()[1], paint);
                }
    
                @Override
                public void setAlpha(int alpha) {
    
                }
    
                @Override
                public void setColorFilter(ColorFilter cf) {
    
                }
    
                @SuppressLint("WrongConstant")
                @Override
                public int getOpacity() {
                    return 0;
                }
            };
    
            super.setBackgroundDrawable(background);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            Log.d(TAG, "w: " + w + ", h: " + h + ", oldw: " + oldw + ", oldh: " + oldh);
            viewWidth = w;
            setBackgroundDrawable(null);
        }
    
        /**
         * 选中回调
         */
        private void onSeletedCallBack() {
            if (null != onWheelViewListener) {
                onWheelViewListener.onSelected(selectedIndex, items.get(selectedIndex));
            }
    
        }
    
        public void setSeletion(int position) {
            final int p = position;
            selectedIndex = p + offset;
            this.post(new Runnable() {
                @Override
                public void run() {
                    WheelView.this.smoothScrollTo(0, p * itemHeight);
                }
            });
    
        }
    
        public String getSeletedItem() {
            return items.get(selectedIndex);
        }
    
        public int getSeletedIndex() {
            return selectedIndex - offset;
        }
    
    
        @Override
        public void fling(int velocityY) {
            super.fling(velocityY / 3);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_UP) {
    
                startScrollerTask();
            }
            return super.onTouchEvent(ev);
        }
    
        private OnWheelViewListener onWheelViewListener;
    
        public OnWheelViewListener getOnWheelViewListener() {
            return onWheelViewListener;
        }
    
        public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) {
            this.onWheelViewListener = onWheelViewListener;
        }
    
        private int dip2px(float dpValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        private int getViewMeasuredHeight(View view) {
            int width = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            int expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
            view.measure(width, expandSpec);
            return view.getMeasuredHeight();
        }
    
    }
    

    外面设置属性和传数据的使用方式如下:

    val layout_wheelview = findViewById<WheelView>(R.id.layout_wheelview).apply {
               //设置选中的字体颜色
                setCheckTextColor(Color.BLACK)
                //设置条目字体大小
                setTextSize(18)
                //设置列表数据
                setItems(listContent)
                //添加滑动监听
                onWheelViewListener = object : WheelView.OnWheelViewListener() {
                    override fun onSelected(selectedIndex: Int, item: String) {
                    }
                }
            }
    

    外面获取当前选中的条目:

    layout_wheelview.seletedIndex
    
    展开全文
  • android时间滚动控件

    2016-04-07 10:49:43
    时间滚动,仿ios时间控件,包括年、月、日、星期、时、分、秒 希望能够对大家提供帮助
  • Android 具有左右滑动功能的时间轴控件代码源码
  • Android UI组合控件------自定义时间轴控件

    千次阅读 热门讨论 2013-04-17 11:49:40
    最近由于项目需要,需要自定义时间轴控件,废话不多说,直接上图: 控件特点: 1. 宽度高度可自行设定,各个时间点间的间距会自动拉长或缩短。(控件自身有最小长度和最小宽度,小于这个范围就无法拉长或...

    最近由于项目需要,需要自定义时间轴控件,废话不多说,直接上图:



    控件特点:

    1. 宽度高度可自行设定,各个时间点间的间距会自动拉长或缩短。(控件自身有最小长度和最小宽度,小于这个范围就无法拉长或缩短了)

    2.中间彩色的会议时间段的颜色,是随机生成的RGB颜色,避免会议时间相邻,会议时间混淆。

    3.上面的会议时间指针可以向右移动,指到会议时间段的正中间。

    4.时间轴的背景颜色可以通过控件设定。


    具体思路:整个控件布局是LinearLayout,属性设为垂直,在控件布局里面依次放三个LinearLayout,第一个LinearLayout里面是显示Meeting和红三角指示,第二个LinearLayout里面是显示会议时间段和背景,第三个LinearLayout是显示时间点。


    注意细节:

    1.继承LinearLayout必须实现下面的两个方法,导入xml,否则会报错。

        public TimeLineLinearLayout(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    
        public TimeLineLinearLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            // 导入布局
            LayoutInflater.from(context).inflate(R.layout.time_line, this, true);
    
            mTSV = (TimeSpanViewLinearLayout) findViewById(R.id.TimeSpanView_layout);
            // 背景默认为白色,可自行设定
            mTSV.setBackgroundColor(Color.WHITE);
    
            // 时间指针
            mTimePointer = (LinearLayout) findViewById(R.id.time_pointer);
    
        }

    2.引用自定义控件,必须把路径加上,不加会提示xml文件错误

        <com.example.meetingsystem.widget.TimeLineLinearLayout
            android:id="@+id/TimeLine_layout"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center" />



    实现源码:

    TimeSpanViewLinearLayout.java(TimeLine控件第二个LinearLayout,也是组合控件)

    package com.example.meetingsystem.widget;
    
    
    import com.example.meetingsystem.R;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.LinearLayout;
    
    public class TimeSpanViewLinearLayout extends LinearLayout {
    
        public static final int NUM_TIME_SPAN = 18;
        private View[] mViews;
        private int mColor;
        private View mLeftView;
    
        public TimeSpanViewLinearLayout(Context context) {
            super(context);
        }
    
        public TimeSpanViewLinearLayout(Context context, AttributeSet attrs){
            super(context, attrs);
    
            // 导入布局
            LayoutInflater.from(context).inflate(R.layout.time_span_view, this, true);
    
            init();
        }
    
        void init() {
            int i;
            // 创建18个view数组
            mViews = new View[NUM_TIME_SPAN];
    
            // 实例化一个线性布局的参数
            LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.MATCH_PARENT);
    
            // 设置权重为1
            lp1.weight = 1;
            
            LinearLayout layout = (LinearLayout) findViewById(R.id.time_span_view_linearlayout);
            
            //最左边空一个权重
            mLeftView = new View(this.getContext());
            mLeftView.setVisibility(INVISIBLE);
            layout.addView(mLeftView, lp1);
            
            // 添加时间块
            for (i = 0; i < NUM_TIME_SPAN; i++) {
    
                mViews[i] = new View(this.getContext());
                //时间块默认是蓝色,可自行更改
                mViews[i].setBackgroundColor(Color.BLUE);
                mViews[i].setVisibility(INVISIBLE);
                layout.addView(mViews[i], lp1);
            }
            
            //最右边空一个权重
            View rightView = new View(this.getContext());
            rightView.setVisibility(INVISIBLE);
            layout.addView(rightView, lp1);
        }
    
        
        public void setTimeBlock(int[] temp) {
    
            for (int j : temp) {
    
                if (j > 0) {
                    
                    mViews[j-1].setVisibility(VISIBLE);
                    mViews[j-1].setBackgroundColor(mColor);
                    Log.d("TimeSpanView", "找到第几块---" + (j-1));
                }
            }
        }
        
        public int getLeftPosition(int start,int end){
            
            int left = mViews[start].getLeft();
            
            int right = mViews[end].getLeft();
            
            int leftLength;
            leftLength = (right - left)/2 + left - 50 + mLeftView.getLeft();
            
            return leftLength;
            
        }
        
        public void setTimeBlockColor(int color){
            this.mColor = color;
            
        }
    }
    

    time_span_view.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/time_span_view_linearlayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        >
        
    
    </LinearLayout>

    TimeLineLinearLayout.java(TimeLine控件)

    package com.example.meetingsystem.widget;
    
    import java.util.List;
    
    import com.example.meetingsystem.R;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.LinearLayout;
    
    public class TimeLineLinearLayout extends LinearLayout {
    
        private static final String TIME[] = { "09:00", "09:30", "10:00", "10:30", "11:00", "11:30",
                "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30", "16:00",
                "16:30", "17:00", "17:30", "18:00" };
        
        private TimeSpanViewLinearLayout mTSV;
        private LinearLayout mTimePointer;
        private int mblockNum = 0;
        private int startTimeBlock;
        private int endTimeBlock;
        private int mLeftPosition;
        private LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
    
        public TimeLineLinearLayout(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    
        public TimeLineLinearLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            // 导入布局
            LayoutInflater.from(context).inflate(R.layout.time_line, this, true);
    
            mTSV = (TimeSpanViewLinearLayout) findViewById(R.id.TimeSpanView_layout);
            // 背景默认为白色,可自行设定
            mTSV.setBackgroundColor(Color.WHITE);
    
            // 时间指针
            mTimePointer = (LinearLayout) findViewById(R.id.time_pointer);
    
        }
    
        public void setTimeSpans(List<TimeSpan> list) {
            for (TimeSpan ts : list) {
                setTimeSpan(ts);
            }
            
            // 时间指针初始化
            timePointerInit();
            
            //测试移动时间指针
            moveTimePointer() ;
        }
    
        //要求系统版本至少为11
        private void timePointerInit() {
    
            // 移到最左边
            lp2.leftMargin = 0;
    
            mTimePointer.setLayoutParams(lp2);
    
            // 设置时间指针不可见
            mTimePointer.setVisibility(View.INVISIBLE);
            
            Log.d("TimeLine", "timePointer初始化");
        }
    
        private void setTimeSpan(TimeSpan ts) {
            String begin;
            String end;
    
            begin = ts.begin;
            end = ts.end;
    
            Log.d("TimeLine", "会议时间begin----" + begin + "end ----" + end);
    
            int[] temp;
            temp = findTimeBlockArray(begin, end);
            mTSV.setTimeBlock(temp);
        }
    
        private int[] findTimeBlockArray(String begin, String end) {
            int i;
    
            int[] block;
            block = new int[18];
    
            for (i = 0; i < 19; i++) {
    
                if (begin == TIME[i]) {
                    startTimeBlock = i;
                }
                else if (end == TIME[i]) {
                    endTimeBlock = i;
                    break;
                }
            }
    
            for (i = startTimeBlock +1 ; i < endTimeBlock+1; i++) {
                block[mblockNum] = i;
                mblockNum++;
                Log.d("TimeLineLinearLayout", "获得时间点----" + i);
            }
    
            //设置模块的随机色
            setTimeBlockColor(Color.rgb(RandomNum(), RandomNum(), RandomNum()));
            
            return block;
        }
    
        private int getLeftPosition(int start, int end) {
    
            return mTSV.getLeftPosition(start, end);
        }
    
        public void setBackgroundColor(int color) {
            // 将TimeSpanView的背景色改变
            mTSV.setBackgroundColor(color);
        }
    
        public void setTimeBlockColor(int color) {
            // 设置时间块的颜色,默认随机色
            mTSV.setTimeBlockColor(color);
        }
    
        private void moveTimePointer() {
            
          //  lp2.leftMargin = getLeftPosition(13,15);
            lp2.leftMargin = mLeftPosition;
    
            mTimePointer.setLayoutParams(lp2);
    
            
            // 设置时间指针可见
            mTimePointer.setVisibility(View.VISIBLE);
            
            Log.d("TimeLine", "timePointer移动");
        }
    
        
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // TODO Auto-generated method stub
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            
            //默认是出现在0-6块之间
            mLeftPosition = getLeftPosition(2,8);
            
            //测试时间块的移动
            moveTimePointer() ;
        }
        
        //随机0-255整数
        private int RandomNum(){
            
            return (int)(Math.random()*255);
        }
    }
    

    time_line.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="540dp"
        android:orientation="vertical"
        tools:context=".TimeLine" >
    
        <!-- android:minWidth="540dp" -->
    
    
        <!-- 时间轴指向点 -->
    
        <LinearLayout
            android:id="@+id/time_pointer"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:layout_marginLeft="150dp"
            android:orientation="vertical" >
    
            <TextView
                android:id="@+id/time_line_textView1"
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="@string/meeting"
                android:textSize="15sp" />
    
            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="100dp"
                android:layout_height="20dp"
                android:src="@drawable/meeting_pointer" />
        </LinearLayout>
    
        <com.example.meetingsystem.widget.TimeSpanViewLinearLayout
            android:id="@+id/TimeSpanView_layout"
            android:layout_width="match_parent"
            android:layout_height="20dp" 
            />
    
        <!-- 时间轴时间点 -->
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:orientation="horizontal" >
    
            <TextView
                android:id="@+id/time_line_textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_weight="1"
                android:text="09:00" />
    
            <TextView
                android:id="@+id/time_line_textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="10:00" />
    
            <TextView
                android:id="@+id/time_line_textView4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="11:00" />
    
            <TextView
                android:id="@+id/time_line_textView5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="12:00" />
    
            <TextView
                android:id="@+id/time_line_textView6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="13:00" />
    
            <TextView
                android:id="@+id/time_line_textView7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="14:00" />
    
            <TextView
                android:id="@+id/time_line_textView8"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="15:00" />
    
            <TextView
                android:id="@+id/time_line_textView9"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="16:00" />
    
            <TextView
                android:id="@+id/time_line_textView10"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="17:00" />
    
            <TextView
                android:id="@+id/time_line_textView11"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                 android:gravity="center"
                android:layout_weight="1"
                android:text="18:00" />
        </LinearLayout>
    
    </LinearLayout>


    引用TimeLine控件:

    引用activity的xml文件中添加

        <com.example.meetingsystem.widget.TimeLineLinearLayout
            android:id="@+id/TimeLine_layout"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center" />

    在activity中添加:

     	    List<TimeSpan> list = null;
                //得到时间数据
                list = DataUtils.getConferenceTimeSpans();
                //时间轴根据TimeSpan指示正确的会议点
                mTimeLine.setTimeSpans(list);
                
                //改变时间轴的背景色
                mTimeLine.setBackgroundColor(Color.WHITE);
                
                //改变时间块的颜色,默认是随机色
                //mTimeLine.setTimeBlockColor(Color.BLACK);


    文笔不好,敬请见谅,希望能对大家有所帮助!代码编写中存在问题请大家指正,共同学习共同进步!







    展开全文
  • android 仿淘宝物流时间轴控件

    千次阅读 2016-10-19 10:29:28
    Android 仿淘宝物流时间轴控件 在这里感谢一片作者的demo,我在他的基础上做了写修改 ,改成我们项目所用的样式!还是那句话没有实现不了的需求,只有想不到的。首先看我们项目的设计图。  首先看一下别人的...

    Android 仿淘宝物流时间轴控件

    在这里感谢一片作者的demo,我在他的基础上做了写修改 ,改成我们项目所用的样式!还是那句话没有实现不了的需求,只有想不到的。首先看我们项目的设计图。 
    这里写图片描述

    首先看一下别人的自定义时间轴控件,是通过画布的方法自己写的一个view.

    `public class TimeLineView extends View {

    private Paint mPaint;
    /**
     * 第一个节点的外半径
     */
    private float timelineHeadRadius;
    /**
     * 第一个节点的颜色值
     */
    // private int timelineHeadColor;
    /**
     * 第二个节点的颜色值
     */
    private int timelineOtherColor;
    /**
     * 时间线的节点数
     */
    private int timelineCount;
    /**
     * 时间轴的位置
     */
    private int viewWidth;
    /**
     * 时间轴到距离顶部的距离
     */
    private int marginTop;
    /**
     * 时间轴的节点的半径
     */
    private int timelineRadius;
    /**
     * 时间轴节点之间的距离
     */
    private int timelineRadiusDistance;
    /**
     * 时间轴的宽度
     */
    private int timelineWidth;
    /**
     * 时间轴的高度
     */
    private float timeLineViewHeight;
    
    /**
     * 自己需求第一个显示的颜色图片
     * */
    
    private Bitmap bitmapHead;
    
    public TimeLineView(Context context) {
        this(context, null);
    }
    
    public TimeLineView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public TimeLineView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }
    
    /**
     * 初始化
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void init(Context context, AttributeSet attrs, int defStyle) {
    
        final TypedArray a = getContext().obtainStyledAttributes(attrs,
                R.styleable.TimeLineView, defStyle, 0);
        timelineRadiusDistance = (int) a.getDimension(
                R.styleable.TimeLineView_timelineRadiusDistance,
                convertDIP2PX(context, 20));
        // timelineHeadRadius =
        // a.getDimension(R.styleable.TimeLineView_timelineHeadRadius,
        // convertDIP2PX(context, 10));
        timelineRadius = (int) a.getDimension(
                R.styleable.TimeLineView_timelineRadius,
                convertDIP2PX(context, 5));
        // timelineHeadColor =
        // a.getColor(R.styleable.TimeLineView_timelineHeadColor,
        // Color.parseColor("#F15719"));
        timelineOtherColor = a.getColor(
                R.styleable.TimeLineView_timelineOtherColor,
                Color.parseColor("#A8A8A8"));
        timelineCount = a.getInteger(R.styleable.TimeLineView_timelineCount, 0);
        timelineWidth = (int) a.getDimension(
                R.styleable.TimeLineView_timelineWidth,
                convertDIP2PX(context, 1));
        marginTop = (int) a.getDimension(
                R.styleable.TimeLineView_timelineMarginTop,
                convertDIP2PX(context, 50));
        a.recycle();
    
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
    
        Resources res = getResources();
        bitmapHead = BitmapFactory.decodeResource(res,
                R.drawable.icon_logistics);
    
    }
    
    /**
     * 画出Bitmap
     * 
     * @param canvas
     * @param src
     * @param dst
     * @param bitmap
     */
    private void drawBitmap(Canvas canvas, Rect src, Rect dst, Bitmap bitmap) {
        dst = (dst == null ? new Rect(0, 0, bitmap.getWidth(),
                bitmap.getHeight()) : dst);
        Paint paint = new Paint();
        // canvas.drawBitmap(bitmap, src, dst, paint);
        canvas.drawBitmap(bitmap, viewWidth - (bitmap.getWidth() / 2),
                timelineHeadRadius + marginTop - (bitmap.getHeight() / 2) - 10,
                paint);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        // 默认设置时间轴的位置位于view的中间
        viewWidth = getMeasuredWidth() / 2;
        // 设置第一个节点的颜色
        // mPaint.setColor(timelineHeadColor);
        /**
         * 根据时间轴的节点数目,画对应的节点和轴
         */
        for (int j = 1; j <= timelineCount; j++) {
    
            /**
             * 当j==1,画第一个节点的时候,有点特殊,我们需要在节点的外面再换一个圆环
             */
            if (j == 1) {
                Rect dstRect = new Rect();
                drawBitmap(canvas, null, null, bitmapHead);
    
                // 画笔设置为空心
                // canvas.drawCircle(viewWidth, timelineHeadRadius + marginTop,
                // timelineRadius, mPaint);
                // mPaint.setStyle(Paint.Style.STROKE);
                // mPaint.setStrokeWidth(5.0f);
                // //画第一个节点外围的圆环
                // canvas.drawCircle(viewWidth, timelineHeadRadius + marginTop,
                // timelineHeadRadius, mPaint);
                // 设置画笔颜色,画其他时间节点的颜色
                mPaint.setColor(timelineOtherColor);
                // 画笔设置为实心
                mPaint.setStyle(Paint.Style.FILL);
                /**
                 * 画第一个节点下面的轴
                 */
                canvas.drawRect(new Rect(viewWidth - timelineWidth / 2,
                        (int) (2 * timelineHeadRadius + marginTop) + 5,
                        viewWidth + timelineWidth / 2, (int) (2
                                * timelineHeadRadius + timelineRadiusDistance
                                + marginTop + 5)), mPaint);
                continue;
            }
            /**
             * 画时间轴的节点,即画圆形 圆心的x都是一样的,view的中间
             * 圆心的y的计算是根据节点的位置来计算的,例如:第一个节点的y是根据第一个节点距离上面的距离加上第一个节点的半径
             * :timelineHeadRadius + marginTop
             * 其余的节点就是在一个节点的y的基础上,加上两倍半径和节点之间的轴的长度*节点数:(2 * timelineRadius +
             * timelineRadiusDistance) * (j - 1) + timelineHeadRadius -
             * timelineRadius + marginTop
             *
             */
            canvas.drawCircle(viewWidth,
                    (2 * timelineRadius + timelineRadiusDistance) * (j - 1) + 2
                            * timelineHeadRadius - timelineRadius + marginTop,
                    timelineRadius, mPaint);
            /**
             *   画其余的轴 left:每个轴距离左边距离都是一样的   时间轴的中心位置-1/2的时间轴的宽度 viewWidth -
             * timelineWidth / 2 top: (int) (j * (2 * timelineRadius +
             * timelineRadiusDistance) - timelineRadiusDistance + 2 *
             * (timelineHeadRadius-timelineRadius)+ marginTop) 
             * right:每个轴距离右边距离都是一样的   时间轴的中心位置+1/2的时间轴的宽度 viewWidth +
             * timelineWidth / 2 bottom: (int) (j * (2 * timelineRadius +
             * timelineRadiusDistance) + 2 *
             * (timelineHeadRadius-timelineRadius)+ marginTop)
             */
    
            if (j < timelineCount) {
                canvas.drawRect(
                        new Rect(
                                viewWidth - timelineWidth / 2,
                                (int) (j
                                        * (2 * timelineRadius + timelineRadiusDistance)
                                        - timelineRadiusDistance + 2
                                        * (timelineHeadRadius - timelineRadius) + marginTop),
                                viewWidth + timelineWidth / 2,
                                (int) (j
                                        * (2 * timelineRadius + timelineRadiusDistance)
                                        + 2
                                        * (timelineHeadRadius - timelineRadius) + marginTop)),
                        mPaint);
            }
    
        }
    }
    
    public float getTimelineHeadRadius() {
        return timelineHeadRadius;
    }
    
    public void setTimelineHeadRadius(float timelineHeadRadius) {
    
        this.timelineHeadRadius = timelineHeadRadius;
        invalidate();
    }
    
    // public int getTimelineHeadColor() {
    // return timelineHeadColor;
    // }
    //
    // public void setTimelineHeadColor(int timelineHeadColor) {
    //
    // this.timelineHeadColor = timelineHeadColor;
    // invalidate();
    // }
    
    public int getTimelineOtherColor() {
        return timelineOtherColor;
    }
    
    public void setTimelineOtherColor(int timelineOtherColor) {
        this.timelineOtherColor = timelineOtherColor;
        invalidate();
    }
    
    public int getTimelineCount() {
        return timelineCount;
    }
    
    public void setTimelineCount(int timelineCount) {
        this.timelineCount = timelineCount;
        invalidate();
    }
    
    public int getMarginTop() {
        return marginTop;
    }
    
    public void setMarginTop(int marginTop) {
    
        this.marginTop = marginTop;
        invalidate();
    }
    
    public int getTimelineRadius() {
        return timelineRadius;
    }
    
    public void setTimelineRadius(int timelineRadius) {
    
        this.timelineRadius = timelineRadius;
        invalidate();
    }
    
    public int getTimelineRadiusDistance() {
        return timelineRadiusDistance;
    }
    
    public void setTimelineRadiusDistance(int timelineRadiusDistance) {
    
        this.timelineRadiusDistance = timelineRadiusDistance;
        invalidate();
    }
    
    public int getTimelineWidth() {
        return timelineWidth;
    }
    
    public void setTimelineWidth(int timelineWidth) {
        this.timelineWidth = timelineWidth;
    }
    
    public float getTimeLineViewHeight() {
        this.timeLineViewHeight = getMarginTop() + getTimelineCount()
                * (2 * getTimelineRadius() + getTimelineRadiusDistance());
        return timeLineViewHeight;
    }
    
    public void setTimeLineViewHeight(float timeLineViewHeight) {
        this.timeLineViewHeight = timeLineViewHeight;
        invalidate();
    
    }
    
    public int getViewWidth() {
        return viewWidth;
    }
    
    public void setViewWidth(int viewWidth) {
        this.viewWidth = viewWidth;
        invalidate();
    }
    
    /**
     * 转换dip为px
     */
    public static int convertDIP2PX(Context context, int dip) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
    }
    

    }`

    里面写了一些详细的方法等很好用的,其中的bitmapHead是我们项目需求需要的一个头结点,这些是我在原来的基础上自己添加的,通过 
    private void drawBitmap(Canvas canvas, Rect src, Rect dst, Bitmap bitmap) { 
    dst = (dst == null ? new Rect(0, 0, bitmap.getWidth(), 
    bitmap.getHeight()) : dst); 
    Paint paint = new Paint(); 
    // canvas.drawBitmap(bitmap, src, dst, paint); 
    canvas.drawBitmap(bitmap, viewWidth - (bitmap.getWidth() / 2), 
    timelineHeadRadius + marginTop - (bitmap.getHeight() / 2) - 10, 
    paint); 
    }
     
    画自己的头结点,也就是第一个点。

    实现我们的需求需要左边布局是自定义的View,右边用一个listview。

    http://download.csdn.net/detail/u014007519/9454830这是我的demo地址可以下载下看一看,如果有什么问题可以联系

    展开全文
  • 此demo为Android 自定义View实现时间轴,轴的高度可随内容高度自动调整而改变,代码较简单,可供参考
  • 主要介绍了Android基础控件之使用ListView实现时间轴效果的相关资料,本文是以查看物流信息为例,给大家介绍了listview时间轴的实现代码,需要的朋友可以参考下
  • 效果图

     

    效果图
    效果图

     

    展开全文
  • 写了一个Android时间滚轮控件,以备不时之需
  • android 时间控件 酷炫

    2015-03-11 18:14:16
    非常好用的Date控件,酷炫,而且扁平化设计,在什么样的风格环境下都可以使用
  • Android强大的日期时间选择控件

    热门讨论 2012-03-22 12:22:38
    Android强大的日期时间选择控件 安卓 android 日期时间 控件 datepicker
  • android 自定义控件 简易时间轴

    千次阅读 2016-06-14 11:02:50
    之前项目需要写一个消费记录,类似于时间轴似的控件,自身在自定义控件这里不咋地(…),最后搞了一个这个demo 效果图: 这里就是绘制圆和上下两条线 1.资源文件,定义一些基本的属性: <resources> <at
  • 快递查询时间轴 ...时间轴是使用上面一条线(20dp)和中间一个圆(15dp)和下面一条线(40dp)组装成的 在ListView中,设置其分割线为空,并且没有点击效果 效果图: 步骤一:使用xml画出一个灰
  • 零、View在Android中,无论是熟知的布局,还是控件,统统全都继承自基类View。自定义View实现有几种:自定义组合控件:多个控件组合成为一个新的控件,方便多处复用继承系统View控件:继承自TextView等系统控件,在...
  • 一个自定义时间轴控件,有问题可以留言
  • 非常简单,ListView实现的。具体布局右侧都有指表示。 代码就不上了。
  • Android滑动解锁控件

    千次阅读 2015-11-02 13:51:38
    import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.os.Handler; import a

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,450
精华内容 11,380
关键字:

android时间轴控件