>();
170 | for (int i = 0; i < 8; i++) {
171 | childrenList.add(itemInfos);
172 | }
173 | }
174 |
175 | @Override
176 | public void takePicture(int groupPosition, int childPosition) {
177 | Toast.makeText(context, "takePicture", Toast.LENGTH_SHORT).show();
178 |
179 | //判断是否有权限
180 | if (hasPermission(Manifest.permission.CAMERA, Manifest.permission.CAMERA)) {
181 | //有权限
182 | takePhoto();
183 | } else {
184 | //没权限,进行权限请求
185 | requestPermission(REQUEST_CAMERA, Manifest.permission.CAMERA);
186 | }
187 | }
188 |
189 | @Override
190 | public void selectPicture(int groupPosition, int childPosition) {
191 | Toast.makeText(context, "selectPicture", Toast.LENGTH_SHORT).show();
192 | }
193 |
194 | @Override
195 | public void onActivityResult(int req, int res, Intent data) {
196 | switch (req) {
197 | case REQUEST_CAMERA:
198 | if (res == RESULT_OK) {
199 | Log.i(TAG, "拍照成功");
200 |
201 | } else {
202 | Log.i(TAG, "拍照失败");
203 | }
204 | break;
205 | default:
206 | break;
207 | }
208 | }
209 |
210 | /**
211 | * 调用系统相机拍照
212 | */
213 | private void takePhoto() {
214 | String imgName = System.currentTimeMillis() + ".jpg";
215 | Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
216 | intent.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoUri(IMAGE_PATH, imgName));
217 | startActivityForResult(intent, REQUEST_CAMERA);
218 | }
219 |
220 | /**
221 | * 获取照片Uri
222 | *
223 | * @param path 保存照片文件夹名称
224 | * @param name 照片名称
225 | * @return
226 | */
227 | private Uri getPhotoUri(String path, String name) {
228 | String sdStatus = Environment.getExternalStorageState();
229 | if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) {
230 | return null;
231 | }
232 | File file = new File(Environment.getExternalStorageDirectory(), path);
233 | if (!file.exists()) {
234 | file.mkdir();
235 | }
236 | File output = new File(file, name);
237 | try {
238 | if (output.exists()) {
239 | output.delete();
240 | }
241 | output.createNewFile();
242 | } catch (Exception e) {
243 | e.printStackTrace();
244 | }
245 |
246 | // 解决Android7.0相机权限问题方法1 - onCreate中调用solveExceptionByVmPolicy()
247 | // Uri photoURI = Uri.fromFile(output);
248 |
249 | // 解决Android7.0相机权限问题方法2 - FileProvider方式(谷歌官方推荐)
250 | Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", output);
251 |
252 | return photoURI;
253 | }
254 |
255 | /**
256 | * 判断是否拥有权限
257 | *
258 | * @param permissions 形参String...的效果其实就和数组一样,这里的实参可以写多个String
259 | * @return
260 | */
261 | public boolean hasPermission(String... permissions) {
262 | for (String permission : permissions) {
263 | if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
264 | return false;
265 | }
266 | return true;
267 | }
268 |
269 | /**
270 | * 请求权限
271 | */
272 | protected void requestPermission(int code, String... permissions) {
273 | ActivityCompat.requestPermissions(this, permissions, code);
274 | Toast.makeText(context, "如果拒绝授权,会导致应用无法正常使用", Toast.LENGTH_SHORT).show();
275 | }
276 |
277 | /**
278 | * 申请权限的回调
279 | *
280 | * @param requestCode requestCode
281 | * @param permissions permissions
282 | * @param grantResults grantResults 多个权限一起返回
283 | */
284 | @Override
285 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
286 | if (requestCode == REQUEST_CAMERA) {
287 | if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
288 | Log.i(TAG, "获取相机权限成功");
289 | takePhoto();
290 | } else {
291 | Log.i(TAG, "获取相机权限失败");
292 | }
293 | } else {
294 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
295 | }
296 | }
297 |
298 | /**
299 | * android 7.0系统解决拍照的问题
300 | * Android 7.0开始,一个应用提供自身文件给其它应用使用时,如果给出一个file://格式的URI的话,应用会抛出FileUriExposedException
301 | * onCreate中调用此方法即可
302 | */
303 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
304 | private void solveExceptionByVmPolicy() {
305 | StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
306 | StrictMode.setVmPolicy(builder.build());
307 | builder.detectFileUriExposure();
308 | }
309 | }
310 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/adapter/ExpandableListViewAdapter.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.adapter;
2 |
3 | import android.content.Context;
4 | import android.text.Editable;
5 | import android.text.TextWatcher;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseExpandableListAdapter;
10 | import android.widget.EditText;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | import fxp.com.multiexpandablelist.R;
19 | import fxp.com.multiexpandablelist.bean.EquipmentInfo;
20 | import fxp.com.multiexpandablelist.bean.ItemInfo;
21 | import fxp.com.multiexpandablelist.entity.CheckItem;
22 | import fxp.com.multiexpandablelist.fxpInterface.GetPictureListener;
23 | import fxp.com.multiexpandablelist.view.TagCloudLayout;
24 |
25 | /**
26 | * ExpandableListView 适配器
27 | *
28 | * Created by fxp on 2018/3/2.
29 | */
30 |
31 | public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
32 |
33 | private Context context;
34 |
35 | private LayoutInflater mInflater;
36 |
37 | private List groupList;
38 |
39 | private List> childrenList;
40 |
41 | private final int EDITTYPE = 0;
42 |
43 | private final int TEXTTYPE = 1;
44 |
45 | private final int SELECTTYPE = 2;
46 |
47 | private final int CHECKTYPE = 3;
48 |
49 | private final int PICTYPE = 4;
50 |
51 | // 缓存单选型View选择结果,用于界面重绘后恢复选中状态
52 | private String itemState = "";
53 |
54 | // 多选型View标签适配器
55 | private TagCheckAdapter tagCheckAdapter;
56 |
57 | // 多选型View标签列表
58 | private List checkItems = new ArrayList();
59 |
60 | // 多选型View中标签选中状态,存储所有标签的选中状态
61 | private List selectState = new ArrayList();
62 |
63 | private GetPictureListener getPictureListener = null;
64 |
65 | public ExpandableListViewAdapter(Context context, List groupList, List> childrenList) {
66 | this.context = context;
67 | this.groupList = groupList;
68 | this.childrenList = childrenList;
69 | }
70 |
71 | public void setGetPictureListener(GetPictureListener listener) {
72 | this.getPictureListener = listener;
73 | }
74 |
75 | @Override
76 | public int getGroupCount() {
77 | return groupList.size();
78 | }
79 |
80 | @Override
81 | public long getGroupId(int i) {
82 | return i;
83 | }
84 |
85 | @Override
86 | public Object getGroup(int i) {
87 | return groupList.get(i);
88 | }
89 |
90 | @Override
91 | public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
92 | GroupViewHolder holder;
93 | if (convertView == null) {
94 | holder = new GroupViewHolder();
95 | mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
96 | convertView = mInflater.inflate(R.layout.list_outer_item, null);
97 | holder.lable = (TextView) convertView.findViewById(R.id.lable);
98 | convertView.setTag(holder);
99 | } else {
100 | holder = (GroupViewHolder) convertView.getTag();
101 | }
102 |
103 | holder.lable.setText(groupList.get(groupPosition).getE_name());
104 | return convertView;
105 | }
106 |
107 | @Override
108 | public int getChildType(int groupPosition, int childPosition) {
109 | return Integer.parseInt(childrenList.get(groupPosition).get(childPosition).getI_type());
110 | }
111 |
112 | @Override
113 | public int getChildrenCount(int i) {
114 | return childrenList.get(i).size();
115 | }
116 |
117 | @Override
118 | public Object getChild(int i, int i1) {
119 | return childrenList.get(i).get(i1);
120 | }
121 |
122 | @Override
123 | public long getChildId(int i, int i1) {
124 | return i1;
125 | }
126 |
127 | @Override
128 | public boolean hasStableIds() {
129 | return false;
130 | }
131 |
132 | @Override
133 | public boolean isChildSelectable(int i, int i1) {
134 | return false;
135 | }
136 |
137 | /**
138 | * 包含多种类型item布局时,必须重写此方法
139 | *
140 | * 注意:此处返回值必须大于或等于布局种类数,不然会报错FATAL EXCEPTION: main Process: fxp.com.multiexpandablelist, PID: 28232
141 | * java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
142 | * at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6902)
143 | * at android.widget.ListView.measureHeightOfChildren(ListView.java:1338)
144 | * at android.widget.ListView.onMeasure(ListView.java:1233)
145 | *
146 | * @return 子布局种类数目
147 | */
148 | @Override
149 | public int getChildTypeCount() {
150 | return 6;
151 | }
152 |
153 | @Override
154 | public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
155 | int type = getChildType(groupPosition, childPosition);
156 | switch (type) {
157 | //数值型
158 | case EDITTYPE: {
159 | convertView = setEditCell(convertView, groupPosition, childPosition);
160 | break;
161 | }
162 | //字符型
163 | case TEXTTYPE: {
164 | convertView = setTextCell(convertView, groupPosition, childPosition);
165 | break;
166 | }
167 | //单选型
168 | case SELECTTYPE: {
169 | convertView = setSelectCell(convertView, groupPosition, childPosition);
170 | break;
171 | }
172 | //复选型
173 | case CHECKTYPE: {
174 | convertView = setCheckCell(convertView, groupPosition, childPosition);
175 | break;
176 | }
177 | //拍照型
178 | case PICTYPE: {
179 | convertView = setPictureCell(convertView, groupPosition, childPosition);
180 | break;
181 | }
182 | default:
183 | break;
184 | }
185 |
186 | return convertView;
187 | }
188 |
189 | /**
190 | * 数值型View
191 | *
192 | * @param convertView
193 | * @param groupPosition
194 | * @param childPosition
195 | * @return
196 | */
197 | private View setEditCell(View convertView, final int groupPosition, final int childPosition) {
198 | EditViewHolder editViewHolder = null;
199 | final EditText tsEditText;
200 |
201 | if (null != convertView) {
202 | ((LinearLayout) convertView).removeAllViews();
203 | }
204 |
205 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
206 | convertView = inflater.inflate(R.layout.list_inner_edit_item, null);
207 | editViewHolder = new EditViewHolder();
208 | editViewHolder.decrease = (TextView) convertView.findViewById(R.id.decrease_btn);
209 | editViewHolder.lable = (TextView) convertView.findViewById(R.id.lable);
210 | editViewHolder.value = (EditText) convertView.findViewById(R.id.value);
211 | editViewHolder.increase = (TextView) convertView.findViewById(R.id.increase_btn);
212 |
213 | tsEditText = (EditText) convertView.findViewById(R.id.value);
214 |
215 | ItemInfo itemInfo = childrenList.get(groupPosition).get(childPosition);
216 | editViewHolder.lable.setText(itemInfo.getI_name());
217 | editViewHolder.decrease.setText("-" + itemInfo.getI_increment());
218 | editViewHolder.value.setHint(itemInfo.getI_reference());
219 | editViewHolder.increase.setText("+" + itemInfo.getI_increment());
220 |
221 | //界面重绘后,让输入框显示重绘前输入的内容
222 | editViewHolder.value.setText(itemInfo.getI_content());
223 |
224 | editViewHolder.value.addTextChangedListener(new TextWatcher() {
225 | @Override
226 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
227 |
228 | }
229 |
230 | @Override
231 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
232 | //将输入框中内容保存,界面重绘后,让输入框显示保存的内容
233 | childrenList.get(groupPosition).get(childPosition).setI_content(tsEditText.getText().toString());
234 | }
235 |
236 | @Override
237 | public void afterTextChanged(Editable editable) {
238 |
239 | }
240 | });
241 |
242 | return convertView;
243 | }
244 |
245 | /**
246 | * 字符型View
247 | *
248 | * @param convertView
249 | * @param groupPosition
250 | * @param childPosition
251 | * @return
252 | */
253 | private View setTextCell(View convertView, final int groupPosition, final int childPosition) {
254 | TextViewHolder textViewHolder = null;
255 | final EditText tsEditText;
256 |
257 | if (null != convertView) {
258 | ((LinearLayout) convertView).removeAllViews();
259 | }
260 |
261 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
262 | convertView = inflater.inflate(R.layout.list_inner_text_item, null);
263 | textViewHolder = new TextViewHolder();
264 | textViewHolder.lable = (TextView) convertView.findViewById(R.id.lable);
265 | textViewHolder.value = (EditText) convertView.findViewById(R.id.value);
266 |
267 | tsEditText = (EditText) convertView.findViewById(R.id.value);
268 |
269 | textViewHolder.lable.setText(childrenList.get(groupPosition).get(childPosition).getI_name());
270 | textViewHolder.value.setHint("");
271 | //界面重绘后,让输入框显示重绘前输入的内容
272 | textViewHolder.value.setText(childrenList.get(groupPosition).get(childPosition).getI_content());
273 |
274 | textViewHolder.value.addTextChangedListener(new TextWatcher() {
275 | @Override
276 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
277 |
278 | }
279 |
280 | @Override
281 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
282 | //将输入框中内容保存,界面重绘后,让输入框显示保存的内容
283 | childrenList.get(groupPosition).get(childPosition).setI_content(tsEditText.getText().toString());
284 | }
285 |
286 | @Override
287 | public void afterTextChanged(Editable editable) {
288 |
289 | }
290 | });
291 |
292 | return convertView;
293 | }
294 |
295 | /**
296 | * 单选型View
297 | *
298 | * @param convertView
299 | * @param groupPosition
300 | * @param childPosition
301 | * @return
302 | */
303 | private View setSelectCell(View convertView, final int groupPosition, final int childPosition) {
304 | SelectViewHolder selectViewHolder = null;
305 |
306 | if (null != convertView) {
307 | ((LinearLayout) convertView).removeAllViews();
308 | }
309 |
310 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
311 | convertView = inflater.inflate(R.layout.list_inner_select_item, null);
312 |
313 | selectViewHolder = new SelectViewHolder();
314 | selectViewHolder.lable = (TextView) convertView.findViewById(R.id.lable);
315 | selectViewHolder.mContainer = (TagCloudLayout) convertView.findViewById(R.id.container);
316 | convertView.setTag(selectViewHolder);
317 |
318 | selectViewHolder.lable.setText(childrenList.get(groupPosition).get(childPosition).getI_name());
319 |
320 | //获取选择值,用于界面重绘后显示重绘前状态
321 | itemState = childrenList.get(groupPosition).get(childPosition).getI_content();
322 |
323 | List mList = new ArrayList<>();
324 | mList.add(context.getResources().getString(R.string.commen));
325 | mList.add(context.getResources().getString(R.string.error));
326 |
327 | TagBaseAdapter mAdapter = new TagBaseAdapter(context, mList, itemState);
328 | selectViewHolder.mContainer.setAdapter(mAdapter);
329 |
330 | selectViewHolder.mContainer.setItemClickListener(new TagCloudLayout.TagItemClickListener() {
331 | @Override
332 | public void itemClick(int position) {
333 | // 保存状态,正常/异常
334 | if (position == 0) {
335 | itemState = context.getResources().getString(R.string.commen);
336 | childrenList.get(groupPosition).get(childPosition).setI_state(ItemInfo.STATE_CORRECT);
337 | } else if (position == 1) {
338 | itemState = context.getResources().getString(R.string.error);
339 | childrenList.get(groupPosition).get(childPosition).setI_state(ItemInfo.STATE_ERROR);
340 | } else {
341 | }
342 |
343 | // 刷新选中结果
344 | notifyDataSetInvalidated();
345 |
346 | //保存选择值,用于界面重绘后显示重绘前状态
347 | childrenList.get(groupPosition).get(childPosition).setI_content(itemState);
348 | }
349 | });
350 |
351 | return convertView;
352 | }
353 |
354 |
355 | /**
356 | * 复选型View
357 | *
358 | * @param convertView
359 | * @param groupPosition
360 | * @param childPosition
361 | * @return
362 | */
363 | public View setCheckCell(View convertView, final int groupPosition, final int childPosition) {
364 | CheckViewHolder checkViewHolder = null;
365 |
366 | if (null != convertView) {
367 | ((LinearLayout) convertView).removeAllViews();
368 | }
369 |
370 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
371 | convertView = inflater.inflate(R.layout.list_inner_select_item, null);
372 | checkViewHolder = new CheckViewHolder();
373 | checkViewHolder.lable = (TextView) convertView.findViewById(R.id.lable);
374 | checkViewHolder.mContainer = (TagCloudLayout) convertView.findViewById(R.id.container);
375 | convertView.setTag(checkViewHolder);
376 |
377 | checkViewHolder.lable.setText(childrenList.get(groupPosition).get(childPosition).getI_name());
378 |
379 | // 获取多选型View标签列表(过滤各标签选中状态)
380 | getTagList(childrenList.get(groupPosition).get(childPosition));
381 |
382 | tagCheckAdapter = new TagCheckAdapter(context, checkItems);
383 | checkViewHolder.mContainer.setAdapter(tagCheckAdapter);
384 | checkViewHolder.mContainer.setItemClickListener(new TagCloudLayout.TagItemClickListener() {
385 | @Override
386 | public void itemClick(int position) {
387 | boolean isSelect = checkItems.get(position).isSelect();
388 | if (isSelect) {
389 | checkItems.get(position).setIsSelect(false);
390 | tagCheckAdapter.setIsSelect(position, false);
391 | selectState.set(position, false);
392 | } else {
393 | checkItems.get(position).setIsSelect(true);
394 | tagCheckAdapter.setIsSelect(position, true);
395 | selectState.set(position, true);
396 | }
397 |
398 | // 刷新标签列表
399 | notifyDataSetInvalidated();
400 |
401 | // 保存已选标签
402 | childrenList.get(groupPosition).get(childPosition).setI_value(getSelectedTags(checkItems));
403 | }
404 | });
405 |
406 | return convertView;
407 | }
408 |
409 | /**
410 | * 拍照型View
411 | *
412 | * @param convertView
413 | * @param groupPosition
414 | * @param childPosition
415 | * @return
416 | */
417 | private View setPictureCell(View convertView, final int groupPosition, final int childPosition) {
418 | PicViewHolder picViewHolder = null;
419 |
420 | LayoutInflater inflater = LayoutInflater.from(context);
421 | convertView = inflater.inflate(R.layout.list_inner_picture_item, null);
422 |
423 | picViewHolder = new PicViewHolder();
424 | picViewHolder.lable = (TextView) convertView.findViewById(R.id.lable);
425 | picViewHolder.takePicture = (TextView) convertView.findViewById(R.id.take_pic_btn);
426 | picViewHolder.selectPicure = (TextView) convertView.findViewById(R.id.select_pic_btn);
427 |
428 | convertView.setTag(picViewHolder);
429 |
430 | picViewHolder.lable.setText(childrenList.get(groupPosition).get(childPosition).getI_name());
431 | picViewHolder.takePicture.setOnClickListener(new View.OnClickListener() {
432 | @Override
433 | public void onClick(View view) {
434 | getPictureListener.takePicture(groupPosition, childPosition);
435 | }
436 | });
437 | picViewHolder.selectPicure.setOnClickListener(new View.OnClickListener() {
438 | @Override
439 | public void onClick(View view) {
440 | getPictureListener.selectPicture(groupPosition, childPosition);
441 | }
442 | });
443 |
444 | return convertView;
445 | }
446 |
447 | class GroupViewHolder {
448 | private TextView lable;
449 | private ImageView stateIcon;
450 | }
451 |
452 | class EditViewHolder {
453 | private TextView decrease;
454 | private TextView lable;
455 | private EditText value;
456 | private TextView increase;
457 | }
458 |
459 | class TextViewHolder {
460 | private TextView lable;
461 | private EditText value;
462 | }
463 |
464 | class SelectViewHolder {
465 | TextView lable;
466 | TagCloudLayout mContainer;
467 | }
468 |
469 | class CheckViewHolder {
470 | TextView lable;
471 | TagCloudLayout mContainer;
472 | }
473 |
474 | class PicViewHolder {
475 | TextView lable;
476 | TextView takePicture;
477 | TextView selectPicure;
478 | }
479 |
480 | /**
481 | * 多选型View - 获取标签列表(过滤各标签选中状态)
482 | *
483 | * @param itemInfo 当前item项
484 | */
485 | private void getTagList(ItemInfo itemInfo) {
486 |
487 | // 分割i_content,获取到标签数组lableStates
488 | String i_content = itemInfo.getI_content();
489 | String lableStates[] = null;
490 | if (i_content != null && !i_content.equals("")) {
491 | lableStates = i_content.split("/");
492 | }
493 |
494 | // 分割i_value,获取已选标签数组i_values
495 | String i_value = itemInfo.getI_value();
496 | String i_values[] = null;
497 | if (i_value != null && !i_value.equals("")) {
498 | i_values = i_value.split("/");
499 | }
500 |
501 | // 获取所有标签选中状态
502 | if (selectState.size() == 0) {
503 | // 遍历所有标签,获取标签选中状态
504 | for (int i = 0; i < lableStates.length; i++) {
505 | // 匹配flag
506 | boolean match = false;
507 | // 存在已选中的标签
508 | if (i_values != null) {
509 | // 遍历已选中标签,与当前标签lableStates[i]匹配
510 | for (int j = 0; j < i_values.length; j++) {
511 | // 当前标签lableStates[i]已被选中
512 | if (i_values[j].equals(lableStates[i])) {
513 | selectState.add(true);
514 | match = true;
515 | break;
516 | }
517 | }
518 | }
519 | if (!match) {
520 | // 当前标签lableStates[i]已被选中
521 | selectState.add(false);
522 | }
523 | }
524 | }
525 |
526 | // 清空标签列表
527 | checkItems.clear();
528 |
529 | // 组装标签列表
530 | for (int i = 0; i < lableStates.length; i++) {
531 | CheckItem checkItem = new CheckItem();
532 | checkItem.setItemLable(lableStates[i]);
533 | checkItem.setIsSelect(selectState.get(i));
534 | checkItems.add(i, checkItem);
535 | }
536 | }
537 |
538 | /**
539 | * 多选型View - 获取已选标签
540 | *
541 | * @param items 标签列表
542 | * @return 已选标签拼接字符串
543 | */
544 | private String getSelectedTags(List items) {
545 | String tags = "";
546 | for (int i = 0; i < items.size(); i++) {
547 | if (items.get(i).isSelect()) {
548 | if (tags.trim().equals("") || tags == null) {
549 | tags = tags + items.get(i).getItemLable();
550 | } else {
551 | tags = tags + "/" + items.get(i).getItemLable();
552 | }
553 | }
554 | }
555 | return tags;
556 | }
557 |
558 | }
559 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/adapter/TagBaseAdapter.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.adapter;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.TextView;
11 |
12 | import java.util.List;
13 |
14 | import fxp.com.multiexpandablelist.R;
15 |
16 | /**
17 | * 单选型View - 选项适配器
18 | *
19 | * Created by fxp on 2018/3/3.
20 | */
21 |
22 | public class TagBaseAdapter extends BaseAdapter {
23 |
24 | private Context mContext;
25 |
26 | // 选项列表
27 | private List mList;
28 |
29 | // 当前选中状态
30 | private String itemState;
31 |
32 | public TagBaseAdapter(Context context, List list, String itemState) {
33 | this.mContext = context;
34 | this.mList = list;
35 | this.itemState = itemState;
36 | }
37 |
38 | public void setItemState(String itemState) {
39 | this.itemState = itemState;
40 | notifyDataSetChanged();
41 | }
42 |
43 | @Override
44 | public int getCount() {
45 | return mList.size();
46 | }
47 |
48 | @Override
49 | public String getItem(int position) {
50 | return mList.get(position);
51 | }
52 |
53 | @Override
54 | public long getItemId(int position) {
55 | return position;
56 | }
57 |
58 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
59 | @Override
60 | public View getView(int position, View convertView, ViewGroup parent) {
61 | ViewHolder holder;
62 | if (convertView == null) {
63 | convertView = LayoutInflater.from(mContext).inflate(R.layout.list_tagview_item, null);
64 | holder = new ViewHolder();
65 | holder.tagBtn = (TextView) convertView.findViewById(R.id.tag_btn);
66 | convertView.setTag(holder);
67 | } else {
68 | holder = (ViewHolder) convertView.getTag();
69 | }
70 | holder.tagBtn.setText(getItem(position));
71 |
72 | if (position == 0 && itemState.equals("正常")) {
73 | holder.tagBtn.setTextColor(mContext.getResources().getColor(R.color.state_ok));
74 | holder.tagBtn.setBackground(mContext.getResources().getDrawable(R.drawable.tag_view_ok));
75 | } else if (position == 1 && itemState.equals("异常")) {
76 | holder.tagBtn.setTextColor(mContext.getResources().getColor(R.color.state_error));
77 | holder.tagBtn.setBackground(mContext.getResources().getDrawable(R.drawable.tag_view_error));
78 | } else {
79 | holder.tagBtn.setTextColor(mContext.getResources().getColor(R.color.light_gray));
80 | holder.tagBtn.setBackground(mContext.getResources().getDrawable(R.drawable.tag_view));
81 | }
82 |
83 | return convertView;
84 | }
85 |
86 | static class ViewHolder {
87 | TextView tagBtn;
88 | }
89 | }
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/adapter/TagCheckAdapter.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.adapter;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.TextView;
11 |
12 | import java.util.List;
13 |
14 | import fxp.com.multiexpandablelist.R;
15 | import fxp.com.multiexpandablelist.entity.CheckItem;
16 |
17 | /**
18 | * 多选型View - 选项适配器
19 | *
20 | * Created by fxp on 2018/3/3.
21 | */
22 | public class TagCheckAdapter extends BaseAdapter {
23 |
24 | private Context mContext;
25 |
26 | private List checkItems;
27 |
28 | // boolean isSelect = false;
29 |
30 |
31 | public TagCheckAdapter(Context context, List checkItems) {
32 | this.mContext = context;
33 | this.checkItems = checkItems;
34 | }
35 |
36 | @Override
37 | public int getCount() {
38 | return checkItems.size();
39 | }
40 |
41 | @Override
42 | public CheckItem getItem(int position) {
43 | return checkItems.get(position);
44 | }
45 |
46 | @Override
47 | public long getItemId(int position) {
48 | return position;
49 | }
50 |
51 | public void setIsSelect(int position, boolean isSelect) {
52 | checkItems.get(position).setIsSelect(isSelect);
53 | }
54 |
55 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
56 | @Override
57 | public View getView(int position, View convertView, ViewGroup parent) {
58 | ViewHolder holder;
59 | if (convertView == null) {
60 | convertView = LayoutInflater.from(mContext).inflate(R.layout.list_tagview_item, null);
61 | holder = new ViewHolder();
62 | holder.tagBtn = (TextView) convertView.findViewById(R.id.tag_btn);
63 | convertView.setTag(holder);
64 | } else {
65 | holder = (ViewHolder) convertView.getTag();
66 | }
67 | holder.tagBtn.setText(checkItems.get(position).getItemLable());
68 |
69 | boolean isSelect = checkItems.get(position).isSelect();
70 | if (isSelect) {
71 | holder.tagBtn.setTextColor(mContext.getResources().getColor(R.color.state_ok));
72 | holder.tagBtn.setBackground(mContext.getResources().getDrawable(R.drawable.tag_view_ok));
73 | } else {
74 | holder.tagBtn.setTextColor(mContext.getResources().getColor(R.color.light_gray));
75 | holder.tagBtn.setBackground(mContext.getResources().getDrawable(R.drawable.tag_view));
76 | }
77 | return convertView;
78 | }
79 |
80 | static class ViewHolder {
81 | TextView tagBtn;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/bean/EquipmentInfo.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.bean;
2 |
3 | /**
4 | *
5 | * 设备实体类
6 | *
7 | * Created by fxp on 2018/3/2.
8 | */
9 |
10 | public class EquipmentInfo {
11 |
12 | private String e_id;
13 |
14 | private int e_index;
15 |
16 | private String e_name;
17 |
18 | private String e_state;
19 |
20 | private String e_remark;
21 |
22 | public String getE_id() {
23 | return e_id;
24 | }
25 |
26 | public void setE_id(String e_id) {
27 | this.e_id = e_id;
28 | }
29 |
30 | public int getE_index() {
31 | return e_index;
32 | }
33 |
34 | public void setE_index(int e_index) {
35 | this.e_index = e_index;
36 | }
37 |
38 | public String getE_name() {
39 | return e_name;
40 | }
41 |
42 | public void setE_name(String e_name) {
43 | this.e_name = e_name;
44 | }
45 |
46 | public String getE_state() {
47 | return e_state;
48 | }
49 |
50 | public void setE_state(String e_state) {
51 | this.e_state = e_state;
52 | }
53 |
54 | public String getE_remark() {
55 | return e_remark;
56 | }
57 |
58 | public void setE_remark(String e_remark) {
59 | this.e_remark = e_remark;
60 | }
61 |
62 | @Override
63 | public String toString() {
64 | return "EquipmentInfo{" +
65 | "e_id='" + e_id + '\'' +
66 | ", e_index=" + e_index +
67 | ", e_name='" + e_name + '\'' +
68 | ", e_state='" + e_state + '\'' +
69 | ", e_remark='" + e_remark + '\'' +
70 | '}';
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/bean/ItemInfo.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.bean;
2 |
3 | /**
4 | * 设备参数实体类
5 | *
6 | * Created by fxp on 2018/3/2.
7 | */
8 |
9 | public class ItemInfo {
10 |
11 | public static String STATE_CORRECT = "0";
12 |
13 | public static String STATE_ERROR = "1";
14 |
15 | private String i_id;
16 |
17 | private String e_id;
18 |
19 | private String i_index;
20 |
21 | private String i_name;
22 |
23 | private String i_type;
24 |
25 | private String i_value;
26 |
27 | private String i_state;
28 |
29 | private String i_reference;
30 |
31 | private String i_content;
32 |
33 | private String i_content_time;
34 |
35 | private String i_remark;
36 |
37 | private String i_increment;
38 |
39 | private String i_unit;
40 |
41 | public String getI_unit() {
42 | return i_unit;
43 | }
44 |
45 | public void setI_unit(String i_unit) {
46 | this.i_unit = i_unit;
47 | }
48 |
49 | public String getI_id() {
50 | return i_id;
51 | }
52 |
53 | public void setI_id(String i_id) {
54 | this.i_id = i_id;
55 | }
56 |
57 | public String getE_id() {
58 | return e_id;
59 | }
60 |
61 | public void setE_id(String e_id) {
62 | this.e_id = e_id;
63 | }
64 |
65 | public String getI_index() {
66 | return i_index;
67 | }
68 |
69 | public void setI_index(String i_index) {
70 | this.i_index = i_index;
71 | }
72 |
73 | public String getI_name() {
74 | return i_name;
75 | }
76 |
77 | public void setI_name(String i_name) {
78 | this.i_name = i_name;
79 | }
80 |
81 | public String getI_type() {
82 | return i_type;
83 | }
84 |
85 | public void setI_type(String i_type) {
86 | this.i_type = i_type;
87 | }
88 |
89 | public String getI_value() {
90 | return i_value;
91 | }
92 |
93 | public void setI_value(String i_value) {
94 | this.i_value = i_value;
95 | }
96 |
97 | public String getI_state() {
98 | return i_state;
99 | }
100 |
101 | public void setI_state(String i_state) {
102 | this.i_state = i_state;
103 | }
104 |
105 | public String getI_reference() {
106 | return i_reference;
107 | }
108 |
109 | public void setI_reference(String i_reference) {
110 | this.i_reference = i_reference;
111 | }
112 |
113 | public String getI_content() {
114 | return i_content;
115 | }
116 |
117 | public void setI_content(String i_content) {
118 | this.i_content = i_content;
119 | }
120 |
121 | public String getI_content_time() {
122 | return i_content_time;
123 | }
124 |
125 | public void setI_content_time(String i_content_time) {
126 | this.i_content_time = i_content_time;
127 | }
128 |
129 | public String getI_remark() {
130 | return i_remark;
131 | }
132 |
133 | public void setI_remark(String i_remark) {
134 | this.i_remark = i_remark;
135 | }
136 |
137 | public String getI_increment() {
138 | return i_increment;
139 | }
140 |
141 | public void setI_increment(String i_increment) {
142 | this.i_increment = i_increment;
143 | }
144 |
145 | @Override
146 | public String toString() {
147 | return "ItemInfo{" +
148 | "i_id='" + i_id + '\'' +
149 | ", e_id='" + e_id + '\'' +
150 | ", i_index='" + i_index + '\'' +
151 | ", i_name='" + i_name + '\'' +
152 | ", i_type='" + i_type + '\'' +
153 | ", i_value='" + i_value + '\'' +
154 | ", i_state='" + i_state + '\'' +
155 | ", i_reference='" + i_reference + '\'' +
156 | ", i_content='" + i_content + '\'' +
157 | ", i_content_time='" + i_content_time + '\'' +
158 | ", i_remark='" + i_remark + '\'' +
159 | ", i_increment='" + i_increment + '\'' +
160 | ", i_unit='" + i_unit + '\'' +
161 | '}';
162 | }
163 |
164 | }
165 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/entity/CheckItem.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.entity;
2 |
3 | /**
4 | * 多选型View - 标签entity
5 | *
6 | * Created by fxp on 2018/3/3.
7 | */
8 |
9 | public class CheckItem {
10 |
11 | private int ITEM_NORMAL = 0;
12 |
13 | private int ITEM_ERROR = 1;
14 |
15 | private int ITEM_NOTCHECK = 2;
16 |
17 | private String itemLable = null;
18 |
19 | private int itemState = 2;
20 |
21 | private boolean isSelect = true;
22 |
23 | public int getItemState() {
24 | return itemState;
25 | }
26 |
27 | public void setItemState(int itemState) {
28 | this.itemState = itemState;
29 | }
30 |
31 | public String getItemLable() {
32 | return itemLable;
33 | }
34 |
35 | public void setItemLable(String itemLable) {
36 | this.itemLable = itemLable;
37 | }
38 |
39 | public boolean isSelect() {
40 | return isSelect;
41 | }
42 |
43 | public void setIsSelect(boolean isSelect) {
44 | this.isSelect = isSelect;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/entity/TagCloudConfiguration.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.entity;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.AttributeSet;
6 |
7 | import fxp.com.multiexpandablelist.R;
8 |
9 | /**
10 | * @author fyales
11 | * @since date 11/3/15
12 | */
13 | public class TagCloudConfiguration {
14 |
15 | private static final int DEFAULT_LINE_SPACING = 5;
16 | private static final int DEFAULT_TAG_SPACING = 10;
17 | private static final int DEFAULT_FIXED_COLUMN_SIZE = 3; //默认列数
18 |
19 | private int lineSpacing;
20 | private int tagSpacing;
21 | private int columnSize;
22 | private boolean isFixed;
23 |
24 | public TagCloudConfiguration(Context context, AttributeSet attrs) {
25 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TagCloudLayout);
26 | try {
27 | lineSpacing = a.getDimensionPixelSize(R.styleable.TagCloudLayout_lineSpacing, DEFAULT_LINE_SPACING);
28 | tagSpacing = a.getDimensionPixelSize(R.styleable.TagCloudLayout_tagSpacing, DEFAULT_TAG_SPACING);
29 | columnSize = a.getInteger(R.styleable.TagCloudLayout_columnSize, DEFAULT_FIXED_COLUMN_SIZE);
30 | isFixed = a.getBoolean(R.styleable.TagCloudLayout_isFixed, false);
31 | } finally {
32 | a.recycle();
33 | }
34 | }
35 |
36 | public int getLineSpacing() {
37 | return lineSpacing;
38 | }
39 |
40 | public void setLineSpacing(int lineSpacing) {
41 | this.lineSpacing = lineSpacing;
42 | }
43 |
44 | public int getTagSpacing() {
45 | return tagSpacing;
46 | }
47 |
48 | public void setTagSpacing(int tagSpacing) {
49 | this.tagSpacing = tagSpacing;
50 | }
51 |
52 | public int getColumnSize() {
53 | return columnSize;
54 | }
55 |
56 | public void setColumnSize(int columnSize) {
57 | this.columnSize = columnSize;
58 | }
59 |
60 | public boolean isFixed() {
61 | return isFixed;
62 | }
63 |
64 | public void setIsFixed(boolean isFixed) {
65 | this.isFixed = isFixed;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/fxpInterface/GetPictureListener.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.fxpInterface;
2 |
3 | /**
4 | * 获取照片接口
5 | *
6 | * Created by fxp on 2018/3/4.
7 | */
8 |
9 | public interface GetPictureListener {
10 |
11 | // 拍照
12 | void takePicture(int groupPosition, int childPosition);
13 |
14 | // 从相册获取照片F
15 | void selectPicture(int groupPosition, int childPosition);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/java/fxp/com/multiexpandablelist/view/TagCloudLayout.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist.view;
2 |
3 | import android.content.Context;
4 | import android.database.DataSetObserver;
5 | import android.graphics.Canvas;
6 | import android.util.AttributeSet;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 |
11 | import fxp.com.multiexpandablelist.entity.TagCloudConfiguration;
12 |
13 | /**
14 | * 标签流容器
15 | *
16 | * @author fyales
17 | * @since date 2015-03-04
18 | */
19 | public class TagCloudLayout extends ViewGroup {
20 |
21 | private int mLineSpacing;
22 | private int mTagSpacing;
23 | private BaseAdapter mAdapter;
24 | private TagItemClickListener mListener;
25 | private DataChangeObserver mObserver;
26 |
27 | public TagCloudLayout(Context context) {
28 | super(context);
29 | init(context, null, 0);
30 | }
31 |
32 | public TagCloudLayout(Context context, AttributeSet attrs) {
33 | super(context, attrs);
34 | init(context, attrs, 0);
35 | }
36 |
37 | public TagCloudLayout(Context context, AttributeSet attrs, int defStyle) {
38 | super(context, attrs, defStyle);
39 | init(context, attrs, defStyle);
40 | }
41 |
42 | private void init(Context context, AttributeSet attrs, int defStyle) {
43 | TagCloudConfiguration config = new TagCloudConfiguration(context, attrs);
44 | mLineSpacing = config.getLineSpacing();
45 | mTagSpacing = config.getTagSpacing();
46 | }
47 |
48 | private void drawLayout() {
49 | if (mAdapter == null || mAdapter.getCount() == 0) {
50 | return;
51 | }
52 |
53 | this.removeAllViews();
54 |
55 | for (int i = 0; i < mAdapter.getCount(); i++) {
56 | View view = mAdapter.getView(i,null,null);
57 | final int position = i;
58 | view.setOnClickListener(new OnClickListener() {
59 | @Override
60 | public void onClick(View v) {
61 | if (mListener != null) {
62 | mListener.itemClick(position);
63 | }
64 | }
65 | });
66 | this.addView(view);
67 | }
68 | }
69 |
70 | @Override
71 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
72 | int wantHeight = 0;
73 | int wantWidth = resolveSize(0, widthMeasureSpec);
74 | int paddingLeft = getPaddingLeft();
75 | int paddingRight = getPaddingRight();
76 | int paddingTop = getPaddingTop();
77 | int paddingBottom = getPaddingBottom();
78 | int childLeft = paddingLeft;
79 | int childTop = paddingTop;
80 | int lineHeight = 0;
81 |
82 | for (int i = 0; i < getChildCount(); i++) {
83 | final View childView = getChildAt(i);
84 | LayoutParams params = childView.getLayoutParams();
85 | childView.measure(
86 | getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight, params.width),
87 | getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, params.height)
88 | );
89 | int childHeight = childView.getMeasuredHeight();
90 | int childWidth = childView.getMeasuredWidth();
91 | lineHeight = Math.max(childHeight, lineHeight);
92 |
93 | if (childLeft + childWidth + paddingRight > wantWidth) {
94 | childLeft = paddingLeft;
95 | childTop += mLineSpacing + childHeight;
96 | lineHeight = childHeight;
97 | }
98 |
99 | childLeft += childWidth + mTagSpacing;
100 | }
101 | wantHeight += childTop + lineHeight + paddingBottom;
102 | setMeasuredDimension(wantWidth, resolveSize(wantHeight, heightMeasureSpec));
103 | }
104 |
105 | @Override
106 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
107 | int width = r - l;
108 | int paddingLeft = getPaddingLeft();
109 | int paddingTop = getPaddingTop();
110 | int paddingRight = getPaddingRight();
111 | int childLeft = paddingLeft;
112 | int childTop = paddingTop;
113 | int lineHeight = 0;
114 |
115 | for (int i = 0; i < getChildCount(); i++) {
116 | final View childView = getChildAt(i);
117 | if (childView.getVisibility() == View.GONE) {
118 | continue;
119 | }
120 | int childWidth = childView.getMeasuredWidth();
121 | int childHeight = childView.getMeasuredHeight();
122 | lineHeight = Math.max(childHeight, lineHeight);
123 |
124 | if (childLeft + childWidth + paddingRight > width) {
125 | childLeft = paddingLeft;
126 | childTop += mLineSpacing + lineHeight;
127 | lineHeight = childHeight;
128 | }
129 |
130 | childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
131 | childLeft += childWidth + mTagSpacing;
132 | }
133 | }
134 |
135 | @Override
136 | protected void onDraw(Canvas canvas) {
137 | super.onDraw(canvas);
138 | }
139 |
140 | @Override
141 | public LayoutParams generateLayoutParams(AttributeSet attrs) {
142 | return new LayoutParams(this.getContext(), attrs);
143 | }
144 |
145 | public void setAdapter(BaseAdapter adapter){
146 | if (mAdapter == null){
147 | mAdapter = adapter;
148 | if (mObserver == null){
149 | mObserver = new DataChangeObserver();
150 | mAdapter.registerDataSetObserver(mObserver);
151 | }
152 | drawLayout();
153 | }
154 | }
155 |
156 | public void setItemClickListener(TagItemClickListener mListener) {
157 | this.mListener = mListener;
158 | }
159 |
160 | public interface TagItemClickListener {
161 | void itemClick(int position);
162 | }
163 |
164 | class DataChangeObserver extends DataSetObserver {
165 | @Override
166 | public void onChanged() {
167 | TagCloudLayout.this.drawLayout();
168 | }
169 |
170 | @Override
171 | public void onInvalidated() {
172 | super.onInvalidated();
173 | }
174 | }
175 |
176 | }
177 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/edit_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/edit_focus_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/edit_unfocus_empty_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/tag_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/tag_view_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/drawable/tag_view_ok.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/list_inner_edit_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
17 |
18 |
24 |
25 |
38 |
39 |
52 |
53 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/list_inner_picture_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
24 |
25 |
41 |
42 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/list_inner_select_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
31 |
32 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/list_inner_text_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
31 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/list_outer_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
18 |
19 |
27 |
28 |
33 |
34 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/layout/list_tagview_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/camera_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/camera_img.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/img.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/logo.jpg
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/remark_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xxhdpi/remark_img.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 |
5 | #303F9F
6 |
7 | #FF4081
8 |
9 | /** 白色 **/
10 | #ffffff
11 |
12 | /** 黑色 **/
13 | #ff000000
14 |
15 | #CECECE
16 |
17 | #FF673E
18 |
19 | #FF673E
20 |
21 | #FFCDD2
22 |
23 |
24 | #00000000
25 |
26 | #DADADA
27 |
28 | #A0C2FF
29 |
30 | #BDC0C2
31 |
32 | #5D6368
33 |
34 | #7CACFF
35 |
36 | #FB5741
37 |
38 |
39 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MultiExpandableList
3 | 正常
4 | 异常
5 |
6 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/app/src/test/java/fxp/com/multiexpandablelist/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package fxp.com.multiexpandablelist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/android/MultiExpandableList/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/android/MultiExpandableList/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/MultiExpandableList/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/MultiExpandableList/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/android/README.md:
--------------------------------------------------------------------------------
1 | # multi-expandable-list (Android版本)
2 |
--------------------------------------------------------------------------------
/web/.gitattributes:
--------------------------------------------------------------------------------
1 | *.css linguist-language=javascript
--------------------------------------------------------------------------------
/web/css/expandable-list.css:
--------------------------------------------------------------------------------
1 | .theme-bg{
2 | background-color: #057BDD;
3 | }
4 |
5 | .theme-color{
6 | color: #057BDD;
7 | }
8 |
9 | .theme-border {
10 | border: 1px solid #057BDD !important;
11 | }
12 |
13 | .txt-overflow{
14 | white-space:nowrap;
15 | overflow:hidden;
16 | text-overflow:ellipsis;
17 | }
18 |
19 | .accordion_item_li {
20 | border-top: 1px solid #dbdbdb;
21 | border-bottom: 1px solid #dbdbdb;
22 | }
23 |
24 | .accordion_outer_equip_name{
25 | float: left;
26 | width: 60%;
27 | margin-top: 0.5rem;
28 | font-size: 1.2rem;
29 | color: black;
30 | }
31 |
32 | .accordion_outer_remark_icon{
33 | float: right;
34 | margin-right: 1rem;
35 | width: 2rem;
36 | margin-top: 0.2rem;
37 | }
38 |
39 | .accordion_inner_item_name{
40 | height: 100%;
41 | width: 35%;
42 | height: 2.5rem;
43 | float: left;
44 | padding: 0.5rem 0.2rem 0.5rem 0.2rem;
45 | font-size: 1rem;
46 | }
47 |
48 | .num_item_increment{
49 | text-align: center;
50 | width: 2.5rem;
51 | float: left;
52 | margin: 0.5rem 0.15rem;
53 | padding: 0.15rem;
54 | font-size: 0.8rem;
55 | border-radius: 15%;
56 | }
57 |
58 | .num_item_content{
59 | text-align: center;
60 | float: left;
61 | width: 25% !important;
62 | height: calc(100% - 0.8rem) !important;
63 | font-size: 0.8rem !important;
64 | margin: 0.4rem 0.2rem !important;
65 | padding: 0.2rem !important;
66 | border-radius: 10% !important;
67 | }
68 |
69 | .txt_item_content{
70 | float: left;
71 | width: calc(65% - 2.4rem) !important;
72 | height: calc(100% - 0.8rem) !important;
73 | font-size: 0.8rem !important;
74 | margin: 0.4rem 0.2rem !important;
75 | padding: 0.2rem !important;
76 | border-radius: 3px !important;
77 | }
78 |
79 | .pic_item_take_pic_div{
80 | float: left;
81 | height: calc(100% - 0.8rem);
82 | margin: 0.5rem 0;
83 | margin-left: 0.3rem;
84 | border-radius: 3px;
85 | }
86 |
87 | .pic_item_take_pic_img{
88 | width: 1.2rem;
89 | margin-left: 0.2rem;
90 | margin-top: 0.2rem;
91 | }
92 |
93 | .pic_item_take_pic_txt{
94 | font-size: 0.9rem;
95 | color: white;
96 | float: right;
97 | padding: 0.2rem;
98 | }
99 |
100 | .pic_item_select_pic_btn{
101 | float: left;
102 | height: calc(100% - 0.8rem);
103 | width: 5.25rem;
104 | margin: 0.5rem 0;
105 | margin-left: 0.3rem;
106 | padding: 0.2rem 0.3rem;
107 | font-size: 0.9rem;
108 | color: white;
109 | border-radius: 3px;
110 | }
111 |
112 | .pic_item_photo_div{
113 | clear: both;
114 | margin-left: 35%;
115 | }
116 |
117 | .pic_item_photo_img{
118 | width: 2.5rem;
119 | height: 2.5rem;
120 | background: lightgray;
121 | float: left;
122 | margin: 2px;
123 | }
124 |
125 | .select_item_div{
126 | float: left;
127 | width: calc(65% - 2rem);
128 | height: 100%;
129 | margin: 0.5rem 0;
130 | }
131 |
132 | .select_item_radio_btn{
133 | height: 1rem;
134 | width: 1rem;
135 | }
136 |
137 | .select_item_radio_lable{
138 | font-size: 1rem;
139 | }
140 |
141 | .line{
142 | clear: both;
143 | height: 1px;
144 | background-color: lightgrey;
145 | }
146 |
--------------------------------------------------------------------------------
/web/data/list.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "data": [{
4 | "e_id": "0_0",
5 | "e_index": 0,
6 | "e_name": "小米电视A4",
7 | "e_state": "0",
8 | "e_remark": "",
9 | "subs": [{
10 | "i_id": 1,
11 | "e_id": "0_0",
12 | "i_index": 1,
13 | "i_name": "机身温度",
14 | "i_type": 1,
15 | "i_value": "",
16 | "i_status": "",
17 | "i_reference": "-10~60",
18 | "i_content": "",
19 | "i_content_time": "",
20 | "i_remark": "",
21 | "i_default": "",
22 | "i_increment": "0.5",
23 | "i_unit": "C"
24 | }, {
25 | "i_id": 2,
26 | "e_id": "0_0",
27 | "i_index": 2,
28 | "i_name": "开关状态",
29 | "i_type": 2,
30 | "i_value": "开机/关机/待机",
31 | "i_status": "",
32 | "i_reference": "",
33 | "i_content": "",
34 | "i_content_time": "",
35 | "i_remark": "",
36 | "i_default": "",
37 | "i_increment": "",
38 | "i_unit": ""
39 | }, {
40 | "i_id": 3,
41 | "e_id": "0_0",
42 | "i_index": 3,
43 | "i_name": "播放内容",
44 | "i_type": 3,
45 | "i_value": "",
46 | "i_status": "",
47 | "i_reference": "",
48 | "i_content": "海贼王万国篇-路飞VS卡二",
49 | "i_content_time": "",
50 | "i_remark": "",
51 | "i_default": "",
52 | "i_increment": "",
53 | "i_unit": ""
54 | }, {
55 | "i_id": 4,
56 | "e_id": "0_0",
57 | "i_index": 4,
58 | "i_name": "机身状况",
59 | "i_type": 4,
60 | "i_value": "",
61 | "i_status": "",
62 | "i_reference": "",
63 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
64 | "i_content_time": "",
65 | "i_remark": "",
66 | "i_default": "",
67 | "i_increment": "",
68 | "i_unit": ""
69 | }]
70 | }, {
71 | "e_id": "0_0",
72 | "e_index": 0,
73 | "e_name": "小米电视A4",
74 | "e_state": "0",
75 | "e_remark": "remark",
76 | "subs": [{
77 | "i_id": 1,
78 | "e_id": "0_0",
79 | "i_index": 1,
80 | "i_name": "机身温度",
81 | "i_type": 1,
82 | "i_value": "",
83 | "i_status": "",
84 | "i_reference": "-10~60",
85 | "i_content": "",
86 | "i_content_time": "",
87 | "i_remark": "",
88 | "i_default": "",
89 | "i_increment": "0.5",
90 | "i_unit": "C"
91 | }, {
92 | "i_id": 2,
93 | "e_id": "0_0",
94 | "i_index": 2,
95 | "i_name": "开关状态",
96 | "i_type": 2,
97 | "i_value": "开机/关机/待机",
98 | "i_status": "",
99 | "i_reference": "",
100 | "i_content": "",
101 | "i_content_time": "",
102 | "i_remark": "",
103 | "i_default": "",
104 | "i_increment": "",
105 | "i_unit": ""
106 | }, {
107 | "i_id": 3,
108 | "e_id": "0_0",
109 | "i_index": 3,
110 | "i_name": "播放内容",
111 | "i_type": 3,
112 | "i_value": "",
113 | "i_status": "",
114 | "i_reference": "",
115 | "i_content": "海贼王万国篇-路飞VS卡二",
116 | "i_content_time": "",
117 | "i_remark": "",
118 | "i_default": "",
119 | "i_increment": "",
120 | "i_unit": ""
121 | }, {
122 | "i_id": 4,
123 | "e_id": "0_0",
124 | "i_index": 4,
125 | "i_name": "机身状况",
126 | "i_type": 4,
127 | "i_value": "",
128 | "i_status": "",
129 | "i_reference": "",
130 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
131 | "i_content_time": "",
132 | "i_remark": "",
133 | "i_default": "",
134 | "i_increment": "",
135 | "i_unit": ""
136 | }]
137 | }, {
138 | "e_id": "0_0",
139 | "e_index": 0,
140 | "e_name": "小米电视A4",
141 | "e_state": "0",
142 | "e_remark": "remark",
143 | "subs": [{
144 | "i_id": 1,
145 | "e_id": "0_0",
146 | "i_index": 1,
147 | "i_name": "机身温度",
148 | "i_type": 1,
149 | "i_value": "",
150 | "i_status": "",
151 | "i_reference": "-10~60",
152 | "i_content": "",
153 | "i_content_time": "",
154 | "i_remark": "",
155 | "i_default": "",
156 | "i_increment": "0.5",
157 | "i_unit": "C"
158 | }, {
159 | "i_id": 2,
160 | "e_id": "0_0",
161 | "i_index": 2,
162 | "i_name": "开关状态",
163 | "i_type": 2,
164 | "i_value": "开机/关机/待机",
165 | "i_status": "",
166 | "i_reference": "",
167 | "i_content": "",
168 | "i_content_time": "",
169 | "i_remark": "",
170 | "i_default": "",
171 | "i_increment": "",
172 | "i_unit": ""
173 | }, {
174 | "i_id": 3,
175 | "e_id": "0_0",
176 | "i_index": 3,
177 | "i_name": "播放内容",
178 | "i_type": 3,
179 | "i_value": "",
180 | "i_status": "",
181 | "i_reference": "",
182 | "i_content": "海贼王万国篇-路飞VS卡二",
183 | "i_content_time": "",
184 | "i_remark": "",
185 | "i_default": "",
186 | "i_increment": "",
187 | "i_unit": ""
188 | }, {
189 | "i_id": 4,
190 | "e_id": "0_0",
191 | "i_index": 4,
192 | "i_name": "机身状况",
193 | "i_type": 4,
194 | "i_value": "",
195 | "i_status": "",
196 | "i_reference": "",
197 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
198 | "i_content_time": "",
199 | "i_remark": "",
200 | "i_default": "",
201 | "i_increment": "",
202 | "i_unit": ""
203 | }]
204 | }, {
205 | "e_id": "0_0",
206 | "e_index": 0,
207 | "e_name": "小米电视A4",
208 | "e_state": "0",
209 | "e_remark": "remark",
210 | "subs": [{
211 | "i_id": 1,
212 | "e_id": "0_0",
213 | "i_index": 1,
214 | "i_name": "机身温度",
215 | "i_type": 1,
216 | "i_value": "",
217 | "i_status": "",
218 | "i_reference": "-10~60",
219 | "i_content": "",
220 | "i_content_time": "",
221 | "i_remark": "",
222 | "i_default": "",
223 | "i_increment": "0.5",
224 | "i_unit": "C"
225 | }, {
226 | "i_id": 2,
227 | "e_id": "0_0",
228 | "i_index": 2,
229 | "i_name": "开关状态",
230 | "i_type": 2,
231 | "i_value": "开机/关机/待机",
232 | "i_status": "",
233 | "i_reference": "",
234 | "i_content": "",
235 | "i_content_time": "",
236 | "i_remark": "",
237 | "i_default": "",
238 | "i_increment": "",
239 | "i_unit": ""
240 | }, {
241 | "i_id": 3,
242 | "e_id": "0_0",
243 | "i_index": 3,
244 | "i_name": "播放内容",
245 | "i_type": 3,
246 | "i_value": "",
247 | "i_status": "",
248 | "i_reference": "",
249 | "i_content": "海贼王万国篇-路飞VS卡二",
250 | "i_content_time": "",
251 | "i_remark": "",
252 | "i_default": "",
253 | "i_increment": "",
254 | "i_unit": ""
255 | }, {
256 | "i_id": 4,
257 | "e_id": "0_0",
258 | "i_index": 4,
259 | "i_name": "机身状况",
260 | "i_type": 4,
261 | "i_value": "",
262 | "i_status": "",
263 | "i_reference": "",
264 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
265 | "i_content_time": "",
266 | "i_remark": "",
267 | "i_default": "",
268 | "i_increment": "",
269 | "i_unit": ""
270 | }]
271 | }, {
272 | "e_id": "0_0",
273 | "e_index": 0,
274 | "e_name": "小米电视A4",
275 | "e_state": "0",
276 | "e_remark": "remark",
277 | "subs": [{
278 | "i_id": 1,
279 | "e_id": "0_0",
280 | "i_index": 1,
281 | "i_name": "机身温度",
282 | "i_type": 1,
283 | "i_value": "",
284 | "i_status": "",
285 | "i_reference": "-10~60",
286 | "i_content": "",
287 | "i_content_time": "",
288 | "i_remark": "",
289 | "i_default": "",
290 | "i_increment": "0.5",
291 | "i_unit": "C"
292 | }, {
293 | "i_id": 2,
294 | "e_id": "0_0",
295 | "i_index": 2,
296 | "i_name": "开关状态",
297 | "i_type": 2,
298 | "i_value": "开机/关机/待机",
299 | "i_status": "",
300 | "i_reference": "",
301 | "i_content": "",
302 | "i_content_time": "",
303 | "i_remark": "",
304 | "i_default": "",
305 | "i_increment": "",
306 | "i_unit": ""
307 | }, {
308 | "i_id": 3,
309 | "e_id": "0_0",
310 | "i_index": 3,
311 | "i_name": "播放内容",
312 | "i_type": 3,
313 | "i_value": "",
314 | "i_status": "",
315 | "i_reference": "",
316 | "i_content": "海贼王万国篇-路飞VS卡二",
317 | "i_content_time": "",
318 | "i_remark": "",
319 | "i_default": "",
320 | "i_increment": "",
321 | "i_unit": ""
322 | }, {
323 | "i_id": 4,
324 | "e_id": "0_0",
325 | "i_index": 4,
326 | "i_name": "机身状况",
327 | "i_type": 4,
328 | "i_value": "",
329 | "i_status": "",
330 | "i_reference": "",
331 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
332 | "i_content_time": "",
333 | "i_remark": "",
334 | "i_default": "",
335 | "i_increment": "",
336 | "i_unit": ""
337 | }]
338 | }, {
339 | "e_id": "0_0",
340 | "e_index": 0,
341 | "e_name": "小米电视A4",
342 | "e_state": "0",
343 | "e_remark": "remark",
344 | "subs": [{
345 | "i_id": 1,
346 | "e_id": "0_0",
347 | "i_index": 1,
348 | "i_name": "机身温度",
349 | "i_type": 1,
350 | "i_value": "",
351 | "i_status": "",
352 | "i_reference": "-10~60",
353 | "i_content": "",
354 | "i_content_time": "",
355 | "i_remark": "",
356 | "i_default": "",
357 | "i_increment": "0.5",
358 | "i_unit": "C"
359 | }, {
360 | "i_id": 2,
361 | "e_id": "0_0",
362 | "i_index": 2,
363 | "i_name": "开关状态",
364 | "i_type": 2,
365 | "i_value": "开机/关机/待机",
366 | "i_status": "",
367 | "i_reference": "",
368 | "i_content": "",
369 | "i_content_time": "",
370 | "i_remark": "",
371 | "i_default": "",
372 | "i_increment": "",
373 | "i_unit": ""
374 | }, {
375 | "i_id": 3,
376 | "e_id": "0_0",
377 | "i_index": 3,
378 | "i_name": "播放内容",
379 | "i_type": 3,
380 | "i_value": "",
381 | "i_status": "",
382 | "i_reference": "",
383 | "i_content": "海贼王万国篇-路飞VS卡二",
384 | "i_content_time": "",
385 | "i_remark": "",
386 | "i_default": "",
387 | "i_increment": "",
388 | "i_unit": ""
389 | }, {
390 | "i_id": 4,
391 | "e_id": "0_0",
392 | "i_index": 4,
393 | "i_name": "机身状况",
394 | "i_type": 4,
395 | "i_value": "",
396 | "i_status": "",
397 | "i_reference": "",
398 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
399 | "i_content_time": "",
400 | "i_remark": "",
401 | "i_default": "",
402 | "i_increment": "",
403 | "i_unit": ""
404 | }]
405 | }, {
406 | "e_id": "0_0",
407 | "e_index": 0,
408 | "e_name": "小米电视A4",
409 | "e_state": "0",
410 | "e_remark": "remark",
411 | "subs": [{
412 | "i_id": 1,
413 | "e_id": "0_0",
414 | "i_index": 1,
415 | "i_name": "机身温度",
416 | "i_type": 1,
417 | "i_value": "",
418 | "i_status": "",
419 | "i_reference": "-10~60",
420 | "i_content": "",
421 | "i_content_time": "",
422 | "i_remark": "",
423 | "i_default": "",
424 | "i_increment": "0.5",
425 | "i_unit": "C"
426 | }, {
427 | "i_id": 2,
428 | "e_id": "0_0",
429 | "i_index": 2,
430 | "i_name": "开关状态",
431 | "i_type": 2,
432 | "i_value": "开机/关机/待机",
433 | "i_status": "",
434 | "i_reference": "",
435 | "i_content": "",
436 | "i_content_time": "",
437 | "i_remark": "",
438 | "i_default": "",
439 | "i_increment": "",
440 | "i_unit": ""
441 | }, {
442 | "i_id": 3,
443 | "e_id": "0_0",
444 | "i_index": 3,
445 | "i_name": "播放内容",
446 | "i_type": 3,
447 | "i_value": "",
448 | "i_status": "",
449 | "i_reference": "",
450 | "i_content": "海贼王万国篇-路飞VS卡二",
451 | "i_content_time": "",
452 | "i_remark": "",
453 | "i_default": "",
454 | "i_increment": "",
455 | "i_unit": ""
456 | }, {
457 | "i_id": 4,
458 | "e_id": "0_0",
459 | "i_index": 4,
460 | "i_name": "机身状况",
461 | "i_type": 4,
462 | "i_value": "",
463 | "i_status": "",
464 | "i_reference": "",
465 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
466 | "i_content_time": "",
467 | "i_remark": "",
468 | "i_default": "",
469 | "i_increment": "",
470 | "i_unit": ""
471 | }]
472 | }, {
473 | "e_id": "0_0",
474 | "e_index": 0,
475 | "e_name": "小米电视A4",
476 | "e_state": "0",
477 | "e_remark": "remark",
478 | "subs": [{
479 | "i_id": 1,
480 | "e_id": "0_0",
481 | "i_index": 1,
482 | "i_name": "机身温度",
483 | "i_type": 1,
484 | "i_value": "",
485 | "i_status": "",
486 | "i_reference": "-10~60",
487 | "i_content": "",
488 | "i_content_time": "",
489 | "i_remark": "",
490 | "i_default": "",
491 | "i_increment": "0.5",
492 | "i_unit": "C"
493 | }, {
494 | "i_id": 2,
495 | "e_id": "0_0",
496 | "i_index": 2,
497 | "i_name": "开关状态",
498 | "i_type": 2,
499 | "i_value": "开机/关机/待机",
500 | "i_status": "",
501 | "i_reference": "",
502 | "i_content": "",
503 | "i_content_time": "",
504 | "i_remark": "",
505 | "i_default": "",
506 | "i_increment": "",
507 | "i_unit": ""
508 | }, {
509 | "i_id": 3,
510 | "e_id": "0_0",
511 | "i_index": 3,
512 | "i_name": "播放内容",
513 | "i_type": 3,
514 | "i_value": "",
515 | "i_status": "",
516 | "i_reference": "",
517 | "i_content": "海贼王万国篇-路飞VS卡二",
518 | "i_content_time": "",
519 | "i_remark": "",
520 | "i_default": "",
521 | "i_increment": "",
522 | "i_unit": ""
523 | }, {
524 | "i_id": 4,
525 | "e_id": "0_0",
526 | "i_index": 4,
527 | "i_name": "机身状况",
528 | "i_type": 4,
529 | "i_value": "",
530 | "i_status": "",
531 | "i_reference": "",
532 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
533 | "i_content_time": "",
534 | "i_remark": "",
535 | "i_default": "",
536 | "i_increment": "",
537 | "i_unit": ""
538 | }]
539 | }, {
540 | "e_id": "0_0",
541 | "e_index": 0,
542 | "e_name": "小米电视A4",
543 | "e_state": "0",
544 | "e_remark": "remark",
545 | "subs": [{
546 | "i_id": 1,
547 | "e_id": "0_0",
548 | "i_index": 1,
549 | "i_name": "机身温度",
550 | "i_type": 1,
551 | "i_value": "",
552 | "i_status": "",
553 | "i_reference": "-10~60",
554 | "i_content": "",
555 | "i_content_time": "",
556 | "i_remark": "",
557 | "i_default": "",
558 | "i_increment": "0.5",
559 | "i_unit": "C"
560 | }, {
561 | "i_id": 2,
562 | "e_id": "0_0",
563 | "i_index": 2,
564 | "i_name": "开关状态",
565 | "i_type": 2,
566 | "i_value": "开机/关机/待机",
567 | "i_status": "",
568 | "i_reference": "",
569 | "i_content": "",
570 | "i_content_time": "",
571 | "i_remark": "",
572 | "i_default": "",
573 | "i_increment": "",
574 | "i_unit": ""
575 | }, {
576 | "i_id": 3,
577 | "e_id": "0_0",
578 | "i_index": 3,
579 | "i_name": "播放内容",
580 | "i_type": 3,
581 | "i_value": "",
582 | "i_status": "",
583 | "i_reference": "",
584 | "i_content": "海贼王万国篇-路飞VS卡二",
585 | "i_content_time": "",
586 | "i_remark": "",
587 | "i_default": "",
588 | "i_increment": "",
589 | "i_unit": ""
590 | }, {
591 | "i_id": 4,
592 | "e_id": "0_0",
593 | "i_index": 4,
594 | "i_name": "机身状况",
595 | "i_type": 4,
596 | "i_value": "",
597 | "i_status": "",
598 | "i_reference": "",
599 | "i_content": "logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg,logo.jpg",
600 | "i_content_time": "",
601 | "i_remark": "",
602 | "i_default": "",
603 | "i_increment": "",
604 | "i_unit": ""
605 | }]
606 | }]
607 | },
608 | "error_code": "00",
609 | "error_msg": "Succeed"
610 | }
611 |
--------------------------------------------------------------------------------
/web/html/expandable-list.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/html/list-item-tpl.html:
--------------------------------------------------------------------------------
1 | {# 请不要随便格式化此文件代码}
2 |
3 | {@each equips as equip,parentIndex}
4 | -
5 |
9 |
10 |
73 |
74 | {@/each}
75 |
--------------------------------------------------------------------------------
/web/images/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/images/.DS_Store
--------------------------------------------------------------------------------
/web/images/camera_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/images/camera_img.png
--------------------------------------------------------------------------------
/web/images/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/images/img.png
--------------------------------------------------------------------------------
/web/images/item_remark_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/images/item_remark_img.png
--------------------------------------------------------------------------------
/web/images/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/images/logo.jpg
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | fxp
10 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
![]()
50 |
51 |
52 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/web/js/accordion.js:
--------------------------------------------------------------------------------
1 | /*===============================================================================
2 | ************ Accordion ************
3 | ===============================================================================*/
4 | (function () {
5 | var $ = $$, app = myApp;
6 |
7 | app.accordionOpenv1 = function (item) {
8 | item = $(item);
9 | var list = item.parents('.cusv1-accordion-list').eq(0);
10 | var content = item.children('.accordion-item-content');
11 | if (content.length === 0) content = item.find('.accordion-item-content');
12 | var expandedItem = list.length > 0 && item.parent().children('.accordion-item-expanded');
13 | if (expandedItem.length > 0) {
14 | // 打开当前item项时,关闭其他item项
15 | // app.accordionClose(expandedItem);
16 | }
17 | content.css('height', content[0].scrollHeight + 'px').transitionEnd(function () {
18 | if (item.hasClass('accordion-item-expanded')) {
19 | content.transition(0);
20 | content.css('height', 'auto');
21 | var clientLeft = content[0].clientLeft;
22 | content.transition('');
23 | item.trigger('opened');
24 | }
25 | /* else {
26 | content.css('height', '');
27 | item.trigger('closed');
28 | } */
29 | });
30 | item.trigger('open');
31 | item.addClass('accordion-item-expanded');
32 | };
33 | app.accordionClosev1 = function (item) {
34 | item = $(item);
35 | var content = item.children('.accordion-item-content');
36 | if (content.length === 0) content = item.find('.accordion-item-content');
37 | item.removeClass('accordion-item-expanded');
38 | content.transition(0);
39 | content.css('height', content[0].scrollHeight + 'px');
40 | // Relayout
41 | var clientLeft = content[0].clientLeft;
42 | // Close
43 | content.transition('');
44 | content.css('height', '').transitionEnd(function () {
45 | /* if (item.hasClass('accordion-item-expanded')) {
46 | content.transition(0);
47 | content.css('height', 'auto');
48 | var clientLeft = content[0].clientLeft;
49 | content.transition('');
50 | item.trigger('opened');
51 | }
52 | else {*/
53 | content.css('height', '');
54 | item.trigger('closed');
55 | // }
56 | });
57 | item.trigger('close');
58 | };
59 |
60 | })();
--------------------------------------------------------------------------------
/web/js/expandable-list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by fxp on 2018/2/7.
3 | */
4 | var $$ = Dom7;
5 |
6 | var myApp = new Framework7();
7 |
8 | var mainView = myApp.addView('.view-main');
9 |
10 | var expandableList = function () {
11 | var page, // 页面DOM
12 | templateStr, // 列表模板html
13 | imageDir = "images/"; // 图片路径
14 |
15 | /*
16 | * 获取模板文本
17 | * */
18 | $$.get("html/list-item-tpl.html", function (data) {
19 | templateStr = data;
20 | });
21 |
22 | /*
23 | * 加载expandable-list.html
24 | * */
25 | mainView.router.load(
26 | {
27 | url: 'html/expandable-list.html'
28 | }
29 | );
30 |
31 | /**
32 | * 页面生命周期监听-pageBeforeInit
33 | */
34 | $$(document).on('pageBeforeInit', function (e) {
35 | let page = e.detail.page;
36 | if (page.name === 'expandable-list') {
37 | expandableList.beforeInit(page);
38 | }
39 | });
40 |
41 | /**
42 | * 页面生命周期监听-pageInit
43 | */
44 | $$(document).on('pageInit', function (e) {
45 | let page = e.detail.page;
46 | if (page.name === 'expandable-list') {
47 | expandableList.init(page);
48 | }
49 | });
50 |
51 | /**
52 | * 页面生命周期监听-pageBeforeAnimation
53 | */
54 | $$(document).on('pageBeforeAnimation', function (e) {
55 | let page = e.detail.page;
56 | if (page.name === 'expandable-list') {
57 | expandableList.beforeAnimation(page);
58 | }
59 | });
60 |
61 | /**
62 | * 页面生命周期监听-pageBeforeRemove
63 | */
64 | $$(document).on('pageBeforeRemove', function (e) {
65 | let page = e.detail.page;
66 | if (page.name === 'expandable-list') {
67 | expandableList.beforeRemove(page);
68 | }
69 | });
70 |
71 | /**
72 | * pageBeforeInit回调
73 | * @param {*} p
74 | */
75 | function beforeInit(p) {
76 | page = $$(p.container);
77 |
78 | }
79 |
80 | /**
81 | * pageInit回调
82 | * @param {*} p
83 | */
84 | function init(p) {
85 |
86 | initViews();
87 |
88 | bindEvent('on');
89 | }
90 |
91 | /**
92 | * pageBeforeAnimation回调
93 | * @param {*} p
94 | */
95 | function beforeAnimation(p) {
96 |
97 | }
98 |
99 | /**
100 | * pageBeforeRemove回调
101 | * @param {*} p
102 | */
103 | function beforeRemove(p) {
104 |
105 | bindEvent('off');
106 |
107 | destroy();
108 | }
109 |
110 | /**
111 | * 绑定/卸载事件
112 | * @param {*} method
113 | */
114 | function bindEvent(method) {
115 | if (method === 'on' || method === 'off') {
116 | page[method]("click",".accordion_outer_equip_name",listStateHandler);
117 | }
118 | }
119 |
120 | function initViews() {
121 | utils.get("data/list.json",function(res){
122 | var data = JSON.parse(res).data.data;
123 | rendList(data);
124 | },function(error){
125 |
126 | });
127 | }
128 |
129 | /**
130 | * 组装、渲染列表
131 | * @param {*二级列表数据} items
132 | */
133 | function rendList(items) {
134 | var datas, htmlstr = '', accordionList;
135 | datas = {
136 | equips: items,
137 | img_dir: imageDir
138 | };
139 | try {
140 | htmlstr = juicer(templateStr, datas);
141 | accordionList = page.find("#accordion-list");
142 | accordionList.html(htmlstr);
143 | } catch (error) {
144 | console.log(error);
145 | }
146 | }
147 |
148 | /*
149 | * 二级列表打开/收缩事件
150 | * */
151 | function listStateHandler(e) {
152 | let item = $$(this).parents(".cusv1-accordion-item");
153 | if (item.hasClass("accordion-item-expanded")) {
154 | myApp.accordionClosev1(item);
155 | } else {
156 | myApp.accordionOpenv1(item);
157 | }
158 | }
159 |
160 | function destroy() {
161 | page = null;
162 |
163 | }
164 |
165 | return {
166 | beforeInit: beforeInit,
167 | init: init,
168 | beforeAnimation: beforeAnimation,
169 | beforeRemove: beforeRemove,
170 | }
171 | }();
172 |
173 | var utils = {
174 | post: function (data, sf, ef, p) {
175 | var url = utils.postUrl();
176 | $$.ajax({
177 | url: url,
178 | async: true,
179 | method: 'POST',
180 | contentType: 'text/plain',
181 | crossDomain: true,
182 | data: data,
183 | success: function (e) {
184 | if ("function" == typeof sf)
185 | sf(e, p);
186 | },
187 | error: function (e) {
188 | console.log(e);
189 | if ("function" == typeof ef)
190 | ef(e, p);
191 | }
192 | });
193 | },
194 | get: function (url, sf, ef, p) {
195 | $$.ajax({
196 | url: url,
197 | async: true,
198 | method: 'GET',
199 | contentType: 'application/x-www-form-urlencoded',
200 | crossDomain: true,
201 | success: function (e) {
202 | if ('function' == typeof sf)
203 | sf(e, p);
204 | },
205 | error: function (e) {
206 | if ('function' == typeof ef)
207 | ef(e, p);
208 | }
209 | });
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/web/libs/framework7/css/my-app.css:
--------------------------------------------------------------------------------
1 | html * {
2 | box-sizing: border-box;
3 | }
4 |
5 | .page {
6 | background-color: rgb(245, 245, 245) !important;
7 | }
8 |
9 | .page-header {
10 | width: 100%;
11 | height: 46px;
12 | background: #ff7f1f;
13 | }
14 |
15 | .page-body {
16 | width: 100%;
17 | height: calc(100% - 46px);
18 | }
19 |
20 | .page-header-inner {
21 | width: 100%;
22 | height: 100%;
23 | clear: both;
24 | }
25 |
26 | .page-header-inner .left, .page-header-inner .center, .page-header-inner .right {
27 | width: 33.3%;
28 | height: 100%;
29 | float: left;
30 | vertical-align: middle;
31 | line-height: 2.5;
32 | font-size: 1.125rem;
33 | color: white;
34 | }
35 |
36 | .page-header-inner .left {
37 | text-align: left;
38 | padding-left: 1.25rem;
39 | }
40 |
41 | .page-header-inner .center {
42 | text-align: center;
43 | overflow: hidden;
44 | white-space: nowrap;
45 | text-overflow: ellipsis;
46 | }
47 |
48 | .page-header-inner .right {
49 | text-align: right;
50 | padding-right: 1.25rem;
51 | }
52 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-f7-ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/libs/framework7/img/i-f7-ios.png
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-f7-material.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangxiaopeng/multi-expandable-list/97423703d4ecd2cf83c4c15460b7889c5dca0abe/web/libs/framework7/img/i-f7-material.png
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-calendar-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-calendar-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-comment-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-comment-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-email-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-email-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-gender-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-gender-material.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-name-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-name-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-password-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-password-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-settings-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-settings-material.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-tel-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-tel-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-toggle-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-toggle-material.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-url-ios.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/img/i-form-url-material.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/libs/framework7/js/init-app.js:
--------------------------------------------------------------------------------
1 | // Determine theme depending on device
2 | var isAndroid = Framework7.prototype.device.android === true;
3 | var isIos = Framework7.prototype.device.ios === true;
4 |
5 | // Set Template7 global devices flags
6 | Template7.global = {
7 | android: isAndroid,
8 | ios: isIos
9 | };
10 |
11 | // Define Dom7
12 | var $$ = Dom7;
13 |
14 | // Add CSS Styles
15 | if (isAndroid) {
16 | $$('head').append(
17 | '' +
18 | ''
19 | );
20 | } else {
21 | $$('head').append(
22 | '' +
23 | ''
24 | );
25 | }
26 |
27 | // Change Through navbar layout to Fixed
28 | if (!isAndroid) {
29 | // Change class
30 | $$('.view.navbar-through').removeClass('navbar-through').addClass('navbar-fixed');
31 | // And move Navbar into Page
32 | $$('.view .navbar').prependTo('.view .page');
33 | }
34 |
--------------------------------------------------------------------------------
/web/libs/juicer-min.js:
--------------------------------------------------------------------------------
1 | !function(){var e=function(){var t=[].slice.call(arguments);return t.push(e.options),t[0].match(/^\s*#([\w:\-\.]+)\s*$/gim)&&t[0].replace(/^\s*#([\w:\-\.]+)\s*$/gim,function(e,n){var o=document,i=o&&o.getElementById(n);t[0]=i?i.value||i.innerHTML:e}),e.documentHTML&&(e.compile.call(e,e.documentHTML),e.documentHTML=""),1==arguments.length?e.compile.apply(e,t):arguments.length>=2?e.to_html.apply(e,t):void 0},t={escapehash:{"<":"<",">":">","&":"&",'"':""","'":"'","/":"/"},escapereplace:function(e){return t.escapehash[e]},escaping:function(e){return"string"!=typeof e?e:e.replace(/[&<>"']/gim,this.escapereplace)},detection:function(e){return"undefined"==typeof e?"":e}},n=function(e){if("undefined"!=typeof console){if(console.warn)return void console.warn(e);if(console.log)return void console.log(e)}throw e},o=function(e,t){if(e=e!==Object(e)?{}:e,e.__proto__)return e.__proto__=t,e;var n=function(){},o=Object.create?Object.create(t):new(n.prototype=t,n);for(var i in e)e.hasOwnProperty(i)&&(o[i]=e[i]);return o},i=function(e){var t,n,o,i=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,r=/,/,s=/^\s*(_?)(\S+?)\1\s*$/,a=/^function[^{]+{([\s\S]*)}/m,c=[];"function"==typeof e?e.length&&(t=e.toString()):"string"==typeof e&&(t=e),t=t.trim(),o=t.match(i),n=t.match(a)[1].trim();for(var p=0;p1&&(e=i.shift(),o=i.shift().split(","),r="_method."+o.shift()+".call(this, "+[e].concat(o)+")"),"<%= "+(t?"_method.__escapehtml.escaping":"")+"("+(n&&n.detection===!1?"":"_method.__escapehtml.detection")+"("+r+")) %>"},this.__removeShell=function(t,o){var r=0;return t=t.replace(e.settings.helperRegister,function(t,n,o){var r=i(o),s=r[0],a=r[1],c=new Function(s.join(","),a);return e.register(n,c),t}).replace(e.settings.forstart,function(e,t,n,o){var n=n||"value",o=o&&o.substr(1),i="i"+r++;return"<% ~function() {for(var "+i+" in "+t+") {if("+t+".hasOwnProperty("+i+")) {var "+n+"="+t+"["+i+"];"+(o?"var "+o+"="+i+";":"")+" %>"}).replace(e.settings.forend,"<% }}}(); %>").replace(e.settings.ifstart,function(e,t){return"<% if("+t+") { %>"}).replace(e.settings.ifend,"<% } %>").replace(e.settings.elsestart,function(){return"<% } else { %>"}).replace(e.settings.elseifstart,function(e,t){return"<% } else if("+t+") { %>"}).replace(e.settings.noneencode,function(e,t){return n.__interpolate(t,!1,o)}).replace(e.settings.interpolate,function(e,t){return n.__interpolate(t,!0,o)}).replace(e.settings.inlinecomment,"").replace(e.settings.rangestart,function(e,t,n,o){var i="j"+r++;return"<% ~function() {for(var "+i+"="+n+";"+i+"<"+o+";"+i+"++) {{var "+t+"="+i+"; %>"}).replace(e.settings.include,function(e,t,n){return t.match(/^file\:\/\//gim)?e:"<%= _method.__juicer("+t+", "+n+"); %>"}),o&&o.errorhandling===!1||(t="<% try { %>"+t,t+='<% } catch(e) {_method.__throw("Juicer Render Exception: "+e.message);} %>'),t},this.__toNative=function(e,t){return this.__convert(e,!t||t.strip)},this.__lexicalAnalyze=function(t){var n=[],o=[],i="",r=["if","each","_","_method","console","break","case","catch","continue","debugger","default","delete","do","finally","for","function","in","instanceof","new","return","switch","this","throw","try","typeof","var","void","while","with","null","typeof","class","enum","export","extends","import","super","implements","interface","let","package","private","protected","public","static","yield","const","arguments","true","false","undefined","NaN"],s=function(e,t){if(Array.prototype.indexOf&&e.indexOf===Array.prototype.indexOf)return e.indexOf(t);for(var n=0;n=,\(\)\[\]]\s*([A-Za-z_0-9]+)/gim,a);for(var c=0;c"},this.__convert=function(e,t){var n=[].join("");return n+="'use strict';",n+="var _=_||{};",n+="var _out='';_out+='",n+=t!==!1?e.replace(/\\/g,"\\\\").replace(/[\r\t\n]/g," ").replace(/'(?=[^%]*%>)/g," ").split("'").join("\\'").split(" ").join("'").replace(/<%=(.+?)%>/g,"';_out+=$1;_out+='").split("<%").join("';").split("%>").join("_out+='")+"';return _out;":e.replace(/\\/g,"\\\\").replace(/[\r]/g,"\\r").replace(/[\t]/g,"\\t").replace(/[\n]/g,"\\n").replace(/'(?=[^%]*%>)/g," ").split("'").join("\\'").split(" ").join("'").replace(/<%=(.+?)%>/g,"';_out+=$1;_out+='").split("<%").join("';").split("%>").join("_out+='")+"';return _out.replace(/[\\r\\n]\\s+[\\r\\n]/g, '\\r\\n');"},this.parse=function(e,t){var i=this;return t&&t.loose===!1||(e=this.__lexicalAnalyze(e)+e),e=this.__removeShell(e,t),e=this.__toNative(e,t),this._render=new Function("_, _method",e),this.render=function(e,t){return t&&t===n.options._method||(t=o(t,n.options._method)),i._render.call(this,e,t)},this}},e.compile=function(e,t){t&&t===this.options||(t=o(t,this.options));var i=this,r={get:function(e){return t.cachestore?t.cachestore.get(e):i.__cache[e]},set:function(e,n){return t.cachestore?t.cachestore.set(e,n):i.__cache[e]=n}};try{var s=r.get(e)?r.get(e):new this.template(this.options).parse(e,t);return t&&t.cache===!1||r.set(e,s),s}catch(a){return n("Juicer Compile Exception: "+a.message),{render:function(){}}}},e.to_html=function(e,t,n){return n&&n===this.options||(n=o(n,this.options)),this.compile(e,n).render(t,n._method)},"undefined"!=typeof global&&"undefined"==typeof window&&e.set("cache",!1),"undefined"!=typeof document&&document.body&&(e.documentHTML=document.body.innerHTML),"undefined"!=typeof module&&module.exports?module.exports=e:this.juicer=e}();
--------------------------------------------------------------------------------