實現類似課程表或出診表,方法多種多樣,有可以用TabelLayout, 也可用GridView等。這裏我用ListView來實現。最初的項目需求原型是這個樣子滴:
關注的重點:1. 表格線怎麼實現; 2. 用listview的話,怎麼設置item佈局。
分析:listview有個屬性,divider。設置divider, 可以有行分割線。 具體的列分割線的話,在item佈局中一個一個配置好了。另外,佈局也分兩種,一種是titel佈局,設置上午,下午和晚上這個規定的標題。一種是body佈局,配置每天的出診時間安排。
從服務端獲取數據我就一筆帶過, 現在是我拿到了21個數據,我將它們直接放置在一個ArrayList 中(後面會講如何優化這個存儲方式)。 以下看如何設置在adapter中。
先看listview item的2個佈局:
item_time_titel.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:text=""
/>
<View style="@style/style_line_vertical" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:text="上午"
/>
<View style="@style/style_line_vertical" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:text="下午"
/>
<View style="@style/style_line_vertical" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:text="晚上"
/>
</LinearLayout>
item_time_body.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="@+id/tv_week"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:text="星期一"
/>
<View style="@style/style_line_vertical" />
<Button
android:id="@+id/btn_am"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:background="@drawable/default_checked"
/>
<View style="@style/style_line_vertical" />
<Button
android:id="@+id/btn_pm"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:background="@drawable/default_checked"
/>
<View style="@style/style_line_vertical" />
<Button
android:id="@+id/btn_night"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:background="@drawable/default_checked"
/>
</LinearLayout>
現在看代碼:
我先將星期固定在一個數組中,同時listview的行數是固定的
private String[] weekArray = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
//根據position是否爲0, 設置不同的itme 佈局:
@Override
public int getCount() {
return 8;
}
@Override
public View getView(final int position, View convertView, ViewGroup viewGroup) {
if (position == 0) {
convertView = LayoutInflater.from(TimeTableSetActivity.this).inflate(R.layout.item_time_title, null);
} else {
convertView = LayoutInflater.from(TimeTableSetActivity.this).inflate(R.layout.item_time_body, null);
TextView tv_week = (TextView) convertView.findViewById(R.id.tv_week);
final Button btn_am = (Button) convertView.findViewById(R.id.btn_am);
final Button btn_pm = (Button) convertView.findViewById(R.id.btn_pm);
final Button btn_night= (Button) convertView.findViewById(R.id.btn_night);
setVisitTime(position, tv_week, btn_am, btn_pm, btn_night);
btn_am.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String value = timeList.get(3 * (position - 1));
if("1".equals(value)){
btn_am.setBackground(getResources().getDrawable(R.drawable.default_checked));
upateDataList(3 * (position - 1),"0");
notifyDataSetChanged();
}else{
btn_am.setBackground(getResources().getDrawable(R.drawable.green_checked));
upateDataList(3 * (position - 1),"1");
notifyDataSetChanged();
}
}
});
btn_pm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String value = timeList.get(3 * (position - 1)+1);
if("1".equals(value)){
btn_pm.setBackground(getResources().getDrawable(R.drawable.default_checked));
upateDataList(3 * (position - 1)+1,"0");
notifyDataSetChanged();
}else{
btn_pm.setBackground(getResources().getDrawable(R.drawable.green_checked));
upateDataList(3 * (position - 1)+1,"1");
notifyDataSetChanged();
}
}
});
btn_night.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String value = timeList.get(3 * (position - 1)+2);
if("1".equals(value)){
btn_night.setBackground(getResources().getDrawable(R.drawable.default_checked));
upateDataList(3 * (position - 1)+2,"0");
notifyDataSetChanged();
}else{
btn_night.setBackground(getResources().getDrawable(R.drawable.green_checked));
upateDataList(3 * (position - 1)+2,"1");
notifyDataSetChanged();
}
}
});
}
return convertView;
}
private void setVisitTime(int position, TextView tv_week, Button btn_am, Button btn_pm, Button btn_night) {
tv_week.setText(weekArray[position - 1]);
if(timeList!=null&&timeList.size()>0){
String am = timeList.get(3 * (position - 1));
String pm = timeList.get(3 * (position - 1) + 1);
String night = timeList.get(3 * (position - 1) + 2);
if("1".equals(am)){
btn_am.setBackgroundResource(R.drawable.green_checked);
}else{
btn_am.setBackgroundResource(R.drawable.default_checked);
}
if("1".equals(pm)){
btn_pm.setBackgroundResource(R.drawable.green_checked);
}else{
btn_pm.setBackgroundResource(R.drawable.default_checked);
}
if("1".equals(night)){
btn_night.setBackgroundResource(R.drawable.green_checked);
}else{
btn_night.setBackgroundResource(R.drawable.default_checked);
}
}
}
private void upateDataList(int position,String value) {
timeList.set(position,value);
}
以上代碼需要注意的地方是: 集合中裝載的是21個String 類型的數據。而且我們可以發現當item position A = 1(爲什麼不是從position=0開始呢?因爲爲0的時候,是標題欄),集合中數據對應的position B分別是:0,1,2. 當item position A = 2時候,集合中數據對應的position B分別是3,4,5。可以得出規律:B1 = 3*(A-1); B2 = 3*(A-1)+1; B3 = 3*(A-1)+2; 知道了對應關係,就能很好做出來了。
現在看做出來的效果:是不是和項目需求一致 了?
但是,過了一段時間,產品經理想對數據的展示做些改動,看需求變動圖:
當初一看需求(哪一天沒有出診,哪天就不展示),覺得難度有點大哪(原因是我開始的數據存儲這一塊沒有做好,用的一個ArrayList 類型,用的是一種面向過程的思想)。如果對21個數據一一去判斷,排列組合太多種了。後面就改數據存儲方式,方式一:用7個集合分別存儲每一天的3個時間段(上午,下午,晚上)的數據。再用一個大集合來裝這7個小集合。方式二: 還是用一個集合做,不過,每天的數據用一個類來儲存。(這是真正體現了面向對象的思想)。這裏我採用方式二,代碼量大大減少了。
先給大家展示我的數據存儲:
public class DayOutCall {
private String whichDay;//表示週一到周天
private String amTime;
private String pmTime;
private String nightTime;
public DayOutCall(String whichDay, String amTime, String pmTime, String nightTime) {
this.whichDay = whichDay;
this.amTime = amTime;
this.pmTime = pmTime;
this.nightTime = nightTime;
}
public String getWhichDay() {
return whichDay;
}
public void setWhichDay(String whichDay) {
this.whichDay = whichDay;
}
public String getAmTime() {
return amTime;
}
public void setAmTime(String amTime) {
this.amTime = amTime;
}
public String getPmTime() {
return pmTime;
}
public void setPmTime(String pmTime) {
this.pmTime = pmTime;
}
public String getNightTime() {
return nightTime;
}
public void setNightTime(String nightTime) {
this.nightTime = nightTime;
}
public boolean isEmptyDay() {
if("0".equals(amTime)&&"0".equals(pmTime)&&"0".equals(nightTime)){
return true;
}
return false;
}
}
然後在獲取到服務端的數據的時候,開始篩選數據:
private ArrayList<DayOutCall> totalDayList = new ArrayList<DayOutCall>();
DayOutCall monDayOutCall = new DayOutCall("星期一",mondayam,mondaypm,mondaynight);
if(!monDayOutCall.isEmptyDay()){
totalDayList.add(monDayOutCall);
}
DayOutCall tueDayOutCall = new DayOutCall("星期二",tuesdayam,tuesdaypm,tuesdaynight);
if(!tueDayOutCall.isEmptyDay()){
totalDayList.add(tueDayOutCall);
}
DayOutCall wedDayOutCall = new DayOutCall("星期三",wednesdayam,wednesdaypm,wednesdaynight);
if(!wedDayOutCall.isEmptyDay()){
totalDayList.add(wedDayOutCall);
}
DayOutCall thuDayOutCall = new DayOutCall("星期四",thursdayam,thursdaypm,thursdaynight);
if(!thuDayOutCall.isEmptyDay()){
totalDayList.add(thuDayOutCall);
}
DayOutCall friDayOutCall = new DayOutCall("星期五",fridayam,fridaypm,fridaynight);
if(!friDayOutCall.isEmptyDay()){
totalDayList.add(friDayOutCall);
}
DayOutCall satDayOutCall = new DayOutCall("星期六",saturdayam,saturdaypm,saturdaynight);
if(!satDayOutCall.isEmptyDay()){
totalDayList.add(satDayOutCall);
}
DayOutCall sunDayOutCall = new DayOutCall("星期日",sundayam,sundaypm,sundaynight);
if(!sunDayOutCall.isEmptyDay()){
totalDayList.add(sunDayOutCall);
}
// adapter中的數據不能再寫死了,只能是出診的時候才展示:
@Override
public int getCount() {
return totalDayList.size()+1;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if(position==0){
convertView = LayoutInflater.from(DoctorMainInfoActivity.this).inflate(R.layout.item_time_title, null);
}else{
convertView = LayoutInflater.from(DoctorMainInfoActivity.this).inflate(R.layout.item_time_body, null);
TextView tv_week = (TextView) convertView.findViewById(R.id.tv_week);
TextView tv_am = (TextView) convertView.findViewById(R.id.tv_am);
TextView tv_pm= (TextView) convertView.findViewById(R.id.tv_pm);
TextView tv_night= (TextView) convertView.findViewById(R.id.tv_night);
setVisitTime(position, tv_week, tv_am, tv_pm, tv_night);
}
return convertView;
}
private void setVisitTime(int position, TextView tv_week, TextView tv_am, TextView tv_pm, TextView tv_night) {
tv_week.setText(totalDayList.get(position-1).getWhichDay());
String am = totalDayList.get(position-1).getAmTime();
String pm = totalDayList.get(position-1).getPmTime();
String night = totalDayList.get(position-1).getNightTime();
if("1".equals(am)){
tv_am.setBackgroundResource(R.drawable.green_checked);
}else{
tv_am.setBackgroundResource(R.drawable.default_checked);
}
if("1".equals(pm)){
tv_pm.setBackgroundResource(R.drawable.green_checked);
}else{
tv_pm.setBackgroundResource(R.drawable.default_checked);
}
if("1".equals(night)){
tv_night.setBackgroundResource(R.drawable.green_checked);
}else{
tv_night.setBackgroundResource(R.drawable.default_checked);
}
}
現在在看效果圖:是不是沒有出診的就不顯示了呢?