/* * Copyright (C) 2015-present, Ant Financial Services Group * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alipay.hulu.adapter; import android.graphics.Rect; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; import com.alibaba.fastjson.JSON; import com.alipay.hulu.R; import com.alipay.hulu.common.utils.LogUtil; import com.alipay.hulu.common.utils.StringUtil; import com.alipay.hulu.shared.node.tree.OperationNode; import com.alipay.hulu.shared.node.tree.export.OperationStepExporter; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created by qiaoruikai on 2019/2/20 8:05 PM. */ public class CaseStepNodeAdapter extends RecyclerView.Adapter<CaseStepNodeAdapter.NodePropertyHolder> { private static final String TAG = "CaseStepNodeApt"; private OperationNode node; private List<String> properties; public CaseStepNodeAdapter(@NonNull OperationNode node) { this.node = node; properties = loadPropertiesKey(node); } @Override public NodePropertyHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (parent == null) { return null; } View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_case_step_edit_input, parent, false); return new NodePropertyHolder(view, node); } @Override public int getItemViewType(int position) { return StringUtil.equals(properties.get(position), OperationStepExporter.CAPTURE_IMAGE_BASE64)? 1: 0; } @Override public void onBindViewHolder(NodePropertyHolder holder, int position) { String property = properties.get(position); String value = extractNodeProperties(node, property); holder.wrapData(property, value); } @Override public int getItemCount() { return properties.size(); } public static class NodePropertyHolder extends RecyclerView.ViewHolder implements TextWatcher { private String key; private TextView title; private EditText editText; private TextView infoText; private OperationNode node; public NodePropertyHolder(View itemView, OperationNode node) { super(itemView); this.node = node; title = (TextView) itemView.findViewById(R.id.item_case_step_name); editText = (EditText) itemView.findViewById(R.id.item_case_step_edit); editText.addTextChangedListener(this); infoText = (TextView) itemView.findViewById(R.id.item_case_step_create_param); infoText.setText(""); } private void wrapData(String key, String value) { this.key = key; editText.setText(value); title.setText(key); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { boolean result = updateNodeProperty(key, s.toString(), node); if (!result) { infoText.setText(R.string.node__invalid_param); } else { infoText.setText(""); } } } /** * 解析node属性 * @param node * @return */ static String extractNodeProperties(OperationNode node, String key) { switch (key) { case "xpath": return node.getXpath(); case "description": return node.getDescription(); case "text": return node.getText(); case "resourceId": return node.getResourceId(); case "className": return node.getClassName(); case "depth": return Integer.toString(node.getDepth()); case "nodeType": return node.getNodeType(); case "assistantNodes": return JSON.toJSONString(node.getAssistantNodes()); case "nodeBound": Rect nb = node.getNodeBound(); return String.format("%d,%d,%d,%d", nb.left, nb.top, nb.right, nb.bottom); default: if (node.getExtra() == null) { return null; } return node.getExtra().get(key); } } static List<String> loadPropertiesKey(OperationNode node) { List<String> list = new ArrayList<>(12); list.add("xpath"); list.add("description"); list.add("text"); list.add("resourceId"); list.add("className"); list.add("depth"); Rect nb = node.getNodeBound(); if (nb != null) { list.add("nodeBound"); } if (node.getAssistantNodes() != null && node.getAssistantNodes().size() > 0) { list.add("assistantNodes"); } list.add("nodeType"); if (node.getExtra() != null) { Map<String, String> extras = node.getExtra(); list.addAll(extras.keySet()); } // 截图放最前面 if (list.contains(OperationStepExporter.CAPTURE_IMAGE_BASE64)) { list.remove(OperationStepExporter.CAPTURE_IMAGE_BASE64); list.add(0, OperationStepExporter.CAPTURE_IMAGE_BASE64); } return list; } /** * 设置Node属性值 * @param key * @param value * @param node * @return */ static boolean updateNodeProperty(String key, String value, OperationNode node) { switch (key) { case "xpath": node.setXpath(value); return true; case "description": node.setDescription(value); return true; case "text": node.setText(value); return true; case "resourceId": node.setResourceId(value); return true; case "className": node.setClassName(value); return true; case "depth": try { int depth = Integer.parseInt(value); node.setDepth(depth); return true; } catch (NumberFormatException e) { LogUtil.w(TAG, "无法解析数字:" + value, e); return false; } case "nodeBound": // 逗号分隔 String[] split = StringUtil.split(value, ","); if (split == null || split.length != 4) { return false; } try { Rect bound = new Rect(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]), Integer.parseInt(split[3])); node.setNodeBound(bound); return true; } catch (NumberFormatException e) { LogUtil.w(TAG, "parse content failed for " + value, e); return false; } case "assistantNodes": try { List<OperationNode.AssistantNode> assis = JSON.parseArray(value, OperationNode.AssistantNode.class); node.setAssistantNodes(assis); return true; } catch (Exception e) { LogUtil.w(TAG, "can't parse " + value, e); return false; } case "nodeType": node.setNodeType(value); return true; default: if (node.getExtra() != null) { node.getExtra().put(key, value); return true; } return false; } } }