这篇博客作为我写博客之旅的开篇之作,是希望以一个结构清晰的优质代码内容来开启。之前在进行Android开发的过程中,一直都是作为一个汲取者,取猎各位大神们的作品。让我一直觉得很好意思呀。同享一个平台,也希望自己能成为一个优质代码提供者呀。让彼此在开发过程中,都少走弯路,共同进步。废话说了这么多,自己都嫌麻烦了。直接上效果图:
实现此效果的关键 简单来说 就在于: 滚动ListView填入横向滚动HorizontalScrollView中
当然,需要处理的细节还是很多。我会将完整代码以及Demo附上,方便大家查看,使用。
为了便于观看,我就先从MainActivity的代码,来讲起。当然,讲解就不多说了。主要是代码。代码注释部分 已经很多了,每一个细节也都进行了标注。绝对能让大家看得懂,看得明白。
1、MainActivity:
package com.example.administrator.timetabledemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import com.example.administrator.timetabledemo.adapter.TimeTableAdapter;
import com.example.administrator.timetabledemo.view.TableListRecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by YangHao on 2017/7/28 0028.
*/
public class MainActivity extends AppCompatActivity {
TableListRecyclerView tableListRecyclerView; //重写的SuperRecyclerView
TimeTableAdapter timeTableAdapter;
private List<String> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initView() {
tableListRecyclerView = (TableListRecyclerView) findViewById(R.id.rv_data);
}
private void initData() {
/**
* 必须重写 LinearLayoutManager方法 、
* 避免 ScrollView 与 RecyclerView 滑动冲突
* 关闭 RecyclerView的 纵向 滚动事件 即可
*/
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this){
@Override
public boolean canScrollVertically() {
return false;
}
};
tableListRecyclerView.setLayoutManager(linearLayoutManager);
tableListRecyclerView.setRefreshEnabled(false); //关闭 下拉刷新
tableListRecyclerView.setLoadMoreEnabled(false);//关闭 上拉加载更多
list = new ArrayList<>();
timeTableAdapter = new TimeTableAdapter(this,list);
tableListRecyclerView.setAdapter(timeTableAdapter);
upDataList();
}
// 写入 时间格 数据内容
private void upDataList() {
/**
* 将 一天 24 小时 以 半小时为节点 拆分开
* 从 -1 开始 因为 有一个抬头 数据 需要 多一行
*/
for (int i = -1; i < 48; i++) {
StringBuffer hour = new StringBuffer(); // StringBuffer 效率 高于 String 在当前存放地址改变 数据内容
if(i<20){
hour.append("0"+i/2);
}else {
hour.append(i/2+"");
}
if(i%2 == 0){
hour.append(":00");
}else {
hour.append(":30");
}
list.add(hour.toString());
}
timeTableAdapter.setEmptyTimeList();
}
}
2.对应的Adapter:
package com.example.administrator.timetabledemo.adapter;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import com.example.administrator.timetabledemo.R;
import com.example.administrator.timetabledemo.utils.ConstantUtils;
import com.superrecycleview.superlibrary.adapter.BaseViewHolder;
import com.superrecycleview.superlibrary.adapter.SuperBaseAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by YangHao on 2017/7/28 0025.
*/
public class TimeTableAdapter extends SuperBaseAdapter<String> {
private final int HEAD_TYPE = 1;
private final int TIME_TYPE = 2;
private Context context;
private List<String> timeTableList;
private Map<Integer,List<Boolean>>integerListMap; //存放当前 时间格 是否被选中的 Map集合
public TimeTableAdapter(Context context) {
super(context);
}
public TimeTableAdapter(Context context, List<String> data) {
super(context, data);
this.context = context;
timeTableList = data;
integerListMap = new HashMap<>();
}
/**
* 处理数据 View填充内容
* */
@Override
protected void convert(BaseViewHolder holder, String item, final int position) {
switch (getAdapterItemType(position)){
case HEAD_TYPE: //顶部的日期表
TextView head1 = holder.getView(R.id.head1);
TextView head2 = holder.getView(R.id.head2);
TextView head3 = holder.getView(R.id.head3);
TextView head4 = holder.getView(R.id.head4);
TextView head5 = holder.getView(R.id.head5);
TextView head6 = holder.getView(R.id.head6);
TextView head7 = holder.getView(R.id.head7);
TextView head21 = holder.getView(R.id.head21);
TextView head22 = holder.getView(R.id.head22);
TextView head23 = holder.getView(R.id.head23);
TextView head24 = holder.getView(R.id.head24);
TextView head25 = holder.getView(R.id.head25);
TextView head26 = holder.getView(R.id.head26);
TextView head27 = holder.getView(R.id.head27);
// 放入数组中 统一管理 View 优化代码量(处理方式一样 放入更便捷)
TextView[] viewDates = {head1,head2,head3,head4,head5,head6,head7};
TextView[] viewWays = {head21,head22,head23,head24,head25,head26,head27};
// 从 常量工具类中 获取 当前 日期时间 集合
List<String> dates = ConstantUtils.getInstance().get7Date();
List<String> ways = ConstantUtils.getInstance().get7Ways();
for (int i = 0; i < dates.size(); i++) {
viewDates[i].setText(dates.get(i));
viewWays[i].setText(ways.get(i));
}
break;
case TIME_TYPE: // 单位时间表
TextView time1 = holder.getView(R.id.time1);
TextView time2 = holder.getView(R.id.time2);
TextView time3 = holder.getView(R.id.time3);
TextView time4 = holder.getView(R.id.time4);
TextView time5 = holder.getView(R.id.time5);
TextView time6 = holder.getView(R.id.time6);
TextView time7 = holder.getView(R.id.time7);
final TextView timeTexts[] = {time1,time2,time3,time4,time5,time6,time7};
for (int i = 0; i < timeTexts.length; i++) {
timeTexts[i].setText(item);
}
//填充 时间格 当前所处状态
List<Boolean> booleanList = integerListMap.get(position);
for (int i = 0; i < booleanList.size(); i++) {
if(booleanList.get(i)){
timeTexts[i].setBackgroundResource(R.drawable.text_view_frame);
timeTexts[i].setTextColor(context.getResources().getColor(R.color.grass_green));
}else {
timeTexts[i].setTextColor(context.getResources().getColor(R.color.gray));
timeTexts[i].setBackgroundResource(R.drawable.text_view_no_frame);
}
}
/**
* 对时间格 点击状态的处理 同样 放在 数组中 统一管理(优化代码量)
* 处理方式:先改变当前状态 之后改变 存放状态的 数据内容
* 直接处理的优点: 减少页面整体的 重刷次数
*/
for (int i = 0; i < timeTexts.length; i++) {
final int finalI = i;
timeTexts[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean b = integerListMap.get(position).get(finalI);
if(!b){ //被点击后 当前 是 未被选中的状态 即false时,变为选中状态
timeTexts[finalI].setBackgroundResource(R.drawable.text_view_frame);
timeTexts[finalI].setTextColor(context.getResources().getColor(R.color.grass_green));
}else {
timeTexts[finalI].setBackgroundResource(R.drawable.text_view_no_frame);
timeTexts[finalI].setTextColor(context.getResources().getColor(R.color.gray));
}
integerListMap.get(position).set(finalI,!b);
}
});
}
break;
}
}
/**
* 获取多布局对应的 布局样式
*/
@Override
protected int getItemViewLayoutId(int position, String item) {
switch (getAdapterItemType(position)){
case HEAD_TYPE:
return R.layout.item_time_head;
case TIME_TYPE:
return R.layout.item_time_data;
}
return 0;
}
// 布局类型
private int getAdapterItemType(int position){
if(position == 0){
return HEAD_TYPE;
}else {
return TIME_TYPE;
}
}
/**写入数据 更新数据*/
public void setEmptyTimeList(){
for (int i = 0; i < timeTableList.size(); i++) {
List<Boolean>list2 = new ArrayList<>();
for (int j = 0; j < 7; j++) {
list2.add(false);
}
integerListMap.put(i,list2);
}
}
/** 返回所有的数据 即可以返回 处于选中状态的数据 */
public Map<Integer,List<Boolean>> getAllListData(){
return integerListMap;
}
}
3.三个重写的View类:
(1)HorizontalScrollView
package com.example.administrator.timetabledemo.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.HorizontalScrollView;
/**
* Created by YangHao on 2017/7/28 0024.
* 重写 横向滚动 (并未使用到)
* 当 头部 日期 数据 与 时间格 拆分开 存入 不同的 HorizontalScrollView 是会被用到的
*/
public class SyncHorizontalScrollView extends HorizontalScrollView {
private View mView;
public SyncHorizontalScrollView(Context context) {
super(context);
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mView != null) {
mView.scrollTo(l, t);
}
}
// 写入 同步滚动的 View
public void setScrollView(View view) {
mView = view;
}
}
(2).重写SuperRecyclerView 重新 绘制高度 使得内容可以填满 ScrollView
package com.example.administrator.timetabledemo.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import com.superrecycleview.superlibrary.recycleview.SuperRecyclerView;
/**
* Created by YangHao on 2017/7/28 0025.
* SuperRecyclerView RecyclerView 的 二次封装
* 处理更加方便: (下次抽空 可以 详细介绍一下 SuperRecyclerView的 使用 以及 源码 解析)
* 简单介绍一下优点:
* 1、 不需要在写 ViewHolder类;
* 2、 集成了 上拉记载 下拉刷新;
* 3、可以不需要在Adapter中处理头部数据 外边可以添加 头部内容 而且加几个都很方便
*/
public class TableListRecyclerView extends SuperRecyclerView {
public TableListRecyclerView(Context context) {
super(context);
}
public TableListRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TableListRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// 高度重新绘制 的 方法 高度最大化 避免 RecyclerView 展示不全
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
(3).重写 ScrollView 可以实现ScrollView的上拉下拉 返回 弹框(此块内容 借鉴 来自 网友博客)
package com.example.administrator.timetabledemo.view;
/**
* Created by YangHao on 2017/7/28 0028.
*/
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;
/**
* 有弹性的ScrollView
* 实现下拉弹回和上拉弹回
*/
public class ReboundScrollView extends ScrollView {
private static final String TAG = "ElasticScrollView";
//移动因子, 是一个百分比, 比如手指移动了100px, 那么View就只移动50px
//目的是达到一个延迟的效果
private static final float MOVE_FACTOR = 0.5f;
//松开手指后, 界面回到正常位置需要的动画时间
private static final int ANIM_TIME = 300;
//ScrollView的子View, 也是ScrollView的唯一一个子View
private View contentView;
//手指按下时的Y值, 用于在移动时计算移动距离
//如果按下时不能上拉和下拉, 会在手指移动时更新为当前手指的Y值
private float startY;
//用于记录正常的布局位置
private Rect originalRect = new Rect();
//手指按下时记录是否可以继续下拉
private boolean canPullDown = false;
//手指按下时记录是否可以继续上拉
private boolean canPullUp = false;
//在手指滑动的过程中记录是否移动了布局
private boolean isMoved = false;
public ReboundScrollView(Context context) {
super(context);
}
public ReboundScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
contentView = getChildAt(0);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (contentView == null) return;
//ScrollView中的唯一子控件的位置信息, 这个位置信息在整个控件的生命周期中保持不变
originalRect.set(contentView.getLeft(), contentView.getTop(), contentView
.getRight(), contentView.getBottom());
}
/**
* 在触摸事件中, 处理上拉和下拉的逻辑
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (contentView == null) {
return super.dispatchTouchEvent(ev);
}
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
//判断是否可以上拉和下拉
canPullDown = isCanPullDown();
canPullUp = isCanPullUp();
//记录按下时的Y值
startY = ev.getY();
break;
case MotionEvent.ACTION_UP:
if (!isMoved) break; //如果没有移动布局, 则跳过执行
// 开启动画
TranslateAnimation anim = new TranslateAnimation(0, 0, contentView.getTop(),
originalRect.top);
anim.setDuration(ANIM_TIME);
contentView.startAnimation(anim);
// 设置回到正常的布局位置
contentView.layout(originalRect.left, originalRect.top,
originalRect.right, originalRect.bottom);
//将标志位设回false
canPullDown = false;
canPullUp = false;
isMoved = false;
break;
case MotionEvent.ACTION_MOVE:
//在移动的过程中, 既没有滚动到可以上拉的程度, 也没有滚动到可以下拉的程度
if (!canPullDown && !canPullUp) {
startY = ev.getY();
canPullDown = isCanPullDown();
canPullUp = isCanPullUp();
break;
}
//计算手指移动的距离
float nowY = ev.getY();
int deltaY = (int) (nowY - startY);
//是否应该移动布局
boolean shouldMove =
(canPullDown && deltaY > 0) //可以下拉, 并且手指向下移动
|| (canPullUp && deltaY < 0) //可以上拉, 并且手指向上移动
|| (canPullUp && canPullDown); //既可以上拉也可以下拉(这种情况出现在ScrollView包裹的控件比ScrollView还小)
if (shouldMove) {
//计算偏移量
int offset = (int) (deltaY * MOVE_FACTOR);
//随着手指的移动而移动布局
contentView.layout(originalRect.left, originalRect.top + offset,
originalRect.right, originalRect.bottom + offset);
isMoved = true; //记录移动了布局
}
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
/**
* 判断是否滚动到顶部
*/
private boolean isCanPullDown() {
return getScrollY() == 0 ||
contentView.getHeight() < getHeight() + getScrollY();
}
/**
* 判断是否滚动到底部
*/
private boolean isCanPullUp() {
return contentView.getHeight() <= getHeight() + getScrollY();
}
}
4、附上封装好的当前时间工具类
package com.example.administrator.timetabledemo.utils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
/**
* Created by YangHao on 2017/7/28 0025.
* 常量工具类
*/
public class ConstantUtils {
private static ConstantUtils constantUtils;
private ConstantUtils(){}
public static ConstantUtils getInstance(){
if(constantUtils == null){
constantUtils = new ConstantUtils();
}
return constantUtils;
}
/**
* 日期类
*/
private String mYear;
private String mMonth;
private String mDay;
private String mWay;
private Calendar calendar = Calendar.getInstance();
public void setNowDate(){
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
mYear = String.valueOf(calendar.get(Calendar.YEAR)); // 获取当前年份
mMonth = String.valueOf(calendar.get(Calendar.MONTH) + 1);// 获取当前月份
mDay = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码
mWay = String.valueOf(calendar.get(Calendar.DAY_OF_WEEK));
if("1".equals(mWay)){
mWay ="星期天";
}else if("2".equals(mWay)){
mWay ="星期一";
}else if("3".equals(mWay)){
mWay ="星期二";
}else if("4".equals(mWay)){
mWay ="星期三";
}else if("5".equals(mWay)){
mWay ="星期四";
}else if("6".equals(mWay)){
mWay ="星期五";
}else if("7".equals(mWay)){
mWay ="星期六";
}
}
/**获取当前周几*/
public String getTodayWay(){
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
String mWay = String.valueOf(calendar.get(Calendar.DAY_OF_WEEK));
if("1".equals(mWay)){
mWay ="星期天";
}else if("2".equals(mWay)){
mWay ="星期一";
}else if("3".equals(mWay)){
mWay ="星期二";
}else if("4".equals(mWay)){
mWay ="星期三";
}else if("5".equals(mWay)){
mWay ="星期四";
}else if("6".equals(mWay)){
mWay ="星期五";
}else if("7".equals(mWay)){
mWay ="星期六";
}
return mWay;
}
/**获取未来一周星期集合*/
public List<String> get7Ways(){
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
String todayWay = getTodayWay();
String mWay = String.valueOf(calendar.get(Calendar.DAY_OF_WEEK));
String []strings = {"星期天","星期一","星期二","星期三","星期四","星期五","星期六",};
int t = -1;
List<String> ways = new ArrayList<>();
for (int i = 0; i < 7; i++) {
if(todayWay.equals(strings[i])){
t = i;
int j = i;
for (; t < j+7; t++) {
ways.add(strings[t%7]);
}
}
}
return ways;
}
/** 返回 01-01 样式的 日期 */
public String getMMdd(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd");
String date = simpleDateFormat.format(calendar.getTime());
return date;
}
/**
* 返回今天往后一星期的集合
*/
public List<String> get7Date() {
List<String> dates = new ArrayList<String>();
final Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
SimpleDateFormat sim = new SimpleDateFormat("MM-dd");
String date = sim.format(c.getTime());
dates.add(date);
for (int i = 0; i < 6; i++) {
c.add(Calendar.DAY_OF_MONTH, 1);
date = sim.format(c.getTime());
dates.add(date);
}
return dates;
}
}
5、接下来就是很重要的布局样式了。
(1)首先是MainActivity的:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:background="#f8faf6"
tools:context=".MainActivity">
<com.example.administrator.timetabledemo.view.ReboundScrollView
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/lin_data_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical">
<com.example.administrator.timetabledemo.view.SyncHorizontalScrollView
android:id="@+id/data_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="none">
<com.example.administrator.timetabledemo.view.TableListRecyclerView
android:id="@+id/rv_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
/>
</com.example.administrator.timetabledemo.view.SyncHorizontalScrollView>
</LinearLayout>
</LinearLayout>
</com.example.administrator.timetabledemo.view.ReboundScrollView>
</LinearLayout>
(2)时间表头布局的
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="vertical"
android:layout_marginTop="18dp"
android:background="#f4f4f4"
android:paddingTop="5dp"
android:paddingBottom="5dp"
>
<LinearLayout
android:id="@+id/lin_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/head1"
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:text="1"/>
<TextView
android:id="@+id/head2"
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:text="2" />
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head3"
android:text="3"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head4"
android:text="4"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head5"
android:text="5"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head6"
android:text="6"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head7"
android:text="7"/>
</LinearLayout>
<LinearLayout
android:id="@+id/lin_content_way"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/head21"
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:text="1"/>
<TextView
android:id="@+id/head22"
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:text="2" />
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head23"
android:text="3"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head24"
android:text="4"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head25"
android:text="5"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head26"
android:text="6"/>
<TextView
android:layout_width="90dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/head27"
android:text="7"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
(3)时间表 时间格内容的
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/lin_content"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/time1"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:text="00:00"
android:layout_margin="10dp"
/>
<TextView
android:id="@+id/time2"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:text="00:00"
android:layout_margin="10dp"
/>
<TextView
android:id="@+id/time3"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="10dp"
android:text="00:00"/>
<TextView
android:id="@+id/time4"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="10dp"
android:text="00:00"/>
<TextView
android:id="@+id/time5"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="10dp"
android:text="00:00"/>
<TextView
android:id="@+id/time6"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="10dp"
android:text="00:00"/>
<TextView
android:id="@+id/time7"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="10dp"
android:text="00:00"/>
<!--<View-->
<!--android:layout_width="1px"-->
<!--android:layout_height="30dp"-->
<!--android:background="#cccccc"/>-->
</LinearLayout>
</LinearLayout>
(4)然后需要的就是两个对应的drawable样式了。这个直接附 代码
1 、text_view_frame
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 实心 -->
<solid android:color="@android:color/white" />
<!-- 边框 -->
<stroke
android:width="0.5dp"
android:color="@color/grass_green" />
<!-- 圆角 -->
<corners android:radius="10dp" />
<!-- 边距 -->
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
2、text_view_no_frame
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>
这三种布局都是很简单的样式的,就不给大家附图了。
附言:其中用到了 SuperRecyclerView ,需要的jar包呢,大家直接在demo中就可以找到,当然 apk文件也附在其中。
祝各位码农大家生活娱乐,技能步步升。