Android CheckBox多選時間段,合并重復時間

coolffe 8年前發布 | 10K 次閱讀 安卓開發 Android開發 移動開發

來自: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0123/3907.html

之前拿到了一個問題,在訂購機票界面中需要一個時間篩選的功能,需求是讓用戶能夠自由組合時間段,并且相鄰時間段要合并,盡量少用if else 嵌套,可能問題看上去蠻簡單,但對我這種沒學過算法的還是要動一番腦子的,最終效果是這樣

</div>

具體需求:

點擊不不限的時候其他時間全部取消

兩個相鄰的時間勾上的時候中間相同的部分去掉,如00:00-14:00

四個時間全部選上的時候,時間的勾全部去掉,然后顯示不限

說下思路,這里面有5個CheckBox,既然是要根據它們的選中狀態來組合改變數據,那怎么做?我想到了創建五個時間對象TimeTree,其中第一個和下面四個時間需要區分開來,所以加入一個int屬性,名字就叫type,有0和1兩個值。

對于下面4個TimeTree,肯定需要有start和end兩個String屬性,分別對應起始時間和結束時間,如tt1的start是"0:00",end是"12:00"。

另外每個對象中都應該持有對左右兩個TimeTree對象的引用LeftTimeTree和RightTimeTree,這樣方便接下來判斷是否為相鄰時間。當然一頭一尾兩個時間分別只有RightTimeTree和LeftTimeTree。

其余部分都很簡單,主要就是合并重復時間花了一番功夫,我的做法是用一個集合保存所有選中的TimeTree,只有下面4個會保存到集合中,點擊'不限'會清空這個集合。

在集合中有多個元素時,首先遍歷集合,如果LeftTimeTree為空或者LeftTimeTree不包含在這個集合中,說明這是一個 頭時間點 ,記錄下它的start,關鍵是求end,這里我寫了一個遞歸方法,如果RightTimeTree包含在集合中,end就是RightTimeTree的end,再對RightTimeTree的end如此循環,就得到了最終應該顯示的end。下面是代碼

TimeTree類

public class TimeTree {
    public int type = 0;
    public String start;
    public String end;
    public String timeStr;
    public TimeTree leftTime;
    public TimeTree rightTime;
}

主界面

public class MainThreeAct extends Activity implements OnClickListener {
    List<String> timeNodes = Arrays.asList("0:00", "12:00", "14:00", "18:00", "24:00");
    private TextView tv;
    private LinearLayout ll;
    private CheckBox cb_012;
    private CheckBox cb_1214;
    private CheckBox cb_1418;
    private CheckBox cb_1824;
    private CheckBox cb_unlimit;
    // CheckBox集合
    private List<CheckBox> cbs;
    // 時間對象集合
    private List<TimeTree> times;
    // 選中的時間對象集合
    private List<TimeTree> selectedTimes = new ArrayList<TimeTree>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_three_activity);
        initVariables();
        initViews();
    }
    private void initVariables() {
        TimeTree tt0 = new TimeTree();
        TimeTree tt1 = new TimeTree();
        TimeTree tt2 = new TimeTree();
        TimeTree tt3 = new TimeTree();
        TimeTree tt4 = new TimeTree();
        times = Arrays.asList(tt0, tt1, tt2, tt3, tt4);
        for (int i = 1; i < times.size(); i++) {
            // type用來區分是不限(0),還是具體時間(1)
            times.get(i).type = 1;
            // 為每一個時間對象添加開始和結束時間
            times.get(i).start = timeNodes.get(i - 1);
            times.get(i).end = timeNodes.get(i);
            times.get(i).timeStr = timeNodes.get(i - 1) + "-" + times.get(i);
            // 為每一個時間對象添加相鄰時間對象
            times.get(i).leftTime = i - 1 <= 0 ? null : times.get(i - 1);
            times.get(i).rightTime = i + 1 >= times.size() ? null : times.get(i + 1);
        }
    }
    private void initViews() {
        tv = (TextView) findViewById(R.id.tv);
        ll = (LinearLayout) findViewById(R.id.ll);
        cb_012 = (CheckBox) findViewById(R.id.cb012);
        cb_1214 = (CheckBox) findViewById(R.id.cb1214);
        cb_1418 = (CheckBox) findViewById(R.id.cb1418);
        cb_1824 = (CheckBox) findViewById(R.id.cb1824);
        cb_unlimit = (CheckBox) findViewById(R.id.cb_unlimit);
        cbs = Arrays.asList(cb_unlimit, cb_012, cb_1214, cb_1418, cb_1824);
        cb_012.setOnClickListener(this);
        cb_1214.setOnClickListener(this);
        cb_1418.setOnClickListener(this);
        cb_1824.setOnClickListener(this);
        cb_unlimit.setOnClickListener(this);
    }
    /**

 * CheckBox的點擊監聽
 */
@Override
public void onClick(View v) {
    CompoundButton buttonView = (CompoundButton) v;
    boolean isChecked = buttonView.isChecked();
    // 獲取CheckBox的位置索引值
    int index = ll.indexOfChild(buttonView);
    // 根據位置索引,獲取對應的時間對象
    TimeTree timeTree = times.get(index);
    // 取消CheckBox
    if (!isChecked) {
        if (index == 0) {
            return;
        }
        // 更新選中時間的集合
        selectedTimes.remove(timeTree);
        if (selectedTimes.size() == 0) {
            // 不限時間
            unlimitTime();
            return;
        }
        // 更新TextView
        setText();
        return;
    }
    // 選中CheckBox
    // 選中的是'不限'
    if (timeTree.type == 0) {
        unlimitTime();
        return;
    }
    // 選中了具體時間,首先將對應的時間對象記錄下來
    selectedTimes.add(timeTree);
    // 全選中時不限時間
    if (selectedTimes.size() == times.size() - 1) {
        unlimitTime();
        return;
    }
    // 取消全選
    cbs.get(0).setChecked(false);
    // 更新TextView
    setText();
}
/**
 * 不限時間
 */
private void unlimitTime() {
    selectedTimes.clear();
    for (int i = 1; i < cbs.size(); i++) {
        cbs.get(i).setChecked(false);
    }
    cbs.get(0).setChecked(true);
    tv.setText("不限");
}
/**
 * 根據選中的時間,來更新TextView
 */
private void setText() {
    // 排序
    Collections.sort(selectedTimes, new Comparator<TimeTree>() {
        @Override
        public int compare(TimeTree lhs, TimeTree rhs) {
            return lhs.start.compareTo(rhs.start);
        }
    });
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < selectedTimes.size(); i++) {
        TimeTree timeTree = selectedTimes.get(i);
        if (timeTree.leftTime == null || !selectedTimes.contains(timeTree.leftTime)) {
            String start = timeTree.start;
            String end = timeTree.end;
            // 獲取合并后的endTime
            end = updateEndTime(timeTree);
            sb.append(start + "-" + end + ",");
        }
    }
    String text = sb.toString();
    tv.setText(text.substring(0, text.length() - 1));
}
/**
 * 遞歸,獲取合并后的endTime
 */
private String updateEndTime(TimeTree timeTree) {
    String end = timeTree.end;
    if (timeTree.rightTime != null && selectedTimes.contains(timeTree.rightTime)) {
        end = updateEndTime(timeTree.rightTime);
    }
    return end;
}

}</pre> </div>

 本文由用戶 coolffe 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!