Android 时间轴的实现

实现Android回放功能下的时间轴的绘制

1.思路  横向的滑动  那我们就会想到HorizontalScrollView这个控件来实现的横向的滑动 ,

那我们就需要先画出布局,但是HorizontalScrollView 是没有滑动监听事件的,那我们就需要

重写HorizontalScrollView获取他的滑动监听,应为技术菜,自己也不会 所以就网上找了一下(这是转载别人的,出处没有,因为那里都有)


import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

public class ScrollListenerHorizontalScrollView extends HorizontalScrollView
{
    
    public ScrollListenerHorizontalScrollView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }
    
    public ScrollListenerHorizontalScrollView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    
    public ScrollListenerHorizontalScrollView(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }
    
    public interface ScrollViewListener
    {
        
        void onScrollChanged(ScrollType scrollType);
        
    }
    
    private Handler mHandler;
    
    private ScrollViewListener scrollViewListener;
    
    
    /**
     * 滚动状态 IDLE 滚动停止 TOUCH_SCROLL 手指拖动滚动 FLING滚动
     * @version XHorizontalScrollViewgallery
     * @author DZC
     * @Time 2014-12-7 上午11:06:52
     *
     *
     */
    public enum ScrollType
    {
        IDLE, TOUCH_SCROLL, FLING
    };
    
    /**
     * 记录当前滚动的距离
     */
    private int currentX = -9999999;
    
    /**
     * 当前滚动状态
     */
    private ScrollType scrollType = ScrollType.IDLE;
    
    /**
     * 滚动监听间隔
     */
    private int scrollDealy = 50;
    
    /**
     * 滚动监听runnable
     */
    private Runnable scrollRunnable = new Runnable()
    {
        
        @Override
        public void run()
        {
            // TODO Auto-generated method stub
            if (getScrollX() == currentX)
            {
                // 滚动停止 取消监听线程
                Log.d("", "停止滚动");
                scrollType = ScrollType.IDLE;
                if (scrollViewListener != null)
                {
                    scrollViewListener.onScrollChanged(scrollType);
                }
                mHandler.removeCallbacks(this);
                return;
            }
            else
            {
                // 手指离开屏幕 view还在滚动的时候
                Log.d("", "Fling。。。。。");
                scrollType = ScrollType.FLING;
                if (scrollViewListener != null)
                {
                    scrollViewListener.onScrollChanged(scrollType);
                }
            }
            currentX = getScrollX();
            mHandler.postDelayed(this, scrollDealy);
        }
    };
    
    @Override
    public boolean onTouchEvent(MotionEvent ev)
    {
        switch (ev.getAction())
        {
            case MotionEvent.ACTION_MOVE:
                this.scrollType = ScrollType.TOUCH_SCROLL;
                scrollViewListener.onScrollChanged(scrollType);
                // 手指在上面移动的时候 取消滚动监听线程
                mHandler.removeCallbacks(scrollRunnable);
                break;
            case MotionEvent.ACTION_UP:
                // 手指移动的时候
                mHandler.post(scrollRunnable);
                break;
        }
        return super.onTouchEvent(ev);
    }
    
    /**
     * 必须先调用这个方法设置Handler 不然会出错
     * 
     * @author DZC
     * @return void
     * @param handler
     * @TODO
     */
    public void setHandler(Handler handler)
    {
        this.mHandler = handler;
    }
    
    /**
     * 设置滚动监听
     * 
     * @author DZC
     * @return void
     * @param listener
     * @TODO
     */
    public void setOnScrollStateChangedListener(ScrollViewListener listener)
    {
        this.scrollViewListener = listener;
    }
    
}
然后是 首页的布局

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

    <TextView
        android:id="@+id/now_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textColor="@android:color/white"
        android:textSize="20sp" />

    <com.example.test.ScrollListenerHorizontalScrollView
        android:id="@+id/view"
        android:layout_width="fill_parent"
        android:layout_height="80dp"
        android:layout_below="@+id/now_time"
        android:scrollbars="none" >

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="#ffffff" >

            <LinearLayout
                android:id="@+id/flipper1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" />
        </RelativeLayout>
    </com.example.test.ScrollListenerHorizontalScrollView>

    <View
        android:layout_width="1dp"
        android:layout_height="80dp"
        android:layout_below="@+id/now_time"
        android:layout_centerHorizontal="true"
        android:background="#DC143C" />

</RelativeLayout>
下面 我们就开始绘制图像了,然而我这边的处理是将一个片段一个片的链接成时间轴的,所以又需要item的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        android:id="@+id/gaodu"
        android:layout_width="120dp"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/ling"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00"
            android:textColor="#DC143C"
            android:textSize="18sp" />

        <RelativeLayout
            android:id="@+id/line"
            android:layout_width="120dp"
            android:layout_height="1dp"
            android:layout_below="@+id/ling"
            android:layout_marginTop="10dp"
            android:background="@color/timeline_light_grey" />

        <TextView
            android:id="@+id/zheng"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:textColor="#DC143C"
            android:textSize="18sp" />

        <RelativeLayout
            android:id="@+id/shu"
            android:layout_width="1dp"
            android:layout_height="10dp"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/zheng"
            android:background="@color/timeline_light_grey" />

        <RelativeLayout
            android:id="@+id/play_line"
            android:layout_width="match_parent"
            android:layout_height="5dp"
            android:layout_below="@+id/line"
            android:layout_marginTop="10dp"
            android:background="@color/timeline_light_grey" />
    </RelativeLayout>

</RelativeLayout>
最后就是功能的实现了

import com.example.test.ScrollListenerHorizontalScrollView.ScrollType;
import com.example.test.ScrollListenerHorizontalScrollView.ScrollViewListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

@SuppressLint({"InflateParams", "ClickableViewAccessibility", "HandlerLeak"})
public class MainActivity extends Activity
{
    // 时间刻度的布局
    private LinearLayout flipper1;
    
    // 横向滑动的scroll
    private ScrollListenerHorizontalScrollView scrollView;
    
    // 整個時間軸的总长度
    private int maxlength = 0;
    
    // 可滑动最大距离
    private int scroll_max = 0;
    
    // 屏幕的宽度
    private int phone_wegith;
    
    // 用于HorizontalScrollView监听事件的handler
    private Handler handler = new Handler();
    
    // 每一个单位的秒数
    private int m;
    
    private DelayThread thread;
    
    private TextView now_time;
    
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        flipper1 = (LinearLayout)findViewById(R.id.flipper1);
        now_time = (TextView)findViewById(R.id.now_time);
        scrollView = (ScrollListenerHorizontalScrollView)findViewById(R.id.view);
        scrollView.setHandler(handler);
        // 获取手机屏幕的宽度
        WindowManager wm = this.getWindowManager();
        phone_wegith = wm.getDefaultDisplay().getWidth();
        scrollView.setScrollContainer(false);
        for (int i = 0; i < 28; i++)
        {
            addView(i);
        }
        thread = new DelayThread();
        thread.start();
        scrollView.setOnScrollStateChangedListener(new ScrollViewListener()
        {
            @Override
            public void onScrollChanged(final ScrollType scrollType)
            {
                handler = new Handler()
                {
                    @Override
                    public void handleMessage(Message msg)
                    {
                        super.handleMessage(msg);
                        now_time.setText(DateUtil.date(m * scrollView.getScrollX()));
                        if (scrollType == ScrollType.IDLE)
                        {
                            //停止滑动的状态
                            m = 86400 / scroll_max;
                        }
                        if(scrollType==ScrollType.FLING)
                        {
                           //处于正在滑动的状态
                            
                        }
                        
                    }
                };
               
            }
        });
    }
    
    /**
     * 添加时间轴的布局
     */
    @SuppressLint("NewApi")
    private void addView(int i)
    {
        View view = LayoutInflater.from(this).inflate(R.layout.item, null);
        TextView text = (TextView)view.findViewById(R.id.zheng);
        text.setText((i - 1) + ":");
        TextView ling = (TextView)view.findViewById(R.id.ling);
        RelativeLayout play_line = (RelativeLayout)view.findViewById(R.id.play_line);
        RelativeLayout line = (RelativeLayout)view.findViewById(R.id.line);
        RelativeLayout shu = (RelativeLayout)view.findViewById(R.id.shu);
        
        // 获取view的宽高 此方法会加载onMeasure三次
        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        view.measure(w, h);
        int width = view.getMeasuredWidth();
        maxlength = maxlength + width;
        if (i == 0)
        {
            ling.setVisibility(View.INVISIBLE);
            line.setVisibility(View.INVISIBLE);
            play_line.setVisibility(View.INVISIBLE);
            text.setVisibility(View.INVISIBLE);
            // phone_wegith / 2 - width 屏幕一半的宽度 减去view的宽度 得到的值给予第一个view 从而使得时间轴正好对着初始0的位置
            LayoutParams l = new LayoutParams(phone_wegith / 2 - width, RelativeLayout.LayoutParams.MATCH_PARENT);
            view.setLayoutParams(l);
            
        }
        else if (i == 1)
        {
            ling.setVisibility(View.INVISIBLE);
            line.setVisibility(View.INVISIBLE);
            play_line.setVisibility(View.INVISIBLE);
        }
        else if (i == 26)
        {
            text.setVisibility(View.INVISIBLE);
            line.setVisibility(View.INVISIBLE);
            shu.setVisibility(View.INVISIBLE);
            play_line.setVisibility(View.INVISIBLE);
        }
        
        else if (i == 27)
        {
            // phone_wegith / 2 - width 屏幕一半的宽度 减去view的宽度 得到的值给予第一个view 从而使得时间轴正好对着最后24的位置
            LayoutParams l = new LayoutParams(phone_wegith / 2 - width, RelativeLayout.LayoutParams.MATCH_PARENT);
            view.setLayoutParams(l);
            text.setVisibility(View.INVISIBLE);
            line.setVisibility(View.INVISIBLE);
            shu.setVisibility(View.INVISIBLE);
            play_line.setVisibility(View.INVISIBLE);
            ling.setVisibility(View.INVISIBLE);
        }
        else
        {
            play_line.setVisibility(View.VISIBLE);
            scroll_max = scroll_max + width;
        }
        flipper1.addView(view);
    }
    
    @Override
    protected void onStart()
    {
        super.onStart();
    }
    
    @Override
    protected void onResume()
    {
        super.onResume();
    }
    
    /**
     * 线程用于监控滑动状态 以及后去滑动后的值
     */
    class DelayThread extends Thread
    {
        public void run()
        {
            while (true)
            {
                try
                {
                    sleep(100);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                handler.sendEmptyMessage(0);
            }
        }
    }
    
}

写的不好,勿怪,只是给你们一个参考,有什么不好的不要说 不要问,谢谢!

效果图




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值