Android时间轴(使用RecyclerView实现)
时间轴,其实我们平常非常的常见,比如快递信息很多就是以时间轴呈现
那么我们今天就使用RecyclerView实现一个时间轴
实现效果
这个时间轴是基于RecyclerView实现的。
首先准备布局
RecyclerVIew的每一项都是时间轴的一部分
每个RecyclerView的Item都被分为三大块
最外层是一个横向的LinearLayout,其中又嵌套了三个RelativeLayout(高度都为match_parent,宽度可以自定义),从左到右依次是
时间——时间轴——具体信息
时间和具体信息的布局中,只需要根据需要放入具体的控件就可以。
下面具体讲一下中间时间轴的实现
时间轴从上到下由三分部组成,中间是一个代表时间节点的红色圆点,点的上面和下面各有一条线,
首先固定上线(top_line)的长度(该长度可以根据需要改变,上线的长度越大,时间点的位置越靠下),
然后时间点(time_dot)直接紧挨着上线(top_line)就可以,
然后再让时间点的下线(bottom_line)紧挨时间点就可以,并且下线的高度设置为match_parent,使它充满整个剩下的item
timeline.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="70dp"
>
<RelativeLayout
android:layout_width="70dp"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/date_tag"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="2017.01.01"
android:textSize="12sp"
android:textColor="@color/primaryBlack"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="30dp"
android:layout_height="match_parent">
<TextView
android:id="@+id/top_line"
android:layout_width="1dp"
android:layout_height="12dp"
android:background="@color/timeline_line"
android:layout_centerHorizontal="true"
/>
<TextView
android:layout_below="@id/top_line"
android:id="@+id/time_dot"
android:layout_width="6dp"
android:layout_height="6dp"
android:layout_centerHorizontal="true"
android:background="@drawable/timeline_dot"
/>
<TextView
android:id="@+id/bottom_line"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_below="@id/time_dot"
android:background="@color/timeline_line"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:text="This is the test data"
android:textColor="@color/primaryBlack"
/>
<TextView
android:layout_marginTop="5dp"
android:layout_below="@+id/text_title"
android:id="@+id/case_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is the test data"
/>
</RelativeLayout>
</LinearLayout>
这是时间轴的主题布局代码,time_dot是时间点,top_line是时间点上方的线,bottom_line是时间点下方的线。
下面是time_dot时间点的代码
timeline_dot.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
>
<size
android:height="10dp"
android:width="10dp"
>
</size>
<solid
android:color="@color/timeline_line">
</solid>
</shape>
timeline_dot.xml预览效果
时间轴主体的布局已经完成了,MainActivity的布局非常简单,一个RecyclerView就可以了
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/case_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
>
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
布局文件已经准备完毕,我们需要给RecyclerView准备一个Adapter
我们需要自定义Adapter,RecyclerView.Adapter
并且重写该类中的
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
public int getItemCount()
RecyclerView在加载项目时,会先调用onCreateViewHolder方法,先绑定item的布局文件,然后再创建ViewHolder,在创建ViewHolder中我们可以再绑定item布局中对应的控件,然后再调用onBindViewHolder方法。
所以对item布局中的控件操作是放在onBindViewHolder方法中进行。
准备完Adapter之后,我们还需要再自定义的CaseDataListAdapter类中定义一个内部静态类并且继承自RecyclerView.ViewHolde
在定义该类时,加入我们所需要绑定的控件
并在执行public ViewHolder(View view);方法中绑定我们所需要绑定的控件。
public class CaseDataListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context nowcontext;
private List<CaseData> caseDataList;
View root;
public CaseDataListAdapter(Context context,List<CaseData> list)
{
caseDataList = list;
nowcontext = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.timeline,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder viewHolder = (ViewHolder)holder;
if(getItemViewType(position) == 0)
{
//如果这个item是RecyclerView的第一项,让第一项上线设置为不可见
viewHolder.top_line.setVisibility(View.INVISIBLE);
}
else
//其余的item的上线皆可见,保持时间轴的连贯性
viewHolder.top_line.setVisibility(View.VISIBLE);
viewHolder.date.setText(caseDataList.get(position).getDate());
viewHolder.title.setText(caseDataList.get(position).getTitle());
viewHolder.details.setText(caseDataList.get(position).getDetails());
}
@Override
public int getItemViewType(int position) {
//如果position不是0(不是第一项)
if(position == 0)
return 0;
else
return 1;
}
static class ViewHolder extends RecyclerView.ViewHolder{
private TextView date;
private TextView title;
private TextView details;
private TextView top_line;
public ViewHolder(View view)
{
super(view);
Log.e("flag","\tViewHolder");
date = (TextView)view.findViewById(R.id.date_tag);
title = (TextView)view.findViewById(R.id.text_title);
details = (TextView)view.findViewById(R.id.case_details);
top_line = (TextView)view.findViewById(R.id.top_line);
}
}
@Override
public int getItemCount() {
return caseDataList.size();
}
}
在RecyclerView的item布局文件、Adapter和ViewHolder都准备之后,就是在Activity中调用
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
List<CaseData> caseDataList;
CaseDataListAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
public void init()
{
caseDataList = new LinkedList<>();
recyclerView = (RecyclerView)findViewById(R.id.case_list);
//initData()方法用来初始化caseDataList的数据,该方法可以根据需要自行添加数据
initData(caseDataList);
//新建一个我们自定义的RecyclerView的adapter
adapter = new CaseDataListAdapter(this,caseDataList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter); //为RecyclerView设置adapter
}
}
这行代码
recyclerView.setLayoutManager(new LinearLayoutManager(this))
RecyclerView的布局由LayoutManager管理
所以此处为RecyclerView设置LayoutManager
LayoutManager有:
LinearLayoutManager 用来实现和ListView一样的效果
GridLayoutManager 用来实现网格布局
StaggeredGridLayoutManager用来实现瀑布流的布局
由于我们要实现和ListView一样的效果,所以使用LinearLayoutManager
至此,使用 RecyclerView实现时间轴就完成了。