Android UI组合控件------自定义时间轴控件

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



控件特点:

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);


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







评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值