1. 程式人生 > >基於flowlayout的單選、多選功能展示

基於flowlayout的單選、多選功能展示

當前這個Demo是基於’com.zhy:flowlayout-lib:1.0.3’進行的單選、多選功能進行的展示。
單選效果圖
多選效果圖

通過這個Demo可學到如下的技術點:
1 此專案使用dataBinding技術
2 在BindingAdapter類中,展示了幾個自定義BindingAdapter的方法

// 預設載入自帶圖片,當存在網路上的圖片時則載入網路圖片
@android.databinding.BindingAdapter({"imageUrl", "android:src"})
public static void loadImageFromUrl(ImageView view, String url, Drawable drawable) 

// TextView 載入 富文字格式的內容
@android.databinding.BindingAdapter({"htmlTxt"})
public static void loadText(TextView view, String statebg) 

// WebView 載入 富文字格式的內容
@android.databinding.BindingAdapter({"htmlWeb"})
public static void loadText(WebView view, String statebg)

3 通過Convert類,把json字串轉成物件類、和物件類陣列的方法
QuestionItemEntity questionItem = Convert.fromJson(sData, QuestionItemEntity.class);
QuestionItemEntity[] list = Convert.fromJson(sData, QuestionItemEntity[].class);

此處特別注意  xxx[]的用法

4 在初始化題目類時,可看到對答案選項的處理方法
String[] zimu = {“A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”, “N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”};
if (item.getQuestiontype().equals(“judge”)){
item.selector.add(“正確”);
item.selector.add(“錯誤”);
}
else if(item.getQuestiontype().equals(“single”) || item.getQuestiontype().equals(“choice”)) {
int iCount = item.getCount() % zimu.length;
for (int i = 0; i < iCount; i++) {
item.selector.add(zimu[i]);
}
}

5 通過BindingViewHolder實現 RecyclerView.Adapter 的適配,此技術可在QuestionAdapter單元中瞭解

6 在QuestionAdapter單元的 public void addAll(List datas) 方法中實現了資料載入、資料預處理,
根據題目的型別設定了項選的個數、佈局檔案ID、選項佈局ID
if (itemEntity.getQuestiontype().equals(“normal”)) {
itemEntity.setMaxSelect(-1);
itemEntity.setLayoutID(R.layout.item_question_main);
itemEntity.setLayoutItem(R.layout.tv);
} else if (itemEntity.getQuestiontype().equals(“judge”)) {
itemEntity.setMaxSelect(1);
itemEntity.setLayoutID(R.layout.item_question_choice);
itemEntity.setLayoutItem(R.layout.tv_single);
}
在此處理資料後,在onBindViewHolder方法中可以直接使用相關屬性,不必每次在判斷處理,極大的優化資料展示速度

7 BindingViewHolder是可以強制進行轉意,使用佈局控制元件的,參見下面的程式碼
((ItemQuestionChoiceBinding) holder.getBinding()).flowLayout.setAdapter(tagAdapter);

8 TagFlowLayout設定預選中項、及監聽選擇的方法,參見

((ItemQuestionChoiceBinding) holder.getBinding()).flowLayout.setOnSelectListener(new TagFlowLayout.OnSelectListener() {
    @Override
    public void onSelected(Set<Integer> selectPosSet) {
        questionEntity.setSelected(selectPosSet);
        if (selectPosSet.size() == 0) {
            questionEntity.setAnswer("");
        } else {
            String sAnswer = "";

            //實現選中項從小到大進行組合,設定成答案
            for (int i = 0; i < questionEntity.getSelector().size(); i++) {
                if (selectPosSet.contains(i)) {
                    sAnswer += questionEntity.getSelector().get(i) + ",";
                }
            }

            sAnswer = sAnswer.substring(0, sAnswer.length() - 1);
            questionEntity.setAnswer(sAnswer);
        }
    }
});
這裡需要注意Set<Integer>的用法

9 需要特別注意TagAdapter的建立方法,是關鍵所在
TagAdapter tagAdapter = new TagAdapter(questionEntity.getSelector()) {

    @Override
    public View getView(FlowLayout parent, final int position, String s) {
        TextView tv = (TextView) LayoutInflater.from(mContext).inflate(questionEntity.getLayoutItem(), ((ItemQuestionChoiceBinding) holder.getBinding()).flowLayout, false);
        tv.setText(questionEntity.getSelector().get(position));
        return tv;
    }

    @Override
    public boolean setSelected(int position, String s) {
        return questionEntity.getSelected().contains(position);
    }
};
這裡需要特別注意設定選中項的方法  public boolean setSelected(int position, String s) ,不然在列表上下重新整理時會看不到之前的選中項,這要與  questionEntity.setSelected(selectPosSet);   連用

10通過佈局檔案實現控制元件屬性的選中、不選中的不同樣式,看過下面的佈局檔案及可明白
tv_single.xml
tv_single
text_color.xml
text_color
tag_bg_single.xml
tag_bg_single

這裡需要注意item中的屬性名,只可以用drawable,不必再使用要設定的屬性名