精华内容
下载资源
问答
  • React Dom制作垂直时间轴布局是一款垂直的圆点时间轴ui布局,可用于公司大事记时间轴特效。
  • 简单时间轴布局

    2017-02-14 15:46:37
    在进行时间历程显示的时候我们会用到基于listview显示的时间轴布局,效果如下: 现在来说下实现步骤: 首先这个布局我们可以发现其实是一个listview,在listview的左边是一个显示连接起来的时间轴,右边用来显示...

    在进行时间历程显示的时候我们会用到基于listview显示的时间轴布局,效果如下:


    现在来说下实现步骤:

    首先这个布局我们可以发现其实是一个listview,在listview的左边是一个显示连接起来的时间轴,右边用来显示内容,下面我们来看看怎么实现这个时间轴:
    这个自定义的View如下:
    public class TimeListView extends View {
        private int mMakeSize,mLineSize;
        private Drawable mStartLine;
        private Drawable mEndLine;
        private Drawable mMaker;
        private Rect bounds;
    
        private void init(AttributeSet attrs){
            //获取控件的属性集合
            TypedArray array=getContext().obtainStyledAttributes(attrs, R.styleable.TimeListView);
            //中心圆大小
            mMakeSize=array.getDimensionPixelSize(R.styleable.TimeListView_circle,10);
            //线段大小
            mLineSize=array.getDimensionPixelSize(R.styleable.TimeListView_lineSize,10);
            //顶部线条
            mStartLine=array.getDrawable(R.styleable.TimeListView_startLine);
            //底部线条
            mEndLine=array.getDrawable(R.styleable.TimeListView_endLine);
            //中心圆
            mMaker=array.getDrawable(R.styleable.TimeListView_maker);
            array.recycle();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //获取中心圆以及距离左右的大小和
            int w=mMakeSize+getPaddingLeft()+getPaddingRight();
            int h=mMakeSize+getPaddingTop()+getPaddingBottom();
            //将这个值与测量的控件大小进行比较得出较小的那个值从而确定具体控件的大小
            int widthsize=resolveSizeAndState(w,widthMeasureSpec,0);
            int heightsize=resolveSizeAndState(h,heightMeasureSpec,0);
            //将这个值设置给控件大小
            setMeasuredDimension(widthsize,heightsize);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            //获取左右上下的Padding值
            int pLeft=getPaddingLeft();
            int pRight=getPaddingRight();
            int pTop=getPaddingTop();
            int pBottom=getPaddingBottom();
            //获取控件宽高
            int width=getWidth();
            int height=getHeight();
            //中心圆圈的矩形定位
            int cWidth=width-pLeft-pRight;
            int cHeight=height-pTop-pBottom;
            if(mMaker!=null){
                int makesize=Math.min(mMakeSize,Math.min(cWidth,cHeight));
                mMaker.setBounds(pLeft,pTop,pLeft+makesize,pTop+makesize);
                bounds = mMaker.getBounds();
            }else {
                bounds=new Rect(pLeft,pTop,pLeft+cWidth,pTop+cHeight);
            }
            int lineleft=bounds.centerX()-mLineSize>>1;
            if(mStartLine!=null){
                mStartLine.setBounds(pLeft+lineleft,0,pLeft+lineleft+mLineSize,bounds.top);
            }
            if(mEndLine!=null){
                mEndLine.setBounds(pLeft+lineleft,bounds.bottom,pLeft+lineleft+mLineSize,height);
            }
    
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (mStartLine!=null){
                mStartLine.draw(canvas);
            }
            if(mEndLine!=null){
                mEndLine.draw(canvas);
            }
            if(mMaker!=null){
                mMaker.draw(canvas);
            }
            super.onDraw(canvas);
        }
    
        public Drawable getmMaker() {
            return mMaker;
        }
    
        public void setmMaker(Drawable mMaker) {
            this.mMaker = mMaker;
        }
    
        public Drawable getmEndLine() {
            return mEndLine;
        }
    
        public void setmEndLine(Drawable mEndLine) {
            this.mEndLine = mEndLine;
        }
    
        public Drawable getmStartLine() {
            return mStartLine;
        }
    
        public void setmStartLine(Drawable mStartLine) {
            this.mStartLine = mStartLine;
        }
    
        public int getmLineSize() {
            return mLineSize;
        }
    
        public void setmLineSize(int mLineSize) {
            this.mLineSize = mLineSize;
        }
    
        public int getmMakeSize() {
            return mMakeSize;
        }
    
        public void setmMakeSize(int mMakeSize) {
            this.mMakeSize = mMakeSize;
        }
        public TimeListView(Context context) {
            super(context);
    
        }
    
        public TimeListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);
        }
    
        public TimeListView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(attrs);
        }
    }
    属性集合attrs为:
        <declare-styleable name="TimeListView">
            <attr name="lineSize" format="dimension"/>
            <attr name="circle" format="dimension"/>
            <attr name="startLine" format="color|reference"/>
            <attr name="endLine" format="color|reference"/>
            <attr name="maker" format="color|reference"/>
        </declare-styleable>

    下面我们的使用:
    activity的布局
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycle_timelist"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    activity如下:
    public class TimeListViewActivity extends Activity {
    
        private RecyclerView ry;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_timelist);
            ry = (RecyclerView)findViewById(R.id.recycle_timelist);
            LinearLayoutManager layoutManager=new LinearLayoutManager(this);
            ry.setLayoutManager(layoutManager);
            List<String> list=new ArrayList<>();
            list.add("20170108");
            list.add("20170109");
            list.add("20170110");
            list.add("20170111");
            list.add("20170112");
            list.add("20170113");
            ry.setAdapter(new TimeListAdapter(this,list));
        }
    }
    recycleview的adapter的代码如下:
    public class TimeListAdapter extends RecyclerView.Adapter<MyViewHolder> {
        private Context context;
        private List<String> datas;
        private LayoutInflater inflater;
        public TimeListAdapter(Context context, List<String> datas) {
            this.context=context;
            this.datas=datas;
            inflater=LayoutInflater.from(context);
        }
    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view=inflater.inflate(R.layout.item_recycle_timelist,parent,false);
            MyViewHolder myViewHolder=new MyViewHolder(view,inflater.getContext(),viewType);
            return myViewHolder;
        }
    
        @Override
        public int getItemViewType(int position) {
            //为Item设置type
            int size=datas.size()-1;
            if(size==0){
                return ItemType.NO;
            }else if(position==0){
                return ItemType.TOP;
            }else if(position==size){
                return ItemType.BOTTOM;
            }else {
                return ItemType.NORMAL;
            }
        }
    
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.tv.setText(datas.get(position));
        }
    
        @Override
        public int getItemCount() {
            return datas.size();
        }
    }
    class MyViewHolder extends RecyclerView.ViewHolder{
        TextView tv;
        public MyViewHolder(View itemView,Context context,int type) {
            super(itemView);
            tv= (TextView) itemView.findViewById(R.id.tv);
            TimeListView timeListView= (TimeListView) itemView.findViewById(R.id.tlv);
            if (type==ItemType.NO){
                timeListView.setmStartLine(null);
                timeListView.setmEndLine(null);
            }else if(type==ItemType.TOP){
                timeListView.setmStartLine(null);
            }else if(type==ItemType.BOTTOM){
                timeListView.setmEndLine(null);
            }
        }
    }
    值得一提的是RecycleView中的方法:
    public int getItemViewType(int position) 
    这个方法返回一个int类型的值可以改item的type,这个type值就是
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view=inflater.inflate(R.layout.item_recycle_timelist,parent,false);
            MyViewHolder myViewHolder=new MyViewHolder(view,inflater.getContext(),viewType);
            return myViewHolder;
        }
    里面的viewType这个值,然后根据这个值来设置第一条和最后一条item的属性,从而让第一条的上边部分线条和最后的条目的下边部分线条取消掉从而形成一个完整的时间轴布局.

    布局Item的type如下:
    public class ItemType {
        public static int NO=0;
        public static int TOP=1;
        public static int NORMAL=2;
        public static int BOTTOM=3;
    }
    
    最后再Recycleview里面的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="60dp"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <com.zxf.androidcustomlayout.CanvasAndPaint.TimeListDemo.TimeListView
            android:id="@+id/tlv"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:paddingTop="20dp"
            android:paddingLeft="10dp"
            android:paddingBottom="20dp"
            android:layout_centerVertical="true"
            app:startLine="@color/colorAccent"
            app:endLine="@color/colorPrimary"
            app:maker="@mipmap/x5"
            app:circle="20dp"
            app:lineSize="2dp"
            />
        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="这个是时间轴数据"
            android:layout_marginLeft="100dp"
            android:layout_marginTop="20dp"/>
    </RelativeLayout>

    点击查看源码



    展开全文
  • 纯css3响应式的水平时间轴布局代码 纯css3响应式的水平时间轴布局代码
  • 主要为大家详细介绍了Android自定义View实现垂直时间轴布局的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 通过继承LinearLayout简易做出时间轴布局.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 类似时间轴布局HTML5模板是一款适合做相册网站的HTML5模板。
  • css3响应式垂直时间轴布局效果演示
  • 这是一个左右交叉的时间轴布局,在大屏幕上有可能用到.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • jQuery html5响应式布局制作垂直时间轴特效,bootstrap设计响应式网页垂直时间轴代码
  • 这是一个左右交叉的时间轴布局,在大屏幕上有可能用到
  • 主要为大家详细介绍了JQuery+HTML5+CSS3制作时间轴,支持响应式布局时间轴插件,感兴趣的小伙伴们可以参考一下
  • jQuery水平布局软件版本更新信息时间轴代码是一款以圆形风格样式水平线性布局的网页时间轴代码,还可以用于记录企业大事记等信息。
  • 竖直时间轴之左右交叉布局

    千次阅读 2016-06-26 16:17:49
    最近学习了时间轴的用法,用到了一个左右交叉布局,其间有些东西我觉得可以跟大家分享一下,还是那句话:我是小菜鸟,大家多多指教。

    最近学习了时间轴的用法,用到了一个左右交叉布局,其间有些东西我觉得可以跟大家分享一下,还是那句话:我是小菜鸟,大家多多指教。

    先给大家看下效果图,至于GIF动画,目前还在学习中,后期希望能上传GIF动画,这是正在做的项目中抽取出来的一部分



    该时间轴参考了网上很流行的ListView控件制作的,每一行都加载相同的Item布局文件,将divider的高度设置为0,就可以达到效果了。

    下面看代码,我喜欢从布局文件开始。

    首先是main.xml布局,这个布局没什么好讲的,主要是一个Listview控件,大家可以根据需要添加其他辅助控件

    <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"
        tools:context="com.cjt.timelinedemo.MainActivity" >
    
        <ListView
            android:id="@+id/timeLine"
            android:layout_width="match_parent"
            android:layout_height="match_parent"        
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" >
        </ListView>
    
    </RelativeLayout>

        因为是左右交叉的时间轴布局,左右肯定不能复用,所以要创建两个布局文件,分别对应左右的布局视图


    如上图,以左侧的时间为区分,分为左右布局,上代码left_list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal" >
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginRight="3dp"
            android:gravity="center|right"
            android:orientation="vertical" >
    
            <TextView
                android:id="@+id/left_tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:textStyle="bold"
                android:text="2016-06-28 17:50" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical" >
    
            <!-- 上下各画一根橙色的线条,线宽设置为2dp -->
    
            <View
                android:layout_width="2dp"
                android:layout_height="0dp"
                android:layout_weight="1" 
                android:background="#FB7F02"/>
    
            <!-- 设置中间的节点大小为20x20 -->
    
            <ImageView
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:src="@drawable/item_center_circle" />
    
            <View
                android:layout_width="2dp"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="#FB7F02" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="3dp"
            android:background="@drawable/right_item_bg"
            android:gravity="center"
            android:orientation="vertical" >
    
            <ImageView
                android:id="@+id/left_item_img"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_launcher" />
    
            <TextView
                android:id="@+id/left_item_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#fff"
                android:text="这里可以放自定义的布局或内容" />
    
        </LinearLayout>
    
    </LinearLayout>
    同样的,右边布局的代码right_list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal" >
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginRight="3dp"
            android:layout_weight="1"
            android:background="@drawable/left_item_bg"
            android:gravity="center"
            android:orientation="vertical" >
    
            <ImageView
                android:id="@+id/right_item_img"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_launcher" />
    
            <TextView
                android:id="@+id/right_item_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="我是右边布局的内容"
                android:textColor="#fff" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical" >
    
            <!-- 上下各画一根橙色的线条,线宽设置为2dp -->
    
            <View
                android:layout_width="2dp"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="#FB7F02" />
    
            <!-- 设置中间的节点大小为20x20 -->
    
            <ImageView
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:src="@drawable/item_center_circle" />
    
            <View
                android:layout_width="2dp"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="#FB7F02" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="3dp"
            android:layout_weight="1"
            android:gravity="center|left"
            android:orientation="vertical" >
    
            <TextView
                android:id="@+id/right_tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="2016-06-27 14:45"
                android:textSize="14sp"
                android:textStyle="bold" />
        </LinearLayout>
    
    </LinearLayout>

    左右布局稍稍有些不一样,但是大同小异。好了下面开始讲代码了。核心主要在TimeLineAdapter,也就是这个ListView控件的适配器。注释我已经详细的写在代码中了,所以不做过多的解释。看代码

    public class TimeLineAdapter extends BaseAdapter {
    
    	/** 上下文环境 **/
    	private Context mContext;
    	/**
    	 * 实体类列表 建议最好用实体类,当然也可以用Map之类的来动态添加或生成, 我自己在这里建了一个实体类,配套后面的holder来用
    	 * **/
    	private List<InfoBean> infoList;
    	/** 对应要用到的实体类 **/
    	private InfoBean infoBean;
    	/** 布局渲染器 **/
    	private LayoutInflater inflater;
    
    	public TimeLineAdapter() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    
    	/**
    	 * 构造函数
    	 * 
    	 * @param mContext
    	 *            上下文环境
    	 * @param infoList
    	 *            实体类列表
    	 */
    	public TimeLineAdapter(Context mContext, List<InfoBean> infoList) {
    		super();
    		this.mContext = mContext;
    		this.infoList = infoList;
    	}
    
    	@Override
    	public int getCount() {
    		// TODO Auto-generated method stub
    		return infoList.size();
    	}
    
    	@Override
    	public Object getItem(int position) {
    		// TODO Auto-generated method stub
    		return position;
    	}
    
    	@Override
    	public long getItemId(int position) {
    		// TODO Auto-generated method stub
    		return position;
    	}
    
    	/**
    	 * 注意这个方法最重要
    	 * 
    	 */
    	@Override
    	public View getView(int position, View convertView, ViewGroup parent) {
    		ViewHolder holder = null;
    		// 如果convertView为空,则加载界面布局文件
    		inflater = LayoutInflater.from(parent.getContext());
    		// 如果为空,就重新加载布局文件
    		if (null == convertView) {
    			/*
    			 * 由于我这里有两种不同的布局,而且是交叉呈现,所以做如下处理,将position对2求余,
    			 * 如果为0就加载左边布局,为1就加载右边布局
    			 */
    			if (position % 2 == 0) {
    				// 加载左边布局
    				convertView = inflater.inflate(R.layout.left_list_item, null);
    				// 创建一个VIewHolder用以缓存
    				holder = new ViewHolder();
    				holder.mInfoDate = (TextView) convertView
    						.findViewById(R.id.left_tv_time);
    				holder.mInfoContent = (TextView) convertView
    						.findViewById(R.id.left_item_content);
    				holder.mInfoIcon = (ImageView) convertView
    						.findViewById(R.id.left_item_img);
    				// 这里多了一个变量
    				holder.isLeftOrRight = true;
    
    				// 设置holder标签
    				convertView.setTag(holder);
    			} else {
    				// 加载右边布局
    				convertView = inflater.inflate(R.layout.right_list_item, null);
    				// 创建一个VIewHolder用以缓存
    				holder = new ViewHolder();
    				holder.mInfoDate = (TextView) convertView
    						.findViewById(R.id.right_tv_time);
    				holder.mInfoContent = (TextView) convertView
    						.findViewById(R.id.right_item_content);
    				holder.mInfoIcon = (ImageView) convertView
    						.findViewById(R.id.right_item_img);
    				// 这里多了一个变量
    				holder.isLeftOrRight = false;
    
    				// 设置holder标签
    				convertView.setTag(holder);
    			}
    
    		} else {// 如果不为空,就直接从缓存中去取
    			holder =  (ViewHolder)convertView.getTag();//本来直接这样取是没有问题的,但是会发现有重叠的bug
    			
    			// 所以接下来的处理是为了解决会出现的bug,如果有同学不明白的话,可以进下面的注释掉,然后运行一遍,就会发现问题了
    			// 如何来解释这个呢?如果一屏幕有三个item,那么holder就将缓存三个item,到第四个的时候,
    			// 就会将holder中原来缓存的第一个去覆盖第四个,这样就会出现,本来应该是右边出现的布局跑到了左边,还跟下面出现的布局重合的现象
    			// 建议注释掉之后看效果,这样有点讲不明白
    			if (0 == position%2 && !holder.isLeftOrRight) {
    				// 加载左边布局
    				convertView = inflater.inflate(R.layout.left_list_item, null);
    				// 创建一个VIewHolder用以缓存
    				holder = new ViewHolder();
    				holder.mInfoDate = (TextView) convertView
    						.findViewById(R.id.left_tv_time);
    				holder.mInfoContent = (TextView) convertView
    						.findViewById(R.id.left_item_content);
    				holder.mInfoIcon = (ImageView) convertView
    						.findViewById(R.id.left_item_img);
    				// 这里多了一个变量
    				holder.isLeftOrRight = true;
    
    				// 设置holder标签
    				convertView.setTag(holder);
    			}else if(1 == position%2 && holder.isLeftOrRight){
    				// 加载右边布局
    				convertView = inflater.inflate(R.layout.right_list_item, null);
    				// 创建一个VIewHolder用以缓存
    				holder = new ViewHolder();
    				holder.mInfoDate = (TextView) convertView
    						.findViewById(R.id.right_tv_time);
    				holder.mInfoContent = (TextView) convertView
    						.findViewById(R.id.right_item_content);
    				holder.mInfoIcon = (ImageView) convertView
    						.findViewById(R.id.right_item_img);
    				// 这里多了一个变量
    				holder.isLeftOrRight = false;
    
    				// 设置holder标签
    				convertView.setTag(holder);
    			}else{
    				
    			}		
    		}
    
    		// 在这里给holder中对应的控件填充内容
    		for (int i = 0; i < infoList.size(); i++) {
    			// 先遍历列表中的对象,一个个来填充
    			infoBean = infoList.get(i);
    			// 下面填充数据
    			holder.mInfoDate.setText(infoBean.getInfoDate().toString());
    			holder.mInfoContent.setText(infoBean.getInfoContent().toString());
    			holder.mInfoIcon.setImageResource(infoBean.getInfoPicResourse());			
    		}
    		
    		// 返回填充好了的convertView
    		return convertView;
    	}
    
    	/** 按照流行的写法,用holder来做缓存 **/
    	public class ViewHolder {
    		/** 时间 **/
    		TextView mInfoDate;
    		/** 内容 **/
    		TextView mInfoContent;
    		/** 新闻图标 **/
    		ImageView mInfoIcon;
    		/** 左布局还是由布局,为true表示加载左布局,为false表示加载右边布局 **/
    		boolean isLeftOrRight;
    
    		public ViewHolder() {
    			super();
    		}
    	}
    
    }
    

    对应的实体类infoBean

    public class InfoBean {
    	/** 时间 **/
    	private String infoDate;
    	/** 内容 **/
    	private String infoContent;
    	/** 图片 **/
    	private int infoPicResourse;
    
    	public InfoBean() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    
    	public String getInfoDate() {
    		return infoDate;
    	}
    
    	public void setInfoDate(String infoDate) {
    		this.infoDate = infoDate;
    	}
    
    	public String getInfoContent() {
    		return infoContent;
    	}
    
    	public void setInfoContent(String infoContent) {
    		this.infoContent = infoContent;
    	}
    
    	public int getInfoPicResourse() {
    		return infoPicResourse;
    	}
    
    	public void setInfoPicResourse(int infoPicResourse) {
    		this.infoPicResourse = infoPicResourse;
    	}
    
    }


    下面是MainActivity源码

    public class MainActivity extends Activity implements OnItemClickListener{
    
    	/**界面的ListView控件**/
    	private ListView mTimeList ;
    	/**时间轴适配器**/
    	private TimeLineAdapter mAdapter ;
    	/**对应的实体类的数据列表**/
    	List<InfoBean> infoList = new ArrayList<InfoBean>();
    	/**信息实体类**/
    	InfoBean infoBean ;
    	
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // 获取控件,并为该控件绑定事件监听器
            mTimeList = (ListView) this.findViewById(R.id.timeLine);
            mTimeList.setOnItemClickListener(this);
            // 设置DIvider高度为0
            mTimeList.setDividerHeight(0);
            
            // 填充数据,这里也可以用Map来自己造数据,不需要另外在新建实体类
            for (int i = 0; i < 30 ; i++) {
            	infoBean = new InfoBean();
            	infoBean.setInfoDate("2016-06-28 18:30");
            	infoBean.setInfoContent("我是内容详情");
            	infoBean.setInfoPicResourse(R.drawable.ic_launcher);
            	
            	// 将实体添加到列表中
            	infoList.add(infoBean);
    		}       
            
            // 设置适配器
            mAdapter = new TimeLineAdapter(getApplicationContext(), infoList);       
            mTimeList.setAdapter(mAdapter);
            
        }
    
        
    	@Override
    	public void onItemClick(AdapterView<?> parent, View view, int position,
    			long id) {
    		// TODO Auto-generated method stub
    		Toast.makeText(getApplicationContext(), "你点击了" + position, 1000).show();
    	}
    
    
    }

    这里有异常的情况可以给大家展示一下,主要是这一句代码在处理异常,
    			holder =  (ViewHolder)convertView.getTag();//本来直接这样取是没有问题的,但是会发现有重叠的bug
    			
    			// 所以接下来的处理是为了解决会出现的bug,如果有同学不明白的话,可以进下面的注释掉,然后运行一遍,就会发现问题了
    			// 如何来解释这个呢?如果一屏幕有三个item,那么holder就将缓存三个item,到第四个的时候,
    			// 就会将holder中原来缓存的第一个去覆盖第四个,这样就会出现,本来应该是右边出现的布局跑到了左边,还跟下面出现的布局重合的现象
    			// 建议注释掉之后看效果,这样有点讲不明白
    			if (0 == position%2 && !holder.isLeftOrRight) {
    				// 加载左边布局
    				convertView = inflater.inflate(R.layout.left_list_item, null);
    				// 创建一个VIewHolder用以缓存
    				holder = new ViewHolder();
    				holder.mInfoDate = (TextView) convertView
    						.findViewById(R.id.left_tv_time);
    				holder.mInfoContent = (TextView) convertView
    						.findViewById(R.id.left_item_content);
    				holder.mInfoIcon = (ImageView) convertView
    						.findViewById(R.id.left_item_img);
    				// 这里多了一个变量
    				holder.isLeftOrRight = true;
    
    				// 设置holder标签
    				convertView.setTag(holder);
    			}else if(1 == position%2 && holder.isLeftOrRight){
    				// 加载右边布局
    				convertView = inflater.inflate(R.layout.right_list_item, null);
    				// 创建一个VIewHolder用以缓存
    				holder = new ViewHolder();
    				holder.mInfoDate = (TextView) convertView
    						.findViewById(R.id.right_tv_time);
    				holder.mInfoContent = (TextView) convertView
    						.findViewById(R.id.right_item_content);
    				holder.mInfoIcon = (ImageView) convertView
    						.findViewById(R.id.right_item_img);
    				// 这里多了一个变量
    				holder.isLeftOrRight = false;
    
    				// 设置holder标签
    				convertView.setTag(holder);
    			}else{
    				
    			}		

    如果注释掉将会出现以下异常



    好了,分享到此为止,鉴于我也是菜鸟一枚,大家可以相互学习和探讨,后面将给出去源码链接。


    这种布局情况在手机上可能不多见,但是在比较大的屏幕上有可能用到,最近我自己在做的项目就用到了这个。


    源码下载







    展开全文
  • 很多情况下,我们都会遇到需要类似于时间轴的一个布局,网上也有很多,但是很多情况下我们其实并不需要那么多库,毕竟64k限制就在那,不管我们用还是不用,它依然在那。。。 而且更多时候,我们的时间轴也许并不...

    先上图:

    underlinelayout.gif



    很多情况下,我们都会遇到需要类似于时间轴的一个布局,网上也有很多,但是很多情况下我们其实并不需要那么多库,毕竟64k限制就在那,不管我们用还是不用,它依然在那。。。


    而且更多时候,我们的时间轴也许并不需要那么多数据(比如转账流程?)


    事实上这次的教程也是因为我司需要弄一个转账流程,这个转账流程包含了基本的三个状态:

    1 - 转账开始

    2 - 转账中

    3 - 转账成功

    而失败后重新转账可以看到前面的状态,也就是前面的三个状态的重复

    一般而言,转账3~4次失败我们也就算了,同时因为布局比较简单,所以我这次就没打算用listview,而是简单的继承LinearLayout


    当然,如果数据比较多,为了内存建议还是用listview好


    那么下面正文开始:

     首先规划一下我们需要的元素,从图中我们可以看到的元素有:

          线(颜色,宽),点(大小,颜色),图标

     为了方便调整,我们还需要引入两个值

          点距离父控件左边的偏移值(调整左右间距),每个节点距离childView的偏移值(调整上下间距)

     

    于是我们的attrs.xml就出来了

    1.png

    然后继承LinearLayout,开始我们的简易时间轴

    2.png


    构造器我们获取各种参数,至于变量就不解释了


    我们的主要方法都在onDraw里面,onDraw我们执行一个方法

    4.png

    而我们的drawTimeLine的方法如下:

    3.png

    按照我的设想,是想着横着也做一个的,但由于时间原因,就暂时未能实现,但其实实现原理都是一样的。


    接下来就是最主要的几个方法了:

    5.png

    6.png

    7.png

    这里说说思路:


      首先我们在ondraw里面获取子控件的数量,然后通过子控件的属性定位我们的时间轴


      第一步我们先确定第一个子控件的位置,这里因为垂直的时间轴,所以我们通过top+paddingTop来确定我们的结点Y位置,同时引用我们xml定义好的dynamic值来微调。同时记录下此时第一个结点的x,y

      

      第二步我们确定最后一个控件的位置,方法同第一步,也记录下此时最后一个节点的x,y。同时调用drawBitmap画出我们的icon


      第三步我们就画第一个和最后一个之间的子控件的线和结点。相关注释都在代码中标注好了,所以这里就不再详细阐述了



    这个工程还没完成,以后如果有时间我希望能把水平方向的也弄出来。当然,如果诸位有更nice的修正欢迎PullRequest.


    这是一个简单的时间轴定制,希望能够帮到你-V-(详细代码请看github)

    展开全文
  • 效果图: 代码: 时间线左右布局 {{activity.timestamp}} {{activity.company}} {{activity. comtype}}  {{activity.title}} 查看修改留痕 {{activity.content1}} {{activity.content2}}

    效果图:

    代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!--引入 element-ui 的样式,-->
        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
        <!-- 必须先引入vue,  后使用element-ui -->
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
        <!-- 引入element 的组件库-->
        <script src="https://unpkg.com/element-ui/lib/index.js"></script>
        <title>时间线左右布局</title>
        <style>
    
            #app {
              position: absolute;
              top: 50px;
              left:250px;
              width: 25%;
            }
    
            .companydel {
                color: #909399;
                position: absolute;
                left: -200px;
                top: 1px;
                font-size: 12px;
    
              }
    
              .fl {
                  float: left;
              }
    
              .fr {
                  float: right;
              }
    
        </style>
    
    </head>
    
    <body>
    
        <!-- 下载地址  vue.js: https://cdn.jsdelivr.net/npm/vue/dist/vue.js
        element.js:  https://unpkg.com/element-ui@2.4.11/lib/index.js   
        element.css: https://unpkg.com/element-ui@2.4.11/lib/theme-chalk/index.css
       我是粘贴复制到本地的,注意element-ui使用的是2.4.11版本的。 -->
    
    <div id="app">
        <el-timeline>
            <el-timeline-item  
            v-for="(activity, index) in activities1"
            :key="index"
            :icon="activity.icon"
            :type="activity.type"
            :size="activity.size"
            >
    
            <!-- 时间线左侧 -->
                <div class="companydel">
                    {{activity.timestamp}}
                    <p style="font-size: 14px;">{{activity.company}}</p>
                    <p style="font-size: 14px;">{{activity. comtype}}</p>
                </div>
                <!-- 时间线右侧 -->
              <div>
               <div class="el-row">
                   <div class="fl"> <strong>{{activity.title}}</strong></div>
                   <div class="fr"> <el-link type="primary">查看修改留痕</el-link></div>
               </div>
                <p style="color: #909399;">{{activity.content1}}</p>
                <p style="color: #909399; margin-bottom: 40px;">{{activity.content2}}</p>
              </div>
    
            </el-timeline-item>
    
           
          </el-timeline>
    
    
    
    
    </div>
    </body>
    </html>
    <script>
        new Vue({
          el: '#app'
          data: function() {
            return { 
              drawer: false, 
              activities1: [{
              title: '装箱单',
              content1:'收货人:我爱我的家弟弟吧爸爸妈妈 我爱我的家弟弟爸爸妈妈',
              content2:'翻译:',
              company:'我爱我的家弟弟吧爸爸妈妈',
              comtype:'核心企业',
              timestamp: '2018-04-12 20:46',
              size: 'large',
              type: 'primary',
              icon: 'el-icon-more'
    
            },
    
            {
    
              title: '分提运单',
              content1:'收货人:我爱我的家弟弟吧爸爸妈妈 我爱我的家弟弟爸爸妈妈',
              content2:'翻译:',
              company:'我爱我的家弟弟吧爸爸妈妈',
              comtype:'核心企业',
              timestamp: '2018-04-12 20:46',
              size: 'large',
              type: 'primary',
              icon: 'el-icon-more'
            },
    
            {
    
              title: '发票',
              content1:'收货人:我爱我的家弟弟吧爸爸妈妈 我爱我的家弟弟爸爸妈妈',
              content2:'翻译:',
              company:'我爱我的家弟弟吧爸爸妈妈',
              comtype:'核心企业',
              timestamp: '2018-04-12 20:46',
              size: 'large',
              type: 'primary',
              icon: 'el-icon-more'
    
            }
    
            , {
    
              title: '进口采购订单',
              content1:'收货人:我爱我的家弟弟吧爸爸妈妈 我爱我的家弟弟爸爸妈妈',
              content2:'翻译:',
              company:'我爱我的家弟弟吧爸爸妈妈',
              comtype:'核心企业',
              timestamp: '2018-04-12 20:46',
              size: 'large',
              type: 'primary',
              icon: 'el-icon-more'
    
            }]
    
              }
    
          }
    
        })
    
      </script>

    展开全文
  • React时间轴 使用React在美观的布局中可视化时间表 这个项目是关于什么的? 很简单您有想要记住的时代。 我们有一个应用程序。 如果您不希望看到某个时间段或另一个时间段的可视化, 可以将自己作为专门为这些目的...
  • 两个很强大的js实现的时间轴

    热门讨论 2012-09-05 16:32:17
    有很多要求以时间为变量来标记事件的,这里有两个很好的开源js库,一大一小(timeglider,chronoline)。 但有个共同的缺点时间都只精确到天为单位。 个人把chronoline改成精确到分,但还不是很完善,如有需要的同鞋可以...
  • 1、清晰的效果图; 2、完整的源代码以及详细的说明
  • 这是一款css3跑道式时间轴设计效果。该时间轴以弯曲的跑道作为时间轴的路线,以不同的颜色来区分时间点,采用响应式设计,效果非常酷。
  • 一款多彩风格的创意响应式CSS3垂直时间轴样式布局代码,纯CSS3制作的纵向时间轴样式,电脑手机端可通用。
  • 主要介绍了微信小程序时间轴实现方法,结合实例形式分析了微信小程序wx:for语句使用与时间轴纵向布局相关操作技巧,需要的朋友可以参考下
  • 网页制作课件:页面布局、层、行为和时间轴的使用
  • image.png <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ... android:layout_width="match_parent" android:layout_height..
  • bootstrap时间轴插件

    2018-05-09 22:10:12
    bootstrap垂直时间轴插件,方便好用,操作便捷,值得拥有
  • Recycleview基本使用,包括线性布局、Grid布局、瀑布流效果,以及讲解自定义ItemDecoration实现各种效果,以及自定义控件时间轴
  • Pr:时间轴面板

    2021-01-19 00:00:00
    每个序列都对应一个时间轴,所以时间轴面板又称序列面板。V1、V2、V3 等表示视频轨道,A1、A2、A3 等表示音频轨道。应将视频或音频剪辑拖入到相应类型的轨道。说明:1、Pr 采用层叠...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,781
精华内容 48,312
关键字:

时间轴布局