Просмотр исходного кода

1.RedAnt Mobile Android导入Common Editor。
2.RedAnt Mobile Android导入Search Result。
3.修改RedAnt Mobile Android Login Setting,实现Connect。
4.修改RedAnt Mobile Android Network实现Login和Connect。

Pen Li 8 лет назад
Родитель
Сommit
5d586bdd6f
85 измененных файлов с 10212 добавлено и 332 удалено
  1. 19 0
      RedAnt Mobile/RedAnt Mobile Android.iml
  2. 37 4
      RedAnt Mobile/app/src/main/AndroidManifest.xml
  3. 52 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/AddressEditorActivity.java
  4. 14 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/Application.java
  5. 204 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/BrushView.java
  6. 191 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/BundleItemDialog.java
  7. 161 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/BundleModelActivity.java
  8. 27 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorActionCellHolder.java
  9. 34 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorCellHolder.java
  10. 30 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorEditCellHolder.java
  11. 33 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorEnumCellHolder.java
  12. 125 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorImageCellHolder.java
  13. 34 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorLabelCellHolder.java
  14. 69 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorModelCellHolder.java
  15. 31 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorMultipleActionCellHolder.java
  16. 69 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorSectionHeaderHolder.java
  17. 30 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorSignatureCellHolder.java
  18. 32 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorSwitchCellHolder.java
  19. 44 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorTextViewCellHolder.java
  20. 4337 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditorActivity.java
  21. 59 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/ContactListActivity.java
  22. 66 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CreditCardEditorActivity.java
  23. 42 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/DatePickerActivity.java
  24. 377 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/EnumSlectActivity.java
  25. 204 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/ImageUploadActivity.java
  26. 16 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/ImageViewActivity.java
  27. 113 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/MonthPickerActivity.java
  28. 93 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/SignatureActivity.java
  29. 241 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/Utils.java
  30. 966 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/Result/SearchResultActivity.java
  31. 0 316
      RedAnt Mobile/app/src/main/java/com/usai/redant/raimage/ServerSettingActivity.java
  32. 2 3
      RedAnt Mobile/app/src/main/java/com/usai/redant/redantmobile/LoginActivity.java
  33. 2 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/redantmobile/RedAntApplication.java
  34. 436 0
      RedAnt Mobile/app/src/main/java/com/usai/redant/redantmobile/ServerSettingActivity.java
  35. 22 5
      RedAnt Mobile/app/src/main/java/com/usai/redant/util/Network.java
  36. BIN
      RedAnt Mobile/app/src/main/res/drawable-hdpi/more_info.png
  37. BIN
      RedAnt Mobile/app/src/main/res/drawable-mdpi/more_info.png
  38. BIN
      RedAnt Mobile/app/src/main/res/drawable-xhdpi/more_info.png
  39. BIN
      RedAnt Mobile/app/src/main/res/drawable-xxhdpi/more_info.png
  40. BIN
      RedAnt Mobile/app/src/main/res/drawable/album.png
  41. BIN
      RedAnt Mobile/app/src/main/res/drawable/camera.png
  42. BIN
      RedAnt Mobile/app/src/main/res/drawable/check.png
  43. BIN
      RedAnt Mobile/app/src/main/res/drawable/not_found.png
  44. 45 0
      RedAnt Mobile/app/src/main/res/drawable/result_black_border.xml
  45. BIN
      RedAnt Mobile/app/src/main/res/drawable/upload.png
  46. 21 0
      RedAnt Mobile/app/src/main/res/layout/activity_address_editor.xml
  47. 71 0
      RedAnt Mobile/app/src/main/res/layout/activity_bundle_model.xml
  48. 20 0
      RedAnt Mobile/app/src/main/res/layout/activity_common_editor.xml
  49. 10 0
      RedAnt Mobile/app/src/main/res/layout/activity_contact_list.xml
  50. 10 0
      RedAnt Mobile/app/src/main/res/layout/activity_credit_card_editor.xml
  51. 16 0
      RedAnt Mobile/app/src/main/res/layout/activity_date_picker.xml
  52. 16 0
      RedAnt Mobile/app/src/main/res/layout/activity_enum_slect.xml
  53. 57 0
      RedAnt Mobile/app/src/main/res/layout/activity_image_upload.xml
  54. 10 0
      RedAnt Mobile/app/src/main/res/layout/activity_image_view.xml
  55. 56 0
      RedAnt Mobile/app/src/main/res/layout/activity_month_picker.xml
  56. 31 0
      RedAnt Mobile/app/src/main/res/layout/activity_search_result.xml
  57. 2 2
      RedAnt Mobile/app/src/main/res/layout/activity_service_setting.xml
  58. 16 0
      RedAnt Mobile/app/src/main/res/layout/activity_signature.xml
  59. 55 0
      RedAnt Mobile/app/src/main/res/layout/bundle_item_cell.xml
  60. 18 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_action_cell.xml
  61. 62 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_edit_cell.xml
  62. 65 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_edit_cell_small.xml
  63. 88 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_enum_cell.xml
  64. 88 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_enum_cell_small.xml
  65. 67 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_image_cell.xml
  66. 79 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_image_cell_small.xml
  67. 41 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_label_cell.xml
  68. 41 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_label_cell_small.xml
  69. 204 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_model_cell.xml
  70. 62 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_multiple_action_cell.xml
  71. 44 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_section_header.xml
  72. 58 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_signature_cell.xml
  73. 58 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_signature_cell_small.xml
  74. 50 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_switch_cell.xml
  75. 68 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_switch_cell_small.xml
  76. 59 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_text_view_cell.xml
  77. 59 0
      RedAnt Mobile/app/src/main/res/layout/common_editor_text_view_cell_small.xml
  78. 37 0
      RedAnt Mobile/app/src/main/res/layout/enum_select_cell.xml
  79. 18 0
      RedAnt Mobile/app/src/main/res/layout/result_cell.xml
  80. 9 0
      RedAnt Mobile/app/src/main/res/menu/action_bar_menu.xml
  81. 11 0
      RedAnt Mobile/app/src/main/res/menu/result_menu.xml
  82. 10 0
      RedAnt Mobile/app/src/main/res/menu/set_menu.xml
  83. 15 0
      RedAnt Mobile/app/src/main/res/menu/signature_action_bar_menu.xml
  84. 250 0
      RedAnt Mobile/app/src/main/res/raw/result.json
  85. 3 2
      RedAnt Mobile/local.properties

+ 19 - 0
RedAnt Mobile/RedAnt Mobile Android.iml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="RedAnt Mobile Android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 37 - 4
RedAnt Mobile/app/src/main/AndroidManifest.xml

@@ -21,6 +21,12 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
+
+        <activity
+            android:name=".ServerSettingActivity"
+            android:label="@string/title_activity_service_setting"
+            android:screenOrientation="portrait"/>
+
         <activity android:name=".LoginActivity"
             android:label="@string/title_activity_full_screen_login"
             android:screenOrientation="portrait"
@@ -107,10 +113,7 @@
         android:name="com.usai.redant.raimage.LicenseActivity"
         android:label="@string/title_activity_license"
         android:screenOrientation="sensorLandscape"/>
-    <activity
-        android:name="com.usai.redant.raimage.ServerSettingActivity"
-        android:label="@string/title_activity_service_setting"
-        android:screenOrientation="portrait"/>
+
 
 
 
@@ -155,6 +158,36 @@
         android:stateNotNeeded="true"
         android:theme="@style/Theme.AppCompat.Light">
     </activity>
+
+        <!-- CommonEditor -->
+
+        <activity android:name="com.usai.redant.CommonEditor.CommonEditorActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.ImageUploadActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.ImageViewActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.BundleModelActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.AddressEditorActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.CreditCardEditorActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.ContactListActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.EnumSlectActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.DatePickerActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.MonthPickerActivity">
+        </activity>
+        <activity android:name="com.usai.redant.CommonEditor.SignatureActivity">
+        </activity>
+
+        <!-- Result -->
+        <activity android:name="com.usai.redant.Result.SearchResultActivity">
+        </activity>
+
 </application>
 
 </manifest>

+ 52 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/AddressEditorActivity.java

@@ -0,0 +1,52 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.usai.redant.redantmobile.R;
+
+public class AddressEditorActivity extends AppCompatActivity {
+
+
+    static String URL_TYPE = "url_type";
+    static String REQUEST_URL = "request_url";
+    static String IS_SUBACTION = "is_subaction";
+    static String SUBACTION_TAG = "subaction_tag";
+    static String GROUP = "group";
+    static String CHILD = "child";
+    static String RETURN_VALUE = "return_value";
+
+    public static class Builder {
+
+        public Intent build(Context ctx,int url_type,String request_url,String is_subaction,String subaction_tag,int group,int child) {
+            if (ctx == null) {
+                return null;
+            }
+            Intent intent = new Intent(ctx,AddressEditorActivity.class);
+
+            intent.putExtra(URL_TYPE ,url_type);
+
+            if (request_url != null) {
+                intent.putExtra(REQUEST_URL,request_url);
+            }
+            if (is_subaction != null) {
+                intent.putExtra(IS_SUBACTION,is_subaction);
+            }
+            if (subaction_tag != null) {
+                intent.putExtra(SUBACTION_TAG,subaction_tag);
+            }
+            intent.putExtra(GROUP,group);
+            intent.putExtra(CHILD,child);
+
+            return intent;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_address_editor);
+    }
+}

+ 14 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/Application.java

@@ -0,0 +1,14 @@
+package com.usai.redant.CommonEditor;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/22.
+ */
+
+public class Application {
+
+    public static JSONObject customerInfo;
+    public static String order_code;
+
+}

+ 204 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/BrushView.java

@@ -0,0 +1,204 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by macmini1 on 2017/8/31.
+ */
+
+public class BrushView extends View {
+
+
+    private Paint brush = new Paint();
+    private Path path = new Path();
+
+    private float minX;
+    private float minY;
+    private float maxX;
+    private float maxY;
+    private float lineWidth;
+
+    public BrushView(Context context) {
+        this(context,null);
+    }
+
+    public BrushView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs,0);
+    }
+
+    public BrushView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        lineWidth = 10.f;
+        init();
+    }
+
+
+    private void init() {
+
+        // fix saved jpg file seen black
+        // 没有颜色的位置默认使用的是白色的替代的,但是保存成png后,没有颜色的位置使用的是黑色替代的,所以会看到生成的图片是全黑的。
+        setBackgroundColor(Color.WHITE);
+
+        // 抗锯齿
+        brush.setAntiAlias(true);
+        brush.setColor(Color.BLACK);
+        brush.setStyle(Paint.Style.STROKE);
+        brush.setStrokeJoin(Paint.Join.ROUND);
+        brush.setStrokeWidth(lineWidth);
+        brush.setStrokeCap(Paint.Cap.ROUND); // 线条两端圆角
+
+        minX = Float.MAX_VALUE;
+        minY = Float.MAX_VALUE;
+
+        maxX = Float.MIN_VALUE;
+        maxY = Float.MIN_VALUE;
+
+
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+
+        float x = event.getX();
+        float y = event.getY();
+
+
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN: {
+                path.moveTo(x,y);
+                checkPoin(x,y);
+                return true;
+            }
+
+            case MotionEvent.ACTION_MOVE: {
+                path.lineTo(x,y);
+                checkPoin(x,y);
+                ispainted = true;
+            }
+            break;
+            case MotionEvent.ACTION_UP:
+                break;
+            default:
+            return false;
+        }
+
+        postInvalidate();
+
+        return false;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        canvas.drawPath(path,brush);
+
+    }
+
+    private void checkPoin(float x,float y) {
+
+        if (x < minX) {
+            minX = x;
+        }
+
+        if (y < minY) {
+            minY = y;
+        }
+
+        if (x > maxX) {
+            maxX = x;
+        }
+
+        if (y > maxY) {
+            maxY = y;
+        }
+
+
+    }
+
+    public void setBrushColor(int color) {
+        brush.setColor(color);
+    }
+
+    public void setLineWidth(float width) {
+        brush.setStrokeWidth(width);
+    }
+
+    public void clear() {
+
+        ispainted = false;
+        path.reset();
+        postInvalidate();
+
+    }
+
+    private boolean ispainted = false;
+
+    public boolean checkCanSave() {
+
+        return ispainted;
+    }
+
+    public Bitmap getDrawBitmap() {
+
+//        setDrawingCacheEnabled(true);
+//        buildDrawingCache();
+//        Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
+//        Canvas c = new Canvas(b);
+//        draw(c);
+//        Bitmap bitmap = b;
+
+
+        setDrawingCacheEnabled(true);
+        buildDrawingCache();
+        Bitmap bitmap = getDrawingCache();
+
+        // 裁剪绘图区域
+        String path = Utils.cacheTmpImage(bitmap);
+
+        int width = getWidth();
+        int height = getHeight();
+
+        // 裁剪区域,默认原图
+        Rect cropRect = new Rect(0, 0, width, height);
+
+        try {
+            final Matrix outputMatrix = new Matrix();//用于最图图片的精确缩放
+            InputStream inputStream = new FileInputStream(path);
+            final BitmapFactory.Options ops = new BitmapFactory.Options();
+            BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(inputStream, false);
+
+            cropRect.left = (int) (minX - lineWidth * 0.5);
+            cropRect.top = (int) (minY - lineWidth * 0.5);
+            cropRect.right = (int) (maxX + lineWidth * 0.5);
+            cropRect.bottom = (int) (maxY + lineWidth * 0.5);
+
+            final Bitmap source = decoder.decodeRegion(cropRect, ops);
+            return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), outputMatrix, false);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return bitmap;
+
+    }
+
+}

+ 191 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/BundleItemDialog.java

@@ -0,0 +1,191 @@
+package com.usai.redant.CommonEditor; 
+
+import android.app.Dialog;
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StyleRes;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+import java.util.List;
+
+
+public class BundleItemDialog extends Dialog {
+
+    public Context mCtx;
+    private ListView item_list;
+    public BundleItemDialog(@NonNull Context context) {
+        super(context);
+        mCtx = context;
+    }
+
+    public BundleItemDialog(@NonNull Context context, @StyleRes int themeResId) {
+        super(context, themeResId);
+        mCtx = context;
+    }
+
+    protected BundleItemDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
+        super(context, cancelable, cancelListener);
+        mCtx = context;
+    }
+
+    private JSONObject items_json;
+    public BundleItemDialog setItems(String items) {
+
+        if (items != null || !items.isEmpty()) {
+
+            try {
+
+                items_json = new JSONObject(items);
+
+                if (item_list != null) {
+                    item_list.setAdapter(new Adapter());
+                }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+
+        return this;
+    }
+
+    public static class Builder {
+
+        public  BundleItemDialog build(Context context) {
+            final BundleItemDialog dialog = new BundleItemDialog(context, R.style.AppTheme);
+            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            View layout = inflater.inflate(R.layout.activity_bundle_model,null);
+            dialog.addContentView(layout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+
+            dialog.item_list = (ListView) layout.findViewById(R.id.bundle_list_view);
+
+            return dialog;
+        }
+
+    }
+
+    public class Adapter extends BaseAdapter {
+
+        /**
+         * How many items are in the data set represented by this Adapter.
+         *
+         * @return Count of items.
+         */
+        @Override
+        public int getCount() {
+            if (items_json != null) {
+                int count = items_json.optInt("count");
+                return count;
+            }
+            return 0;
+        }
+
+        /**
+         * Get the data item associated with the specified position in the data set.
+         *
+         * @param position Position of the item whose data we want within the adapter's
+         *                 data set.
+         * @return The data at the specified position.
+         */
+        @Override
+        public Object getItem(int position) {
+            if (items_json != null) {
+                return items_json.optJSONObject("item_" + position);
+            }
+            return null;
+        }
+
+        /**
+         * Get the row id associated with the specified position in the list.
+         *
+         * @param position The position of the item within the adapter's data set whose row id we want.
+         * @return The id of the item at the specified position.
+         */
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Get a View that displays the data at the specified position in the data set. You can either
+         * create a View manually or inflate it from an XML layout file. When the View is inflated, the
+         * parent View (GridView, ListView...) will apply default layout parameters unless you use
+         * {@link LayoutInflater#inflate(int, ViewGroup, boolean)}
+         * to specify a root view and to prevent attachment to the root.
+         *
+         * @param position    The position of the item within the adapter's data set of the item whose view
+         *                    we want.
+         * @param convertView The old view to reuse, if possible. Note: You should check that this view
+         *                    is non-null and of an appropriate type before using. If it is not possible to convert
+         *                    this view to display the correct data, this method can create a new view.
+         *                    Heterogeneous lists can specify their number of view types, so that this View is
+         *                    always of the right type (see {@link #getViewTypeCount()} and
+         *                    {@link #getItemViewType(int)}).
+         * @param parent      The parent that this view will eventually be attached to
+         * @return A View corresponding to the data at the specified position.
+         */
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+
+            BundleItemHolder holder;
+
+            if (convertView == null) {
+
+                convertView = LayoutInflater.from(mCtx).inflate(R.layout.bundle_item_cell,null);
+                holder = new BundleItemHolder(convertView);
+
+            } else {
+                holder = (BundleItemHolder) convertView.getTag();
+            }
+
+            JSONObject item_json = (JSONObject) getItem(position);
+            if (item_json != null) {
+                holder.name_tv.setText(item_json.optString("model"));
+                if (item_json.optString("unit_price").equals("No Price")) {
+                    holder.up_tv.setText("No Price");
+                } else {
+                    holder.up_tv.setText(String.format("$ %.2f",Float.valueOf(item_json.optString("unit_price"))));
+                }
+                holder.qty_tv.setText(item_json.optString("modulus"));
+
+                holder.desc_tv.setText(item_json.optString("description"));
+            }
+
+
+            return convertView;
+        }
+
+        public class BundleItemHolder {
+
+            public TextView name_tv;
+            public TextView desc_tv;
+            public TextView qty_tv;
+            public TextView up_tv;
+
+            public BundleItemHolder(View cell) {
+                name_tv = (TextView) cell.findViewById(R.id.model_name_tv);
+                desc_tv = (TextView) cell.findViewById(R.id.model_desc_tv);
+                qty_tv = (TextView) cell.findViewById(R.id.model_qty_tv);
+                up_tv = (TextView) cell.findViewById(R.id.model_unit_price_tv);
+                cell.setTag(this);
+            }
+
+        }
+    }
+
+
+
+}

+ 161 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/BundleModelActivity.java

@@ -0,0 +1,161 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+public class BundleModelActivity extends AppCompatActivity {
+
+
+    private JSONObject items_json;
+    private ListView item_list;
+    private Context mCtx = this;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_bundle_model);
+
+        setTitle("Bundle");
+        item_list = (ListView) findViewById(R.id.bundle_list_view);
+
+        Intent intent = getIntent();
+        String items = intent.getStringExtra("bundle_items");
+        if (items != null || !items.isEmpty()) {
+            try {
+
+                items_json = new JSONObject(items);
+
+                if (item_list != null) {
+                    item_list.setAdapter(new Adapter());
+                }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+
+    public class Adapter extends BaseAdapter {
+
+        /**
+         * How many items are in the data set represented by this Adapter.
+         *
+         * @return Count of items.
+         */
+        @Override
+        public int getCount() {
+            if (items_json != null) {
+                int count = items_json.optInt("count");
+                return count;
+            }
+            return 0;
+        }
+
+        /**
+         * Get the data item associated with the specified position in the data set.
+         *
+         * @param position Position of the item whose data we want within the adapter's
+         *                 data set.
+         * @return The data at the specified position.
+         */
+        @Override
+        public Object getItem(int position) {
+            if (items_json != null) {
+                return items_json.optJSONObject("item_" + position);
+            }
+            return null;
+        }
+
+        /**
+         * Get the row id associated with the specified position in the list.
+         *
+         * @param position The position of the item within the adapter's data set whose row id we want.
+         * @return The id of the item at the specified position.
+         */
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Get a View that displays the data at the specified position in the data set. You can either
+         * create a View manually or inflate it from an XML layout file. When the View is inflated, the
+         * parent View (GridView, ListView...) will apply default layout parameters unless you use
+         * {@link LayoutInflater#inflate(int, ViewGroup, boolean)}
+         * to specify a root view and to prevent attachment to the root.
+         *
+         * @param position    The position of the item within the adapter's data set of the item whose view
+         *                    we want.
+         * @param convertView The old view to reuse, if possible. Note: You should check that this view
+         *                    is non-null and of an appropriate type before using. If it is not possible to convert
+         *                    this view to display the correct data, this method can create a new view.
+         *                    Heterogeneous lists can specify their number of view types, so that this View is
+         *                    always of the right type (see {@link #getViewTypeCount()} and
+         *                    {@link #getItemViewType(int)}).
+         * @param parent      The parent that this view will eventually be attached to
+         * @return A View corresponding to the data at the specified position.
+         */
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+
+            BundleItemHolder holder;
+
+            if (convertView == null) {
+
+                convertView = LayoutInflater.from(mCtx).inflate(R.layout.bundle_item_cell,null);
+                holder = new BundleItemHolder(convertView);
+
+            } else {
+                holder = (BundleItemHolder) convertView.getTag();
+            }
+
+            JSONObject item_json = (JSONObject) getItem(position);
+            if (item_json != null) {
+                holder.name_tv.setText(item_json.optString("model"));
+                if (item_json.optString("unit_price").equals("No Price")) {
+                    holder.up_tv.setText("No Price");
+                } else {
+                    holder.up_tv.setText(String.format("$ %.2f",Float.valueOf(item_json.optString("unit_price"))));
+                }
+                holder.qty_tv.setText(item_json.optString("modulus"));
+
+                holder.desc_tv.setText(item_json.optString("description"));
+            }
+
+
+            return convertView;
+        }
+
+        public class BundleItemHolder {
+
+            public TextView name_tv;
+            public TextView desc_tv;
+            public TextView qty_tv;
+            public TextView up_tv;
+
+            public BundleItemHolder(View cell) {
+                name_tv = (TextView) cell.findViewById(R.id.model_name_tv);
+                desc_tv = (TextView) cell.findViewById(R.id.model_desc_tv);
+                qty_tv = (TextView) cell.findViewById(R.id.model_qty_tv);
+                up_tv = (TextView) cell.findViewById(R.id.model_unit_price_tv);
+                cell.setTag(this);
+            }
+
+        }
+    }
+
+}

+ 27 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorActionCellHolder.java

@@ -0,0 +1,27 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+public class CommonEditorActionCellHolder extends CommonEditorCellHolder {
+
+    public TextView action_lb;
+    public String action_code;
+
+    public CommonEditorActionCellHolder(Context context,View view) {
+        super(context,view);
+        action_lb = (TextView) view.findViewById(R.id.action_cell_lb);
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 34 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorCellHolder.java

@@ -0,0 +1,34 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+
+public class CommonEditorCellHolder {
+
+    public Context mCtx;
+    public TextView startMark;
+    public int group;
+    public int child;
+
+    public CommonEditorCellHolder(Context context,View view) {
+        mCtx = context;
+        startMark = (TextView) view.findViewById(R.id.start_mark);
+        view.setTag(this);
+        if (startMark != null) {
+            startMark.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    public void setItem(JSONObject item_json,boolean readonly,View view) {
+
+    }
+
+
+}

+ 30 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorEditCellHolder.java

@@ -0,0 +1,30 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+
+public class CommonEditorEditCellHolder extends CommonEditorCellHolder {
+
+    public TextView name_lb;
+    public EditText text_field;
+
+    public CommonEditorEditCellHolder(Context context, View view) {
+        super(context,view);
+        name_lb = (TextView) view.findViewById(R.id.name_lb);
+        text_field = (EditText) view.findViewById(R.id.textField);
+
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 33 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorEnumCellHolder.java

@@ -0,0 +1,33 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorEnumCellHolder extends CommonEditorCellHolder {
+
+    public TextView title_lb;
+    public TextView value_lb;
+
+    public CommonEditorEnumCellHolder(Context context, View view) {
+        super(context,view);
+
+        title_lb = (TextView) view.findViewById(R.id.enum_title_lb);
+        value_lb = (TextView) view.findViewById(R.id.enum_value_lb);
+
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 125 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorImageCellHolder.java

@@ -0,0 +1,125 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+
+import com.usai.redant.CommonEditor.ImageUploadActivity;
+import com.usai.redant.CommonEditor.ImageViewActivity;
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+
+public class CommonEditorImageCellHolder extends CommonEditorCellHolder{
+
+    public TextView title_lb;
+    public TextView desc_lb;
+    public ImageButton img_btn_0;
+    public ImageButton img_btn_1;
+    public ImageButton img_btn_2;
+    public boolean editable;
+
+
+    public CommonEditorImageCellHolder(Context context, View view) {
+        super(context, view);
+
+        title_lb = (TextView) view.findViewById(R.id.img_cell_title_lb);
+        desc_lb = (TextView) view.findViewById(R.id.img_cell_desc_lb);
+
+        img_btn_0 = (ImageButton) view.findViewById(R.id.img_btn_0);
+        img_btn_1 = (ImageButton) view.findViewById(R.id.img_btn_1);
+        img_btn_2 = (ImageButton) view.findViewById(R.id.img_btn_2);
+
+        img_btn_0.setTag(0);
+        img_btn_1.setTag(1);
+        img_btn_2.setTag(2);
+
+        img_btn_0.setOnClickListener(clickListener);
+        img_btn_1.setOnClickListener(clickListener);
+        img_btn_2.setOnClickListener(clickListener);
+
+    }
+
+    private String path0;
+    public void setImage0(String path,Bitmap bitmap) {
+        img_btn_0.setImageBitmap(bitmap);
+        path0 = path;
+    }
+
+    private String path1;
+    public void setImage1(String path,Bitmap bitmap) {
+        img_btn_1.setImageBitmap(bitmap);
+        path1 = path;
+    }
+
+    private String path2;
+    public void setImage2(String path,Bitmap bitmap) {
+        img_btn_2.setImageBitmap(bitmap);
+        path2 = path;
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+
+    private View.OnClickListener clickListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            ImageButton btn = (ImageButton)v;
+            int btn_tag = (int)btn.getTag()/*Integer.valueOf((String)btn.getTag())*/;
+
+            int UPLOAD_IMAGE_CODE = 1;
+
+            if (editable) {
+                // 上传Image
+
+                Intent intent = new Intent(mCtx,ImageUploadActivity.class);
+                intent.putExtra("group",group);
+                intent.putExtra("child",child);
+                intent.putExtra("btn",btn_tag);
+
+                ((Activity)mCtx).startActivityForResult(intent,UPLOAD_IMAGE_CODE);
+
+            } else {
+                // 查看Image
+
+                Intent intent = new Intent(mCtx,ImageViewActivity.class);
+                if (btn_tag == 0) {
+                    if (path0 == null || path0.isEmpty()) {
+                        intent = null;
+                    } else {
+                        intent.putExtra("data", path0);
+                    }
+                }
+                if (btn_tag == 1) {
+                    if (path1 == null || path1.isEmpty()) {
+                        intent = null;
+                    } else {
+                        intent.putExtra("data", path1);
+                    }
+                }
+                if (btn_tag == 2) {
+                    if (path2 == null || path2.isEmpty()) {
+                        intent = null;
+                    } else {
+                        intent.putExtra("data", path2);
+                    }
+                }
+
+
+                if (intent != null) {
+                    ((Activity)mCtx).startActivity(intent);
+                }
+
+            }
+        }
+    };
+}

+ 34 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorLabelCellHolder.java

@@ -0,0 +1,34 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorLabelCellHolder extends CommonEditorCellHolder {
+
+
+    public TextView title_lb;
+    public TextView value_lb;
+
+    public CommonEditorLabelCellHolder(Context context, View view) {
+        super(context,view);
+
+        title_lb = (TextView) view.findViewById(R.id.cell_title_lb);
+        value_lb = (TextView) view.findViewById(R.id.cell_value_lb);
+
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 69 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorModelCellHolder.java

@@ -0,0 +1,69 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+
+import com.usai.redant.CommonEditor.BundleModelActivity;
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorModelCellHolder extends CommonEditorCellHolder {
+
+    public ImageButton model_img_btn;
+    public TextView desc_lb;
+    public TextView master_pack_lb;
+    public TextView old_price_lb;
+    public TextView discount_lb;
+    public TextView unit_price_lb;
+    public TextView count_lb;
+    public TextView bundle_btn;
+    public TextView total_price_lb;
+
+    public JSONObject bundle_item;
+
+    public CommonEditorModelCellHolder(Context context, View view) {
+        super(context, view);
+        model_img_btn = (ImageButton) view.findViewById(R.id.model_img_view);
+        desc_lb = (TextView) view.findViewById(R.id.model_desc_lb);
+        master_pack_lb = (TextView) view.findViewById(R.id.model_master_pack_lb);
+        old_price_lb = (TextView) view.findViewById(R.id.model_old_price_lb);
+        discount_lb = (TextView) view.findViewById(R.id.model_discount_lb);
+        unit_price_lb = (TextView) view.findViewById(R.id.model_unit_price_lb);
+        count_lb = (TextView) view.findViewById(R.id.model_count_lb);
+        bundle_btn = (TextView) view.findViewById(R.id.model_bundle_btn);
+        total_price_lb = (TextView) view.findViewById(R.id.model_total_price_lb);
+
+        bundle_btn.setOnClickListener(bundleClickListener);
+
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+
+    private View.OnClickListener bundleClickListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (bundle_item != null) {
+                Intent intent = new Intent(mCtx,BundleModelActivity.class);
+                intent.putExtra("bundle_items",bundle_item.toString());
+                ((Activity)mCtx).startActivity(intent);
+
+//                BundleItemDialog dialog = new BundleItemDialog.Builder().build(mCtx);
+//                dialog.setItems(bundle_item.toString());
+//                dialog.show();
+            }
+        }
+    };
+}

+ 31 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorMultipleActionCellHolder.java

@@ -0,0 +1,31 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Button;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorMultipleActionCellHolder extends CommonEditorCellHolder {
+
+    public Button btn0,btn1,btn2,btn3;
+    public CommonEditorMultipleActionCellHolder(Context context, View view) {
+        super(context, view);
+        btn0 = (Button) view.findViewById(R.id.btn_0);
+        btn1 = (Button) view.findViewById(R.id.btn_1);
+        btn2 = (Button) view.findViewById(R.id.btn_2);
+        btn3 = (Button) view.findViewById(R.id.btn_3);
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 69 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorSectionHeaderHolder.java

@@ -0,0 +1,69 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+
+
+public class CommonEditorSectionHeaderHolder extends CommonEditorCellHolder {
+
+    public TextView title_lb;
+    public TextView control_btn;
+    public Boolean show;
+
+
+    public CommonEditorSectionHeaderHolder(Context context, View view) {
+        super(context, view);
+
+
+        title_lb = (TextView) view.findViewById(R.id.title_lb);
+        control_btn = (TextView) view.findViewById(R.id.header_control_btn);
+        setShow(true);
+        hideControlBtn(true);
+//
+//        control_btn.setOnClickListener(new View.OnClickListener() {
+//            @Override
+//            public void onClick(View v) {
+//                setShow(!show);
+//                if (sectionShow != null) {
+//                    sectionShow.sectionShow(group,show);
+//                }
+//            }
+//        });
+    }
+
+
+    public void setShow(boolean show) {
+        this.show = show;
+
+        if (show == true) {
+            control_btn.setText("Hide");
+        } else {
+            control_btn.setText("Show");
+        }
+
+    }
+
+    public void hideControlBtn(boolean hide) {
+        if (hide == true) {
+            control_btn.setVisibility(View.INVISIBLE);
+        } else {
+            control_btn.setVisibility(View.VISIBLE);
+        }
+    }
+
+    public void clickSectionHeader(boolean expand) {
+        setShow(expand);
+    }
+
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 30 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorSignatureCellHolder.java

@@ -0,0 +1,30 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorSignatureCellHolder extends CommonEditorCellHolder {
+
+    public TextView title_lb;
+    public ImageView signature_iv;
+    public CommonEditorSignatureCellHolder(Context context, View view) {
+        super(context, view);
+        title_lb = (TextView) view.findViewById(R.id.signature_title_lb);
+        signature_iv = (ImageView) view.findViewById(R.id.signature_image_view);
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 32 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorSwitchCellHolder.java

@@ -0,0 +1,32 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Switch;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorSwitchCellHolder extends CommonEditorCellHolder {
+
+    public TextView title_lb;
+    public Switch aSwitch;
+
+    public CommonEditorSwitchCellHolder(Context context, View view) {
+        super(context, view);
+        title_lb = (TextView) view.findViewById(R.id.switch_title_lb);
+        aSwitch = (Switch) view.findViewById(R.id.switch_cell_switch);
+    }
+
+    @Override
+    public void setItem(JSONObject item_json, boolean readonly, View view) {
+        super.setItem(item_json, readonly, view);
+    }
+}

+ 44 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditor/CommonEditorTextViewCellHolder.java

@@ -0,0 +1,44 @@
+package com.usai.redant.CommonEditor.CommonEditor;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.text.method.TextKeyListener;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+import static android.view.Gravity.CENTER_VERTICAL;
+import static android.view.Gravity.END;
+import static android.view.Gravity.START;
+
+/**
+ * Created by macmini1 on 2017/8/16.
+ */
+
+public class CommonEditorTextViewCellHolder extends CommonEditorCellHolder {
+
+    public TextView title_lb;
+    public EditText text_view;
+    public CommonEditorTextViewCellHolder(Context context, View view) {
+        super(context, view);
+
+        title_lb = (TextView) view.findViewById(R.id.name_lb);
+        text_view = (EditText) view.findViewById(R.id.text_view);
+    }
+
+    @Override
+    public void setItem(JSONObject item_json,boolean readonly,View view) {
+        super.setItem(item_json,readonly,view);
+
+
+    }
+}

+ 4337 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CommonEditorActivity.java

@@ -0,0 +1,4337 @@
+package com.usai.redant.CommonEditor;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.widget.AbsListView;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.ExpandableListView;
+import android.widget.Switch;
+
+
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorActionCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorEditCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorEnumCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorImageCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorLabelCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorModelCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorMultipleActionCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorSectionHeaderHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorSignatureCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorSwitchCellHolder;
+import com.usai.redant.CommonEditor.CommonEditor.CommonEditorTextViewCellHolder;
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static android.view.Gravity.CENTER_VERTICAL;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
+
+
+
+public class CommonEditorActivity extends AppCompatActivity implements View.OnLayoutChangeListener{
+
+    private ExpandableListView listView;
+    private ExpandAdapter adapter;
+    public String service_url;
+
+    /**Child Activity Override*/
+    public void download_success() {
+
+    }
+
+    public void request_fill() {
+
+    }
+
+    public static class subitem_data {
+        public JSONObject params;
+        public JSONArray missingfields;
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.action_bar_menu,menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+        if (item.getItemId() == R.id.save_item) {
+            JSONObject obj = check_cancomit(true);
+            Log.d("Check Can Commit", "onOptionsItemSelected: ");
+        }
+
+        return true;
+    }
+
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        if (content_data_control != null) {
+            outState.putString("control_content",content_data_control.toString());
+        }
+        if (content_data_download != null) {
+            outState.putString("download_content",content_data_download.toString());
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        service_url = "http://192.168.0.133:8080/site/isales/getAddCustomer.htm";
+
+        listView = (ExpandableListView)findViewById(R.id.list_view);
+
+        adapter = new ExpandAdapter(this);
+
+        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
+            @Override
+            public void onScrollStateChanged(AbsListView view, int scrollState) {
+                // 编辑状态下滑动,去掉焦点
+                if (lastEditText != null) {
+                    lastEditText.clearFocus();
+                }
+            }
+
+            @Override
+            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+
+            }
+        });
+
+        listView.setGroupIndicator(null);
+
+        listView.setOnChildClickListener(new ListChildViewClickListener());
+
+        listView.setAdapter(adapter);
+
+//        loadData();
+
+        if (savedInstanceState != null) {
+            String control_str = savedInstanceState.getString("control_content");
+            String download_str = savedInstanceState.getString("download_content");
+            try {
+                if (control_str != null || !control_str.isEmpty()) {
+                    content_data_control = new JSONArray(control_str);
+                }
+                if (download_str != null || !download_str.isEmpty()) {
+                    content_data_download = new JSONObject(download_str);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                content_data_control = null;
+                content_data_download = null;
+            }
+
+        }
+
+        if (content_data_download == null || content_data_control == null) {
+            JSONObject obj = Utils.testJson(true);
+            if (obj != null) {
+                handleJson(obj);
+            }
+        }
+
+
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        View rootView = findViewById(R.id.root_layout);
+        rootView.addOnLayoutChangeListener(this);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        if (lastEditText != null) {
+            lastEditText.clearFocus();
+        }
+
+    }
+
+    @Override
+    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
+
+        if(oldBottom != 0 && bottom != 0 && oldBottom > bottom){
+
+            Log.d("Keyboard", "show: ");
+
+        }else if(oldBottom != 0 && bottom != 0 && oldBottom < bottom){
+
+            endEditting();
+            Log.d("Keyboard", "hide: ");
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (data == null || resultCode != RESULT_OK) {
+            return;
+        }
+
+        // upload image
+        if (requestCode == 1) {
+            int group = data.getIntExtra("group",0);
+            int child = data.getIntExtra("child",0);
+            int btn = data.getIntExtra("btn",0);
+            String url_down = data.getStringExtra("url_down");
+            String url_up = data.getStringExtra("url_up");
+            String path = data.getStringExtra("path");
+            Utils.cacheLocalImageToURL(path,url_up); // 将图片移动到缓存目录
+            // 对应更新数据,然刷新该行
+            imgIsChanged(url_down,url_up,group,child,btn,url_up);
+        }
+
+        // addr editor
+        if (requestCode == 2) {
+            String value_str = data.getStringExtra(AddressEditorActivity.RETURN_VALUE);
+            JSONObject value = null;
+            if (value_str != null) {
+                try {
+                    value = new JSONObject(value_str);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return;
+                }
+            }
+            int group = data.getIntExtra(AddressEditorActivity.GROUP,0);
+            int child = data.getIntExtra(AddressEditorActivity.CHILD,0);
+            handle_action_return(value,group,child,ACTION_SAVE_DATA);
+        }
+
+        // credit card editor
+        if (requestCode == 3) {
+            String value_str = data.getStringExtra(CreditCardEditorActivity.RETURN_VALUE);
+            JSONObject value = null;
+            if (value_str != null) {
+                try {
+                    value = new JSONObject(value_str);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return;
+                }
+            }
+            int group = data.getIntExtra(CreditCardEditorActivity.GROUP,0);
+            int child = data.getIntExtra(CreditCardEditorActivity.CHILD,0);
+            handle_action_return(value,group,child,ACTION_SAVE_DATA);
+        }
+
+        // contact list
+        if (requestCode == 4 || requestCode == 5 || requestCode == 6 || requestCode == 7 || requestCode == 8 || requestCode == 9) {
+            String value_str = data.getStringExtra(ContactListActivity.RETURN_VALUE);
+            JSONObject value = null;
+            if (value_str != null) {
+                try {
+                    value = new JSONObject(value_str);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return;
+                }
+            }
+            int group = data.getIntExtra(ContactListActivity.GROUP,0);
+            int child = data.getIntExtra(ContactListActivity.CHILD,0);
+            handle_action_return(value,group,child,ACTION_FILL_SECTION);
+        }
+
+        // enum select
+        if (requestCode == 10) {
+
+            String cadedate_str = data.getStringExtra(EnumSlectActivity.CADEDATE);
+            if (cadedate_str == null || cadedate_str.isEmpty()) {
+                return;
+            }
+            try {
+                JSONObject cadedate = new JSONObject(cadedate_str);
+                int group = data.getIntExtra(EnumSlectActivity.GROUP_POSITION,0);
+                int child = data.getIntExtra(EnumSlectActivity.CHILD_POSITION,0);
+
+                setEnumValue(cadedate,group,child);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+
+        // date picker
+        if (requestCode == 11) {
+
+        }
+
+        // month picker
+        if (requestCode == 12) {
+
+            String date_str = data.getStringExtra("value");
+            int group = data.getIntExtra("group",0);
+            int child = data.getIntExtra("child",0);
+            MPValueChanged(date_str,group,child);
+
+        }
+
+        // signature
+        if (requestCode == 13) {
+
+            int group = data.getIntExtra("group",0);
+            int child = data.getIntExtra("child",0);
+            String url_down = data.getStringExtra("url_down"); // avalue
+            String url_up = data.getStringExtra("url_up"); // value
+            String path = data.getStringExtra("path");
+
+            Utils.cacheLocalImageToURL(path,url_down);
+
+            signatureIsChanged(url_down,url_up,group,child);
+        }
+
+    }
+
+    public void signatureIsChanged(String url_down,String url_up,int group,int child) {
+
+        JSONArray section = content_data_control.optJSONArray(group);
+        JSONObject item_json = section.optJSONObject(child);
+
+        try {
+
+            item_json.put("avalue",url_down);
+            item_json.put("value",url_up);
+            item_json.put("dirty","true");
+
+            JSONObject section_json = content_data_download.optJSONObject("section_" + group);
+            section_json.put("item_" + child,item_json);
+
+            content_data_download.put("section_" + group, section_json);
+            content_data_control = translateChange(content_data_download,changed_data);
+
+            adapter.notifyDataSetChanged();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public void handle_action_return(JSONObject value,int group,int child,int action_code) {
+        if (value == null || value.length() == 0) {
+            return;
+        }
+
+        JSONObject section_json = null;
+        JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+
+        boolean is_subaction = value.optBoolean("is_subaction");
+        int subaction_tag = value.optInt("subaction_tag");
+        value.remove("is_subaction");
+        value.remove("subaction_tag");
+
+        if (is_subaction) {
+
+            JSONObject sub_action = item_json.optJSONObject("item_" + subaction_tag);
+            int refresh = sub_action.optInt("refresh");
+            String refresh_trigger = sub_action.optString("name");
+            JSONObject restore_json = sub_action.optJSONObject("restore");
+
+            String subid = sub_action.optString("subid");
+
+            String required = sub_action.optString("required");
+            /** Warning
+             *   get cell
+             *
+             * */
+            if (required.equals("true") && value.length() == 0) {
+                // cell red shadow
+            } else {
+                // cell clear shadow
+            }
+
+            if (value.length() != 0) {
+
+                if (action_code == ACTION_SAVE_DATA) {
+
+                    try {
+                        sub_action.put("data",value);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    if (subid == null || subid.isEmpty()) {
+                        try {
+
+                            sub_action.put("dirty","true");
+                            section_json = content_data_download.optJSONObject("section_" + group);
+                            int count = 0;
+                            count = section_json.optInt("count");
+                            for (int i = 0; i < count; i++) {
+
+                                JSONObject olditem = section_json.optJSONObject("item_" + i);
+                                if (olditem.optString("name").equals(sub_action.optString("name"))) {
+                                    item_json.put("item_" + value.optInt("subaction_tag"),sub_action);
+                                    section_json.put("item_" + i,item_json);
+                                }
+
+                            } // for
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                        // subid == null
+                    } else {
+
+                        String[] idarr = subid.split("_");
+                        int section = Integer.valueOf(idarr[0]);
+                        int item = Integer.valueOf(idarr[1]);
+
+                        section_json = content_data_download.optJSONObject("section_" + section);
+                        JSONObject olditem = section_json.optJSONObject("item_" + item);
+                        sub_action = enum_subitem_changed(olditem,idarr,sub_action,2);
+
+                        try {
+
+                            sub_action.put("dirty","true");
+                            item_json.put("item_" + value.optInt("subaction_tag"),sub_action);
+                            section_json.put("item_" + item,item_json);
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                    } // else
+
+                } else if (action_code == ACTION_FILL_SECTION) {
+                    if (subid == null || subid.isEmpty()) {
+
+                        JSONObject jsonmap = sub_action.optJSONObject("key_map");
+                        section_json = content_data_download.optJSONObject("section_" + group);
+                        int icount = section_json .optInt("count");
+                        for (int ic = 0; ic < icount; ic++) {
+                            JSONObject modify_item = section_json.optJSONObject("item_" + ic);
+                            String valuefrom = jsonmap.optString(modify_item.optString("name"));
+                            String valuestr = value.optString(valuefrom);
+                            if (valuestr != null) {
+                                try {
+
+                                    modify_item.put("value",valuestr);
+                                    modify_item.put("dirty","true");
+                                    section_json.put("item_" + ic,modify_item);
+
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        }
+
+                        // subid == null
+                    } else {
+
+                        String[] idarr = subid.split("_");
+                        int section = Integer.valueOf(idarr[0]);
+                        int item = Integer.valueOf(idarr[1]);
+                        JSONObject jsonmap = sub_action.optJSONObject("key_map");
+
+                        section_json = content_data_download.optJSONObject("section_" + section);
+                        JSONObject olditem = section_json.optJSONObject("item_" + item);
+                        JSONObject olditem_sub_action = olditem.optJSONObject("item_" + subaction_tag);
+
+                        olditem_sub_action = fill_switch_subitem_subid_mapping(olditem,null,value,jsonmap);
+
+                        try {
+
+                            olditem_sub_action.put("dirty","true");
+                            olditem.put("item_" + value.optInt("subaction_tag"),olditem_sub_action);
+                            section_json.put("item_" + item,olditem);
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+
+                try {
+                    content_data_download.put("section_" + group,section_json);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+            } // value.length != 0
+
+            content_data_control = translateChange(content_data_download,changed_data);
+
+            if (refresh == 1) {
+
+                if (restore_json != null) {
+                    int rc = restore_json.optInt("count");
+                    for (int ir = 0; ir < rc; ir++) {
+                        String name = restore_json.optString("item_" + ir);
+                        int section_count = content_data_download.optInt("section_count");
+                        for (int i = 0; i< section_count; i++) {
+                            JSONObject sectionjson = content_data_download.optJSONObject("section_" + i);
+                            int item_count = sectionjson.optInt("count");
+                            try {
+                                for (int j = 0; j < item_count; j++) {
+                                    JSONObject itemjson = sectionjson.optJSONObject("item_" + j);
+                                    if (itemjson.optString("name").equals(name)) {
+                                        itemjson.remove("dirty");
+                                        sectionjson.put("item_" + j,itemjson);
+                                    }
+                                }
+                                content_data_download.put("section_" + i,sectionjson);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }
+
+                refresh(refresh_trigger);
+                return;
+            }
+            adapter.notifyDataSetChanged();
+
+            // is_subaction
+        } else {
+            int refresh = item_json.optInt("refresh");
+            String refresh_trigger = item_json.optString("name");
+            JSONObject restore_json = item_json.optJSONObject("restore");
+
+            String subid = item_json.optString("subid");
+            String required = item_json.optString("required");
+
+            /** Warning
+             *
+             * get cell
+             * */
+            if (required.equals("true") && value.length() == 0) {
+                // cell red shadow
+            } else {
+                // cell clear shadow
+            }
+
+            if (value.length() != 0) {
+                if (action_code == ACTION_SAVE_DATA) {
+
+                    try {
+                        item_json.put("data",value);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+
+                    if (subid == null || subid.isEmpty()) {
+                        try {
+                            item_json.put("dirty","true");
+                            section_json = content_data_download.optJSONObject("section_" + group);
+                            int count = 0;
+                            count = section_json.optInt("count");
+                            for (int i = 0; i < count; i++) {
+                                JSONObject olditem = section_json.optJSONObject("item_" + i);
+                                if (olditem.optString("name").equals(item_json.optString("name"))) {
+                                    section_json.put("item_" + i,item_json);
+                                }
+                            }
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                    } else {
+                        String[] idarr = subid.split("_");
+                        int section = Integer.valueOf(idarr[0]);
+                        int item = Integer.valueOf(idarr[1]);
+
+                        section_json = content_data_download.optJSONObject("section_" + section);
+                        JSONObject olditem = section_json.optJSONObject("item_" + item);
+                        item_json = enum_subitem_changed(olditem,idarr,item_json,2);
+                        try {
+                            item_json.put("dirty","true");
+                            section_json.put("item_" + item,item_json);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+
+
+                } else if (action_code == ACTION_FILL_SECTION) {
+
+                    if (subid == null || subid.isEmpty()) {
+
+                        JSONObject jsonmap = item_json.optJSONObject("key_map");
+                        section_json = content_data_download.optJSONObject("section_" + group);
+                        int icount = section_json.optInt("count");
+                        for (int ic = 0; ic < icount; ic++) {
+                            JSONObject modify_item = section_json.optJSONObject("item_" + ic);
+                            String valuefrom = jsonmap.optString(modify_item.optString("name"));
+                            String valuestr = value.optString(valuefrom);
+
+                            if (valuestr != null) {
+                                try {
+                                    modify_item.put("value",valuestr);
+                                    modify_item.put("dirty","true");
+                                    section_json.put("item_" + ic,modify_item);
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        }
+
+                    } else {
+
+                        String[] idarr = subid.split("_");
+                        int section = Integer.valueOf(idarr[0]);
+                        int item = Integer.valueOf(idarr[1]);
+                        JSONObject jsonmap = item_json.optJSONObject("key_map");
+
+                        section_json = content_data_download.optJSONObject("section_" + section);
+                        JSONObject olditem = section_json.optJSONObject("item_" + item);
+
+                        olditem = fill_switch_subitem_subid_mapping(olditem,null,value,jsonmap);
+
+                        try {
+                            olditem.put("dirty","true");
+                            section_json.put("item_" + item,olditem);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                    }
+
+                }
+
+                try {
+                    content_data_download.put("section_" + group,section_json);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+            content_data_control = translateChange(content_data_download,changed_data);
+
+            if (refresh != 1) {
+
+                if (restore_json != null) {
+                    int rc = restore_json.optInt("count");
+                    for (int ir = 0; ir < rc; ir++) {
+                        String name = restore_json.optString("item_" + ir);
+                        int section_count = content_data_download.optInt("section_count");
+                        for (int i = 0; i < section_count; i++) {
+                            JSONObject sectionjson = content_data_download.optJSONObject("section_" + i);
+                            int item_count = sectionjson.optInt("count");
+                            try {
+                                for (int j = 0; j < item_count; j++) {
+                                    JSONObject itemjson = sectionjson.optJSONObject("item_" + j);
+                                    if (itemjson.optString("name").equals(name)) {
+                                        itemjson.remove("dirty");
+                                        sectionjson.put("item_" + j,itemjson);
+                                    }
+                                }
+                                content_data_download.put("section_" + i,sectionjson);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+
+                    }
+                }
+
+                refresh(refresh_trigger);
+                return;
+            }
+
+            adapter.notifyDataSetChanged();
+        }
+
+    }
+
+    public JSONObject enum_subitem_changed(JSONObject item,String[] subid,JSONObject value,int step) {
+
+        int index = Integer.valueOf(subid[step]);
+        JSONObject cadedate = item.optJSONObject("cadedate");
+        JSONObject subitem = item.optJSONObject("sub_item");
+        if (cadedate != null) {
+            JSONObject valjson = cadedate.optJSONObject("val_" + index);
+            valjson = enum_subitem_changed(valjson,subid,value,step+1);
+
+            try {
+                cadedate.put("val_" + index,valjson);
+                item.put("cadedate",cadedate);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return item;
+
+        } else if (subitem != null) {
+
+            JSONObject itemjson = subitem.optJSONObject("item_" + index);
+            if (step == subid.length - 1) {
+                itemjson = value;
+            } else {
+                itemjson = enum_subitem_changed(itemjson,subid,value,step + 1);
+            }
+
+            try {
+
+                subitem.put("item_" + index,itemjson);
+                item.put("sub_item",subitem);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return item;
+        }
+
+        return null;
+    }
+
+
+    public void loadData() {
+
+        if (service_url == null || service_url.isEmpty()) {
+            return;
+        }
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                HttpURLConnection connection = null;
+                try {
+
+                    URL url = new URL(service_url);
+                    connection = (HttpURLConnection)url.openConnection();
+                    connection.setRequestMethod("POST");
+                    connection.setConnectTimeout(1500);
+                    connection.setReadTimeout(1500);
+                    connection.setUseCaches(false);
+                    connection.setDoInput(true);
+                    connection.setDoOutput(true);
+                    connection.setRequestProperty("Content-Type","multipart/form-data; boundary=AaB03x");
+                    connection.setRequestProperty("Connection","close");
+
+                    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream());
+                    outputStreamWriter.write("password=123456&app_ver=170814&idfv=D3CE97F6-3586-4804-B7E6-7C7AB027A235&ipad_perm={\"submit_order_logout\":\"true\",\"can_submit_order\":\"true\",\"can_set_tearsheet_price\":\"true\",\"can_update_contact_info\":\"true\",\"can_see_price\":\"true\",\"alert_sold_in_quantities\":\"true\",\"can_show_price\":\"true\",\"can_create_portfolio\":\"true\",\"can_set_cart_price\":\"true\",\"save_order_logout\":\"true\",\"can_create_order\":\"true\"}&app_short_ver=1.90&user=Admin");
+
+                    InputStream inputStream = connection.getInputStream();
+                    readInputStream(inputStream);
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+    }
+
+    JSONObject changed_data;
+    private void readInputStream(InputStream inputStream) {
+        try {
+            // 对获取到到输入流读取
+            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+            StringBuilder response = new StringBuilder();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                response.append(line);
+            }
+            JSONObject object = new JSONObject(response.toString());
+
+            int result = object.optInt("result");
+            if (result == 2) {
+
+                content_data_download = copyDirtyTo(content_data_download,object);
+                content_data_control = translateChange(content_data_download,changed_data);
+
+                download_success();
+                adapter.notifyDataSetChanged();
+
+            } else {
+
+            }
+
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void handleJson(final JSONObject object) {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                int result = object.optInt("result");
+                if (result == 2) {
+
+                    content_data_download = copyDirtyTo(content_data_download,object);
+                    content_data_control = translateChange(content_data_download,changed_data);
+
+                    download_success();
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            defaulExpandSections();
+                            adapter.notifyDataSetChanged();
+                        }
+                    });
+
+                } else {
+                    Utils.message_alert(mCtx,"Warning","Error");
+                }
+            }
+        }).start();
+    }
+
+    public JSONObject copyDirtyTo(JSONObject dirty, JSONObject to) {
+
+        if (dirty == null) {
+            return to;
+        }
+
+        int section_count = dirty.optInt("section_count");
+
+        try {
+            for(int i=0;i<section_count;i++)
+            {
+                JSONObject sectionjson = dirty.optJSONObject("section_" + i);
+                JSONObject to_sectionjson = to.optJSONObject("section_" + i);
+                int item_count = sectionjson.optInt("count");
+                for(int j=0;j<item_count;j++)
+                {
+                    JSONObject itemjson = sectionjson.optJSONObject("item_" + j);
+
+                    if(itemjson.optString("dirty").equals("true"))
+                    {
+                        to_sectionjson.put("item_" + j ,itemjson);
+                    }
+
+                }
+                to.put("section_" + i,to_sectionjson);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return to;
+    }
+
+    public JSONArray translateChange(JSONObject obj, JSONObject change_data) {
+
+        if (obj == null)
+            return null;
+
+        JSONArray retarray = new JSONArray();
+
+        int section_count = obj.optInt("section_count");
+        for (int i = 0; i < section_count; i++) {
+            JSONArray sectionarr = new JSONArray();
+
+            JSONObject sectionjson = obj.optJSONObject("section_" + i);
+            int item_count = sectionjson.optInt("count");
+            for(int j=0;j<item_count;j++)
+            {
+                JSONObject itemjson=sectionjson.optJSONObject("item_" + j);
+
+                sectionarr.put(itemjson);
+
+                addSubItemToParent(itemjson,sectionarr,i + "_" + j);
+
+            }
+
+        retarray.put(sectionarr);
+        }
+
+        Log.e("Content Data Control", "translateChange: ");
+        return retarray;
+    }
+
+    public JSONArray addSubItemToParent(JSONObject itemjson,JSONArray sectionarr,String parent) {
+
+        try {
+
+            String control_type = itemjson.optString("control");
+            boolean single_select = itemjson.optBoolean("single_select");
+            if (control_type.equals("enum") && single_select) {
+
+                JSONObject cadedatejson = itemjson.optJSONObject("cadedate");
+                int cade_count = cadedatejson.optInt("count");
+                for (int k = 0; k < cade_count; k++) {
+                    JSONObject valjson = cadedatejson.optJSONObject("val_" + k);
+                    int check = valjson.optInt("check");
+                    JSONObject subjson = valjson.optJSONObject("sub_item");
+                    boolean active = valjson.optBoolean("active");
+                    active = false;
+                    if (check == 1 && subjson != null && !active) {
+                        int sub_count = subjson.optInt("count");
+                        for (int l = 0; l < sub_count; l++) {
+                            JSONObject addjson = subjson.optJSONObject("item_" + l);
+                            String subself = parent + "_" + k + "_" + l;
+                            addjson.put("subid",subself);
+                            sectionarr.put(addjson);
+                            addSubItemToParent(addjson,sectionarr,subself);
+
+                        }
+                        valjson.put("active",true);
+                        cadedatejson.put("val_" + k,valjson);
+                    }
+                }
+
+            } else if (control_type.equals("switch")) {
+
+                String value = itemjson.optString("value");
+                JSONObject subjson = null;
+                if (value.equals("true")) {
+                    JSONObject true_obj = itemjson.optJSONObject("true");
+                    if (true_obj != null) {
+                        subjson = true_obj.optJSONObject("sub_item");
+                    }
+                } else {
+                    JSONObject false_obj = itemjson.optJSONObject("false");
+                    if (false_obj != null) {
+                        subjson = false_obj.optJSONObject("sub_item");
+                    }
+                }
+
+                if (subjson != null) {
+                    int sub_count = subjson.optInt("count");
+                    for (int l = 0; l < sub_count; l++) {
+                        JSONObject addjson = subjson.optJSONObject("item_" + l);
+                        String subself = parent + "_" + l;
+                        addjson.put("subid",subself);
+                        sectionarr.put(addjson);
+                        addSubItemToParent(addjson,sectionarr,subself);
+                    }
+                }
+
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sectionarr;
+    }
+
+    public void defaulExpandSections() {
+        int groupCount = 0;
+        if (content_data_control != null) {
+            groupCount = content_data_control.length();
+        } else {
+            groupCount = 0;
+        }
+
+        if (groupCount <= 0) {
+            return;
+        }
+
+        for (int i = 0; i < groupCount; i++) {
+            JSONObject section_json = content_data_download.optJSONObject("section_" + i);
+            boolean hide = section_json.optBoolean("hide");
+            if (hide) {
+                listView.collapseGroup(i); // 默认关闭
+            } else {
+                listView.expandGroup(i); // 默认展开
+            }
+        }
+
+    }
+
+    public int url_type = URL_REMOTE;
+    public void refresh(String trigger) {
+
+        if (lastEditText != null) {
+            endEditting();
+        }
+        if (url_type == URL_REMOTE) {
+
+            final ProgressDialog pd = Utils.waiting_alert(mCtx,"loading","please wait");
+            if (trigger != null) {
+                try {
+                    selfParams.put("refresh_trigger",trigger);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    JSONObject refresh_params = get_refresh_param();
+                    Iterator<String> iterator = refresh_params.keys();
+                    while (iterator.hasNext()) {
+                        String key = iterator.next();
+                        String obj_str = "" + refresh_params.optString(key);
+                        try {
+                            selfParams.put(key,obj_str);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+
+                    final JSONObject editor_json = Utils.request_editor(service_url,selfParams);
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            pd.dismiss();
+                            if (editor_json == null) {
+                                Utils.message_alert(mCtx,"Warning","net error");
+                                adapter.notifyDataSetChanged();
+                                return;
+                            }
+                            if (Integer.valueOf(editor_json.optString("result")) == 2) {
+                                content_data_download = copyDirtyTo(content_data_download,editor_json);
+                                content_data_control = translateChange(content_data_download,changed_data);
+
+                                download_success();
+                                adapter.notifyDataSetChanged();
+
+                            } else {
+                                Utils.message_alert(mCtx,"Warning",editor_json.optString("err_msg"));
+                            }
+                        }
+                    });
+                }
+            }).start();
+
+
+        } // url remote
+        else {
+
+            try {
+
+                InputStreamReader isr = new InputStreamReader(getAssets().open(service_url + ".json"),"UTF-8");
+                BufferedReader br = new BufferedReader(isr);
+                String line;
+                StringBuilder builder = new StringBuilder();
+                while((line = br.readLine()) != null){
+                    builder.append(line);
+                }
+                br.close();
+                isr.close();
+                content_data_download = new JSONObject(builder.toString());//builder读取了JSON中的数据。
+
+                request_fill();
+
+                content_data_control = translateChange(content_data_download,changed_data);
+                adapter.notifyDataSetChanged();
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+    }
+
+    public JSONObject selfParams = new JSONObject();
+    public JSONObject get_refresh_param() {
+        try {
+            JSONObject params = new JSONObject();
+            JSONObject param_names = content_data_download.optJSONObject("up_params");
+            int param_count = param_names.optInt("count");
+            for (int pc = 0; pc < param_count; pc++) {
+                String param_name = param_names.optString("val_" + pc);
+                String param_val = getValue(param_name);
+                selfParams.put(param_name,param_val);
+            }
+            return params;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public  subitem_data subitem_param_addto_alert(JSONObject itemjson,JSONObject upparam,boolean alert) {
+
+        try {
+
+            subitem_data data = new subitem_data();
+
+            JSONArray fields = new JSONArray();
+            String control_type = itemjson.optString("control");
+            boolean single_select = itemjson.optBoolean("single_select");
+            if (control_type.equals("enum") && single_select) {
+
+                JSONObject cadedatejson = itemjson.optJSONObject("cadedate");
+                int cade_count = cadedatejson.optInt("count");
+
+                for (int k = 0; k < cade_count; k++) {
+                    JSONObject valjson  = cadedatejson.optJSONObject("val_" + k);
+                    int check = valjson.optInt("check");
+
+                    JSONObject subjson = valjson.optJSONObject("sub_item");
+                    boolean active = valjson.optBoolean("active");
+                    if (check == 1 && subjson != null && !active) {
+
+                        int sub_count = subjson.optInt("count");
+                        for (int l = 0; l < sub_count; l++) {
+
+                            JSONObject addjson = subjson.optJSONObject("item_" + l);
+                            String required = addjson.optString("required");
+                            String key = addjson.optString("name");
+                            if (key == null || key.isEmpty()) {
+                                continue;
+                            } //
+                            if (addjson.optString("control").equals("enum")) {
+                                String add_single_select = addjson.optString("single_select");
+                                if (add_single_select.equals("true")) {
+
+                                    JSONObject cadejson = addjson.optJSONObject("cadedate");
+                                    int count = cadejson.optInt("count");
+                                    boolean setvalue = false;
+                                    for (int cc = 0; cc < count; cc++) {
+                                        JSONObject cade_valjson = cadejson.optJSONObject("val_" + cc);
+                                        if (Integer.valueOf(cade_valjson.optString("check")) == 1) {
+                                            upparam.put(addjson.optString("name"),cade_valjson.optString("value_id"));
+                                            setvalue = true;
+                                            break;
+                                        } // check == 1
+
+                                    } // for cc
+
+                                    if (addjson.optString("required").equals("true") && setvalue == false) {
+                                        cancommit = false;
+
+                                        String mfield = String.format("%d. %s is missing",fields.length() + 1,addjson.optString("aname"));
+
+                                        fields.put(mfield);
+
+                                        IndexPath indexPath = get_indexpath1(addjson.optString("name"));
+                                        if (alert) {
+                                            listView.expandGroup(indexPath.section);
+                                        }
+                                        if (fields.length() == 1) {
+                                            first_miss_pos = indexPath;
+                                        }
+
+                                    }
+
+
+                                } else {
+                                    // not support multiple selection
+                                }
+
+                            } // addjson control enum
+                            else if (addjson.optString("control").equals("action")) {
+
+                                JSONObject action_data = addjson.optJSONObject("data");
+                                int section_count = action_data.optInt("section_count");
+
+                                if (required.equals("true") && action_data != null) {
+
+                                    cancommit = false;
+                                    String mfield = String.format("%d. %@ is missing",fields.length() + 1,addjson.optString("aname"));
+                                    fields.put(mfield);
+
+                                    IndexPath indexPath = get_indexpath1(addjson.optString("name"));
+                                    if (alert) {
+                                        listView.expandGroup(indexPath.section);
+                                    }
+                                    if (fields.length() == 1) {
+                                        first_miss_pos = indexPath;
+                                    }
+
+                                } // required true && action_data
+
+                                for (int i = 0; i < section_count; i++) {
+
+                                    JSONObject sectionjson = action_data.optJSONObject("section_" + i);
+                                    int item_count = sectionjson.optInt("count");
+                                    for (int j = 0; j < item_count; j++) {
+                                        JSONObject itemjson_j = sectionjson.optJSONObject("item_" + j);
+                                        String key_j = itemjson_j.optString("name");
+
+                                        if (key_j == null || key_j.isEmpty()) {
+                                            continue;
+                                        }
+
+                                        if (itemjson_j.optString("control").equals("enum")) {
+
+                                            String single_select_j = itemjson_j.optString("single_select");
+                                            if (single_select_j.equals("true")) {
+
+                                                JSONObject cadejson = itemjson_j.optJSONObject("cadedate");
+                                                int count = cadejson.optInt("count");
+                                                boolean setvalue = false;
+                                                for (int cc = 0; cc < count; cc++) {
+                                                    JSONObject valjson_cc = cadejson.optJSONObject("val_" + cc);
+                                                    if (valjson_cc.optInt("check") == 1) {
+                                                        upparam.put(itemjson_j.optString("name"),valjson_cc.optString("value_id"));
+                                                        setvalue = true;
+                                                        break;
+                                                    } // check
+                                                }
+
+                                                if (itemjson_j.optString("required").equals("true") && setvalue == false) {
+                                                    cancommit = false;
+                                                    String mfield = String.format("%d. %@ is missing",fields.length() + 1,itemjson_j.optString("aname"));
+                                                    fields.put(mfield);
+
+                                                    IndexPath indexPath = get_indexpath1(addjson.optString("name"));
+                                                    if (alert) {
+                                                        listView.expandGroup(indexPath.section);
+                                                    }
+                                                    if (fields.length() == 1) {
+                                                        first_miss_pos = indexPath;
+                                                    }
+                                                }
+
+                                            } // single select true
+                                            else {
+                                                // not support multiple selection
+                                            }
+
+                                        } // enum
+                                        else {
+
+                                            if (itemjson_j.optString("value") != null && !itemjson_j.optString("value").equals("")) {
+                                                upparam.put(itemjson_j.optString("name"),itemjson_j.optString("value"));
+                                            } else {
+
+                                                if (itemjson_j.optString("required").equals("true")) {
+                                                    cancommit = false;
+                                                    String mfield = String.format("%d. %@ is missing",fields.length() + 1,itemjson_j.optString("aname"));
+                                                    fields.put(mfield);
+
+                                                    IndexPath indexPath = get_indexpath1(addjson.optString("name"));
+                                                    if (alert) {
+                                                        listView.expandGroup(indexPath.section);
+                                                    }
+                                                    if (fields.length() == 1) {
+                                                        first_miss_pos = indexPath;
+                                                    }
+                                                }
+
+                                            } // else
+
+                                        } // else
+
+                                        subitem_data data1 = subitem_param_addto_alert(itemjson_j,upparam,alert);
+                                        upparam = data1.params;
+                                        for (int fl = 0; fl < data1.missingfields.length(); fl++) {
+                                            fields.put(data1.missingfields.opt(fl));
+                                        }
+
+                                    } // for j
+
+                                } // for i
+
+                            } // addjson control action
+                            else {
+                                if (addjson.optString("value") != null && !addjson.optString("value").isEmpty()) {
+                                    upparam.put(key,addjson.optString("value"));
+                                } else {
+                                    if (addjson.optString("required").equals("true")) {
+                                        cancommit = false;
+                                        String mfield = String.format("%d. %@ is missing",fields.length() + 1,addjson.optString("aname"));
+                                        fields.put(mfield);
+
+                                        IndexPath indexPath = get_indexpath1(addjson.optString("name"));
+                                        if (alert) {
+                                            listView.expandGroup(indexPath.section);
+                                        }
+                                        if (fields.length() == 1) {
+                                            first_miss_pos = indexPath;
+                                        }
+                                    }
+                                }
+                            }
+                            subitem_data data2 = subitem_param_addto_alert(addjson,upparam,alert);
+                            upparam = data2.params;
+                            for (int fl = 0; fl < data2.missingfields.length(); fl++) {
+                                fields.put(data2.missingfields.opt(fl));
+                            }
+
+                        } // for l
+
+                    } // check == 1 && subjson != null && !active
+
+                } // for k
+
+            } // enum single select
+
+            data.params = upparam;
+            data.missingfields = fields;
+
+            return data;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static class IndexPath {
+        public int section;
+        public int row;
+    }
+
+    public IndexPath first_miss_pos;
+
+    public IndexPath get_indexpath1(String name) {
+        if (first_miss_pos != null) {
+            return first_miss_pos;
+        }
+
+        for (int i = 0; i < content_data_control.length();i++) {
+            JSONArray items = content_data_control.optJSONArray(i);
+            for (int j = 0; j < items.length(); j++) {
+                JSONObject item = items.optJSONObject(j);
+                String item_name = item.optString("name");
+                if (item_name.equals(name)) {
+                    IndexPath indexPath = new IndexPath();
+                    indexPath.section = i;
+                    indexPath.row = j;
+                    return indexPath;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public JSONObject check_cancomit(boolean alert) {
+        first_miss_pos = null;
+        cancommit =  true;
+
+        try {
+
+            JSONArray fields = new JSONArray();
+            JSONObject upparams = new JSONObject();
+
+            int section_count = content_data_control.length();
+            for (int i = 0; i < section_count; i++) {
+
+                JSONArray sectionjson = content_data_control.optJSONArray(i);
+                int item_count = sectionjson.length();
+                for (int j = 0; j < item_count; j++) {
+                    JSONObject itemjson = sectionjson.optJSONObject(j);
+                    String key = itemjson.optString("name");
+                    if (key == null || key.length() == 0) {
+                        continue;
+                    }
+
+                    if (itemjson.optString("control").equals("enum")) {
+                        String single_select = itemjson.optString("single_select");
+                        if (single_select.equals("true")) {
+                            JSONObject cadejson = itemjson.optJSONObject("cadedate");
+                            int count = cadejson.optInt("count");
+                            boolean setvalue = false;
+                            for (int cc = 0; cc < count; cc++) {
+                                JSONObject valjson = cadejson.optJSONObject("val_" + cc);
+                                if (valjson.optInt("check") == 1) {
+                                    upparams.put(itemjson.optString("name"),valjson.optString("value_id"));
+                                    setvalue = true;
+                                    break;
+                                }
+                            } // for cc
+
+                            if (itemjson.optString("required").equals("true") && setvalue == false) {
+                                cancommit = false;
+                                String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                                fields.put(mfield);
+
+                                IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                                if (alert) {
+                                    listView.expandGroup(indexPath.section);
+                                }
+                                if (fields.length() == 1) {
+                                    first_miss_pos = indexPath;
+                                }
+                            }
+
+                        } // single select true
+                        else { // multiple selection
+
+                            JSONArray checked = new JSONArray();
+                            JSONObject cadejson = itemjson.optJSONObject("cadedate");
+                            int count = cadejson.optInt("count");
+                            for (int cc = 0; cc < count; cc++) {
+                                JSONObject valjson = cadejson.optJSONObject("val_" + cc);
+                                if (valjson.optInt("check") == 1) {
+                                    checked.put(valjson.optString("value_id"));
+                                } // check == 1
+                            } // for cc
+                            if (itemjson.optString("required").equals("true") && checked.length() == 0) {
+
+                                cancommit = false;
+                                String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                                fields.put(mfield);
+
+                                IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                                if (alert) {
+                                    listView.expandGroup(indexPath.section);
+                                }
+                                if (fields.length() == 1) {
+                                    first_miss_pos = indexPath;
+                                }
+
+                            } // required && checked.length == 0
+                            else {
+                                String string = checked.join(",");
+                                upparams.put(itemjson.optString("name"),string);
+                            }
+
+                        }
+
+                    } // enum
+                    else if (itemjson.optString("control").equals("action")) {
+
+                        if (itemjson.optString("required").equals("true") && itemjson.opt("data") == null) {
+                            cancommit = false;
+                            String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                            fields.put(mfield);
+
+                            IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                            if (alert) {
+                                listView.expandGroup(indexPath.section);
+                            }
+                            if (fields.length() == 1) {
+                                first_miss_pos = indexPath;
+                            }
+
+                        }
+
+                    } // action
+                    else if (itemjson.optString("control").equals("signature")) {
+
+                        if (itemjson.optString("required").equals("true") && itemjson.opt("value") == null) {
+                            cancommit = false;
+                            String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                            fields.put(mfield);
+
+                            IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                            if (alert) {
+                                listView.expandGroup(indexPath.section);
+                            }
+                            if (fields.length() == 1) {
+                                first_miss_pos = indexPath;
+                            }
+                        }
+
+                    } // signature
+                    else if (itemjson.optString("control").equals("switch")) {
+
+                        String valuestr = itemjson.optString("value");
+                        upparams.put(itemjson.optString("name"),valuestr);
+
+                        String value = itemjson.optString("value");
+                        JSONObject boolitem = null;
+                        JSONObject subjson = null;
+                        if (value.equals("true")) {
+                            boolitem = itemjson.optJSONObject("true");
+                        } else {
+                            boolitem = itemjson.optJSONObject("false");
+                        }
+                        if (boolitem != null) {
+                            subjson = boolitem.optJSONObject("sub_item");
+                        }
+                        if (subjson != null) {
+
+                            int sub_count = subjson.optInt("count");
+                            for (int l = 0; l < sub_count; l++) {
+                                JSONObject modify_item = subjson.optJSONObject("item_" + l);
+                                if (modify_item.optString("value") != null && !modify_item.optString("value").isEmpty()) {
+                                    upparams.put(modify_item.optString("name"),modify_item.optString("value"));
+                                }
+                                else {
+                                    if (modify_item.optString("required").equals("true")) {
+                                        cancommit = false;
+                                        String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                                        fields.put(mfield);
+
+                                        IndexPath indexPath = get_indexpath1(modify_item.optString("name"));
+                                        if (alert) {
+                                            listView.expandGroup(indexPath.section);
+                                        }
+                                        if (fields.length() == 1) {
+                                            first_miss_pos = indexPath;
+                                        }
+                                    }
+                                }
+                            }
+
+                        } // subjson != null
+
+                    } // switch
+                    else if (itemjson.optString("control").equals("img")) {
+
+                        if (itemjson.optString("avalue") != null && !itemjson.optString("avalue").isEmpty()) {
+                            upparams.put(itemjson.optString("name"),itemjson.optString("avalue"));
+                        } else {
+                            if (itemjson.optString("required").equals("true")) {
+                                cancommit = false;
+                                String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                                fields.put(mfield);
+
+                                IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                                if (alert) {
+                                    listView.expandGroup(indexPath.section);
+                                }
+                                if (fields.length() == 1) {
+                                    first_miss_pos = indexPath;
+                                }
+                            }
+                        }
+
+                    } // img
+                    else if (itemjson.optString("control").equals("edit")) {
+
+                        int min_length = itemjson.optInt("min_length");
+                        String check_len_val = itemjson.optString("value");
+                        if (check_len_val.length() < min_length) {
+                            cancommit = false;
+                            String mfield = String.format("%d. %s is too short",fields.length() + 1,itemjson.optString("aname"));
+                            if (check_len_val.length() == 0 && itemjson.optString("required").equals("true")) {
+                                mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+                            }
+                            fields.put(mfield);
+
+                            IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                            if (alert) {
+                                listView.expandGroup(indexPath.section);
+                            }
+                            if (fields.length() == 1) {
+                                first_miss_pos = indexPath;
+                            }
+
+                        } // < min_length
+                        else if (itemjson.optString("value") != null && !itemjson.optString("value").isEmpty()) {
+                            upparams.put(itemjson.optString("name"),itemjson.optString("value"));
+                        }
+                        else {
+                            if (itemjson.optString("required").equals("true")) {
+                                cancommit = false;
+                                String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                                fields.put(mfield);
+
+                                IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                                if (alert) {
+                                    listView.expandGroup(indexPath.section);
+                                }
+                                if (fields.length() == 1) {
+                                    first_miss_pos = indexPath;
+                                }
+                            }
+                        }
+
+                    } // edit
+                    else {
+
+                        if (itemjson.optString("value") != null && !itemjson.optString("value").isEmpty()) {
+                            upparams.put(itemjson.optString("name"),itemjson.optString("value"));
+                        } else {
+                            if (itemjson.optString("required").equals("true")) {
+                                cancommit = false;
+                                String mfield = String.format("%d. %s is missing",fields.length() + 1,itemjson.optString("aname"));
+
+                                fields.put(mfield);
+
+                                IndexPath indexPath = get_indexpath1(itemjson.optString("name"));
+                                if (alert) {
+                                    listView.expandGroup(indexPath.section);
+                                }
+                                if (fields.length() == 1) {
+                                    first_miss_pos = indexPath;
+                                }
+                            }
+                        }
+
+                    }
+
+                } // for j
+
+            } // for i
+
+            if (cancommit == false && alert) {
+
+                String missfields = fields.join("\n");
+                String msg = missfields;
+
+                new AlertDialog.Builder(mCtx)
+                        .setTitle("Warning")
+                        .setMessage(msg)
+                        .setPositiveButton("OK",null)
+                        .show();
+
+                content_data_control = translateChange(content_data_download,changed_data);
+                adapter.notifyDataSetChanged();
+                listView.setSelectedChild(first_miss_pos.section,first_miss_pos.row,true);
+                return upparams;
+
+
+            } else {
+                cancommit = true;
+            }
+            return upparams;
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static int COMMON_EDITOR_CELL_TYPE_ACTION = 0;
+    public static int COMMON_EDITOR_CELL_TYPE_EDIT = 1;
+    public static int COMMON_EDITOR_CELL_TYPE_ENUM = 2;
+    public static int COMMON_EDITOR_CELL_TYPE_IMAGE = 3;
+    public static int COMMON_EDITOR_CELL_TYPE_LABLE = 4;
+    public static int COMMON_EDITOR_CELL_TYPE_MODEL = 5;
+    public static int COMMON_EDITOR_CELL_TYPE_MULTIPLE_ACTION = 6;
+    public static int COMMON_EDITOR_CELL_TYPE_SIGNATURE = 7;
+    public static int COMMON_EDITOR_CELL_TYPE_SWITCH = 8;
+    public static int COMMON_EDITOR_CELL_TYPE_TEXT_VIEW = 9;
+    public static int COMMON_EDITOR_CELL_TYPE_SECTION_HEADER = 10;
+    /**
+     * ExpandListView Adapter
+     * */
+    JSONArray content_data_control;
+    JSONObject content_data_download;
+
+    public class ExpandAdapter extends BaseExpandableListAdapter {
+
+        private Context mCtx;
+
+        public ExpandAdapter(Context ctx) {
+            mCtx = ctx;
+        }
+
+        @Override
+        public int getGroupCount() {
+           if (content_data_control != null) {
+               return content_data_control.length();
+           } else {
+               return 0;
+           }
+        }
+
+        @Override
+        public int getChildrenCount(int groupPosition) {
+            if (content_data_download == null) {
+                return 0;
+            }
+            JSONObject section_json = content_data_download.optJSONObject("section_" + groupPosition);
+            boolean hide = section_json.optBoolean("hide");
+            if (hide) {
+                return 0;
+            } else {
+                JSONArray section = content_data_control.optJSONArray(groupPosition);
+                return section.length();
+            }
+        }
+
+        @Override
+        public Object getGroup(int groupPosition) {
+            if (content_data_control == null) {
+                return null;
+            }
+            JSONArray section = content_data_control.optJSONArray(groupPosition);
+            return section;
+        }
+
+        @Override
+        public Object getChild(int groupPosition, int childPosition) {
+            if (content_data_control == null) {
+                return null;
+            }
+            JSONArray section = content_data_control.optJSONArray(groupPosition);
+            JSONObject item = section.optJSONObject(childPosition);
+            return item;
+        }
+
+        @Override
+        public long getGroupId(int groupPosition) {
+            return groupPosition;
+        }
+
+        @Override
+        public long getChildId(int groupPosition, int childPosition) {
+            return childPosition;
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        @Override
+        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+
+            JSONObject section_json = content_data_download.optJSONObject("section_" + groupPosition);
+
+            CommonEditorSectionHeaderHolder holder;
+            if (convertView == null) {
+                convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_section_header,null);
+                holder = new CommonEditorSectionHeaderHolder(mCtx,convertView);
+            } else {
+                holder = (CommonEditorSectionHeaderHolder)convertView.getTag();
+            }
+            setUpSectionHeaderCellHolder(holder,convertView,section_json,groupPosition,-1);
+            holder.clickSectionHeader(isExpanded);
+
+
+            return convertView;
+        }
+
+        @Override
+        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
+
+            JSONObject item_json = (JSONObject) getChild(groupPosition,childPosition);
+            String control = null;
+            boolean readonly = false;
+            try {
+
+                control = item_json.getString("control");
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+
+            CommonEditorCellHolder holder;
+            if (convertView == null) {
+
+                if (control != null) {
+                    if (control.equals("text_view")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_text_view_cell_small,null);
+                        holder = new CommonEditorTextViewCellHolder(mCtx,convertView);
+                        setUpTextViewCellHolder((CommonEditorTextViewCellHolder) holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("img")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_image_cell_small,null);
+                        holder = new CommonEditorImageCellHolder(mCtx,convertView);
+                        setUpImageCellHolder((CommonEditorImageCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("edit")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_edit_cell_small,null);
+                        holder = new CommonEditorEditCellHolder(mCtx,convertView);
+                        setUpEditCellHolder((CommonEditorEditCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("text")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_label_cell_small,null);
+                        holder = new CommonEditorLabelCellHolder(mCtx,convertView);
+                        setUpLabelCellHolder((CommonEditorLabelCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("action")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_action_cell,null);
+                        holder = new CommonEditorActionCellHolder(mCtx,convertView);
+                        setUpActionCellHolder((CommonEditorActionCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("multi_action")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_multiple_action_cell,null);
+                        holder = new CommonEditorMultipleActionCellHolder(mCtx,convertView);
+                        setUpMultipleActionCellHolder((CommonEditorMultipleActionCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("switch")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_switch_cell_small,null);
+                        holder = new CommonEditorSwitchCellHolder(mCtx,convertView);
+                        setUpSwitchCellHolder((CommonEditorSwitchCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("enum")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_enum_cell_small,null);
+                        holder = new CommonEditorEnumCellHolder(mCtx,convertView);
+                        setUpEnumCellHolder((CommonEditorEnumCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("model")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_model_cell,null);
+                        holder = new CommonEditorModelCellHolder(mCtx,convertView);
+                        setUpModelCellHolder((CommonEditorModelCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("datepicker")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_enum_cell_small,null);
+                        holder = new CommonEditorEnumCellHolder(mCtx,convertView);
+                        setUpDatePickerCellHolder((CommonEditorEnumCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("monthpicker")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_enum_cell_small,null);
+                        holder = new CommonEditorEnumCellHolder(mCtx,convertView);
+                        setUpMonthPickerCellHolder((CommonEditorEnumCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("signature")) {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_signature_cell_small,null);
+                        holder = new CommonEditorSignatureCellHolder(mCtx,convertView);
+                        setUpSignatureCellHolder((CommonEditorSignatureCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else {
+                        convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_edit_cell_small,null);
+                        holder = new CommonEditorEditCellHolder(mCtx,convertView);
+                        setUpEditCellHolder((CommonEditorEditCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    }
+                } else {
+                    convertView = LayoutInflater.from(mCtx).inflate(R.layout.common_editor_edit_cell_small,null);
+                    holder = new CommonEditorEditCellHolder(mCtx,convertView);
+                    setUpEditCellHolder((CommonEditorEditCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+                }
+
+            } else {
+
+                if (control != null) {
+                    if (control.equals("text_view")) {
+                        holder = (CommonEditorTextViewCellHolder)convertView.getTag();
+                        setUpTextViewCellHolder((CommonEditorTextViewCellHolder) holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("img")) {
+                        holder = (CommonEditorImageCellHolder)convertView.getTag();
+                        setUpImageCellHolder((CommonEditorImageCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("edit")) {
+                        holder = (CommonEditorEditCellHolder)convertView.getTag();
+                        setUpEditCellHolder((CommonEditorEditCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("text")) {
+                        holder = (CommonEditorLabelCellHolder)convertView.getTag();
+                        setUpLabelCellHolder((CommonEditorLabelCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("action")) {
+                        holder = (CommonEditorActionCellHolder)convertView.getTag();
+                        setUpActionCellHolder((CommonEditorActionCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("multi_action")) {
+                        holder = (CommonEditorMultipleActionCellHolder)convertView.getTag();
+                        setUpMultipleActionCellHolder((CommonEditorMultipleActionCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("switch")) {
+                        holder = (CommonEditorSwitchCellHolder)convertView.getTag();
+                        setUpSwitchCellHolder((CommonEditorSwitchCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("enum")) {
+                        holder = (CommonEditorEnumCellHolder)convertView.getTag();
+                        setUpEnumCellHolder((CommonEditorEnumCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("model")) {
+                        holder = (CommonEditorModelCellHolder)convertView.getTag();
+                        setUpModelCellHolder((CommonEditorModelCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("datepicker")) {
+                        holder = (CommonEditorEnumCellHolder)convertView.getTag();
+                        setUpDatePickerCellHolder((CommonEditorEnumCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("monthpicker")) {
+                        holder = (CommonEditorEnumCellHolder)convertView.getTag();
+                        setUpMonthPickerCellHolder((CommonEditorEnumCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else if (control.equals("signature")) {
+                        holder = (CommonEditorSignatureCellHolder)convertView.getTag();
+                        setUpSignatureCellHolder((CommonEditorSignatureCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    } else {
+                        holder = (CommonEditorEditCellHolder)convertView.getTag();
+                        setUpEditCellHolder((CommonEditorEditCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                    }
+                } else {
+                    holder = (CommonEditorEditCellHolder)convertView.getTag();
+                    setUpEditCellHolder((CommonEditorEditCellHolder)holder,convertView,item_json,readonly,groupPosition,childPosition);
+
+                }
+
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public boolean isChildSelectable(int groupPosition, int childPosition) {
+            return true;
+        }
+
+        @Override
+        public int getChildTypeCount() {
+
+            return 11;
+        }
+
+        @Override
+        public int getChildType(int groupPosition, int childPosition) {
+            JSONObject item_json = (JSONObject) getChild(groupPosition,childPosition);
+            String control;
+            try {
+                control = item_json.getString("control");
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                return COMMON_EDITOR_CELL_TYPE_EDIT;
+            }
+
+            if (control != null) {
+                if (control.equals("text_view")) {
+                    return COMMON_EDITOR_CELL_TYPE_TEXT_VIEW;
+                } else if (control.equals("img")) {
+                    return COMMON_EDITOR_CELL_TYPE_IMAGE;
+                } else if (control.equals("edit")) {
+                    return COMMON_EDITOR_CELL_TYPE_EDIT;
+                } else if (control.equals("text")) {
+                    return COMMON_EDITOR_CELL_TYPE_LABLE;
+                } else if (control.equals("action")) {
+                    return COMMON_EDITOR_CELL_TYPE_ACTION;
+                } else if (control.equals("multi_action")) {
+                    return COMMON_EDITOR_CELL_TYPE_MULTIPLE_ACTION;
+                } else if (control.equals("switch")) {
+                    return COMMON_EDITOR_CELL_TYPE_SWITCH;
+                } else if (control.equals("enum")) {
+                    return COMMON_EDITOR_CELL_TYPE_ENUM;
+                } else if (control.equals("model")) {
+                    return COMMON_EDITOR_CELL_TYPE_MODEL;
+                } else if (control.equals("datepicker")) {
+                    return COMMON_EDITOR_CELL_TYPE_ENUM;
+                } else if (control.equals("monthpicker")) {
+                    return COMMON_EDITOR_CELL_TYPE_ENUM;
+                } else if (control.equals("signature")) {
+                    return COMMON_EDITOR_CELL_TYPE_SIGNATURE;
+                } else if (control.equals("header")){
+                    return COMMON_EDITOR_CELL_TYPE_SECTION_HEADER;
+                } else {
+                    return COMMON_EDITOR_CELL_TYPE_EDIT;
+                }
+            } else {
+                return COMMON_EDITOR_CELL_TYPE_EDIT;
+            }
+        }
+    }
+
+    public class ListChildViewClickListener implements ExpandableListView.OnChildClickListener {
+
+        String requesturl = null;
+        @Override
+        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
+            try {
+
+                Intent intent = null;
+                int request_code = -1;
+
+                boolean readonly = content_data_download.optBoolean("readonly");
+
+                JSONObject item_json = content_data_control.optJSONArray(groupPosition).optJSONObject(childPosition);
+                String control = item_json.optString("control");
+                if (control.equals("enum")) {
+                    int disable = item_json.optInt("disable");
+                    if (disable == 1 || readonly) {
+                        return false;
+                    }
+                    JSONObject cadedate_json = item_json.optJSONObject("cadedate");
+                    String single_select = item_json.optString("single_select");
+                    String title = item_json.optString("aname");
+                    int max_select = item_json.optInt("max");
+                    boolean singleSelect = single_select.toLowerCase().equals("true");
+                    String cadedate_str = cadedate_json.toString();
+                    intent = new EnumSlectActivity.Builder().build(mCtx,title,max_select,groupPosition,childPosition,cadedate_str,singleSelect,true);
+                    request_code = 10;
+
+                } // enum
+                else if (control.equals("action")) {
+
+                    String value = item_json.optString("value");
+                    if (value.equals("new_addr")) {
+                        AddressEditorActivity.Builder builder = new AddressEditorActivity.Builder();
+                        intent = builder.build(mCtx,URL_REMOTE,requesturl,null,null,groupPosition,childPosition);
+                        request_code = 2;
+
+                    } // new addr
+                    else if (value.equals("credit_card")) {
+
+                        JSONObject data = item_json.optJSONObject("data");
+                        int url_type;
+                        JSONObject download_data;
+                        if (data != null) {
+                            download_data = data;
+                            url_type = URL_NONE;
+                            requesturl = null;
+                        } else {
+                            download_data = null;
+                            url_type = URL_REMOTE;
+                            requesturl = "";
+                        }
+                        intent = new CreditCardEditorActivity.Builder().build(mCtx,url_type,requesturl,Application.order_code,null,null,download_data,groupPosition,childPosition);
+                        request_code = 3;
+                    }
+                    else if (value.equals("Sales_Order_Freight_Bill_To")) {
+
+                        request_code = 4;
+                        intent = new ContactListActivity.Builder().build(mCtx,null,null,value,true,groupPosition,childPosition);
+
+                    }
+                    else if (value.equals("Sales_Order_Ship_From")) {
+
+                        request_code = 5;
+                        intent = new ContactListActivity.Builder().build(mCtx,null,null,value,true,groupPosition,childPosition);
+
+                    }
+                    else if (value.equals("Sales_Order_Customer")) {
+
+                        request_code = 6;
+                        intent = new ContactListActivity.Builder().build(mCtx,null,null,value,true,groupPosition,childPosition);
+
+                    }
+                    else if (value.equals("Sales_Order_Merchandise_Bill_To")) {
+
+                        request_code = 7;
+                        intent = new ContactListActivity.Builder().build(mCtx,null,null,value,true,groupPosition,childPosition);
+
+                    }
+                    else if (value.equals("Contact_Return_To")) {
+
+                        request_code = 8;
+                        intent = new ContactListActivity.Builder().build(mCtx,null,null,value,true,groupPosition,childPosition);
+
+                    }
+                    else if (value.equals("Sales_Order_Ship_To")) {
+
+                        request_code = 9;
+                        intent = new ContactListActivity.Builder().build(mCtx,null,null,value,true,groupPosition,childPosition);
+                    }
+
+                } // action
+                else if (control.equals("datepicker")) {
+
+                    request_code = 11;
+
+                    String value = item_json.optString("value");
+                    String type = item_json.optString("type");
+
+                    SimpleDateFormat dateFormatter = new SimpleDateFormat();
+                    int pickerMode = 0;
+                    if (type.toLowerCase().equals("date")) {
+                        pickerMode = 0; // Date
+                        dateFormatter.applyPattern("yyyy/MM/dd");
+                    }
+                    else if (type.toLowerCase().equals("time")) {
+                        pickerMode = 1; // time
+                        dateFormatter.applyPattern("HH:mm:ss");
+                    }
+                    else {
+                        pickerMode = 2; // date and time
+                        dateFormatter.applyPattern("yyyy/MM/dd HH:mm:ss");
+                    }
+
+                    Date date = dateFormatter.parse(value);
+                    intent = new DatePickerActivity.Builder().build(mCtx,date,dateFormatter,pickerMode,value,groupPosition,childPosition);
+
+
+                } // date picker
+                else if (control.equals("monthpicker")) {
+
+                    request_code = 12;
+                    String value = item_json.optString("value");
+                    if (value == null || value.isEmpty()) {
+                        value = "1/2017";
+                    }
+
+
+                    intent = new MonthPickerActivity.Builder().build(mCtx,value,groupPosition,childPosition);
+
+                } // month picker
+                else if (control.equals("signature")) {
+
+                    request_code = 13;
+                    intent = new SignatureActivity.Builder().build(mCtx,groupPosition,childPosition);
+
+                }
+
+                if (intent != null) {
+                    startActivityForResult(intent,request_code);
+                }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return false;
+        }
+    }
+
+    public boolean cancommit = false;
+
+
+    public void setUpTextViewCellHolder(CommonEditorTextViewCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+        String control = null;
+        String required = null;
+        String title = null;
+        String value = null;
+        String align = "";
+        int capital = 0;
+        int disable = 0;
+
+        // 重用时先保存
+        if (holder.text_view.getText().length() > 0) {
+            editTextEndEditing(holder.text_view,false,holder.group,holder.child);
+        }
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(null);
+        holder.text_view.setText(null);
+
+        try {
+            control = item_json.optString("control");
+            required = item_json.optString("required");
+            title = item_json.optString("aname");
+            value = item_json.optString("value");
+            align = item_json.optString("align");
+            capital = item_json.optInt("capital");
+            disable = item_json.optInt("disable");
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        if (align.equals("right")) {
+            holder.text_view.setGravity(TOP | RIGHT);
+        } else {
+            holder.text_view.setGravity(TOP | LEFT);
+        }
+
+        /**设置大写模式*/
+        switch (capital) {
+            case 1: {
+                holder.text_view.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
+            }
+            break;
+            case 2: {
+                holder.text_view.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE  | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
+            }
+            break;
+            case 3: {
+                holder.text_view.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE  | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
+            }
+            break;
+            default: {
+                holder.text_view.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE  | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
+            }
+            break;
+        }
+
+        if (disable == 1 || readonly) {
+            holder.text_view.setEnabled(false);
+            holder.text_view.setTextColor(Color.LTGRAY);
+        } else {
+            holder.text_view.setEnabled(true);
+            holder.text_view.setTextColor(Color.BLACK);
+        }
+
+        holder.title_lb.setText(title);
+
+        holder.text_view.setTag(group + "_" + child + "_" + "TextView");
+        holder.text_view.setText(value);
+        holder.text_view.addTextChangedListener(new TextViewTextWatcher(mCtx,holder.text_view,group,child));
+        holder.text_view.setOnFocusChangeListener(new EditTextFocusListener(mCtx,holder.text_view,group,child));
+
+
+        if (required.equals("true")) {
+            holder.startMark.setVisibility(View.VISIBLE);
+        } else {
+            holder.startMark.setVisibility(View.INVISIBLE);
+        }
+
+        if (cancommit == false && required.equals("true") && (value == null || value.length() == 0)) {
+            // 阴影 red
+        } else {
+            // 无阴影
+        }
+
+    }
+
+    public void setUpImageCellHolder(CommonEditorImageCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = null;
+        String value = null;
+        String img_url_0 = null;
+        String img_url_1 = null;
+        String img_url_2 = null;
+        String img_url_up_0 = null;
+        String img_url_up_1 = null;
+        String img_url_up_2 = null;
+        int disable = 0;
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(null);
+        holder.desc_lb.setText(null);
+        holder.img_btn_0.setImageBitmap(null);
+        holder.img_btn_1.setImageBitmap(null);
+        holder.img_btn_2.setImageBitmap(null);
+
+//        LinearLayout.LayoutParams layoutParams0 = (LinearLayout.LayoutParams)holder.img_btn_0.getLayoutParams();
+//        layoutParams0.height = layoutParams0.width;
+//        holder.img_btn_0.setLayoutParams(layoutParams0);
+//
+//        LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams)holder.img_btn_1.getLayoutParams();
+//        layoutParams1.height = layoutParams1.width;
+//        holder.img_btn_1.setLayoutParams(layoutParams1);
+//
+//        LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams)holder.img_btn_2.getLayoutParams();
+//        layoutParams2.height = layoutParams2.width;
+//        holder.img_btn_2.setLayoutParams(layoutParams2);
+
+        try {
+
+            title = item_json.optString("aname");
+            value = item_json.optString("value");
+            disable = item_json.optInt("disable");
+            img_url_0 = item_json.optString("img_url_0");
+            img_url_up_0 = item_json.optString("img_url_aname_0");
+            img_url_1 = item_json.optString("img_url_1");
+            img_url_up_1 = item_json.optString("img_url_aname_1");
+            img_url_2 = item_json.optString("img_url_2");
+            img_url_up_2 = item_json.optString("img_url_aname_2");
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        if (disable == 1 || readonly) {
+            holder.editable = false;
+        } else {
+            holder.editable = true;
+        }
+
+        holder.title_lb.setText(title);
+        holder.desc_lb.setText(value);
+
+        Bitmap placeHolder = BitmapFactory.decodeResource(getResources(),R.drawable.not_found);
+        if (img_url_0 != null && !img_url_0.isEmpty()) {
+            Bitmap bmp0 = Utils.loadCacheImage(img_url_up_0,placeHolder);
+            if (bmp0 != null) {
+                holder.setImage0(img_url_up_0,bmp0);
+            } else {
+                // 异步记载数据
+                loadImageForPosition(group,child,0,img_url_up_0);
+            }
+        }
+
+        if (img_url_1 != null && !img_url_1.isEmpty()) {
+            Bitmap bmp1 = Utils.loadCacheImage(img_url_up_1,placeHolder);
+            if (bmp1 != null) {
+                holder.setImage1(img_url_up_1,bmp1);
+            } else {
+                // 异步记载数据
+                loadImageForPosition(group,child,1,img_url_up_1);
+            }
+        }
+
+        if (img_url_2 != null && !img_url_2.isEmpty()) {
+            Bitmap bmp2 = Utils.loadCacheImage(img_url_up_2,placeHolder);
+            if (bmp2 != null) {
+                holder.setImage2(img_url_up_2,bmp2);
+            } else {
+                // 异步记载数据
+                loadImageForPosition(group,child,2,img_url_up_2);
+            }
+        }
+
+    }
+
+    private void loadImageForPosition(int group, int child, int item_tag, final String path) {
+
+        return;
+
+//        if (path == null || path.isEmpty()) {
+//            return;
+//        }
+//        new Thread(new Runnable() {
+//            @Override
+//            public void run() {
+//                HttpURLConnection cnn = null;
+//                Bitmap bitmap = null;
+//                try {
+//                    URL url = new URL(path);
+//                    cnn = (HttpURLConnection)url.openConnection();
+//                    cnn.setRequestMethod("GET");
+//                    cnn.setUseCaches(false);
+//                    cnn.setConnectTimeout(1500);
+//                    cnn.setReadTimeout(1500);
+//                    bitmap = BitmapFactory.decodeStream(cnn.getInputStream());
+//                    if (bitmap == null) {
+//                        // 缓存not found
+//                        bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.not_found);
+//                    }
+//
+//
+//                } catch (IOException e) {
+//                    e.printStackTrace();
+//
+//                    bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.not_found);
+//
+//                } finally {
+//                    if (cnn != null) {
+//                        cnn.disconnect();
+//                    }
+//                    if (bitmap == null) {
+//                        bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.not_found);
+//                    }
+//                    Utils.cacheImage(path,bitmap);
+//                    // 更新数据,刷新行
+//                    runOnUiThread(new Runnable() {
+//                        @Override
+//                        public void run() {
+//                            adapter.notifyDataSetChanged();
+//                        }
+//                    });
+//                }
+//            }
+//        }).start();
+    }
+
+    public void setUpEditCellHolder(final CommonEditorEditCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+        String title = null;
+        String value = null;
+        String align = null;
+        int capital = 0;
+        int disable = 0;
+        String keyboard = null;
+        String required = null;
+
+        // 重用时先保存
+        if (holder.text_field.getText().length() > 0) {
+            editTextEndEditing(holder.text_field,true,holder.group,holder.child);
+        }
+        holder.group = group;
+        holder.child = child;
+        holder.name_lb.setText(null);
+        holder.text_field.setText(null);
+
+        try {
+
+            required = item_json.optString("required");
+            title = item_json.optString("aname");
+            value = item_json.optString("value");
+            align = item_json.optString("align");
+            capital = item_json.optInt("capital");
+            disable = item_json.optInt("disable");
+            keyboard = item_json.optString("keyboard");
+
+            if (!keyboard.equals("number") && !keyboard.equals("int")) {
+                holder.text_field.setFilters(new InputFilter[]{});
+            } else {
+                int lenght = item_json.optInt("length");
+                holder.text_field.setFilters(new InputFilter[]{new InputFilter.LengthFilter(lenght)});
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        if (align != null && align.equals("right")) {
+            holder.text_field.setGravity(CENTER_VERTICAL | RIGHT);
+        } else {
+            holder.text_field.setGravity(CENTER_VERTICAL | LEFT);
+        }
+
+        int inputType = 0;
+        /**设置大写模式*/
+        switch (capital) {
+            case 1: {
+                inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS;
+            }
+            break;
+            case 2: {
+                inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES;
+            }
+            break;
+            case 3: {
+                inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS;
+            }
+            break;
+            default: {
+                inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS;
+            }
+            break;
+        }
+
+        if (keyboard != null) {
+            if (keyboard.equals("number")) {
+                inputType |= EditorInfo.TYPE_CLASS_NUMBER;
+            } else if (keyboard.equals("email")) {
+                inputType |= EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+            } else if (keyboard.equals("phone")) {
+                inputType |= EditorInfo.TYPE_CLASS_PHONE;
+            } else {
+                inputType |= EditorInfo.TYPE_CLASS_TEXT;
+            }
+        }
+
+        holder.text_field.setInputType(inputType);
+
+        if (disable == 1 || readonly) {
+            holder.text_field.setEnabled(false);
+            holder.text_field.setTextColor(Color.LTGRAY);
+        } else {
+            holder.text_field.setEnabled(true);
+            holder.text_field.setTextColor(Color.BLACK);
+        }
+
+        holder.name_lb.setText(title);
+
+        holder.text_field.setTag(group + "_" + child + "_" + "TextFiled");
+        holder.text_field.setText(value);
+        holder.text_field.addTextChangedListener(new TextFieldTextWatcher(mCtx,holder.text_field,group,child));
+        holder.text_field.setOnFocusChangeListener(new EditTextFocusListener(mCtx,holder.text_field,group,child));
+
+
+
+
+        if (required != null && required.equals("true")) {
+            holder.startMark.setVisibility(View.VISIBLE);
+        } else {
+            holder.startMark.setVisibility(View.INVISIBLE);
+        }
+
+        if (cancommit == false && required.equals("true") && (value == null || value.length() == 0)) {
+            // 阴影 red
+        } else {
+            // 无阴影
+        }
+
+
+
+
+    }
+
+    private boolean can_see_price = true;
+    private boolean price_hidden = false;
+    public void setUpLabelCellHolder(CommonEditorLabelCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = null;
+        String value = null;
+        String align = null;
+        String color = null;
+        String type = null;
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(null);
+        holder.value_lb.setText(null);
+
+        try {
+
+            title = item_json.optString("aname");
+            value = item_json.optString("value");
+            align = item_json.optString("align");
+            color = item_json.optString("color");
+            type = item_json.optString("type");
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        if (align.equals("right")) {
+            holder.value_lb.setGravity(CENTER_VERTICAL | RIGHT);
+        } else {
+            holder.value_lb.setGravity(CENTER_VERTICAL | LEFT);
+        }
+
+        if (type.equals("price")) {
+            if (can_see_price && price_hidden == false) {
+
+            } else {
+                value = null;
+            }
+        }
+
+        if (color.toLowerCase().equals("red")) {
+            holder.value_lb.setTextColor(Color.RED);
+        } else {
+            holder.value_lb.setTextColor(Color.BLACK);
+        }
+
+        holder.title_lb.setText(title);
+        holder.value_lb.setText(value);
+
+    }
+
+
+    public void setUpActionCellHolder(CommonEditorActionCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = null;
+        String value = null;
+        String required = null;
+        JSONObject data = null;
+
+        holder.group = group;
+        holder.child = child;
+        holder.action_lb.setText(null);
+
+        try {
+            title = item_json.optString("aname");
+            value = item_json.optString("value");
+            required = item_json.optString("required");
+            data = item_json.optJSONObject("data");
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        if (required.equals("true")) {
+            title = title + "*";
+        }
+
+        holder.action_lb.setText(title);
+        holder.action_code = value;
+
+        if (cancommit && required.equals("true") && data == null) {
+            // Shadow red
+        } else {
+            // no shadow
+        }
+
+    }
+
+    public void setUpMultipleActionCellHolder(CommonEditorMultipleActionCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        int count = 0;
+
+        holder.group = group;
+        holder.child = child;
+
+        try {
+            count = item_json.optInt("count");
+            for (int i = 0; i < count; i++) {
+                JSONObject sub_action = item_json.optJSONObject("item_" + i);
+                String title = sub_action.optString("aname");
+                Button btn = null;
+                switch (i) {
+                    case 0: {
+                        btn = holder.btn0;
+                    }
+                    break;
+                    case 1: {
+                        btn = holder.btn1;
+                    }
+                    break;
+                    case 2: {
+                        btn = holder.btn2;
+                    }
+                    break;
+                    case 3: {
+                        btn = holder.btn3;
+                    }
+                    break;
+                }
+                if (btn != null) {
+                    btn.setText(title);
+                    btn.setOnClickListener(multipleActionClickListener);
+                    btn.setVisibility(View.VISIBLE);
+                    btn.setTag(group + "_" + child + "_" + i);
+                }
+            }
+            if (count < 4) {
+                holder.btn3.setVisibility(View.INVISIBLE);
+            }
+            if (count < 3) {
+                holder.btn2.setVisibility(View.INVISIBLE);
+            }
+            if (count < 2) {
+                holder.btn1.setVisibility(View.INVISIBLE);
+            }
+            if (count < 1) {
+                holder.btn0.setVisibility(View.INVISIBLE);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public void setUpSwitchCellHolder(CommonEditorSwitchCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = null;
+        String value = null;
+        String required = null;
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(null);
+        holder.aSwitch.setTag(group + "_" + child + "_" + "switch");
+        try {
+
+            title = item_json.optString("aname");
+            value = item_json.optString("value");
+            required = item_json.optString("required");
+
+            holder.title_lb.setText(title);
+
+            if (required.equals("true")) {
+                holder.startMark.setVisibility(View.VISIBLE);
+            } else {
+                holder.startMark.setVisibility(View.INVISIBLE);
+            }
+
+
+            holder.aSwitch.setOnCheckedChangeListener(null);
+            if (value.toLowerCase().equals("true")) {
+                holder.aSwitch.setChecked(true);
+            } else {
+                holder.aSwitch.setChecked(false);
+            }
+            holder.aSwitch.setOnCheckedChangeListener(new SwitchCheckListener());
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public void setUpEnumCellHolder(CommonEditorEnumCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+        String title = null;
+        String value = "";
+        JSONObject cadedate_json = null;
+        int disable = 0;
+        String align = null;
+        String required = null;
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(null);
+        holder.value_lb.setText(null);
+
+        try {
+
+            title = item_json.optString("aname");
+            cadedate_json = item_json.optJSONObject("cadedate");
+            disable = item_json.optInt("disable");
+            align = item_json.optString("align");
+            required = item_json.optString("required");
+
+            if (disable == 1 && readonly) {
+                holder.value_lb.setTextColor(Color.LTGRAY);
+            } else {
+                holder.value_lb.setTextColor(Color.BLACK);
+            }
+
+            if (align != null && align.equals("right")) {
+                holder.value_lb.setGravity(CENTER_VERTICAL | RIGHT);
+            } else {
+                holder.value_lb.setGravity(CENTER_VERTICAL | LEFT);
+            }
+
+            int count = cadedate_json.optInt("count");
+            for (int i = 0; i < count; i++) {
+                JSONObject val_json = cadedate_json.optJSONObject("val_" + i);
+                if (val_json != null) {
+                    int check = val_json.optInt("check");
+                    if (check == 1) {
+                        value += val_json.getString("value") + " | ";
+                    }
+                }
+            }
+            if (value.length() > 1) {
+                value = value.substring(0,value.length() - 3);
+            }
+
+            holder.value_lb.setText(value);
+            holder.title_lb.setText(title);
+
+            if (required.equals("true")) {
+                holder.startMark.setVisibility(View.VISIBLE);
+            } else {
+                holder.startMark.setVisibility(View.INVISIBLE);
+            }
+
+
+            if (cancommit == false && required.equals("true") && (value == null || value.length() == 0)) {
+                // 阴影 red
+            } else {
+                // 无阴影
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public void setUpModelCellHolder(CommonEditorModelCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+
+        holder.group = group;
+        holder.child = child;
+        holder.model_img_btn.setImageBitmap(null);
+        holder.desc_lb.setText(null);
+        holder.master_pack_lb.setText(null);
+        holder.old_price_lb.setText(null);
+        holder.discount_lb.setText(null);
+        holder.unit_price_lb.setText(null);
+        holder.discount_lb.setText(null);
+        holder.bundle_btn.setText(null);
+        holder.total_price_lb.setText(null);
+
+        try {
+            int count = item_json.optInt("count");
+            JSONObject combine_json = item_json.optJSONObject("combine");
+            holder.bundle_item = combine_json;
+            double dprice = 0.0f;
+            if (holder.bundle_item != null) {
+                int citem = 0;
+                int bcount = holder.bundle_item.optInt("count");
+                for (int bc = 0; bc < bcount; bc++) {
+                    JSONObject bitem = holder.bundle_item.optJSONObject("item_" + bc);
+                    int modulus = bitem.optInt("modulus");
+                    citem += modulus;
+                    double uprice = bitem.optDouble("unit_price");
+                    dprice += uprice * modulus;
+                }
+                if (citem == 1) {
+                    holder.bundle_btn.setText(String.format("%d bundle item with price of $ %.2f",citem,dprice));
+                } else {
+                    holder.bundle_btn.setText(String.format("%d bundle items with price of $ %.2f",citem,dprice));
+                }
+                holder.bundle_btn.setVisibility(View.VISIBLE);
+            } else {
+                holder.bundle_btn.setVisibility(View.INVISIBLE);
+            }
+
+            String availability = item_json.optString("quantity_available");
+            String available_str = "Available Now";
+            if (isNumber(availability) && Integer.valueOf(availability) > 0) {
+                available_str = String.format("Available: %s",availability);
+            } else {
+                available_str = "Available: In Production";
+            }
+            holder.count_lb.setText(available_str);
+
+            String img_url = item_json.optString("img_url");
+            String description = item_json.optString("description");
+            double unitprice = item_json.optDouble("unit_price");
+            int stockUom = item_json.optInt("stockUom");
+
+            double discount = 0.0;
+            String dis_str = item_json.optString("discount");
+            if (dis_str == null || dis_str.isEmpty()) {
+                discount = 0.0;
+            } else {
+                discount = Double.valueOf(dis_str);
+            }
+            String discount_str = String.format("%s%% off",floatFormat(discount));
+
+            String oldprice = String.format("%.2f",unitprice);
+            String new_unit_price = "";
+            if (dprice > 0) {
+                new_unit_price = String.format("%.2f+%.2f",unitprice* (1.0-discount/100),dprice);
+            } else {
+                new_unit_price = String.format("%.2f",unitprice* (1.0-discount/100));
+            }
+            String totalprice = String.format("%.2f",(unitprice* (1.0-discount/100)+dprice)*count);
+
+            if (can_see_price ==true && price_hidden == false) {
+
+            } else {
+                oldprice = null;
+                new_unit_price = null;
+                totalprice = null;
+            }
+
+            holder.discount_lb.setText(discount_str);
+            holder.old_price_lb.setText(oldprice);
+            holder.master_pack_lb.setText(String.format("Sold in QTY of:%d", stockUom));
+
+            boolean isfree = item_json.optBoolean("is_free");
+
+            if (isfree) {
+                holder.old_price_lb.setVisibility(View.VISIBLE);
+                holder.old_price_lb.setTextColor(Color.RED);
+                holder.old_price_lb.setText("Free");
+                holder.discount_lb.setVisibility(View.INVISIBLE);
+                // old_price_lb.hideline = true
+            } else {
+                holder.old_price_lb.setTextColor(Color.BLACK);
+                // old_price_lb.hideline = false
+                if (discount == 0) {
+                    holder.old_price_lb.setVisibility(View.INVISIBLE);
+                    holder.discount_lb.setVisibility(View.INVISIBLE);
+                } else {
+                    holder.old_price_lb.setVisibility(View.VISIBLE);
+                    holder.discount_lb.setVisibility(View.VISIBLE);
+                }
+            }
+
+            holder.desc_lb.setText(description);
+            holder.count_lb.setText(String.format("x %d",count));
+            holder.total_price_lb.setText(totalprice);
+            holder.unit_price_lb.setText(new_unit_price);
+
+            img_url = "http://img.gank.io/6ade6383-bc8e-40e4-9919-605901ad0ca5?imageView2/0/w/100";
+            Bitmap placeHolder = BitmapFactory.decodeResource(getResources(),R.drawable.not_found);
+            Bitmap bmp = Utils.loadCacheImage(img_url,placeHolder);
+            if (bmp != null) {
+                holder.model_img_btn.setImageBitmap(bmp);
+            } else {
+                // 异步记载数据
+                loadImageForPosition(group,child,0,img_url);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+    /**
+     * 利用正则表达式判断字符串是否是数字
+     * @param str
+     * @return
+     */
+    public boolean isNumber(String str){
+        Pattern pattern = Pattern.compile("[0-9]*");
+        Matcher isNum = pattern.matcher(str);
+        if( !isNum.matches() ){
+            return false;
+        }
+        return true;
+    }
+
+    private String floatFormat(double value) {
+
+        if (Math.IEEEremainder(value, 1)==0)
+        {
+
+            return String.format("%.0f",value);
+
+        } else if (Math.IEEEremainder(value*10, 1)==0)
+        {
+
+            return String.format("%.1f",value);
+
+        }
+        else if (Math.IEEEremainder(value*100, 1)==0)
+        {
+
+            return String.format("%.2f",value);
+
+        }
+        else if (Math.IEEEremainder(value*1000, 1)==0)
+        {
+
+            return String.format("%.3f",value);
+
+        }
+        else
+        {
+
+            return String.format("%.4f",value);
+
+
+        }
+    }
+
+    public void setUpDatePickerCellHolder(CommonEditorEnumCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = item_json.optString("aname");
+        String value = item_json.optString("value");
+        String required = item_json.optString("required");
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(title);
+        holder.value_lb.setText(value);
+
+        if (required.equals("true")) {
+            holder.startMark.setVisibility(View.VISIBLE);
+        } else {
+            holder.startMark.setVisibility(View.INVISIBLE);
+        }
+
+        if (cancommit == false && required.equals("true") && (value == null || value.length() == 0)) {
+            // red shadow
+        } else {
+            // no shadow
+        }
+
+    }
+
+    public void setUpMonthPickerCellHolder(CommonEditorEnumCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = item_json.optString("aname");
+        String value = item_json.optString("value");
+        String required = item_json.optString("required");
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(title);
+        holder.value_lb.setText(value);
+
+        if (required.equals("true")) {
+            holder.startMark.setVisibility(View.VISIBLE);
+        } else {
+            holder.startMark.setVisibility(View.INVISIBLE);
+        }
+
+        if (cancommit == false && required.equals("true") && (value == null || value.length() == 0)) {
+            // red shadow
+        } else {
+            // no shadow
+        }
+
+    }
+
+    public void setUpSignatureCellHolder(CommonEditorSignatureCellHolder holder, View cell, JSONObject item_json, boolean readonly, int group, int child) {
+
+        String title = item_json.optString("aname");
+        String img_url = item_json.optString("avalue");
+        String required = item_json.optString("required");
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(title);
+
+        if (required.equals("true")) {
+            holder.startMark.setVisibility(View.VISIBLE);
+        } else {
+            holder.startMark.setVisibility(View.INVISIBLE);
+        }
+        Bitmap placeHolder = BitmapFactory.decodeResource(getResources(),R.drawable.not_found);
+        if (img_url != null && !img_url.isEmpty()) {
+            Bitmap bmp = Utils.loadCacheImage(img_url,placeHolder);
+            if (bmp != null) {
+                holder.signature_iv.setImageBitmap(bmp);
+            } else {
+                // 异步记载数据
+                loadImageForPosition(group,child,2,img_url);
+            }
+        }
+    }
+
+    public void setUpSectionHeaderCellHolder(CommonEditorSectionHeaderHolder holder, View cell, JSONObject item_json, int group, int child) {
+        String title = item_json.optString("title");
+        boolean hide = item_json.optBoolean("hide");
+        boolean hideControlBtn = item_json.optBoolean("hideControlBtn");
+
+        holder.group = group;
+        holder.child = child;
+        holder.title_lb.setText(title);
+        holder.setShow(!hide);
+        holder.hideControlBtn(hideControlBtn);
+    }
+
+    private Context mCtx = this;
+
+    /**Month Picker*/
+    public void MPValueChanged(String value,int group,int child) {
+
+        try {
+
+            JSONObject section_json = null;
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+
+            String subid = item_json.optString("subid");
+            item_json.put("value",value);
+            if (subid == null || subid.isEmpty()) {
+
+                section_json = content_data_download.optJSONObject("section_" + group);
+                int count = 0;
+                count = section_json.optInt("count");
+                for (int i = 0; i < count; i++) {
+                    JSONObject olditem = section_json.optJSONObject("item_" + i);
+                    if (olditem.optString("name").equals(item_json.optString("name"))) {
+                        section_json.put("item_" + i,item_json);
+                    }
+                }
+
+            } else {
+
+                String[] idarr = subid.split("_");
+                int section = Integer.valueOf(idarr[0]);
+                int item = Integer.valueOf(idarr[1]);
+
+                section_json = content_data_download.optJSONObject("section_" + section);
+                JSONObject olditem = section_json.optJSONObject("item_" + item);
+                String control_type = olditem.optString("control");
+
+                if (control_type.equals("enum")) {
+                    item_json = enum_subitem_changed(olditem,idarr,item_json,2);
+                } else if (control_type.equals("switch")){
+                    item_json = switch_subitem_changed(olditem,idarr,item_json,2);
+                }
+                item_json.put("dirty","true");
+                section_json.put("item_" + item,item_json);
+            }
+
+            content_data_download.put("section_" + group,section_json);
+            content_data_control = translateChange(content_data_download,changed_data);
+
+            adapter.notifyDataSetChanged();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**Image Change*/
+    public void imgIsChanged(String url_down, String url_up, int group, int child, int index, String url_index) {
+
+        try {
+
+            JSONObject section_json = null;
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+            int refresh = item_json.optInt("refresh");
+            String refresh_trigger = item_json.optString("name");
+            String subid = item_json.optString("subid");
+            item_json.put("img_url_" + index,url_down);
+            item_json.put("avalue",url_up);
+            item_json.put("img_url_aname_" + index,url_index);
+            item_json.put("dirty","true");
+            if (subid == null || subid.isEmpty()) {
+
+                section_json = content_data_download.optJSONObject("section_" + group);
+                int count = 0;
+                count = section_json.optInt("count");
+                for (int i = 0; i < count; i++) {
+                    JSONObject olditem = section_json.optJSONObject("item_" + i);
+                    if (olditem.optString("name").equals(item_json.optString("name"))) {
+                        section_json.put("item_" + i,item_json);
+                    }
+                }
+
+            } else {
+
+                String[] idarr = subid.split("_");
+                int section = Integer.valueOf(idarr[0]);
+                int item = Integer.valueOf(idarr[1]);
+
+                section_json = content_data_download.optJSONObject("section_" + section);
+                JSONObject olditem = section_json.optJSONObject("item_" + item);
+                item_json = enum_subitem_changed(olditem,idarr,item_json,2);
+                section_json.put("item_" + item,item_json);
+
+            }
+
+            content_data_download.put("section_" + group,section_json);
+            content_data_control = translateChange(content_data_download,changed_data);
+
+            if (refresh == 1) {
+                refresh(refresh_trigger);
+            }
+
+            adapter.notifyDataSetChanged();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+    /**Switch Check Listener**/
+    public class SwitchCheckListener implements CompoundButton.OnCheckedChangeListener {
+
+        @Override
+        public void onCheckedChanged(CompoundButton v, boolean isChecked) {
+            Switch aSwitch = (Switch)v;
+
+            String[] tag_arr = ((String) v.getTag()).split("_");
+            int group =  Integer.valueOf(tag_arr[0]);
+            int child = Integer.valueOf(tag_arr[1]);
+
+            JSONObject section_json = null;
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+
+            int refresh = item_json.optInt("refresh");
+            String refresh_trigger = item_json.optString("name");
+            String subid = item_json.optString("subid");
+            String check = "false";
+
+            if (isChecked) {
+                check = "true";
+            }
+
+            try {
+
+                item_json.put("dirty","true");
+                item_json.put("value",check);
+
+                if (subid == null || subid.isEmpty()) {
+                    section_json = content_data_download.optJSONObject("section_" + group);
+                    int count = 0;
+                    count = section_json.optInt("count");
+                    for (int i = 0; i < count; i++) {
+                        JSONObject olditem = section_json.optJSONObject("item_" + i);
+                        if (olditem.optString("name").equals(item_json.optString("name"))) {
+                            section_json.put("item_" + i,item_json);
+                        }
+                    }
+                } else {
+                    String[] idarr = subid.split("_");
+                    int section = Integer.valueOf(idarr[0]);
+                    int item = Integer.valueOf(idarr[1]);
+
+                    section_json = content_data_download.optJSONObject("section_" + section);
+                    JSONObject olditem = section_json.optJSONObject("item_" + item);
+                    item_json = enum_subitem_changed(olditem,idarr,item_json,2);
+                    item_json.put("dirty","true");
+                    section_json.put("item_" + item,item_json);
+                }
+
+                content_data_download.put("section_" + group,section_json);
+                content_data_control = translateChange(content_data_download,changed_data);
+
+                adapter.notifyDataSetChanged();
+
+                if (refresh == 1) {
+                    refresh(refresh_trigger);
+                }
+
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    static int URL_REMOTE = 1;
+    static int URL_LOCAL = 0;
+    static int URL_NONE = 2;
+    static int URL_RESTORE = 3;
+    // 如何处理commoneditor action 类型调用的返回值
+    static int ACTION_SAVE_DATA = 0;
+    static int ACTION_FILL_SECTION = 1;
+    /**Multiple Action**/
+    private View.OnClickListener multipleActionClickListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+
+            Button btn = (Button)v;
+            String tag = (String) btn.getTag();
+            String[] arr = tag.split("_");
+            int group = Integer.valueOf(arr[0]);
+            int child = Integer.valueOf(arr[1]);
+            int i = Integer.valueOf(arr[2]);
+
+            int refresh = 0;
+            JSONObject section_json = null;
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+            String subid = item_json.optString("subid");
+            String refresh_trigger = item_json.optString("name");
+            JSONObject sub_action = item_json.optJSONObject("item_" + i);
+            String type = sub_action.optString("type");
+
+            if (type != null && type.equals("pull")) {
+
+                // end edit
+
+                refresh = sub_action.optInt("refresh");
+                JSONObject keymap = sub_action.optJSONObject("key_map");
+                JSONObject value = create_value_map(keymap);
+
+                if (subid == null || subid.isEmpty()) {
+                    JSONObject jsonmap = sub_action.optJSONObject("key_map");
+                    section_json = content_data_download.optJSONObject("section_" + group);
+                    int icount = section_json.optInt("count");
+                    for (int ic = 0; ic < icount; ic++) {
+                        JSONObject modity_item = section_json.optJSONObject("item_" + ic);
+                        String mapto = modity_item.optString("name");
+
+                        if (mapto.isEmpty()) {
+                            continue;
+                        }
+                        String valuefrom = jsonmap.optString(modity_item.optString("name"));
+                        if (valuefrom == null) {
+                            continue;
+                        }
+                        String valuestr = value.optString(valuefrom);
+
+                        try {
+                            if (valuestr.isEmpty()) {
+                                modity_item.put("value","");
+                            } else {
+                                modity_item.put("value",valuestr);
+                            }
+                            modity_item.put("dirty","true");
+                            section_json.put("item_" + ic,modity_item);
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                    }
+                } else {
+                    String[] idarr = subid.split("_");
+                    int section = Integer.valueOf(idarr[0]);
+                    int item = Integer.valueOf(idarr[1]);
+
+                    JSONObject jsonmap = sub_action.optJSONObject("key_map");
+                    section_json = content_data_download.optJSONObject("section_" + section);
+                    JSONObject olditem = section_json.optJSONObject("item_" + item);
+
+                    String control_type = olditem.optString("control");
+                    if (control_type.equals("switch")) {
+                        olditem = fill_switch_subitem_subid_mapping(olditem,null,value,jsonmap);
+                    } else if (control_type.equals("enum")) {
+                        olditem = fill_enum_subitem_subid_mapping(olditem,null,value,jsonmap);
+                    } else {
+                        new AlertDialog.Builder(mCtx)
+                                .setMessage("not impl")
+                                .setPositiveButton("OK",null)
+                                .show();
+                    }
+                    try {
+                        olditem.put("dirty","true");
+                        section_json.put("item_" + item,olditem);
+
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+
+                }
+
+                try {
+
+                    content_data_download.put("section_" + group,section_json);
+                    content_data_control = translateChange(content_data_download,changed_data);
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+                if (refresh == 1) {
+                    refresh(refresh_trigger);
+                    return;
+                }
+                adapter.notifyDataSetChanged();
+
+            } else {
+                JSONObject itemjson = sub_action;
+                String value = itemjson.optString("value");
+                Intent intent = null;
+                String requesturl = null;
+                int request_code = -1;
+                if (value.equals("new_addr")) {
+
+                    AddressEditorActivity.Builder builder = new AddressEditorActivity.Builder(); // 创建内部类实例需要外部类的实例,或者声明内部类为static
+                    intent = builder.build(mCtx,URL_REMOTE,requesturl,"true",String.format("%d",i),group,child);
+                    request_code = 2;
+
+                } else if (value.equals("credit_card")) {
+
+                    request_code = 3;
+                    JSONObject data = item_json.optJSONObject("data");
+                    int url_type;
+                    JSONObject download_data;
+                    if (data != null) {
+                        download_data = data;
+                        url_type = URL_NONE;
+                        requesturl = null;
+                    } else {
+                        download_data = null;
+                        url_type = URL_REMOTE;
+                        requesturl = "";
+                    }
+                    intent = new CreditCardEditorActivity.Builder().build(mCtx,url_type,requesturl,Application.order_code,"true",String.format("%d",i),download_data,group,child);
+
+                } else if (value.equals("Sales_Order_Freight_Bill_To")) {
+
+                    request_code = 4;
+                    intent = new ContactListActivity.Builder().build(mCtx,"true",String.format("%d",i),value,true,group,child);
+
+                } else if (value.equals("Sales_Order_Ship_From")) {
+
+                    request_code = 5;
+                    intent = new ContactListActivity.Builder().build(mCtx,"true",String.format("%d",i),value,true,group,child);
+
+                } else if (value.equals("Sales_Order_Customer")) {
+
+                    request_code = 6;
+                    intent = new ContactListActivity.Builder().build(mCtx,"true",String.format("%d",i),value,true,group,child);
+
+                } else if (value.equals("Sales_Order_Merchandise_Bill_To")) {
+
+                    request_code = 7;
+                    intent = new ContactListActivity.Builder().build(mCtx,"true",String.format("%d",i),value,true,group,child);
+
+                } else if (value.equals("Contact_Return_To")) {
+
+                    request_code = 8;
+                    intent = new ContactListActivity.Builder().build(mCtx,"true",String.format("%d",i),value,true,group,child);
+
+                } else if (value.equals("Sales_Order_Ship_To")) {
+
+                    request_code = 9;
+                    intent = new ContactListActivity.Builder().build(mCtx,"true",String.format("%d",i),value,true,group,child);
+                }
+
+               if (intent != null) {
+                   startActivityForResult(intent,request_code);
+               }
+            }
+
+        }
+    };
+
+    public JSONObject fill_switch_subitem_subid_mapping(JSONObject switch_item,JSONArray subid,JSONObject source, JSONObject mapping) {
+
+        String value = switch_item.optString("value");
+        JSONObject boolitem = null;
+        JSONObject subjson = null;
+        if (value.equals("true")) {
+            boolitem = switch_item.optJSONObject("true");
+        } else {
+            boolitem = switch_item.optJSONObject("false");
+        }
+        subjson = boolitem.optJSONObject("sub_item");
+        if (subjson != null) {
+            int sub_count = subjson.optInt("count");
+            for (int l = 0; l <sub_count; l++) {
+                JSONObject modify_item = subjson.optJSONObject("item_" + l);
+                String mapto = modify_item.optString("name");
+                if (mapto == null || mapto.isEmpty()) {
+                    continue;
+                }
+                String valuefrom = mapping.optString(modify_item.optString("name"));
+                if (valuefrom == null) {
+                    continue;
+                }
+                String valuestr = source.optString(valuefrom);
+
+                try {
+                    if (valuestr.length() > 0) {
+                        modify_item.put("value",valuestr);
+                    } else {
+                        modify_item.put("value","");
+                    }
+
+                    modify_item.put("dirty","true");
+                    subjson.put("item_" + l,modify_item);
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+            try {
+                boolitem.put("sub_item",subjson);
+                if (value.equals("true")) {
+                    switch_item.put("true",boolitem);
+                } else {
+                    switch_item.put("false",boolitem);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        return switch_item;
+    }
+
+    public JSONObject fill_enum_subitem_subid_mapping(JSONObject enum_item,JSONArray subid,JSONObject source, JSONObject mapping) {
+
+        JSONObject cadedatejson = enum_item.optJSONObject("cadedate");
+        int count = cadedatejson.optInt("count");
+        for (int i = 0; i < count; i++) {
+            JSONObject val_json = cadedatejson.optJSONObject("val_" + i);
+            int check = val_json.optInt("check");
+            if (check == 1) {
+                JSONObject subjson = val_json.optJSONObject("sub_item");
+                if (subjson != null) {
+                    int sub_count = subjson.optInt("count");
+                    for (int l = 0; l < sub_count; l++) {
+                        JSONObject modify_item = subjson.optJSONObject("item_" + l);
+                        String control_type = modify_item.optString("control");
+                        if (control_type.equals("switch")) {
+                            modify_item = fill_switch_subitem_subid_mapping(modify_item,null,source,mapping);
+                        } else if (control_type.equals("enum")) {
+                            modify_item = fill_enum_subitem_subid_mapping(modify_item,null,source,mapping);
+                        } else {
+                            String mapto = modify_item.optString("name");
+                            if (mapto == null || mapto.isEmpty()) {
+                                continue;
+                            }
+                            String valuefrom = mapping.optString(modify_item.optString("name"));
+                            if (valuefrom == null) {
+                                continue;
+                            }
+                            String valuestr = source.optString(valuefrom);
+
+                            try {
+                                if (valuefrom != null && valuefrom.length() > 0) {
+                                    modify_item.put("value",valuestr);
+                                } else {
+                                    modify_item.put("value","");
+                                }
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                        try {
+                            modify_item.put("dirty","true");
+                            subjson.put("item_" + l,modify_item);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                    try {
+                        val_json.put("sub_item",subjson);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+            try {
+                cadedatejson.put("val_" + i,val_json);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            enum_item.put("cadedate",cadedatejson);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return enum_item;
+    }
+
+    public JSONObject create_value_map(JSONObject key_map) {
+        JSONObject ret = new JSONObject();
+
+        Iterator<String> keys = key_map.keys();
+        try {
+
+            while (keys.hasNext()) {
+                String key = keys.next();
+                String valuefrom = key_map.optString(key);
+                if (valuefrom != null && !valuefrom.isEmpty()) {
+                    String value = getValue(valuefrom);
+                    ret.put(valuefrom,value);
+                }
+            }
+            JSONObject customerinfo = create_customer_info_from_table();
+
+            String ext = create_customer_ext(customerinfo);
+            String first_name = customerinfo.optString("customer_first_name");
+            String last_name = customerinfo.optString("customer_last_name");
+            if (ext != null) {
+                ret.put("customer_contact_ext",ext);
+            }
+            if (first_name != null) {
+                ret.put("customer_first_name",first_name);
+            }
+            if (last_name != null) {
+                ret.put("customer_last_name",last_name);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return ret;
+    }
+
+    public String getValue(String name) {
+
+        String ret = "";
+        int count = content_data_control.length();
+        for (int i = 0; i < count; i++) {
+            JSONArray items = content_data_control.optJSONArray(i);
+            for (int j = 0; j < items.length(); j++) {
+                JSONObject item = items.optJSONObject(j);
+                String item_name = item.optString("name");
+                if (item_name.equals(name)) {
+                    String control = item.optString("control");
+                    if (control.equals("enum")) {
+                        JSONObject cadedate = item.optJSONObject("cadedate");
+                        int cc = cadedate.optInt("count");
+                        for (int l = 0; l < cc; l++) {
+                            JSONObject val_json = cadedate.optJSONObject("val_" + l);
+                            if (val_json.optInt("check") == 1) {
+                                return val_json.optString("value_id");
+                            }
+                        }
+                    } else {
+                        return item.optString("value");
+                    }
+
+                }
+            }
+
+        }
+
+        return ret;
+    }
+
+    public JSONObject create_customer_info_from_table() {
+
+        JSONObject ret = Application.customerInfo;
+
+
+
+        try {
+
+            if (ret == null) {
+                ret = new JSONObject();
+            }
+
+            ret.put("customer_country",getValue("customer_country"));
+            ret.put("customer_phone",getValue("customer_phone"));
+            ret.put("customer_email",getValue("customer_email"));
+            ret.put("customer_name",getValue("customer_name"));
+            ret.put("customer_address4",getValue("customer_address4"));
+            ret.put("customer_address3",getValue("customer_address3"));
+            ret.put("customer_address2",getValue("customer_address2"));
+            ret.put("customer_address1",getValue("customer_address1"));
+            ret.put("customer_zipcode",getValue("customer_zipcode"));
+            ret.put("customer_city",getValue("customer_city"));
+            ret.put("customer_state",getValue("customer_state"));
+            ret.put("customer_cid",getValue("customer_cid"));
+            ret.put("customer_state",getValue("customer_state"));
+            ret.put("customer_contact",getValue("customer_contact"));
+            ret.put("customer_fax",getValue("customer_fax"));
+
+            String firstname = "";
+            String lastname = "";
+            String contact_name = getValue("customer_contact");
+            if (contact_name != null) {
+                String[] arr = contact_name.split(" ");
+                if (arr.length >= 1) {
+                    firstname = arr[0];
+                    if (arr.length > 1) {
+                        lastname = arr[1];
+                        int length = arr.length;
+                        if (length > 2) {
+                            for (int i = 2; i < length; i++) {
+                                lastname = lastname + " " + arr[i];
+                            }
+                        }
+                    }
+                }
+            }
+            ret.put("customer_first_name",firstname);
+            ret.put("customer_last_name",lastname);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+        return ret;
+    }
+
+    public String create_customer_ext(JSONObject customerinfo) {
+
+        String ret = null;
+        String customer_address1 = customerinfo.optString("customer_address1");
+        String customer_address2 = customerinfo.optString("customer_address2");
+        String customer_address3 = customerinfo.optString("customer_address3");
+        String customer_address4 = customerinfo.optString("customer_address4");
+
+        String addr_str = "";
+        if (customer_address1 != null && customer_address1.length() > 0) {
+            addr_str = addr_str + customer_address1 + "\r\n";
+        }
+        if (customer_address2 != null && customer_address2.length() > 0) {
+            addr_str = addr_str + customer_address2 + "\r\n";
+        }
+        if (customer_address3 != null && customer_address3.length() > 0) {
+            addr_str = addr_str + customer_address3 + "\r\n";
+        }
+        if (customer_address4 != null && customer_address4.length() > 0) {
+            addr_str = addr_str + customer_address4 + "\r\n";
+        }
+        if (addr_str.length() > 0) {
+            addr_str = addr_str.substring(0,addr_str.length() - 3);
+        }
+
+        String city = customerinfo.optString("customer_city");
+        String country = customerinfo.optString("customer_country");
+        String zipcode = customerinfo.optString("customer_zipcode");
+        String state = customerinfo.optString("customer_state");
+
+        String cty_str = "";
+        if (city != null && city.length() > 0) {
+            cty_str = cty_str + city + ", ";
+        }
+        if (state != null && state.length() > 0) {
+            cty_str = cty_str + state + ", ";
+        }
+        if (zipcode != null && zipcode.length() > 0) {
+            cty_str = cty_str + zipcode + ", ";
+        }
+        if (country != null && country.length() > 0) {
+            cty_str = cty_str + country + ", ";
+        }
+        if (cty_str.length() > 0) {
+            cty_str = cty_str.substring(0,cty_str.length() - 3);
+        }
+
+        String ext_str = "";
+        if (addr_str != null && addr_str.length() > 0) {
+            ext_str = ext_str + addr_str + "\r\n";
+        }
+        if (cty_str != null && cty_str.length() > 0) {
+            ext_str = ext_str + cty_str;
+        }
+
+        ret = ext_str;
+
+        return ret;
+    }
+
+    public void textFieldSetValue(String val,int group,int child) {
+
+        try {
+
+            JSONObject section_json = null;
+
+            val = val.trim();
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+
+            String subid = item_json.optString("subid");
+            String refresh_trigger = item_json.optString("name");
+
+            item_json.put("dirty","true");
+            item_json.put("value",val);
+            if (item_json.optString("keyboard").equals("number")) {
+                float f = Float.valueOf(val);
+                item_json.put("value",String.format("%.2f",f));
+            }
+
+            if (subid == null || subid.isEmpty()) {
+
+                section_json = content_data_download.optJSONObject("section_" + group);
+                int count = 0;
+
+                count = section_json.optInt("count");
+                for (int i = 0; i < count; i++) {
+                    JSONObject olditem = section_json.optJSONObject("item_" + i);
+                    if (olditem.optString("name").equals(item_json.optString("name"))) {
+                        section_json.put("item_" + i,item_json);
+                    }
+                } // for
+
+                content_data_download.put("section_" + group,section_json);
+                content_data_control = translateChange(content_data_download,changed_data);
+
+                int refresh = item_json.optInt("refresh");
+                JSONObject restore_json = item_json.optJSONObject("restore");
+                boolean partial_refresh = item_json.optBoolean("partial_refresh");
+                if (refresh == 1) {
+
+                    if (restore_json != null) {
+                        int rc = restore_json.optInt("count");
+                        for (int ir = 0; ir < rc; ir++) {
+                            String name = restore_json.optString("item_" + ir);
+                            int section_count = content_data_download.optInt("section_count");
+                            for (int i = 0; i < section_count; i++) {
+                                JSONObject sectionjson = content_data_download.optJSONObject("section_" + i);
+                                int item_count = sectionjson.optInt("count");
+                                for (int j = 0; j < item_count; j++) {
+                                    JSONObject itemjson = sectionjson.optJSONObject("item_" + j);
+                                    if (itemjson.optString("name").equals(name)) {
+                                        itemjson.remove("dirty");
+                                        sectionjson.put("item_" + j,itemjson);
+                                    }
+                                }
+                                content_data_download.put("section_" + i,sectionjson);
+                            }
+                        }
+                    }
+                    refresh(refresh_trigger);
+
+                } // refresh == 1
+                else if (partial_refresh) {
+
+                    String name = item_json.optString("name");
+                    final String url = item_json.optString("data_interface");
+
+                    JSONObject params = new JSONObject();
+                    params.put(name,val);
+
+                    final ProgressDialog pd = Utils.waiting_alert(mCtx,"loading","please wait");
+                    final JSONObject final_params = params;
+                    new Thread(new Runnable() {
+                        @Override
+                        public void run() {
+                            final JSONObject editor_json = Utils.commoneditor_partialrefresh(final_params,url);
+
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+
+                                    pd.dismiss();
+
+                                    if (Integer.valueOf(editor_json.optString("result")) == 2) {
+                                        int prcount = editor_json.optInt("count");
+                                        for (int ipr = 0; ipr < prcount; ipr++) {
+                                            JSONObject pr_item = editor_json.optJSONObject("item_" + ipr);
+                                            String name = pr_item.optString("name");
+                                            String value = pr_item.optString("value");
+                                            setValue(name,value);
+                                        }
+                                    } else {
+                                        Utils.message_alert(mCtx,"",editor_json.optString("err_msg"));
+                                    }
+
+                                }
+                            });
+                        }
+                    }).start();
+
+
+                } // partial refresh
+
+                lastEditText = null;
+                last_edit_group = -1;
+                last_edit_child = -1;
+
+                return;
+            } // subid == null
+            else
+            {
+
+                String[] idarr = subid.split("_");
+                int section = Integer.valueOf(idarr[0]);
+                int item = Integer.valueOf(idarr[1]);
+
+                section_json = content_data_download.optJSONObject("section_" + section);
+                JSONObject olditem = section_json.optJSONObject("item_" + item);
+
+                String control_type = olditem.optString("control");
+                JSONObject new_item = null;
+                item_json.put("dirty","true");
+                if (control_type.equals("enum")) {
+                    new_item = enum_subitem_changed(olditem,idarr,item_json,2);
+                } else if (control_type.equals("switch")) {
+                    new_item = switch_subitem_changed(olditem,idarr,item_json,2);
+                }
+                section_json.put("item_" + item,new_item);
+
+                content_data_download.put("section_" + group,section_json);
+                content_data_control = translateChange(content_data_download,changed_data);
+
+                int refresh = item_json.optInt("refresh");
+                JSONObject restore_json = item_json.optJSONObject("restore");
+                boolean partial_refresh = item_json.optBoolean("partial_refresh");
+                if (refresh == 1) {
+
+                    if (restore_json != null) {
+                        int rc = restore_json.optInt("count");
+                        for (int ir = 0; ir < rc; ir++) {
+                            String name = restore_json.optString("item_" + ir);
+                            int section_count = content_data_download.optInt("section_count");
+                            for (int i = 0; i < section_count; i++) {
+                                JSONObject sectionjson = content_data_download.optJSONObject("section_" + i);
+                                int item_count = sectionjson.optInt("count");
+                                for (int j = 0; j < item_count; j++) {
+                                    JSONObject itemjson = sectionjson.optJSONObject("item_" + j);
+                                    if (itemjson.optString("name").equals(name)) {
+                                        itemjson.remove("dirty");
+                                        sectionjson.put("item_" + j,itemjson);
+                                    }
+                                }
+                                content_data_download.put("section_" + i,sectionjson);
+                            }
+                        }
+                    }
+                    refresh(refresh_trigger);
+
+                } // refresh == 1
+                else if (partial_refresh) {
+
+                    String name = item_json.getString("name");
+                    final String url = item_json.optString("data_interface");
+
+                    JSONObject params = new JSONObject();
+                    params.put(name,val);
+                    final ProgressDialog pd = Utils.waiting_alert(mCtx,"loading","please wait");
+                    final JSONObject final_params = params;
+                    new Thread(new Runnable() {
+                        @Override
+                        public void run() {
+
+                            final JSONObject editor_json = Utils.commoneditor_partialrefresh(final_params,url);
+
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+
+                                    pd.dismiss();
+
+                                    if (Integer.valueOf(editor_json.optString("result")) == 2) {
+                                        int prcount = editor_json.optInt("count");
+                                        for (int ipr = 0; ipr < prcount; ipr++) {
+                                            JSONObject pr_item = editor_json.optJSONObject("item_" + ipr);
+                                            String name = pr_item.optString("name");
+                                            String value = pr_item.optString("value");
+                                            setValue(name,value);
+                                        }
+                                    } else {
+                                        Utils.message_alert(mCtx,"",editor_json.optString("err_msg"));
+                                    }
+
+                                }
+                            });
+
+                        }
+                    }).start();
+
+
+                } // partial refresh
+
+
+                // fix crash when sub item value changed
+                adapter.notifyDataSetChanged();
+
+                lastEditText = null;
+                // lastedit_from = null
+                last_edit_group = -1;
+                last_edit_child = -1;
+
+                return;
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public JSONObject switch_subitem_changed(JSONObject switch_item,String[] subid,JSONObject valuejson,int step) {
+
+        try {
+
+            int index = Integer.valueOf(subid[step]);
+            String value = switch_item.optString("value");
+
+            JSONObject boolitem = null;
+            JSONObject subjson = null;
+            if (value.equals("true")) {
+                boolitem = switch_item.optJSONObject("true");
+            } else {
+                boolitem = switch_item.optJSONObject("false");
+            }
+            subjson = boolitem.optJSONObject("sub_item");
+
+            if (subjson != null) {
+                JSONObject itemjson = subjson.optJSONObject("item_" + index);
+                if (step == subid.length - 1) {
+                    itemjson = valuejson;
+                }
+                subjson.put("item_" + index,itemjson);
+                boolitem.put("sub_item",subjson);
+
+                if (value.equals("true")) {
+                    switch_item.put("true",boolitem);
+                } else {
+                    switch_item.put("false",boolitem);
+                }
+
+                return switch_item;
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+
+    }
+
+    public void setEnumValue(JSONObject value, int group, int child) {
+
+        try {
+
+            JSONObject section_json = null;
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+
+            int refresh = item_json.optInt("refresh");
+            String refresh_trigger = item_json.optString("name");
+            String subid = item_json.optString("subid");
+
+            item_json.put("cadedate",value);
+
+            if (subid == null || subid.isEmpty()) {
+                item_json.put("dirty","dirty");
+                section_json = content_data_download.optJSONObject("section_" + group);
+                int count = 0;
+                count = section_json.optInt("count");
+                for (int i = 0; i < count; i++) {
+                    JSONObject olditem = section_json.optJSONObject("item_" + i);
+                    if (olditem.optString("name").equals(item_json.optString("name"))) {
+                        section_json.put("item_" + i,item_json);
+                    }
+                }
+            } else {
+
+                String[] idarr = subid.split("_");
+                int section = Integer.valueOf(idarr[0]);
+                int item = Integer.valueOf(idarr[1]);
+
+                section_json = content_data_download.optJSONObject("section_" + section);
+                JSONObject olditem = section_json.optJSONObject("item_" + item);
+                item_json = enum_subitem_changed(olditem,idarr,item_json,2);
+                item_json.put("dirty","true");
+                section_json.put("item_" + item,item_json);
+
+            }
+
+            content_data_download.put("section_" + group,section_json);
+            content_data_control = translateChange(content_data_download,changed_data);
+
+            JSONObject restore_json = item_json.optJSONObject("restore");
+            if (refresh == 1) {
+                if (restore_json != null) {
+                    int rc = restore_json.optInt("count");
+                    for(int ir=0;ir<rc;ir++) {
+                        String name = restore_json.optString("item_" + ir);
+                        int section_count = content_data_download.optInt("section_count");
+
+                        for (int i = 0; i < section_count; i++) {
+                            JSONObject sectionjson = content_data_download.optJSONObject("section_" + i);
+                            int item_count = sectionjson.optInt("count");
+                            for (int j = 0; j < item_count; j++) {
+                                JSONObject itemjson = sectionjson.optJSONObject("item_" + j);
+                                if (itemjson.optString("name").equals(name)) {
+                                    itemjson.remove("dirty");
+                                    sectionjson.put("item_" + j,itemjson);
+                                }
+                            }
+                            content_data_download.put("section_" + i,sectionjson);
+                        }
+                    }
+                }
+                refresh(refresh_trigger);
+                return;
+            }
+            adapter.notifyDataSetChanged();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+
+    }
+
+    public void setValue(String key,String val) {
+
+
+        try {
+
+            for (int i = 0; i < content_data_control.length(); i++) {
+                JSONArray items = content_data_control.optJSONArray(i);
+                for (int j = 0; j < items.length(); j++) {
+                    JSONObject item = items.optJSONObject(j);
+                    String item_name = item.optString("name");
+                    int group = i;
+                    int child = j;
+                    if (item_name.equals(key)) {
+                        String control = item.optString("control");
+                        if (control.equals("enum")) {
+
+                            JSONObject cadedate = item.optJSONObject("cadedate");
+                            int cc = cadedate.optInt("count");
+                            for (int l = 0; l < cc; l++) {
+
+                                JSONObject val_json = cadedate.optJSONObject("val_" + l);
+                                if (val_json.optString("val_id").equals(val)) {
+                                    val_json.put("check",1);
+                                } else {
+                                    val_json.put("check",0);
+                                }
+                                cadedate.put("val_" + l,val_json);
+
+                            } // for
+
+                            setEnumValue(cadedate,group,child);
+
+                        }// enum
+                        else if (control.equals("edit")) {
+                            textFieldSetValue(val,group,child);
+                        } // edit
+                    } // key
+
+                }
+            }
+            adapter.notifyDataSetChanged();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**Text Field Change*/
+    public class TextFieldTextWatcher implements TextWatcher {
+
+        Context mCtx;
+        int group;
+        int child;
+        EditText textView;
+
+        public TextFieldTextWatcher(Context ctx,EditText textView,int group,int child) {
+            this.mCtx = ctx;
+            this.textView = textView;
+            this.group = group;
+            this.child = child;
+
+        }
+
+        String origin_text;
+        String string;
+        int start_position;
+        int change_length; // 修改原文长度
+        int new_string_length;
+
+
+        /**
+         * s        改变前的内容
+         * start    增加内容前光标位置,删除内容后光标位置 (起始位置)
+         * count    选中s中的内容长度(发生改变的原内容长度),未选中为0
+         * after    新添加的内容长度,删除为0
+         * */
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+//            Log.d("TextChange", "before Text Changed: " + s + " Start: " + start + " Count: " + count + " After: " + after);
+
+            origin_text = s.toString();
+            start_position = start;
+            change_length = count;
+            new_string_length = after;
+        }
+
+        /**
+         * s        改变后的内容
+         * start    增加内容前光标位置,删除内容后光标位置 (起始位置)
+         * before   选中s中的内容长度(发生改变的原内容长度),未选中为0
+         * count    增加内容长度,删除内容为0
+         * */
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+//            Log.d("TextChange", "on Text Changed: " + s + " Start: " + start + " Before: " + before + " Count: " + count);
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+
+            /**
+             * 文本处理
+             * */
+            if (new_string_length == 0) {
+                string = "";
+            } else {
+                string = s.toString().substring(start_position,start_position + new_string_length);
+            }
+
+            if (change_length == 0) { // 新加内容
+
+            } else { // 替换原文或删除原文
+
+            }
+
+            /**
+             * 业务逻辑
+             * */
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+            if (item_json == null) {
+                return;
+            }
+            String required = item_json.optString("required");
+
+            if (required.equals("true") && string.length() == 0 && (origin_text == null || origin_text.length() < 1)) {
+
+                // cell red shadow
+
+            } else {
+                // cell clear shadow
+            }
+
+            String keyboard = item_json.optString("keyboard");
+            if (!keyboard.equals("number") && !keyboard.equals("int")) {
+
+                return;
+            }
+            String filterStr;
+            if (keyboard.equals("number")) {
+                filterStr = string.replaceAll("[^(0-9/.)]", "");
+            } else {
+                filterStr = string.replaceAll("[^(0-9)]", "");
+            }
+            boolean canChange = string.equals(filterStr);
+            int lenght = item_json.optInt("length");
+
+            // 长度控制在textView初始化时
+            if (lenght == 0) {
+
+                if (!canChange) {
+                    textView.setText(origin_text);
+                } else {
+
+                }
+
+            } else {
+                if (canChange) {
+
+                } else {
+                    textView.setText(origin_text);
+                }
+            }
+
+        }
+    }
+
+    /**EditText Focus Listener**/
+    public class EditTextFocusListener implements View.OnFocusChangeListener {
+
+        Context mCtx;
+        int group;
+        int child;
+        EditText et;
+        boolean is_text_field;
+
+        public EditTextFocusListener(Context ctx,EditText textView,int group,int child) {
+            this.mCtx = ctx;
+            this.et = textView;
+            this.group = group;
+            this.child = child;
+
+            String[] tag_arr = ((String) textView.getTag()).split("_");
+            String tag_identifier = tag_arr[2];
+            if (tag_identifier.equals("TextFiled")) {
+                is_text_field = true;
+            } else {
+                is_text_field = false;
+            }
+        }
+
+        @Override
+        public void onFocusChange(View v, boolean hasFocus) {
+
+            if (hasFocus) {
+
+                editTextBeginEditing(et,is_text_field,group,child);
+
+            } else {
+
+                editTextEndEditing(et,is_text_field,group,child);
+                lastEditText = null;
+                last_edit_group = -1;
+                last_edit_child = -1;
+            }
+
+
+        }
+    }
+
+    public EditText lastEditText;
+    public int last_edit_group;
+    public int last_edit_child;
+    public String last_edit_str;
+
+    public void endEditting() {
+        if (lastEditText != null) {
+            lastEditText.clearFocus(); // 辞去焦点
+            lastEditText = null;
+        }
+    }
+
+    public void editTextEndEditing(EditText et,boolean is_text_field,int group,int child) {
+        Log.e("Edit", "end editing");
+        if (is_text_field) {
+
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+            if (item_json == null) {
+                return;
+            }
+            String fillText = item_json.optString("fill");
+            if (fillText != null && et.getText().length() == 0) {
+                et.setText(fillText);
+            }
+            textFieldSetValue(et.getText().toString(),group,child);
+
+        } else {
+
+            try {
+                JSONObject section_json = null;
+                JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+                String subid = item_json.optString("subid");
+                item_json.put("dirty","true");
+                item_json.put("value",et.getText().toString());
+                if (subid == null || subid.isEmpty()) {
+                    section_json = content_data_download.optJSONObject("section_" + group);
+                    int count = 0;
+                    count = section_json.optInt("count");
+                    for (int i = 0; i < count;i++) {
+                        JSONObject olditem = section_json.optJSONObject("item_" + i);
+                        if (olditem.optString("name").equals(item_json.optString("name"))) {
+                            section_json.put("item_" + i,item_json);
+                        }
+                    }
+                } else {
+                    String[] idarr = subid.split("_");
+                    int section = Integer.valueOf(idarr[0]);
+                    int item = Integer.valueOf(idarr[1]);
+
+                    section_json = content_data_download.optJSONObject("section_" + section);
+                    JSONObject olditem = section_json.optJSONObject("item_" + item);
+                    String control_type = olditem.optString("control");
+                    if (control_type.equals("enum")) {
+                        item_json = enum_subitem_changed(olditem,idarr,item_json,2);
+                    } else if (control_type.equals("switch")) {
+                        item_json = switch_subitem_changed(olditem,idarr,item_json,2);
+                    }
+                    item_json.put("dirty","true");
+                    section_json.put("item_" + item,item_json);
+
+                }
+
+                content_data_download.put("section_" + group, section_json);
+                content_data_control = translateChange(content_data_download,changed_data);
+
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+
+    }
+
+    public void editTextBeginEditing(EditText et,boolean is_text_field,int group,int child) {
+        Log.e("Edit", "begin editing");
+
+        lastEditText = et;
+        last_edit_group = group;
+        last_edit_child = child;
+
+        et.setSelection(et.getText().length());
+        if (is_text_field) {
+
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+            String clear_str = item_json.optString("clear");
+            String et_str = et.getText().toString();
+            if (clear_str != null && !clear_str.isEmpty() && et_str != null && !et_str.isEmpty()) {
+                double clear_double = Double.valueOf(clear_str);
+                double et_double = Double.valueOf(et_str);
+                boolean clear = clear_double == et_double;
+                if (clear == true) {
+                    et.setText(null);
+                }
+            }
+
+
+        } else {
+            // Text View
+
+        }
+    }
+
+
+    /**Text View Change**/
+    public class TextViewTextWatcher implements TextWatcher {
+
+        Context mCtx;
+        int group;
+        int child;
+        EditText textView;
+
+        public TextViewTextWatcher(Context ctx,EditText textView,int group,int child) {
+            this.mCtx = ctx;
+            this.textView = textView;
+            this.group = group;
+            this.child = child;
+        }
+
+        String origin_text;
+        String string;
+        int start_position;
+        int change_length; // 修改原文长度
+        int new_string_length;
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+            origin_text = s.toString();
+            start_position = start;
+            change_length = count;
+            new_string_length = after;
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+
+            /**
+             * 文本处理
+             * */
+            if (new_string_length == 0) {
+                string = "";
+            } else {
+                string = s.toString().substring(start_position,start_position + new_string_length);
+            }
+
+            if (change_length == 0) { // 新加内容
+
+            } else { // 替换原文或删除原文
+
+            }
+
+            /**
+             * 业务逻辑
+             * */
+
+            JSONObject item_json = content_data_control.optJSONArray(group).optJSONObject(child);
+            if (item_json == null) {
+                return;
+            }
+            String required = item_json.optString("required");
+            if (required.equals("true") && string.length() == 0 && (origin_text == null || origin_text.length() < 1)) {
+                // cell red shadow
+            } else {
+                // cell clear shadow
+            }
+
+        }
+    }
+}

+ 59 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/ContactListActivity.java

@@ -0,0 +1,59 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+import java.io.Serializable;
+
+public class ContactListActivity extends AppCompatActivity {
+
+
+    static String IS_SUBACTION = "is_subaction";
+    static String SUBACTION_TAG = "subaction_tag";
+    static String GROUP = "group";
+    static String CHILD = "child";
+    static String CONTACT_TYPE = "contact_type";
+    static String SHOW_NAV_BAR = "show_navigation_bar";
+    static String RETURN_VALUE = "return_value";
+
+
+    public static class Builder {
+
+        public Intent build(Context ctx, String is_subaction, String subaction_tag,String contact_type,boolean show_nav_bar,int group, int child) {
+            if (ctx == null) {
+                return null;
+            }
+
+            Intent intent = new Intent(ctx,CreditCardEditorActivity.class);
+
+            if (is_subaction != null) {
+                intent.putExtra(IS_SUBACTION,is_subaction);
+            }
+            if (subaction_tag != null) {
+                intent.putExtra(SUBACTION_TAG,subaction_tag);
+            }
+            if (contact_type != null) {
+                intent.putExtra(CONTACT_TYPE,contact_type);
+            }
+
+            intent.putExtra(SHOW_NAV_BAR,show_nav_bar);
+            intent.putExtra(GROUP,group);
+            intent.putExtra(CHILD,child);
+
+
+            return intent;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_contact_list);
+    }
+}

+ 66 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/CreditCardEditorActivity.java

@@ -0,0 +1,66 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+import java.io.Serializable;
+
+public class CreditCardEditorActivity extends AppCompatActivity {
+
+
+    static String URL_TYPE = "url_type";
+    static String REQUEST_URL = "request_url";
+    static String IS_SUBACTION = "is_subaction";
+    static String SUBACTION_TAG = "subaction_tag";
+    static String GROUP = "group";
+    static String CHILD = "child";
+    static String ORDERCODE = "order_code";
+    static String DOWNLOADDATA = "download_data";
+    static String RETURN_VALUE = "return_value";
+
+    public static class Builder {
+
+        public Intent build(Context ctx, int url_type, String request_url, String order_code, String is_subaction, String subaction_tag, JSONObject download_data, int group, int child) {
+            if (ctx == null) {
+                return null;
+            }
+            Intent intent = new Intent(ctx,CreditCardEditorActivity.class);
+
+            intent.putExtra(URL_TYPE ,url_type);
+
+            if (request_url != null) {
+                intent.putExtra(REQUEST_URL,request_url);
+            }
+            if (is_subaction != null) {
+                intent.putExtra(IS_SUBACTION,is_subaction);
+            }
+            if (subaction_tag != null) {
+                intent.putExtra(SUBACTION_TAG,subaction_tag);
+            }
+            if (order_code != null) {
+                intent.putExtra(ORDERCODE,order_code);
+            }
+            if (download_data != null) {
+                intent.putExtra(DOWNLOADDATA,download_data.toString());
+            }
+
+            intent.putExtra(GROUP,group);
+            intent.putExtra(CHILD,child);
+
+
+            return intent;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_credit_card_editor);
+    }
+}

+ 42 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/DatePickerActivity.java

@@ -0,0 +1,42 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.usai.redant.redantmobile.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DatePickerActivity extends AppCompatActivity {
+
+    public static class Builder {
+        public Intent build(Context context, Date date, SimpleDateFormat formatter,int pickerMode,String time,int group,int child) {
+
+            if (context == null) {
+                return null;
+            }
+            Intent intent = new Intent(context,DatePickerActivity.class);
+
+            if (date != null) {
+
+            }
+            if (formatter != null) {
+
+            }
+            if (time != null) {
+
+            }
+
+            return intent;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_date_picker);
+    }
+}

+ 377 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/EnumSlectActivity.java

@@ -0,0 +1,377 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONObject;
+
+import java.io.Serializable;
+import java.util.zip.Inflater;
+
+public class EnumSlectActivity extends AppCompatActivity {
+
+    static String MAX_SELECT = "max_select";
+    static String GROUP_POSITION = "group";
+    static String CHILD_POSITION = "child";
+    static String CADEDATE = "cadedate";
+    static String SINGLE_SELECT = "single_select";
+    static String TITLE = "title";
+    static String AUTO_CLOSE = "auto_close";
+
+    public static class Builder {
+        public Intent build(Context context,String title, int max_select, int group, int child, String cadedate,boolean single_select,boolean auto_close) {
+            if (context == null) {
+                return null;
+            }
+
+            Intent intent = new Intent(context,EnumSlectActivity.class);
+
+            intent.putExtra(MAX_SELECT,max_select);
+            intent.putExtra(GROUP_POSITION,group);
+            intent.putExtra(CHILD_POSITION,child);
+            if (cadedate != null) {
+                intent.putExtra(CADEDATE,(Serializable) cadedate);
+            }
+            intent.putExtra(SINGLE_SELECT,single_select);
+            if (title != null) {
+                intent.putExtra(TITLE,title);
+            }
+            intent.putExtra(AUTO_CLOSE,auto_close);
+
+            return intent;
+        }
+    }
+
+
+    private int maxSelect;
+    private int mGroup;
+    private int mChild;
+    private boolean mSingleSelect;
+    private String mTitle;
+    private boolean mAuto_close;
+    private JSONObject mCadedate;
+    private boolean mDirty;
+
+    private String mKeywords;
+    private int filter_count;
+
+    private ListView enum_list_view;
+    private EnumAdapter adapter;
+    private Context mCtx;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_enum_slect);
+
+        init();
+
+        setTitle(mTitle);
+
+        enum_list_view = (ListView)findViewById(R.id.enum_list_view);
+
+        adapter = new EnumAdapter(mCtx);
+        enum_list_view.setAdapter(adapter);
+
+        enum_list_view.setOnItemClickListener(new CellClickListener(mCtx));
+
+
+    }
+
+    @Override
+    public void finish() {
+
+        if (mDirty != false) {
+            Intent intent = new Intent();
+            intent.putExtra(CADEDATE,mCadedate.toString());
+            intent.putExtra(GROUP_POSITION,mGroup);
+            intent.putExtra(CHILD_POSITION,mChild);
+
+            setResult(RESULT_OK,intent);
+        }
+
+
+        super.finish();
+    }
+
+    private void init() {
+        mCtx = this;
+        Intent intent = getIntent();
+        String cadedate_str = intent.getStringExtra(CADEDATE);
+        try {
+            mCadedate = new JSONObject(cadedate_str);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        mSingleSelect = intent.getBooleanExtra(SINGLE_SELECT,true);
+        mGroup = intent.getIntExtra(GROUP_POSITION,0);
+        mChild = intent.getIntExtra(CHILD_POSITION,0);
+        mTitle = intent.getStringExtra(TITLE);
+        maxSelect = intent.getIntExtra(MAX_SELECT,0);
+        mAuto_close = intent.getBooleanExtra(AUTO_CLOSE,true);
+
+
+    }
+
+    private class CellClickListener implements AdapterView.OnItemClickListener {
+
+        private Context ctx;
+        public CellClickListener(Context ctx) {
+            this.ctx = ctx;
+        }
+
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+
+            mDirty = true;
+
+            try {
+                if (mSingleSelect) {
+
+                    if (mKeywords == null || mKeywords.isEmpty()) {
+
+                        for (int i = 0; i < mCadedate.optInt("count"); i++) {
+                            JSONObject val_json = mCadedate.optJSONObject("val_" + i);
+
+                            if (i == position) {
+                                val_json.put("check","1");
+                            } else {
+                                val_json.put("check","0");
+                            }
+                            mCadedate.put("val_" + i,val_json);
+
+                        } // for
+
+                    } // keywords null
+                    else {
+
+
+                        JSONObject val_json = null;
+                        int count = 0;
+                        for (int cc = 0; cc < mCadedate.optInt("count"); cc++) {
+                            if (count >= filter_count) {
+                                break;
+                            }
+                            JSONObject search_json = mCadedate.optJSONObject("val_" + cc);
+                            String value = search_json.optString("value");
+                            boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
+                            if (contain) {
+                                count++;
+                            }
+
+                            if (count - 1 == position) {
+                                val_json = search_json;
+                            }
+                        } // for cc
+
+                        for (int sc = 0; sc < mCadedate.optInt("count"); sc++) {
+
+                            JSONObject sc_json = mCadedate.optJSONObject("val_" + sc);
+                            if (sc_json.optString("value").equals(val_json.optString("value"))) {
+                                sc_json.put("check","1");
+                            } else {
+                                sc_json.put("check","0");
+                            }
+                            mCadedate.put("val_" + sc,sc_json);
+
+                        } // for sc
+
+
+                    }
+
+                    if (mAuto_close) {
+                        finish();
+                    } else {
+                        adapter.notifyDataSetChanged();
+                    }
+
+                } // single select
+                else {
+
+                    JSONObject val_json = null;
+                    if (mKeywords == null || mKeywords.isEmpty()) {
+                        val_json = mCadedate.optJSONObject("val_" + position);
+                    } else {
+                        int count = 0;
+                        for (int i = 0; i < mCadedate.optInt("count"); i++) {
+                            if (count >= filter_count) {
+                                break;
+                            }
+                            JSONObject search_json = mCadedate.optJSONObject("val_" + i);
+                            String value = search_json.optString("value");
+                            boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
+                            if (contain) {
+                                count++;
+                            }
+
+                            if (count - 1 == position) {
+                                val_json = search_json;
+                            }
+                        }
+                    }
+
+                    int check = val_json.optInt("check");
+                    if (check == 1) {
+                        val_json.put("check","0");
+                    } else {
+                        if (check_count() >= maxSelect && maxSelect > 0) {
+                            new AlertDialog.Builder(this.ctx)
+                                    .setTitle("Max count reached")
+                                    .setMessage(maxSelect + " items at most for this field.")
+                                    .setPositiveButton("OK",null)
+                                    .show();
+                            return;
+
+                        }
+                        val_json.put("check","1");
+                    }
+                    mCadedate.put("val_" + position,val_json);
+
+                }
+                adapter.notifyDataSetChanged();
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+    }
+
+    public int check_count() {
+
+        int check_count = 0;
+        for (int i = 0; i < mCadedate.optInt("count"); i++) {
+            JSONObject val_json = mCadedate.optJSONObject("val_" + i);
+            int check = val_json.optInt("check");
+            if (check == 1) {
+                check_count++;
+            }
+        }
+        return check_count;
+    }
+
+
+    private class EnumAdapter extends BaseAdapter {
+
+        public class Holder {
+            public TextView value_tv;
+            public ImageView check_iv;
+
+            public Holder(View cell) {
+                if (cell == null) {
+                    return;
+                }
+                value_tv = (TextView)cell.findViewById(R.id.enum_value_tv);
+                check_iv = (ImageView)cell.findViewById(R.id.enum_check_iv);
+                check_iv.setClickable(false);
+                check_iv.setFocusable(false);
+                cell.setTag(this);
+
+            }
+        }
+
+
+        private Context ctx;
+        public EnumAdapter(Context context) {
+            this.ctx = context;
+        }
+
+        @Override
+        public int getCount() {
+
+            if (mCadedate == null) {
+                return 0;
+            }
+
+            if (mKeywords == null || mKeywords.isEmpty()) {
+                filter_count = 0;
+                return mCadedate.optInt("count");
+            }
+
+            int count = 0;
+            for (int i = 0; i < mCadedate.optInt("count"); i++) {
+                JSONObject val_json = mCadedate.optJSONObject("val_" + i);
+                String value = val_json.optString("value");
+                boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
+                if (contain) {
+                    count++;
+                }
+            }
+            filter_count = count;
+            return count;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            JSONObject val_json = mCadedate.optJSONObject("val_" + position);
+            return val_json;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            JSONObject val_json = null;
+            if (mKeywords == null || mKeywords.isEmpty()) {
+                val_json = mCadedate.optJSONObject("val_" + position);
+            } else {
+                int count = 0;
+                for (int i = 0; i < val_json.optInt("count"); i++) {
+                    if (count >= filter_count) {
+                        break;
+                    }
+                    JSONObject search_json = mCadedate.optJSONObject("val_" + i);
+                    String value = search_json.optString("value");
+                    boolean contain = value.toUpperCase().contains(mKeywords.toUpperCase());
+                    if (contain) {
+                        count++;
+                    }
+
+                    if (count - 1 == position) {
+                        val_json = search_json;
+                    }
+
+                }
+            }
+
+            Holder holder;
+            if (convertView == null) {
+
+                convertView = LayoutInflater.from(this.ctx).inflate(R.layout.enum_select_cell,null);
+                holder = new Holder(convertView);
+
+            } else {
+                holder = (Holder) convertView.getTag();
+            }
+
+            String value = val_json.optString("value");
+            holder.value_tv.setText(value);
+
+            int check = val_json.optInt("check");
+            if (check == 1) {
+                holder.check_iv.setVisibility(View.VISIBLE);
+            } else {
+                holder.check_iv.setVisibility(View.INVISIBLE);
+            }
+
+            return convertView;
+        }
+    }
+}

+ 204 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/ImageUploadActivity.java

@@ -0,0 +1,204 @@
+package com.usai.redant.CommonEditor;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+
+import com.usai.redant.redantmobile.R;
+
+import java.io.File;
+import java.util.UUID;
+
+public class ImageUploadActivity extends AppCompatActivity {
+
+    private ImageView imageView;
+    private ImageButton albumBtn;
+    private ImageButton takeBtn;
+    private ImageButton uploadBtn;
+    private String img_path;
+    private Bitmap bitmap;
+
+    private Context mCtx = this;
+
+    private static int ALBUM_REQUEST_CODE = 1;
+    private static int CAMERA_REQUEST_CODE = 2;
+
+    private int group;
+    private int child;
+    private int btn_tag;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_image_upload);
+
+        imageView = (ImageView) findViewById(R.id.img_view);
+        albumBtn = (ImageButton) findViewById(R.id.photo_library_btn);
+        takeBtn = (ImageButton) findViewById(R.id.tack_photo_btn);
+        uploadBtn = (ImageButton) findViewById(R.id.photo_upload_btn);
+
+        Intent intent = getIntent();
+        group = intent.getIntExtra("group",0);
+        child = intent.getIntExtra("child",0);
+        btn_tag = intent.getIntExtra("btn",0);
+
+
+        if (savedInstanceState != null) {
+            img_path = savedInstanceState.getString("img_path");
+            if (img_path != null && !img_path.isEmpty()) {
+                bitmap = BitmapFactory.decodeFile(img_path);
+                imageView.setImageBitmap(bitmap);
+            }
+        }
+
+        albumBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_PICK, null);
+                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
+                intent.setAction(Intent.ACTION_GET_CONTENT);
+                startActivityForResult(intent, ALBUM_REQUEST_CODE);
+            }
+        });
+
+        takeBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                img_path = startCamera((ImageUploadActivity)mCtx,CAMERA_REQUEST_CODE);
+            }
+        });
+
+        uploadBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+
+
+                if (img_path != null && !img_path.isEmpty()) {
+                    // upload
+
+
+                    UUID uuid = UUID.randomUUID();
+                    String img_path = Utils.cacheTmpImage(bitmap);
+
+                    // upload success
+                    Intent intent = new Intent();
+                    intent.putExtra("url_down",uuid.toString());
+                    intent.putExtra("url_up",uuid.toString());
+                    intent.putExtra("path",img_path);
+                    intent.putExtra("group",group);
+                    intent.putExtra("child",child);
+                    intent.putExtra("btn",btn_tag);
+                    setResult(RESULT_OK,intent);
+                    finish();
+                }
+
+            }
+        });
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putString("img_path",img_path);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+
+        if (requestCode == ALBUM_REQUEST_CODE) {
+            if (resultCode == RESULT_OK) {
+                try {
+                    Uri uri = data.getData();
+                    final String absolutePath= getAbsolutePath(this, uri);
+                    img_path = absolutePath;
+                    if (img_path != null) {
+                        bitmap = BitmapFactory.decodeFile(img_path);
+                        imageView.setImageBitmap(bitmap);
+                    }
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        if (requestCode == CAMERA_REQUEST_CODE) {
+            if (resultCode == RESULT_OK) {
+
+                if (img_path != null) {
+                    bitmap = BitmapFactory.decodeFile(img_path);
+                    imageView.setImageBitmap(bitmap);
+                }
+
+            }
+        }
+
+    }
+
+    public String getAbsolutePath(final Context context, final Uri uri) {
+        if (null == uri) return null;
+        final String scheme = uri.getScheme();
+        String data = null;
+        if (scheme == null)
+            data = uri.getPath();
+        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
+            data = uri.getPath();
+        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
+            Cursor cursor = context.getContentResolver().query(uri,
+                    new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
+            if (null != cursor) {
+                if (cursor.moveToFirst()) {
+                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
+                    if (index > -1) {
+                        data = cursor.getString(index);
+                    }
+                }
+                cursor.close();
+            }
+        }
+        return data;
+    }
+
+    public static String startCamera(Activity activity, int requestCode) {
+        // 指定相机拍摄照片保存地址
+        String state = Environment.getExternalStorageState();
+        if (state.equals(Environment.MEDIA_MOUNTED)) {
+            Intent intent = new Intent();
+            // 指定开启系统相机的Action
+            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
+            File outDir = Environment
+                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+            if (!outDir.exists()) {
+                outDir.mkdirs();
+            }
+            File outFile = new File(outDir, System.currentTimeMillis() + ".jpg");
+            // 把文件地址转换成Uri格式
+            Uri uri = Uri.fromFile(outFile);
+            // 设置系统相机拍摄照片完成后图片文件的存放地址
+            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+            // 此值在最低质量最小文件尺寸时是0,在最高质量最大文件尺寸时是1
+            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
+            activity.startActivityForResult(intent, requestCode);
+            return outFile.getAbsolutePath();
+        } else {
+            Toast.makeText(activity, "请确认已经插入SD卡",
+                    Toast.LENGTH_LONG).show();
+            return null;
+        }
+    }
+}

+ 16 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/ImageViewActivity.java

@@ -0,0 +1,16 @@
+package com.usai.redant.CommonEditor;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.usai.redant.redantmobile.R;
+
+
+public class ImageViewActivity extends AppCompatActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_image_view);
+    }
+}

+ 113 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/MonthPickerActivity.java

@@ -0,0 +1,113 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.NumberPicker;
+
+import com.usai.redant.redantmobile.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class MonthPickerActivity extends AppCompatActivity {
+
+    public static class Builder {
+        public Intent build(Context context, String date, int group, int child) {
+
+            if (context == null) {
+                return null;
+            }
+            Intent intent = new Intent(context,MonthPickerActivity.class);
+
+            if (date != null) {
+                intent.putExtra("date",date);
+            }
+
+            intent.putExtra("group",group);
+            intent.putExtra("child",child);
+
+
+            return intent;
+        }
+    }
+
+    private NumberPicker yearPicker = null;
+    private NumberPicker monthPicker = null;
+
+    private int year;
+    private int month;
+    private int group;
+    private int child;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_month_picker);
+
+
+        yearPicker = (NumberPicker) findViewById(R.id.year_picker);
+        yearPicker.setMaxValue(2050);
+        yearPicker.setMinValue(2000);
+
+        monthPicker = (NumberPicker) findViewById(R.id.month_picker);
+        String[] monthArr = {"January","February","March","April","May","June","July","August","September","October","November","December"};
+        monthPicker.setDisplayedValues(monthArr);
+        monthPicker.setMinValue(0);
+        monthPicker.setMaxValue(monthArr.length - 1);
+
+        init();
+    }
+
+    private void init() {
+
+        Intent intent = getIntent();
+
+
+        group = intent.getIntExtra("group",0);
+        child = intent.getIntExtra("child",0);
+        String date_str = intent.getStringExtra("date");
+
+        if (date_str != null) {
+            String[] date_arr = date_str.split("/");
+            year = Integer.valueOf(date_arr[1]);
+            month = Integer.valueOf(date_arr[0]);
+        } else {
+            month = 1;
+            year = 2017;
+        }
+
+        yearPicker.setValue(year);
+        monthPicker.setValue(month - 1);
+
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.set_menu,menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.set_item: {
+                int year = yearPicker.getValue();
+                int month = monthPicker.getValue() + 1;
+                String date_str = month + "/" + year;
+                Intent intent = new Intent();
+                intent.putExtra("value",date_str);
+                intent.putExtra("group",group);
+                intent.putExtra("child",child);
+                setResult(RESULT_OK,intent);
+                finish();
+            }
+            break;
+        }
+        return true;
+    }
+}

+ 93 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/SignatureActivity.java

@@ -0,0 +1,93 @@
+package com.usai.redant.CommonEditor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.usai.redant.redantmobile.R;
+
+public class SignatureActivity extends AppCompatActivity {
+
+
+    public static class Builder {
+        public Intent build(Context context,int group, int child) {
+            Intent intent = new Intent(context,SignatureActivity.class);
+
+            intent.putExtra("group",group);
+            intent.putExtra("child",child);
+
+            return intent;
+        }
+    }
+
+    private BrushView brushView;
+    private int group,child;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_signature);
+
+        brushView = (BrushView) findViewById(R.id.brush_view);
+
+//        brushView = new BrushView(this);
+//        setContentView(brushView);
+
+        Intent intent = getIntent();
+        group = intent.getIntExtra("group",0);
+        child = intent.getIntExtra("child",0);
+
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.signature_action_bar_menu,menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+        switch (item.getItemId()) {
+            case R.id.save_signature_item: {
+                if (brushView.checkCanSave()) {
+                    Bitmap bitmap = brushView.getDrawBitmap();
+                    String path = Utils.cacheTmpImage(bitmap);
+
+                    // upload signature
+
+                    // upload success
+                    Intent intent = new Intent();
+                    intent.putExtra("url_down",path);
+                    intent.putExtra("url_up",path);
+                    intent.putExtra("path",path);
+                    intent.putExtra("group",group);
+                    intent.putExtra("child",child);
+
+                    setResult(RESULT_OK,intent);
+                    finish();
+                } else {
+
+                    new AlertDialog.Builder(this)
+                            .setTitle("Warning")
+                            .setMessage("Please Sign")
+                            .setPositiveButton("Ok",null)
+                            .show();
+
+                }
+            }
+            break;
+            case R.id.clear_signature_item: {
+                brushView.clear();
+            }
+            break;
+        }
+
+        return true;
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 241 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/CommonEditor/Utils.java


+ 966 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/Result/SearchResultActivity.java

@@ -0,0 +1,966 @@
+package com.usai.redant.Result;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.text.Layout;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.HorizontalScrollView;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+
+import com.usai.redant.redantmobile.BuildConfig;
+import com.usai.redant.redantmobile.R;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+public class SearchResultActivity extends AppCompatActivity implements AbsListView.OnScrollListener {
+
+    private JSONObject mParams;
+    private JSONObject resultData;
+
+    private Context mContext;
+    private ListView resultListView;
+    private ResultAdapter adapter;
+
+    private View clickedView;
+    private View.OnTouchListener resultRowClickListener;
+    private GestureDetector detector;
+
+    private TextView footer;
+    private int footer_height = 60;
+
+    ProgressDialog progressDialog;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_search_result);
+
+        mContext = this;
+        resultListView = (ListView)findViewById(R.id.result_table);
+
+        progressDialog = new ProgressDialog(mContext);
+        progressDialog.setCancelable(false);
+
+        initClickListener();
+
+
+        footer = new TextView(mContext);
+        footer.setBackgroundColor(Color.WHITE);
+        footer.setGravity(Gravity.CENTER);
+        footer.setText("Load More");
+        footer.setTextSize(sp2px(mContext,8));
+        footer.setVisibility(View.INVISIBLE);
+
+        AbsListView.LayoutParams footerLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,footer_height);
+        footer.setLayoutParams(footerLayoutParams);
+
+        resultListView.addFooterView(footer);
+
+
+        adapter = new ResultAdapter(mContext);
+        resultListView.setAdapter(adapter);
+        resultListView.setDividerHeight(0);
+
+        resultListView.setOnScrollListener(this);
+
+        loadData();
+
+    }
+
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.result_menu,menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+        if (item.getItemId() == R.id.result_menu) {
+
+            try {
+
+                JSONArray menu = resultData.getJSONArray("menu");
+
+                if (menu.length() > 0) {
+                    ArrayList<String> titleList = new ArrayList<>();
+
+                    for (int i = 0; i < menu.length(); i++) {
+                        JSONObject json = menu.getJSONObject(i);
+                        String title = json.getString("title");
+                        titleList.add(title);
+                    }
+
+                    new AlertDialog.Builder(mContext)
+                            .setSingleChoiceItems((String[])titleList.toArray(new String[titleList.size()]), -1, new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+
+                                    try {
+                                        JSONArray menu = resultData.getJSONArray("menu");
+                                        JSONObject json = menu.getJSONObject(which);
+
+                                        String actionType = json.getString("action");
+                                        String url = json.optString("url");
+
+                                        if (actionType.equals("download")) {
+                                            export(url);
+                                        } else if (actionType.equals("save")) {
+                                            if(BuildConfig.DEBUG && true){
+                                                //do something for assert aim
+                                                Log.e("Result", "onOptionsItemSelected DialogClick: not implement");
+                                            }
+                                        }
+
+                                    } catch (JSONException exception) {
+                                        Log.d("Result", "onClick: ",exception);
+                                    }
+                                    dialog.dismiss();
+                                }
+                            })
+                            .show();
+                }
+
+            } catch (JSONException e) {
+                Log.e("Result", "onOptionsItemSelected: ", e);
+            }
+
+        }
+
+        return true;
+    }
+
+    public int last_index;
+    public int total_index;
+    public boolean isLoading = false;//表示是否正处于加载状态
+
+    @Override
+    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+        last_index = firstVisibleItem+visibleItemCount;
+        total_index = totalItemCount;
+    }
+
+    @Override
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+        if(last_index == total_index && (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE))
+        {
+            // 表示此时需要显示刷新视图界面进行新数据的加载(要等滑动停止)
+            if(!isLoading)
+            {
+                // 设置刷新界面可见
+                footer.setVisibility(View.VISIBLE);
+                loadMore();
+            }
+        }
+    }
+
+    private void setupUI() {
+        try {
+            JSONObject layout = resultData.getJSONObject("layout");
+
+            JSONObject header = layout.getJSONObject("header");
+            int width = header.getInt("width");
+            width = convertDp2Px(width);
+
+            AbsListView.LayoutParams footerLayoutParams = (AbsListView.LayoutParams)footer.getLayoutParams();
+            if (footerLayoutParams == null) {
+                footerLayoutParams = new AbsListView.LayoutParams(width,footer_height);
+            }
+            footerLayoutParams.height = footer_height;
+            footerLayoutParams.width = width;
+
+            footer.setLayoutParams(footerLayoutParams);
+
+
+        } catch (JSONException e) {
+            Log.e("Result", "setupUI: ", e);
+        }
+
+    }
+
+    public void loadComplete() {
+        footer.setVisibility(View.GONE);//设置刷新界面不可见
+        resultListView.forceLayout();
+
+        isLoading = false;//设置正在刷新标志位false
+        invalidateOptionsMenu();
+
+        progressDialog.hide();
+    }
+
+
+    private void showProgressDialog(String title, String msg) {
+        progressDialog.setTitle(title);
+        progressDialog.setMessage(msg);
+        progressDialog.show();
+    }
+
+    private void loadData() {
+
+        isLoading = true;
+
+        showProgressDialog(null,"Loading");
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                try {
+
+                    Thread.sleep(2000);
+
+                    InputStream in = getResources().openRawResource( R.raw.result);
+                    int length = in.available();
+                    byte[] buffer = new byte[length];
+                    in.read(buffer);
+                    String res = new String(buffer,"utf8");
+                    in.close();
+                    resultData = new JSONObject(res);
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            setupUI();
+                            loadComplete();
+                            adapter.notifyDataSetChanged();
+                        }
+                    });
+
+                } catch (Exception e) {
+                    Log.e("Result", "onCreate: ",e);
+                }
+
+
+
+
+            }
+        }).start();
+
+    }
+
+    private void loadMore() {
+
+        isLoading = true;
+        showProgressDialog(null,"Loading");
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                try {
+
+                    Thread.sleep(2000);
+
+                    InputStream in = getResources().openRawResource( R.raw.result);
+                    int length = in.available();
+                    byte[] buffer = new byte[length];
+                    in.read(buffer);
+                    String res = new String(buffer,"utf8");
+                    in.close();
+
+                    JSONObject newJson = new JSONObject(res);
+
+                    JSONObject newData = newJson.getJSONObject("data");
+                    int add_count = newData.getInt("count");
+
+                    JSONObject data = resultData.getJSONObject("data");
+                    int count = data.getInt("count");
+
+                    for (int i = 0; i < add_count; i++) {
+                        JSONArray new_data_item = newData.getJSONArray("item_" + i);
+                        if (new_data_item != null) {
+                            data.put("item_" + count++,new_data_item);
+                        }
+                    }
+                    data.put("count",count);
+                    resultData.put("data",data);
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            setupUI();
+                            loadComplete();
+                            adapter.notifyDataSetChanged();
+                        }
+                    });
+
+                } catch (Exception e) {
+                    Log.e("Result", "onCreate: ",e);
+                }
+
+
+
+
+            }
+        }).start();
+    }
+
+    private JSONObject contentData() {
+        try {
+            return resultData.getJSONObject("data");
+        } catch (JSONException e) {
+            Log.e("Result", "contentData: ", e);
+        }
+        return null;
+    }
+
+    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent e) {
+
+
+            if (e.getAction() == MotionEvent.ACTION_UP) {
+
+                TableRow cellRow = (TableRow)clickedView.getParent();
+                RelativeLayout cell = (RelativeLayout)cellRow.getParent();
+
+                int position = resultListView.getPositionForView(cell);
+//                Log.d("Result", "onDoubleTapEvent: " + position);
+
+                if (position == 0) {
+                    return false;
+                }
+
+                try {
+
+                    JSONArray row_action = resultData.getJSONArray("row_action");
+                    if (row_action != null) {
+
+                        if (row_action.length() == 1) {
+
+                            JSONObject action = row_action.getJSONObject(0);
+                            String module = action.getString("module");
+
+                            if (module.equals("quick_look")) {
+                                JSONObject param = action.getJSONObject("params");
+                                String url = action.getString("url");
+                                showQuickLook(param,url);
+                            } else if (module.equals("kv_detail")) {
+                                JSONObject params = new JSONObject();
+                                params.put("query_id",mParams.get("query_id"));
+
+                                JSONObject criteria = new JSONObject();
+                                JSONObject action_params = action.getJSONObject("params");
+                                Iterator<String> iterator = action_params.keys();
+                                while (iterator.hasNext()) {
+                                    String key = iterator.next();
+                                    JSONArray item = contentData().getJSONArray("item_" + position);
+                                    int idx = action_params.getInt(key);
+                                    criteria.put(key,item.get(idx));
+                                }
+
+                                params.put("criteria",criteria.toString());
+                                showKVDetail(params);
+
+                            } else if (module.equals("order_detail")) {
+
+                                showOrderDetail();
+
+                            }
+
+
+                        } else if (row_action.length() > 1) {
+
+                            ArrayList<String> titleList = new ArrayList<>();
+
+                            for (int i = 0; i < row_action.length(); i++) {
+                                JSONObject json = row_action.getJSONObject(i);
+                                String title = json.getString("title");
+                                titleList.add(title);
+                            }
+
+                            new AlertDialog.Builder(mContext)
+                                    .setSingleChoiceItems((String[])titleList.toArray(new String[titleList.size()]), -1, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+
+                                            try {
+                                                JSONArray content_action = resultData.getJSONArray("row_action");
+                                                JSONObject json = content_action.getJSONObject(which);
+                                                String module = json.getString("module");
+                                                JSONObject add_params = json.getJSONObject("params");
+
+                                                if (module.equals("quick_look")) {
+                                                    JSONObject param = json.getJSONObject("params");
+                                                    String url = json.getString("url");
+                                                    showQuickLook(param,url);
+                                                } else if (module.equals("kv_detail")) {
+
+                                                    JSONObject params = json.getJSONObject("params");
+                                                    showKVDetail(params);
+
+                                                } else if (module.equals("order_detail")) {
+
+                                                    showOrderDetail();
+
+                                                }
+
+
+                                            } catch (JSONException exception) {
+                                                Log.d("Result", "onClick: ",exception);
+                                            }
+                                            dialog.dismiss();
+
+                                        }
+                                    })
+                                    .show();
+
+                        }
+
+                    }
+
+                } catch (JSONException exception) {
+                    Log.e("Result", "onDoubleTapEvent: ",exception);
+                }
+
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            if (clickedView instanceof TextView) {
+                TextView tv = (TextView)clickedView;
+                if (ellipsisTextView(tv)) {
+                    showAlert(tv.getText().toString());
+                }
+            }
+            return false;
+        }
+    }
+
+    private void initClickListener() {
+
+        // 需要作为成员变量
+        detector = new GestureDetector(mContext, new GestureListener());
+
+        resultRowClickListener = new View.OnTouchListener() {
+
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+
+                clickedView = v;
+
+                detector.onTouchEvent(event);
+
+                return true;
+            }
+        };
+
+    }
+
+
+
+    private class ResultAdapter extends BaseAdapter {
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return true;
+        }
+
+        private class ResultHoder {
+            public ResultHoder(View view) {
+                row = (TableRow)view.findViewById(R.id.result_row);
+                view.setTag(this);
+            }
+            TableRow row;
+        }
+
+        public ResultAdapter(Context ctx) {
+
+        }
+
+        @Override
+        public void registerDataSetObserver(DataSetObserver observer) {
+
+        }
+
+        @Override
+        public void unregisterDataSetObserver(DataSetObserver observer) {
+
+        }
+
+        @Override
+        public int getCount() {
+            if (resultData == null) {
+                return 0;
+            }
+            try {
+                JSONObject data = resultData.getJSONObject("data");
+                int result_count = data.getInt("count");
+                return result_count + 1; // header + data
+
+            } catch (JSONException e) {
+                Log.e("Result", "getCount: ", e);
+            }
+            return 0;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            try {
+                if (position == 0) {
+                    // header
+
+                    JSONObject layout = resultData.getJSONObject("layout");
+                    JSONObject header = layout.getJSONObject("header");
+                    JSONArray col = header.getJSONArray("col");
+
+                    return col;
+
+                } else {
+                    // result row
+
+                    JSONObject data = resultData.getJSONObject("data");
+                    JSONArray item = data.getJSONArray("item_" + (position - 1));
+
+                    return item;
+                }
+
+
+            } catch (JSONException e) {
+                Log.e("Result", "getItem: ", e);
+            }
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return false;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+
+            View cell;
+            ResultHoder holder;
+            if (convertView == null) {
+
+                cell = LayoutInflater.from(mContext).inflate(R.layout.result_cell,null);
+                holder = new ResultHoder(cell);
+
+
+            } else {
+
+                cell = convertView;
+                holder = (ResultHoder)cell.getTag();
+
+            }
+//            holder.row.removeAllViews();
+
+//            cell.setOnTouchListener(resultRowClickListener);
+
+            // setup
+           try {
+
+               JSONObject layout = resultData.getJSONObject("layout");
+
+               JSONObject header = layout.getJSONObject("header");
+               int width = header.getInt("width");
+               int height = header.getInt("height");
+               int margin_t = header.getInt("margin_t");
+               int margin_l = header.getInt("margin_l");
+               int margin_b = header.getInt("margin_b");
+               int margin_r = header.getInt("margin_r");
+
+               width = convertDp2Px(width);
+               height = convertDp2Px(height);
+               margin_t = convertDp2Px(margin_t);
+               margin_l = convertDp2Px(margin_l);
+               margin_b = convertDp2Px(margin_b);
+               margin_r = convertDp2Px(margin_r);
+
+               HorizontalScrollView.LayoutParams listViewLayoutParams = (HorizontalScrollView.LayoutParams)resultListView.getLayoutParams();
+               listViewLayoutParams.width = width;
+               resultListView.setLayoutParams(listViewLayoutParams);
+
+               JSONArray obj = (JSONArray)getItem(position);
+               if (position == 0) {
+
+                   // header
+                   String bg_color = header.getString("bg_color");
+                   String f_color = header.getString("f_color");
+
+                   bg_color = bg_color.replace("0x","#");
+                   f_color = f_color.replace("0x","#");
+
+                   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)holder.row.getLayoutParams();
+                   layoutParams.height = height;
+                   holder.row.setLayoutParams(layoutParams);
+
+                   // col
+                   for (int i = 0; i < obj.length(); i++) {
+
+                       JSONObject value = obj.getJSONObject(i);
+                       int col_w = value.getInt("width");
+                       col_w = convertDp2Px(col_w);
+
+                       String h_align = value.getString("h_align");
+                       String v_center = value.getString("v_center");
+                       String col_bg_color = value.getString("bg_color");
+                       String col_f_color = value.getString("f_color");
+                       String name = value.getString("name");
+
+                       bg_color = bg_color.replace("0x","#");
+                       f_color = f_color.replace("0x","#");
+
+                       TextView tv = (TextView)holder.row.findViewById(i);
+                       if (tv == null) {
+                           tv = new TextView(mContext);
+                           tv.setWidth(col_w);
+                           tv.setHeight(height);
+                           tv.setGravity(convertGravity("h_align",h_align) | convertGravity("v_center",v_center));
+
+                           tv.setTextColor(Color.parseColor(f_color));
+
+                           tv.setSingleLine();
+                           tv.setEllipsize(TextUtils.TruncateAt.END);
+
+                           tv.setPadding(margin_l,margin_t,margin_r,margin_b);
+
+                           TableRow.LayoutParams tvLayoutParams = new  TableRow.LayoutParams(col_w, height);
+//                       tv.setLayoutParams(tvLayoutParams);
+
+                           tv.setId(i);
+                           holder.row.addView(tv,i,tvLayoutParams);
+                           tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.result_black_border));
+
+                           tv.setOnTouchListener(resultRowClickListener);
+                       }
+
+
+                       tv.setText(name);
+
+                   }
+                   holder.row.setBackgroundColor(Color.parseColor(bg_color));
+
+               } else {
+
+                   // row
+                   JSONObject row = layout.getJSONObject("row");
+                   String f_color = row.getString("f_color");
+                   String color_0 = row.getString("color_0");
+                   String color_1 = row.getString("color_1");
+                   f_color = f_color.replace("0x","#");
+                   color_0 = color_0.replace("0x","#");
+                   color_1 = color_1.replace("0x","#");
+
+                   int row_h = row.getInt("height");
+                   row_h = convertDp2Px(row_h);
+
+                   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)holder.row.getLayoutParams();
+                   layoutParams.height = row_h;
+                   holder.row.setLayoutParams(layoutParams);
+
+                   // col
+                   for (int i = 0; i < obj.length(); i++) {
+
+                       JSONArray col_layout = row.getJSONArray("val");
+                       JSONObject layout_val = col_layout.getJSONObject(i);
+
+                       String type = layout_val.getString("type");
+                       String h_align = layout_val.getString("h_align");
+                       String v_center = layout_val.getString("v_center");
+                       String col_bg_color = layout_val.getString("bg_color");
+                       String col_f_color = layout_val.getString("f_color");
+
+                       col_bg_color = col_bg_color.replace("0x","#");
+                       col_f_color = col_f_color.replace("0x","#");
+
+                       String value = obj.getString(i);
+
+
+                       JSONObject size = ((JSONArray)getItem(0)).getJSONObject(i);
+                       int col_w = size.getInt("width");
+                       int col_h = row.getInt("height");
+
+                       col_w = convertDp2Px(col_w);
+                       col_h = convertDp2Px(col_h);
+
+                       TextView tv = (TextView) holder.row.findViewById(i);
+                       if (tv == null) {
+                           tv = new TextView(mContext);
+                           tv.setWidth(col_w);
+                           tv.setHeight(col_h);
+                           tv.setGravity(convertGravity("h_align",h_align) | convertGravity("v_center",v_center));
+                           tv.setTextColor(Color.parseColor(col_f_color));
+
+                           tv.setSingleLine();
+                           tv.setEllipsize(TextUtils.TruncateAt.END);
+
+                           tv.setPadding(margin_l,margin_t,margin_r,margin_b);
+
+                           TableRow.LayoutParams tvLayoutParams = new  TableRow.LayoutParams(col_w, col_h);
+
+                           tv.setId(i);
+                           holder.row.addView(tv,i,tvLayoutParams);
+
+                           tv.setOnTouchListener(resultRowClickListener);
+                           tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.result_black_border));
+                       }
+
+                       tv.setText(value);
+
+
+                   }
+
+                   if ((position - 1) % 2 == 0) {
+                       holder.row.setBackgroundColor(Color.parseColor(color_0));
+                   } else {
+                       holder.row.setBackgroundColor(Color.parseColor(color_1));
+
+                   }
+
+               }
+
+           } catch (JSONException e) {
+               Log.e("Result", "getView: ", e);
+           }
+
+            return cell;
+        }
+
+        private int convertGravity(String key, String align) {
+
+            if (key.equals("h_align")) {
+                if (align.equals("center")) {
+                    return Gravity.CENTER_HORIZONTAL;
+                } else if (align.equals("left")) {
+                    return Gravity.LEFT;
+                } else if (align.equals("right")) {
+                    return Gravity.RIGHT;
+                }
+
+            }
+
+            if (key.equals("v_center")) {
+
+                if (align.equals("center")) {
+                    return Gravity.CENTER_VERTICAL;
+                } else if (align.equals("top")) {
+                    return Gravity.TOP;
+                } else if (align.equals("bottom")) {
+                    return Gravity.BOTTOM;
+                }
+            }
+            return Gravity.CENTER;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return false;
+        }
+    }
+
+
+    public boolean ellipsisTextView(TextView tv) {
+        Layout l = tv.getLayout();
+        if ( l != null){
+            int lines = l.getLineCount();
+            if ( lines > 0) {
+                if (l.getEllipsisCount(lines - 1) > 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public int convertDp2Px(int dp) {
+        return dp2px(mContext,dp);
+    }
+
+    public int px2dp(Context context, float pxValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    public int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    public int px2sp(Context context, float pxValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (pxValue / fontScale + 0.5f);
+    }
+
+    public int sp2px(Context context, float spValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (spValue * fontScale + 0.5f);
+    }
+
+
+    private String documentPath;
+    private String download_query;
+    private void export(String url) {
+
+        if (download_query != null) {
+            documentPath = download_query;
+            Uri uri= Uri.parse(download_query);
+            openFileAtPath(uri,"*/*");
+            return;
+        }
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                // download & get path
+                String path = null;
+
+                if(BuildConfig.DEBUG && true){
+                    //do something for assert aim
+                    Log.e("Result", "onClick: not implement");
+                }
+
+                documentPath = path;
+                download_query = path;
+
+                if (path != null) {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            Uri uri= Uri.parse(documentPath);
+                            openFileAtPath(uri,"*/*");
+                        }
+                    });
+                }
+
+            }
+        }).start();
+
+    }
+
+    public void showAlert(String msg) {
+        if (msg == null || msg.isEmpty()) {
+            return;
+        }
+
+        new AlertDialog.Builder(mContext)
+                .setMessage(msg)
+                .show();
+    }
+
+    public void showOrderDetail() {
+        if(BuildConfig.DEBUG && true){
+            //do something for assert aim
+            Log.e("Result", "showOrderDetail: not implement");
+        }
+    }
+
+    public void showKVDetail(JSONObject param) {
+        if(BuildConfig.DEBUG && true){
+            //do something for assert aim
+            Log.e("Result", "showKVDetail: not implement");
+        }
+    }
+
+    public void showQuickLook(JSONObject param, String url) {
+
+        // 下载文件
+        if(BuildConfig.DEBUG && true){
+            //do something for assert aim
+            Log.e("Result", "showQuickLook: not implement");
+        }
+
+        // path mimeType
+        String path = null;
+        String type = null;
+        if (path != null && !path.isEmpty()) {
+            Uri uri= Uri.parse(path);
+            if (type == null) {
+                type = "*/*";
+            }
+            openFileAtPath(uri,type);
+        }
+    }
+
+    private void openFileAtPath(Uri uri, String type) {
+        // type "application/pdf"
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setDataAndType(uri, type);
+        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
+            // someone knows how to handle this mime type with this scheme, don't download.
+            try {
+                startActivity(intent);
+                return;
+            } catch (Exception ex) {
+                Log.d("Open File", "activity not found for " + type + " over " + uri, ex);
+            }
+
+        } else {
+            Log.d("Open File", "openFileAtPath: " + "No App " + uri);
+            try {
+                shareFile(uri,type);
+            } catch (Exception e) {
+                Log.e("Show Dialog Error", "openFileAtPath: ", e);
+            }
+        }
+
+    }
+
+    private void shareFile(Uri uri, String type) {
+
+        Intent shareIntent = new Intent();
+        shareIntent.setAction(Intent.ACTION_SEND);
+        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
+        shareIntent.setType(type);
+        startActivity(Intent.createChooser(shareIntent, "Share"));
+    }
+
+
+}

+ 0 - 316
RedAnt Mobile/app/src/main/java/com/usai/redant/raimage/ServerSettingActivity.java

@@ -1,316 +0,0 @@
-package com.usai.redant.raimage;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import com.usai.redant.redantmobile.R;
-import com.usai.redant.redantmobile.RedAntApplication;
-
-public class ServerSettingActivity extends Activity
-{
-	static final int	REQUEST_SCAN_BARCODE	= 2;
-
-//	public boolean checkCameraPermission() {
-//		int permission = ContextCompat.checkSelfPermission(ServerSettingActivity.this, "android.permission.CAMERA");
-//		if (permission == PackageManager.PERMISSION_DENIED) {
-//
-//			new AlertDialog.Builder(this)
-//					.setTitle("Warning")
-//					.setMessage("RA Image need camera permission")
-//					.setPositiveButton("Setting", new DialogInterface.OnClickListener() {
-//						@Override
-//						public void onClick(DialogInterface dialog, int which) {
-//							Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
-//							intent.setData(Uri.parse("package:" + getPackageName()));
-//							startActivity(intent);
-//						}
-//					})
-//					.setNegativeButton("No", new DialogInterface.OnClickListener() {
-//						@Override
-//						public void onClick(DialogInterface dialog, int which) {
-//							finish();
-//						}
-//					})
-//					.show();
-//
-//			return false;
-//		}
-//		return true;
-//	}
-
-	@Override
-	protected void onCreate(Bundle savedInstanceState)
-	{
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.activity_service_setting);
-
-		SharedPreferences pref = RedAntApplication.getInstance()
-				.getSharedPreferences("RA Image", 0);
-
-//		String ia = pref.getString("ia", null);
-//		String ea = pref.getString("ea", null);
-		String aa = pref.getString("aa", null);
-		String station_name = pref.getString("station name", null);
-//		RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1);
-
-//		if (!TextUtils.isEmpty(aa) && aa.equals(ia))
-//			rg.check(R.id.radio0);
-
-//		if (!TextUtils.isEmpty(aa) && aa.equals(ea))
-//			rg.check(R.id.radio1);
-
-		EditText et_ia = (EditText) findViewById(R.id.et_ia);
-//		EditText et_ea = (EditText) findViewById(R.id.et_ea);
-		EditText et_name = (EditText) findViewById(R.id.et_name);
-//		et_ea.setText(ea);
-		et_ia.setText(aa);
-		et_name.setText(station_name);
-
-//		ImageButton ibtn = (ImageButton) findViewById(R.id.ibtn_scan);
-//		ibtn.setOnClickListener(new OnClickListener()
-//		{
-//
-//			@Override
-//			public void onClick(View v)
-//			{
-//			//	Log.d(TAG, "==============>Click Scan button");
-////				if (!RAUtil.checkPermission(ServerSettingActivity.this,"android.permission.CAMERA")) {
-////
-////					return;
-////				}
-//
-//				Intent intent = new Intent();
-//
-//				intent.setClass(ServerSettingActivity.this,
-//						CaptureActivity.class);
-//				startActivityForResult(intent, REQUEST_SCAN_BARCODE);
-//
-//			}
-//		});
-	}
-
-	@Override
-	public boolean onCreateOptionsMenu(Menu menu)
-	{
-		// Inflate the menu; this adds items to the action bar if it is present.
-		getMenuInflater().inflate(R.menu.server_setting, menu);
-		return true;
-	}
-
-	@Override
-	public void onActivityResult(int requestCode, int resultCode, Intent data)
-	{
-
-		if (requestCode == REQUEST_SCAN_BARCODE)
-		{
-			if (resultCode == Activity.RESULT_OK)
-			{
-				Bundle bundle = data.getExtras();
-				String jstr = bundle.getString("pid");
-				
-				if (jstr == null || jstr.length() <= 0)
-				{
-					//Log.d(TAG, "json is wrong");
-					toast();
-					return ;//Network.RESULT_NET_ERROR;
-				}	
-				String address[]=jstr.split(";");
-				EditText et_ia = (EditText) findViewById(R.id.et_ia);
-//				EditText et_ea = (EditText) findViewById(R.id.et_ea);
-				EditText et_name = (EditText) findViewById(R.id.et_name);
-				if (address.length==3)
-				{
-					et_ia.setText(address[2].trim());
-					et_name.setText(address[0].trim());
-				}
-				else if(address.length==2)
-				{
-					et_ia.setText(address[1].trim());
-					et_name.setText(address[0].trim());
-				}
-				else
-				{
-					toast();
-					return;
-				}
-
-//				et_ea.setText(address[2].trim());
-
-//				JSONObject jsobj;
-//				try
-//				{
-//					jsobj = new JSONObject(jstr);
-//					if (jsobj.length() > 0)
-//					{
-//						String name = jsobj.getString("name");
-//						String ia = jsobj.getString("ia");
-//						String ea = jsobj.getString("ea");
-//						EditText et_ia = (EditText) findViewById(R.id.et_ia);
-//						EditText et_ea = (EditText) findViewById(R.id.et_ea);
-//						et_ea.setText(ea);
-//						et_ia.setText(ia);
-////						int iresult = jsobj.getInt("result");
-////						if (iresult == Network.AP_USER_AUTH)
-////						{
-////							return ;//RESULT_TRUE;
-////						}
-////
-////						else
-////						{
-////
-////							return ;//RESULT_FALSE;
-////						}
-//					}
-//					return ;
-//				}
-//				catch (JSONException e)
-//				{
-//					// TODO Auto-generated catch block
-//					e.printStackTrace();
-//					return ;
-//				}
-				//Log.d(TAG,
-//						"REQUEST_SCAN_BARCODE==========>pid="
-//								+ bundle.getString("pid"));
-//				TextView pidval = (TextView) findViewById(R.id.pidval);
-//				pidval.setText(pid);
-//				updateUploadButton();
-			}
-		}
-		super.onActivityResult(requestCode, resultCode, data);
-	}
-
-	@Override
-	public boolean onOptionsItemSelected(MenuItem item)
-	{
-		// Handle action bar item clicks here. The action bar will
-		// automatically handle clicks on the Home/Up button, so long
-		// as you specify a parent activity in AndroidManifest.xml.
-		int id = item.getItemId();
-		if (id == R.id.action_save)
-		{
-			EditText et_ia = (EditText) findViewById(R.id.et_ia);
-//			EditText et_ea = (EditText) findViewById(R.id.et_ea);
-			EditText et_name = (EditText) findViewById(R.id.et_name);
-			String ia = et_ia.getText().toString();
-//			String ea = et_ea.getText().toString();
-			String name = et_name.getText().toString();
-			if (TextUtils.isEmpty(ia) )
-			{
-				showdialog("Server address can not be empty!");
-				return true;
-			}
-
-			SharedPreferences pref = RedAntApplication.getInstance()
-					.getSharedPreferences("RA Image", 0);
-			SharedPreferences.Editor editor = pref.edit();
-
-
-
-
-			if (TextUtils.isEmpty(name))
-			{
-				showdialog("Station name can not be empty!");
-				return true;
-			}
-			else {
-				
-				editor.putString("station name", name);
-			}
-			if (!TextUtils.isEmpty(ia))
-			{
-
-				if (!ia.substring(ia.length() - 1).equals("/"))
-					ia = ia + "/";
-				editor.putString("aa", ia);
-				RedAntApplication.active_address = ia;
-
-			}
-//			if (!TextUtils.isEmpty(ea))
-//			{
-//				if (!ea.substring(ea.length() - 1).equals("/"))
-//					ea = ea + "/";
-//				editor.putString("ea", ea);
-//			}
-//			RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1);
-//			if (rg.getCheckedRadioButtonId() == R.id.radio0)
-//			{
-//				if (!TextUtils.isEmpty(ia))
-//				{
-//					editor.putString("aa", ia);
-//					RedAntApplication.active_address = ia;
-//				}
-//				else
-//				{
-//					showdialog("Active server address can not be empty!");
-//					return true;
-//				}
-//			}
-//			else
-//			{
-//				if (!TextUtils.isEmpty(ea))
-//				{
-//					editor.putString("aa", ea);
-//					RedAntApplication.active_address = ea;
-//				}
-//				else
-//				{
-//					showdialog("Active server address can not be empty!");
-//					return true;
-//				}
-//			}
-
-			RedAntApplication.station_name = name;
-
-			editor.remove("Lat");
-			editor.remove("Lon");
-			editor.commit();
-			//sendBroadcast(new Intent("REDANT.POP.RESET_LOCATION"));
-
-
-			String result = pref.getString("aa","");
-			Intent intent = new Intent();
-			intent.putExtra("server", result);
-                /*
-                 * 调用setResult方法表示我将Intent对象返回给之前的那个Activity,这样就可以在onActivityResult方法中得到Intent对象,
-                 */
-			setResult(1001, intent);
-			finish();
-			return true;
-		}
-		return super.onOptionsItemSelected(item);
-	}
-
-	private void toast()
-	{
-		Toast toast = Toast.makeText(this,"Wrong server setting format",
-				Toast.LENGTH_LONG);
-		toast.setGravity(Gravity.CENTER, 0, 0);
-		toast.show();
-	}
-	private void showdialog(String msg)
-	{
-		new AlertDialog.Builder(ServerSettingActivity.this)
-				.setIcon(android.R.drawable.ic_dialog_info).setTitle("Error!")
-				.setMessage(msg)
-				.setPositiveButton("OK", new DialogInterface.OnClickListener()
-				{
-					public void onClick(DialogInterface dialog, int whichButton)
-					{
-
-						// finish();
-						/* User clicked OK so do some stuff */
-					}
-				}).show();
-	}
-}

+ 2 - 3
RedAnt Mobile/app/src/main/java/com/usai/redant/redantmobile/LoginActivity.java

@@ -30,7 +30,6 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import com.usai.redant.raimage.ModeActivity;
-import com.usai.redant.raimage.ServerSettingActivity;
 import com.usai.redant.util.AES;
 import com.usai.redant.util.Network;
 import com.usai.redant.util.RAUtil;
@@ -130,7 +129,7 @@ public class LoginActivity extends AppCompatActivity {
                 dbUtil.CloseDB(db);*/
 
                 SharedPreferences pref = RedAntApplication.getInstance()
-                        .getSharedPreferences("RA Image", 0);
+                        .getSharedPreferences("redant mobile", 0);
                 SharedPreferences.Editor editor = pref.edit();
 
                 if (m_swSave.isChecked()&&!TextUtils.isEmpty(encryptPass)&&!TextUtils.isEmpty(encryptUser))
@@ -394,7 +393,7 @@ public class LoginActivity extends AppCompatActivity {
         m_etName = (AutoCompleteTextView) findViewById(R.id.et_user);
 
         SharedPreferences pref = RedAntApplication.getInstance()
-                .getSharedPreferences("RA Image", 0);
+                .getSharedPreferences("redant mobile", 0);
 
 
         HashSet<String> user_list= (HashSet<String>) pref.getStringSet("user_list",new HashSet<String>());

+ 2 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/redantmobile/RedAntApplication.java

@@ -33,6 +33,8 @@ public class RedAntApplication extends Application
 	public static String device_id;
 	public static JSONObject server_info;
 
+	public static String server;
+
     public static RedAntApplication getInstance() {  
         return instance;  
     }  

+ 436 - 0
RedAnt Mobile/app/src/main/java/com/usai/redant/redantmobile/ServerSettingActivity.java

@@ -0,0 +1,436 @@
+package com.usai.redant.redantmobile;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.usai.redant.util.AES;
+import com.usai.redant.util.Network;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class ServerSettingActivity extends Activity
+{
+	static final int	REQUEST_SCAN_BARCODE	= 2;
+
+//	public boolean checkCameraPermission() {
+//		int permission = ContextCompat.checkSelfPermission(ServerSettingActivity.this, "android.permission.CAMERA");
+//		if (permission == PackageManager.PERMISSION_DENIED) {
+//
+//			new AlertDialog.Builder(this)
+//					.setTitle("Warning")
+//					.setMessage("RA Image need camera permission")
+//					.setPositiveButton("Setting", new DialogInterface.OnClickListener() {
+//						@Override
+//						public void onClick(DialogInterface dialog, int which) {
+//							Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+//							intent.setData(Uri.parse("package:" + getPackageName()));
+//							startActivity(intent);
+//						}
+//					})
+//					.setNegativeButton("No", new DialogInterface.OnClickListener() {
+//						@Override
+//						public void onClick(DialogInterface dialog, int which) {
+//							finish();
+//						}
+//					})
+//					.show();
+//
+//			return false;
+//		}
+//		return true;
+//	}
+
+	private Context mContext;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_service_setting);
+
+		mContext = this;
+
+		EditText et_ia = (EditText) findViewById(R.id.et_ia);
+		EditText et_name = (EditText) findViewById(R.id.et_name);
+
+		SharedPreferences pref = RedAntApplication.getInstance()
+				.getSharedPreferences("redant mobile", 0);
+
+
+		String password = pref.getString("companyPassword", null);
+		String company_id = pref.getString("companyID", null);
+
+		et_ia.setText(password);
+		et_name.setText(company_id);
+
+
+		((Button)findViewById(R.id.btn_connect)).setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View view) {
+				connect();
+			}
+		});
+
+	}
+
+	private void connect() {
+		// password
+		EditText et_ia = (EditText) findViewById(R.id.et_ia);
+		// company id
+		EditText et_name = (EditText) findViewById(R.id.et_name);
+
+		String ia = et_ia.getText().toString();
+		String name = et_name.getText().toString();
+
+		if (TextUtils.isEmpty(ia) )
+		{
+			showdialog("Password can not be empty!");
+			return;
+		}
+
+		if (TextUtils.isEmpty(name))
+		{
+			showdialog("Company ID can not be empty!");
+			return;
+		}
+
+		requestServer(name,ia);
+	}
+
+	private void requestServer(final String company_id, final String password) {
+
+		final ProgressDialog pd = showProgressAlert(null,"Please wait");
+		new Thread(new Runnable() {
+			@Override
+			public void run() {
+
+				Bundle params = new Bundle();
+				params.putString("company_id", AES.encrypt("Usai2010",company_id));
+				params.putString("pwd", AES.encrypt("Usai2010",password));
+
+				final JSONObject result_json = Network.requestServer(params);
+
+				runOnUiThread(new Runnable() {
+					@Override
+					public void run() {
+						pd.dismiss();
+
+						if (result_json == null) {
+							showAlert("Error","Some error occurred");
+						} else {
+							try {
+								int result = result_json.getInt("result");
+								switch (result) {
+									case Network.RESULT_FALSE: {
+										showAlert("Warning",result_json.getString("msg"));
+									}
+									break;
+									case Network.RESULT_TRUE: {
+
+										String url = result_json.getString("url");
+										if (url == null || url.isEmpty()) {
+											url = "";
+										}
+										String logo = result_json.optString("logo");
+										if (logo == null || logo.isEmpty()) {
+											logo = "";
+										}
+										String servername = result_json.getString("server_name");
+										if (servername == null || servername.isEmpty()) {
+											servername = "";
+										}
+
+										RedAntApplication.server = url;
+
+
+										SharedPreferences pref = RedAntApplication.getInstance().getSharedPreferences("redant mobile", 0);
+										SharedPreferences.Editor editor = pref.edit();
+
+										editor.putString("serverAddress",url);
+										editor.putString("serverName",servername);
+										editor.putString("companyLogo",logo);
+										editor.putString("companyPassword",password);
+										editor.putString("companyID",company_id);
+
+										editor.commit();
+
+
+										Intent intent = new Intent();
+										intent.putExtra("server",servername);
+										setResult(1001, intent);
+										finish();
+
+									}
+									break;
+
+									default:
+									case Network.RESULT_ERROR: {
+										showAlert("Request server information",result_json.getString("msg"));
+									}
+								}
+							} catch (JSONException e) {
+								e.printStackTrace();
+								showAlert("Error","Some error occurred");
+							}
+						}
+					}
+				});
+
+			}
+		}).start();
+
+	}
+
+	private ProgressDialog showProgressAlert(String title,String msg) {
+		ProgressDialog pd = new ProgressDialog(mContext);
+		pd.setTitle(title);
+		pd.setMessage(msg);
+		/**
+		 * false,表示 ProgressDialog 是不能通过 Back 键取消
+		 * 数据加载完成后必须要调用 ProgressDialog 的 dismiss() 方法来关闭对话框
+		 * */
+		pd.setCancelable(false);
+		pd.show();
+
+		return pd;
+	}
+
+//	private void showAlert(String)
+
+//	@Override
+//	public boolean onCreateOptionsMenu(Menu menu)
+//	{
+//		// Inflate the menu; this adds items to the action bar if it is present.
+//		getMenuInflater().inflate(R.menu.server_setting, menu);
+//		return true;
+//	}
+
+	@Override
+	public void onActivityResult(int requestCode, int resultCode, Intent data)
+	{
+
+		if (requestCode == REQUEST_SCAN_BARCODE)
+		{
+			if (resultCode == Activity.RESULT_OK)
+			{
+				Bundle bundle = data.getExtras();
+				String jstr = bundle.getString("pid");
+				
+				if (jstr == null || jstr.length() <= 0)
+				{
+					//Log.d(TAG, "json is wrong");
+					toast();
+					return ;//Network.RESULT_NET_ERROR;
+				}	
+				String address[]=jstr.split(";");
+				EditText et_ia = (EditText) findViewById(R.id.et_ia);
+//				EditText et_ea = (EditText) findViewById(R.id.et_ea);
+				EditText et_name = (EditText) findViewById(R.id.et_name);
+				if (address.length==3)
+				{
+					et_ia.setText(address[2].trim());
+					et_name.setText(address[0].trim());
+				}
+				else if(address.length==2)
+				{
+					et_ia.setText(address[1].trim());
+					et_name.setText(address[0].trim());
+				}
+				else
+				{
+					toast();
+					return;
+				}
+
+//				et_ea.setText(address[2].trim());
+
+//				JSONObject jsobj;
+//				try
+//				{
+//					jsobj = new JSONObject(jstr);
+//					if (jsobj.length() > 0)
+//					{
+//						String name = jsobj.getString("name");
+//						String ia = jsobj.getString("ia");
+//						String ea = jsobj.getString("ea");
+//						EditText et_ia = (EditText) findViewById(R.id.et_ia);
+//						EditText et_ea = (EditText) findViewById(R.id.et_ea);
+//						et_ea.setText(ea);
+//						et_ia.setText(ia);
+////						int iresult = jsobj.getInt("result");
+////						if (iresult == Network.AP_USER_AUTH)
+////						{
+////							return ;//RESULT_TRUE;
+////						}
+////
+////						else
+////						{
+////
+////							return ;//RESULT_FALSE;
+////						}
+//					}
+//					return ;
+//				}
+//				catch (JSONException e)
+//				{
+//					// TODO Auto-generated catch block
+//					e.printStackTrace();
+//					return ;
+//				}
+				//Log.d(TAG,
+//						"REQUEST_SCAN_BARCODE==========>pid="
+//								+ bundle.getString("pid"));
+//				TextView pidval = (TextView) findViewById(R.id.pidval);
+//				pidval.setText(pid);
+//				updateUploadButton();
+			}
+		}
+		super.onActivityResult(requestCode, resultCode, data);
+	}
+
+//	@Override
+//	public boolean onOptionsItemSelected(MenuItem item)
+//	{
+//		// Handle action bar item clicks here. The action bar will
+//		// automatically handle clicks on the Home/Up button, so long
+//		// as you specify a parent activity in AndroidManifest.xml.
+//		int id = item.getItemId();
+//		if (id == R.id.action_save)
+//		{
+//			EditText et_ia = (EditText) findViewById(R.id.et_ia);
+////			EditText et_ea = (EditText) findViewById(R.id.et_ea);
+//			EditText et_name = (EditText) findViewById(R.id.et_name);
+//			String ia = et_ia.getText().toString();
+////			String ea = et_ea.getText().toString();
+//			String name = et_name.getText().toString();
+//			if (TextUtils.isEmpty(ia) )
+//			{
+//				showdialog("Server address can not be empty!");
+//				return true;
+//			}
+//
+//			SharedPreferences pref = RedAntApplication.getInstance()
+//					.getSharedPreferences("RA Image", 0);
+//			SharedPreferences.Editor editor = pref.edit();
+//
+//
+//
+//
+//			if (TextUtils.isEmpty(name))
+//			{
+//				showdialog("Station name can not be empty!");
+//				return true;
+//			}
+//			else {
+//
+//				editor.putString("station name", name);
+//			}
+//			if (!TextUtils.isEmpty(ia))
+//			{
+//
+//				if (!ia.substring(ia.length() - 1).equals("/"))
+//					ia = ia + "/";
+//				editor.putString("aa", ia);
+//				RedAntApplication.active_address = ia;
+//
+//			}
+////			if (!TextUtils.isEmpty(ea))
+////			{
+////				if (!ea.substring(ea.length() - 1).equals("/"))
+////					ea = ea + "/";
+////				editor.putString("ea", ea);
+////			}
+////			RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1);
+////			if (rg.getCheckedRadioButtonId() == R.id.radio0)
+////			{
+////				if (!TextUtils.isEmpty(ia))
+////				{
+////					editor.putString("aa", ia);
+////					RedAntApplication.active_address = ia;
+////				}
+////				else
+////				{
+////					showdialog("Active server address can not be empty!");
+////					return true;
+////				}
+////			}
+////			else
+////			{
+////				if (!TextUtils.isEmpty(ea))
+////				{
+////					editor.putString("aa", ea);
+////					RedAntApplication.active_address = ea;
+////				}
+////				else
+////				{
+////					showdialog("Active server address can not be empty!");
+////					return true;
+////				}
+////			}
+//
+//			RedAntApplication.station_name = name;
+//
+//			editor.remove("Lat");
+//			editor.remove("Lon");
+//			editor.commit();
+//			//sendBroadcast(new Intent("REDANT.POP.RESET_LOCATION"));
+//
+//
+//			String result = pref.getString("aa","");
+//			Intent intent = new Intent();
+//			intent.putExtra("server", result);
+//                /*
+//                 * 调用setResult方法表示我将Intent对象返回给之前的那个Activity,这样就可以在onActivityResult方法中得到Intent对象,
+//                 */
+//			setResult(1001, intent);
+//			finish();
+//			return true;
+//		}
+//		return super.onOptionsItemSelected(item);
+//	}
+
+	private void toast()
+	{
+		Toast toast = Toast.makeText(this,"Wrong server setting format",
+				Toast.LENGTH_LONG);
+		toast.setGravity(Gravity.CENTER, 0, 0);
+		toast.show();
+	}
+	private void showdialog(String msg)
+	{
+		new AlertDialog.Builder(ServerSettingActivity.this)
+				.setIcon(android.R.drawable.ic_dialog_info).setTitle("Error!")
+				.setMessage(msg)
+				.setPositiveButton("OK", new DialogInterface.OnClickListener()
+				{
+					public void onClick(DialogInterface dialog, int whichButton)
+					{
+
+						// finish();
+						/* User clicked OK so do some stuff */
+					}
+				}).show();
+	}
+
+	private void showAlert(String title,String msg) {
+		new AlertDialog.Builder(mContext)
+				.setTitle(title)
+				.setMessage(msg)
+				.show();
+	}
+}

+ 22 - 5
RedAnt Mobile/app/src/main/java/com/usai/redant/util/Network.java

@@ -605,21 +605,25 @@ public class Network
 		Bundle parms = new Bundle();
 		try {
 
-			parms.putString("user", AES.encrypt("usai", user));
-			parms.putString("password", AES.encrypt("usai", password));
+			parms.putString("user", AES.encrypt("Usai2010", user));
+			parms.putString("pwd", AES.encrypt("Usai2010", password));
+
+
+
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 
-		parms.putString("_operate","handset_login");
+		parms.putString("_operate","login");
+		parms.putString("_action","ant_mobile");
+
 		// parms.putString("action", "handset_login");
 		// int ver = ApexTrackingApplication
 		// .get_instance()
 		// .getSharedPreferences(name + "_Apex_auth", Context.MODE_PRIVATE)
 		// .getInt("AuthInfoVer", 0);
 		// parms.putString("auth_ver", ver + "");
-		String jstr = getJson(RedAntApplication.active_address
-				+ Network.URL_LOGIN, parms);
+		String jstr = getJson(RedAntApplication.server, parms);
 		/*
 		 * error occur while get authorization info from server. include can not
 		 * reach server , wrong parms ,server get wrong , etc.
@@ -1624,4 +1628,17 @@ public class Network
 		}
 		return img;
 	}
+
+	public static JSONObject requestServer(Bundle params) {
+
+		String request_server_url = "http://192.168.0.155/wm_postgresql/ant_mobile_company_valid.php";
+		String json_string = getJson(request_server_url,params);
+
+		try {
+			return new JSONObject(json_string);
+		} catch (JSONException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
 }

BIN
RedAnt Mobile/app/src/main/res/drawable-hdpi/more_info.png


BIN
RedAnt Mobile/app/src/main/res/drawable-mdpi/more_info.png


BIN
RedAnt Mobile/app/src/main/res/drawable-xhdpi/more_info.png


BIN
RedAnt Mobile/app/src/main/res/drawable-xxhdpi/more_info.png


BIN
RedAnt Mobile/app/src/main/res/drawable/album.png


BIN
RedAnt Mobile/app/src/main/res/drawable/camera.png


BIN
RedAnt Mobile/app/src/main/res/drawable/check.png


BIN
RedAnt Mobile/app/src/main/res/drawable/not_found.png


+ 45 - 0
RedAnt Mobile/app/src/main/res/drawable/result_black_border.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--<selector xmlns:android="http://schemas.android.com/apk/res/android">-->
+
+    <!--<shape xmlns:android="http://schemas.android.com/apk/res/android" >-->
+        <!--&lt;!&ndash;&lt;!&ndash; 实心 &ndash;&gt;&ndash;&gt;-->
+        <!--&lt;!&ndash;背景色&ndash;&gt;-->
+        <!--<solid android:color="#FFFFFF" />-->
+
+        <!--&lt;!&ndash;边框颜色&ndash;&gt;-->
+        <!--<stroke-->
+            <!--android:width="1dp"-->
+            <!--android:color="#000000" />-->
+
+        <!--<padding-->
+            <!--android:bottom="1dp"-->
+            <!--android:left="1dp"-->
+            <!--android:right="1dp"-->
+            <!--android:top="1dp" />-->
+    <!--</shape>-->
+
+<!--</selector>-->
+
+<!--<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >-->
+    <!--&lt;!&ndash; This is the main color &ndash;&gt;-->
+    <!--<item>-->
+        <!--<shape>-->
+            <!--&lt;!&ndash;    边框颜色 &ndash;&gt;-->
+            <!--<solid android:color="#000000"/>-->
+        <!--</shape>-->
+    <!--</item>-->
+    <!--&lt;!&ndash; 给View设置1dp的边框 &ndash;&gt;-->
+    <!--<item android:top="1dp" android:left="1dp" android:right="1dp" android:bottom="1dp">-->
+        <!--<shape>-->
+            <!--&lt;!&ndash;     View填充颜色 &ndash;&gt;-->
+            <!--<solid android:color="#ffffff" />-->
+        <!--</shape>-->
+    <!--</item>-->
+
+<!--</layer-list>-->
+
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
+    <solid android:color="#00000000" />
+    <stroke android:width="1dip" android:color="#000000"/>
+</shape>

BIN
RedAnt Mobile/app/src/main/res/drawable/upload.png


+ 21 - 0
RedAnt Mobile/app/src/main/res/layout/activity_address_editor.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context="com.usai.redant.CommonEditor.AddressEditorActivity">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        />
+    <EditText
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        />
+
+</LinearLayout>

+ 71 - 0
RedAnt Mobile/app/src/main/res/layout/activity_bundle_model.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--<RelativeLayout-->
+    <!--xmlns:android="http://schemas.android.com/apk/res/android"-->
+    <!--xmlns:tools="http://schemas.android.com/tools"-->
+    <!--android:layout_width="match_parent"-->
+    <!--android:layout_height="match_parent"-->
+    <!--tools:context="com.usai.redant.CommonEditor.BundleModelActivity">-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+
+    <LinearLayout
+        android:id="@+id/title_ll"
+        android:layout_width="match_parent"
+        android:layout_height="30dp"
+        android:orientation="horizontal"
+        >
+
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="30dp"
+            android:layout_weight="4"
+            android:gravity="center"
+            android:textColor="#555555"
+            android:text="Model"
+            />
+
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="30dp"
+            android:layout_weight="7"
+            android:gravity="center"
+            android:textColor="#555555"
+            android:text="Description"
+            />
+
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="30dp"
+            android:layout_weight="2"
+            android:gravity="center"
+            android:textColor="#555555"
+            android:text="QTY"
+            />
+
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="30dp"
+            android:layout_weight="3"
+            android:gravity="center"
+            android:textColor="#555555"
+            android:text="Unit Price"
+            />
+
+    </LinearLayout>
+
+    <ListView
+        android:id="@+id/bundle_list_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@id/title_ll"
+        android:layout_marginBottom="5dp"
+        >
+
+    </ListView>
+
+
+</RelativeLayout>

+ 20 - 0
RedAnt Mobile/app/src/main/res/layout/activity_common_editor.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    android:id="@+id/root_layout"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.CommonEditorActivity"
+    android:background="#ffaaff">
+
+    
+    <ExpandableListView
+        android:id="@+id/list_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        />
+
+    
+
+</RelativeLayout>

+ 10 - 0
RedAnt Mobile/app/src/main/res/layout/activity_contact_list.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.ContactListActivity">
+
+</android.support.constraint.ConstraintLayout>

+ 10 - 0
RedAnt Mobile/app/src/main/res/layout/activity_credit_card_editor.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.CreditCardEditorActivity">
+
+</android.support.constraint.ConstraintLayout>

+ 16 - 0
RedAnt Mobile/app/src/main/res/layout/activity_date_picker.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.DatePickerActivity">
+
+    <DatePicker
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:datePickerMode="spinner"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentStart="true"/>
+
+</RelativeLayout>

+ 16 - 0
RedAnt Mobile/app/src/main/res/layout/activity_enum_slect.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.EnumSlectActivity">
+
+    <ListView
+        android:id="@+id/enum_list_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        />
+
+
+</RelativeLayout>

+ 57 - 0
RedAnt Mobile/app/src/main/res/layout/activity_image_upload.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.ImageUploadActivity">
+
+
+    <LinearLayout
+        android:id="@+id/control_bar"
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_alignParentBottom="true"
+        android:orientation="horizontal"
+        >
+
+        <ImageButton
+            android:id="@+id/photo_library_btn"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:scaleType="fitCenter"
+            android:src="@drawable/album"
+            />
+
+        <ImageButton
+            android:id="@+id/tack_photo_btn"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:scaleType="fitCenter"
+            android:src="@drawable/camera"
+            />
+
+        <ImageButton
+            android:id="@+id/photo_upload_btn"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:scaleType="fitCenter"
+            android:src="@drawable/upload"
+            />
+
+
+    </LinearLayout>
+
+    <ImageView
+        android:id="@+id/img_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:src="@drawable/not_found"
+        android:layout_above="@id/control_bar"
+        />
+
+
+</RelativeLayout>

+ 10 - 0
RedAnt Mobile/app/src/main/res/layout/activity_image_view.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.ImageViewActivity">
+
+</android.support.constraint.ConstraintLayout>

+ 56 - 0
RedAnt Mobile/app/src/main/res/layout/activity_month_picker.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.MonthPickerActivity">
+
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_margin="10dp"
+        android:orientation="horizontal"
+        >
+
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_margin="5dp"
+            >
+
+            <NumberPicker
+                android:id="@+id/year_picker"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentRight="true"
+                />
+
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_margin="5dp"
+            >
+
+            <NumberPicker
+                android:id="@+id/month_picker"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                />
+
+        </RelativeLayout>
+
+
+    </LinearLayout>
+
+
+</RelativeLayout>

+ 31 - 0
RedAnt Mobile/app/src/main/res/layout/activity_search_result.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#ffffff"
+    tools:context="com.usai.redant.Result.SearchResultActivity">
+
+
+
+    <HorizontalScrollView
+        android:id="@+id/horizontal_scroll"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:background="#ffffff"
+        >
+
+        <ListView
+            android:id="@+id/result_table"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:background="#ffffff"
+            >
+
+
+        </ListView>
+    </HorizontalScrollView>
+
+
+</RelativeLayout>

+ 2 - 2
RedAnt Mobile/app/src/main/res/layout/activity_service_setting.xml

@@ -3,7 +3,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context="com.usai.redant.raimage.ServerSettingActivity">
+    tools:context=".ServerSettingActivity">
 
     <TextView
         android:id="@+id/tv_name"
@@ -72,7 +72,7 @@
         tools:layout_constraintTop_creator="1" />
 
     <Button
-        android:id="@+id/button"
+        android:id="@+id/btn_connect"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginBottom="8dp"

+ 16 - 0
RedAnt Mobile/app/src/main/res/layout/activity_signature.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.usai.redant.CommonEditor.SignatureActivity">
+
+    <com.example.macmini1.listviewdemo.BrushView
+        android:id="@+id/brush_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        />
+
+
+</RelativeLayout>

+ 55 - 0
RedAnt Mobile/app/src/main/res/layout/bundle_item_cell.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="160dp">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="160dp"
+        >
+
+        <TextView
+            android:id="@+id/model_name_tv"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="4"
+            android:gravity="center"
+            android:textColor="#000000"
+            />
+
+        <TextView
+            android:id="@+id/model_desc_tv"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="7"
+            android:gravity="left|center_vertical"
+            android:textColor="#000000"
+            android:maxLines="10"
+            android:minLines="1"
+            />
+
+        <TextView
+            android:id="@+id/model_qty_tv"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="2"
+            android:gravity="center"
+            android:textColor="#000000"
+            />
+
+        <TextView
+            android:id="@+id/model_unit_price_tv"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="3"
+            android:gravity="center"
+            android:textColor="#000000"
+            />
+
+
+
+    </LinearLayout>
+
+
+</LinearLayout>

+ 18 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_action_cell.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="44dp">
+
+    <TextView
+        android:id="@+id/action_cell_lb"
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        android:layout_margin="5dp"
+        android:textSize="17sp"
+        android:textColor="#000000"
+        android:textAlignment="center"
+        android:gravity="center"
+        android:text="Label"
+        />
+
+</RelativeLayout>

+ 62 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_edit_cell.xml

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="44dp"
+              android:orientation="horizontal">
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        android:orientation="horizontal"
+        >
+
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_centerVertical="true"
+            >
+
+            <TextView
+                android:id="@+id/name_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="left|center_vertical"
+                />
+
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/name_lb"
+                android:layout_toRightOf="@id/name_lb"
+                android:layout_alignTop="@id/name_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+        </RelativeLayout>
+
+        <EditText
+            android:id="@+id/textField"
+            android:layout_width="0dp"
+            android:layout_weight="4"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="5dp"
+            android:layout_marginStart="5dp"
+            android:layout_marginTop="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_marginEnd="5dp"
+            android:lines="1"
+            />
+
+        </LinearLayout>
+
+</LinearLayout>

+ 65 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_edit_cell_small.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="70dp"
+              android:orientation="vertical">
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        android:orientation="vertical"
+        >
+
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:layout_centerVertical="true"
+            >
+
+            <TextView
+                android:id="@+id/name_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="left|center_vertical"
+                />
+
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/name_lb"
+                android:layout_toRightOf="@id/name_lb"
+                android:layout_alignTop="@id/name_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+        </RelativeLayout>
+
+
+        <EditText
+            android:id="@+id/textField"
+            android:layout_width="match_parent"
+            android:layout_weight="2"
+            android:layout_height="0dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginStart="5dp"
+            android:layout_marginTop="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_marginEnd="5dp"
+            android:lines="1"
+            />
+
+
+    </LinearLayout>
+
+</LinearLayout>

+ 88 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_enum_cell.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="44dp"
+                android:orientation="horizontal">
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        android:orientation="horizontal"
+        >
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            >
+
+            <TextView
+                android:id="@+id/enum_title_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="start|center_vertical"
+                android:textAlignment="textStart"
+                />
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/enum_title_lb"
+                android:layout_toRightOf="@id/enum_title_lb"
+                android:layout_alignTop="@id/enum_title_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_weight="4"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            >
+
+            <ImageView
+                android:id="@+id/more_info"
+                android:layout_width="20dp"
+                android:layout_height="match_parent"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentRight="true"
+                android:layout_marginEnd="10dp"
+                android:layout_marginRight="10dp"
+                android:scaleType="centerCrop"
+                android:src="@drawable/more_info"
+                />
+
+            <TextView
+                android:id="@+id/enum_value_lb"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_centerVertical="true"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentLeft="true"
+                android:layout_toLeftOf="@id/more_info"
+                android:layout_toStartOf="@id/more_info"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="start|center_vertical"
+                android:textAlignment="textStart"
+                />
+
+
+
+        </RelativeLayout>
+    </LinearLayout>
+
+</LinearLayout>

+ 88 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_enum_cell_small.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="70dp"
+                android:orientation="vertical">
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        android:orientation="vertical"
+        >
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_weight="1"
+            android:layout_height="0dp"
+            android:layout_centerVertical="true"
+            >
+
+            <TextView
+                android:id="@+id/enum_title_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="start|center_vertical"
+                android:textAlignment="textStart"
+                />
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/enum_title_lb"
+                android:layout_toRightOf="@id/enum_title_lb"
+                android:layout_alignTop="@id/enum_title_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_weight="2"
+            android:layout_height="0dp"
+            android:layout_centerVertical="true"
+            >
+
+            <ImageView
+                android:id="@+id/more_info"
+                android:layout_width="20dp"
+                android:layout_height="match_parent"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentRight="true"
+                android:layout_marginEnd="5dp"
+                android:layout_marginRight="5dp"
+                android:scaleType="centerCrop"
+                android:src="@drawable/more_info"
+                />
+
+            <TextView
+                android:id="@+id/enum_value_lb"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_centerVertical="true"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentLeft="true"
+                android:layout_toLeftOf="@id/more_info"
+                android:layout_toStartOf="@id/more_info"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="start|center_vertical"
+                android:textAlignment="textStart"
+                />
+
+
+
+        </RelativeLayout>
+    </LinearLayout>
+
+</LinearLayout>

+ 67 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_image_cell.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:layout_width="match_parent"
+              android:layout_height="130dp">
+
+   <LinearLayout
+       android:layout_width="match_parent"
+       android:layout_height="130dp">
+
+       <TextView
+           android:id="@+id/img_cell_title_lb"
+           android:layout_width="0dp"
+           android:layout_weight="3"
+           android:layout_height="match_parent"
+           android:layout_margin="5dp"
+           android:textSize="17sp"
+           android:textColor="#000000"
+           android:text="Label"
+           android:gravity="start|center_vertical"
+           android:textAlignment="textStart"
+           />
+       <TextView
+           android:id="@+id/img_cell_desc_lb"
+           android:layout_width="0dp"
+           android:layout_weight="5"
+           android:layout_height="match_parent"
+           android:layout_margin="5dp"
+           android:textSize="17sp"
+           android:textColor="#000000"
+           android:text="Label"
+           android:gravity="start|center_vertical"
+           android:textAlignment="textStart"
+           />
+       <LinearLayout
+           android:orientation="horizontal"
+           android:layout_width="0dp"
+           android:layout_weight="7"
+           android:layout_height="match_parent">
+
+           <ImageButton
+               android:id="@+id/img_btn_0"
+               android:layout_weight="1"
+               android:layout_width="0dp"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               />
+           <ImageButton
+               android:id="@+id/img_btn_1"
+               android:layout_weight="1"
+               android:layout_width="0dp"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               />
+           <ImageButton
+               android:id="@+id/img_btn_2"
+               android:layout_weight="1"
+               android:layout_width="0dp"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               />
+
+       </LinearLayout>
+
+   </LinearLayout>
+
+</LinearLayout>

+ 79 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_image_cell_small.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="160dp">
+
+   <LinearLayout
+       android:layout_width="match_parent"
+       android:layout_height="160dp"
+       android:orientation="vertical"
+       >
+
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+
+           <TextView
+               android:id="@+id/img_cell_title_lb"
+               android:layout_width="0dp"
+               android:layout_weight="3"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               android:textSize="17sp"
+               android:textColor="#000000"
+               android:text="Label"
+               android:gravity="start|center_vertical"
+               android:textAlignment="textStart"
+               />
+           <TextView
+               android:id="@+id/img_cell_desc_lb"
+               android:layout_width="0dp"
+               android:layout_weight="5"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               android:textSize="17sp"
+               android:textColor="#000000"
+               android:text="Label"
+               android:gravity="start|center_vertical"
+               android:textAlignment="textStart"
+               />
+
+       </LinearLayout>
+       <LinearLayout
+           android:orientation="horizontal"
+           android:layout_width="match_parent"
+           android:layout_weight="3"
+           android:layout_height="0dp">
+
+           <ImageButton
+               android:id="@+id/img_btn_0"
+               android:layout_weight="1"
+               android:layout_width="0dp"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               />
+           <ImageButton
+               android:id="@+id/img_btn_1"
+               android:layout_weight="1"
+               android:layout_width="0dp"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               />
+
+           <ImageButton
+               android:id="@+id/img_btn_2"
+               android:layout_width="0dp"
+               android:layout_height="match_parent"
+               android:layout_margin="5dp"
+               android:layout_weight="1"
+               />
+
+       </LinearLayout>
+
+   </LinearLayout>
+
+</LinearLayout>

+ 41 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_label_cell.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="44dp"
+              android:orientation="horizontal">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        android:orientation="horizontal"
+        >
+
+        <TextView
+            android:id="@+id/cell_title_lb"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:textSize="17sp"
+            android:textColor="#000000"
+            android:text="Label"
+            android:gravity="left|center_vertical"
+            android:layout_margin="5dp"
+            />
+
+        <TextView
+            android:id="@+id/cell_value_lb"
+            android:layout_width="0dp"
+            android:layout_weight="4"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="5dp"
+            android:layout_marginStart="5dp"
+            android:textSize="17sp"
+            android:textColor="#000000"
+            android:text="Label"
+            android:gravity="right|center_vertical"
+            android:layout_margin="5dp"
+            />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 41 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_label_cell_small.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="75dp"
+              android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="75dp"
+        android:orientation="vertical"
+        >
+
+        <TextView
+            android:id="@+id/cell_title_lb"
+            android:layout_width="match_parent"
+            android:layout_weight="1"
+            android:layout_height="0dp"
+            android:textSize="17sp"
+            android:textColor="#000000"
+            android:text="Label"
+            android:gravity="left|center_vertical"
+            android:layout_margin="5dp"
+            />
+
+        <TextView
+            android:id="@+id/cell_value_lb"
+            android:layout_width="match_parent"
+            android:layout_weight="2"
+            android:layout_height="0dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginStart="5dp"
+            android:textSize="17sp"
+            android:textColor="#000000"
+            android:text="Label"
+            android:gravity="right|center_vertical"
+            android:layout_margin="5dp"
+            />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 204 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_model_cell.xml

@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="100dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        >
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:gravity="center">
+
+            <ImageButton
+                android:id="@+id/model_img_view"
+                android:layout_width="match_parent"
+                android:layout_height="50dp"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_centerVertical="true"
+                android:layout_margin="5dp"
+                android:background="#00000000"
+                />
+
+        </LinearLayout>
+
+
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="0dp"
+            android:layout_weight="6"
+            android:layout_height="match_parent"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
+            >
+
+            <LinearLayout
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="3"
+                >
+                <TextView
+                    android:id="@+id/model_desc_lb"
+                    android:layout_width="0dp"
+                    android:layout_weight="2"
+                    android:layout_height="match_parent"
+                    android:text="name and description"
+                    android:textSize="10sp"
+                    android:textColor="#000000"
+                    android:gravity="center_vertical|start"
+                    />
+
+                <LinearLayout
+                    android:orientation="vertical"
+                    android:layout_width="0dp"
+                    android:layout_weight="2"
+                    android:layout_height="match_parent"
+                    >
+
+                    <TextView
+                        android:id="@+id/model_master_pack_lb"
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:gravity="center"
+                        android:lines="1"
+                        android:text="Master pack:9999"
+                        android:textColor="#000000"
+                        android:textSize="10sp"
+                        />
+
+                    <TextView
+                        android:id="@+id/model_old_price_lb"
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:gravity="center"
+                        android:lines="1"
+                        android:text="$1234567.00"
+                        android:textColor="@android:color/holo_red_dark"
+                        android:textSize="10sp"
+                        />
+
+                    <TextView
+                        android:id="@+id/model_discount_lb"
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:gravity="center"
+                        android:lines="1"
+                        android:text="Discount 99.99% off"
+                        android:textColor="#000000"
+                        android:textSize="10sp"
+                        />
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:orientation="vertical"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    >
+
+                    <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:gravity="center|right"
+                        android:lines="1"
+                        android:text="Price ($)"
+                        android:textColor="#000000"
+                        android:textSize="10sp"
+                        />
+
+                    <TextView
+                        android:id="@+id/model_unit_price_lb"
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:gravity="center|right"
+                        android:lines="1"
+                        android:text="1234567.00"
+                        android:textColor="#000000"
+                        android:textSize="10sp"
+                        />
+
+                    <TextView
+                        android:id="@+id/model_count_lb"
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:gravity="center|right"
+                        android:lines="1"
+                        android:text="x9999"
+                        android:textColor="#000000"
+                        android:textSize="10sp"
+                        />
+
+                </LinearLayout>
+
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                >
+
+                <RelativeLayout
+                    android:layout_width="0dp"
+                    android:layout_weight="4"
+                    android:layout_height="match_parent"
+                    >
+
+                    <TextView
+                        android:id="@+id/model_bundle_btn"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_centerVertical="true"
+                        android:gravity="center_vertical|start"
+                        android:textColor="#0099ff"
+                        android:text="Button"
+                        android:textSize="10sp"
+                        android:textAllCaps="false"
+                        android:padding="0dp"
+                        />
+
+                </RelativeLayout>
+
+                <TextView
+                    android:id="@+id/model_total_price_lb"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    android:ellipsize="end"
+                    android:gravity="center|right"
+                    android:lines="1"
+                    android:text="123456789.00"
+                    android:textColor="#000000"
+                    android:textSize="10sp"
+                    />
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+
+
+</LinearLayout>

+ 62 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_multiple_action_cell.xml

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:layout_width="match_parent"
+              android:layout_height="70dp">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        >
+        <Button
+            android:id="@+id/btn_0"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:text="Button"
+            android:textSize="10sp"
+            android:textAllCaps="false"
+            android:layout_marginTop="7dp"
+            android:layout_marginBottom="7dp"
+            />
+
+        <Button
+            android:id="@+id/btn_1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:text="Button"
+            android:textSize="10sp"
+            android:textAllCaps="false"
+            android:layout_marginTop="7dp"
+            android:layout_marginBottom="7dp"
+            />
+
+        <Button
+            android:id="@+id/btn_2"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:text="Button"
+            android:textSize="10sp"
+            android:textAllCaps="false"
+            android:layout_marginTop="7dp"
+            android:layout_marginBottom="7dp"
+            />
+
+        <Button
+            android:id="@+id/btn_3"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:text="Button"
+            android:textSize="10sp"
+            android:textAllCaps="false"
+            android:layout_marginTop="7dp"
+            android:layout_marginBottom="7dp"
+            />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 44 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_section_header.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="40dp"
+                android:background="#999999">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        >
+
+        <TextView
+            android:id="@+id/title_lb"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_marginLeft="10dp"
+            android:layout_marginStart="10dp"
+            android:gravity="center_vertical|left"
+            android:textColor="#ffffff"
+            android:textSize="15sp"
+            android:text="Title"
+            />
+
+        <TextView
+            android:id="@+id/header_control_btn"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
+            android:layout_marginRight="10dp"
+            android:layout_marginEnd="10dp"
+            android:textColor="#0088ff"
+            android:textSize="15sp"
+            android:text="Hide"
+            />
+
+    </RelativeLayout>
+
+
+</RelativeLayout>

+ 58 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_signature_cell.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="140dp"
+                android:orientation="horizontal">
+
+
+   <LinearLayout
+       android:layout_width="match_parent"
+       android:layout_height="140dp"
+       android:orientation="horizontal"
+       >
+
+       <RelativeLayout
+           android:layout_width="0dp"
+           android:layout_weight="1"
+           android:layout_height="match_parent"
+           >
+
+           <TextView
+               android:id="@+id/signature_title_lb"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_centerVertical="true"
+               android:layout_marginLeft="5dp"
+               android:layout_marginStart="5dp"
+               android:textSize="17sp"
+               android:textColor="#000000"
+               android:text="Label"
+               android:gravity="left|center_vertical"
+
+               />
+
+           <TextView
+               android:id="@+id/start_mark"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_toEndOf="@id/signature_title_lb"
+               android:layout_toRightOf="@id/signature_title_lb"
+               android:layout_alignTop="@id/signature_title_lb"
+               android:text="*"
+               android:textColor="#000000"
+               />
+
+       </RelativeLayout>
+
+       <ImageView
+           android:id="@+id/signature_image_view"
+           android:layout_width="0dp"
+           android:layout_weight="4"
+           android:layout_height="match_parent"
+           android:gravity="center"
+           android:layout_margin="5dp"
+           />
+
+   </LinearLayout>
+
+</LinearLayout>

+ 58 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_signature_cell_small.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="170dp"
+                android:orientation="vertical">
+
+
+   <LinearLayout
+       android:layout_width="match_parent"
+       android:layout_height="170dp"
+       android:orientation="vertical"
+       >
+
+       <RelativeLayout
+           android:layout_width="match_parent"
+           android:layout_weight="1"
+           android:layout_height="0dp"
+           >
+
+           <TextView
+               android:id="@+id/signature_title_lb"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_centerVertical="true"
+               android:layout_marginLeft="5dp"
+               android:layout_marginStart="5dp"
+               android:textSize="17sp"
+               android:textColor="#000000"
+               android:text="Label"
+               android:gravity="left|center_vertical"
+
+               />
+
+           <TextView
+               android:id="@+id/start_mark"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_toEndOf="@id/signature_title_lb"
+               android:layout_toRightOf="@id/signature_title_lb"
+               android:layout_alignTop="@id/signature_title_lb"
+               android:text="*"
+               android:textColor="#000000"
+               />
+
+       </RelativeLayout>
+
+       <ImageView
+           android:id="@+id/signature_image_view"
+           android:layout_width="match_parent"
+           android:layout_weight="4"
+           android:layout_height="0dp"
+           android:gravity="center"
+           android:layout_margin="5dp"
+           />
+
+   </LinearLayout>
+
+</LinearLayout>

+ 50 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_switch_cell.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="44dp">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        >
+
+        <TextView
+            android:id="@+id/switch_title_lb"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_marginStart="5dp"
+            android:layout_marginLeft="5dp"
+            android:textSize="17sp"
+            android:textColor="#000000"
+            android:text="Label"
+            />
+        <TextView
+            android:id="@+id/start_mark"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toEndOf="@id/switch_title_lb"
+            android:layout_toRightOf="@id/switch_title_lb"
+            android:layout_alignTop="@id/switch_title_lb"
+            android:text="*"
+            android:textColor="#000000"
+            />
+
+        <Switch
+            android:id="@+id/switch_cell_switch"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
+            android:layout_marginRight="5dp"
+            android:layout_marginEnd="5dp"
+            android:layout_marginBottom="10dp"
+            android:layout_marginTop="10dp"
+            />
+
+    </RelativeLayout>
+
+
+
+</RelativeLayout>

+ 68 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_switch_cell_small.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="80dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="80dp"
+        android:orientation="vertical"
+        >
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            >
+
+            <TextView
+                android:id="@+id/switch_title_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_marginStart="5dp"
+                android:layout_marginLeft="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                />
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/switch_title_lb"
+                android:layout_toRightOf="@id/switch_title_lb"
+                android:layout_alignTop="@id/switch_title_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            >
+
+            <Switch
+                android:id="@+id/switch_cell_switch"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
+                android:layout_centerVertical="true"
+                android:layout_marginRight="5dp"
+                android:layout_marginEnd="5dp"
+                android:layout_marginBottom="10dp"
+                android:layout_marginTop="10dp"
+                />
+
+        </RelativeLayout>
+
+    </LinearLayout>
+
+
+
+</RelativeLayout>

+ 59 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_text_view_cell.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="140dp"
+                android:orientation="horizontal">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="140dp"
+        android:orientation="horizontal"
+        >
+
+        <RelativeLayout
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:layout_margin="0dp"
+            >
+            <TextView
+                android:id="@+id/name_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="start|center_vertical"
+                android:textAlignment="textStart"
+                android:layout_centerVertical="true"
+                />
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/name_lb"
+                android:layout_toRightOf="@id/name_lb"
+                android:layout_alignTop="@id/name_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+        </RelativeLayout>
+
+        <EditText
+            android:id="@+id/text_view"
+            android:layout_width="0dp"
+            android:layout_weight="4"
+            android:layout_height="match_parent"
+            android:layout_margin="5dp"
+            android:gravity="top|left"
+            android:minLines="5"
+            android:maxLines="10"
+            android:inputType="none"
+            />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 59 - 0
RedAnt Mobile/app/src/main/res/layout/common_editor_text_view_cell_small.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="170dp"
+                android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="170dp"
+        android:orientation="vertical"
+        >
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_weight="1"
+            android:layout_height="0dp"
+            android:layout_margin="0dp"
+            >
+            <TextView
+                android:id="@+id/name_lb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="5dp"
+                android:layout_marginStart="5dp"
+                android:textSize="17sp"
+                android:textColor="#000000"
+                android:text="Label"
+                android:gravity="start|center_vertical"
+                android:textAlignment="textStart"
+                android:layout_centerVertical="true"
+                />
+            <TextView
+                android:id="@+id/start_mark"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/name_lb"
+                android:layout_toRightOf="@id/name_lb"
+                android:layout_alignTop="@id/name_lb"
+                android:text="*"
+                android:textColor="#000000"
+                />
+
+        </RelativeLayout>
+
+        <EditText
+            android:id="@+id/text_view"
+            android:layout_width="match_parent"
+            android:layout_weight="4"
+            android:layout_height="0dp"
+            android:layout_margin="5dp"
+            android:gravity="top|left"
+            android:minLines="5"
+            android:maxLines="10"
+            android:inputType="none"
+            />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 37 - 0
RedAnt Mobile/app/src/main/res/layout/enum_select_cell.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="40dp">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        >
+
+        <TextView
+            android:id="@+id/enum_value_tv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_marginLeft="5dp"
+            android:layout_marginStart="5dp"
+            android:textColor="#000000"
+            />
+
+        <ImageView
+            android:id="@+id/enum_check_iv"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:layout_marginRight="5dp"
+            android:layout_marginEnd="5dp"
+            android:scaleType="fitCenter"
+            android:src="@drawable/check"/>
+
+    </RelativeLayout>
+
+</RelativeLayout>

+ 18 - 0
RedAnt Mobile/app/src/main/res/layout/result_cell.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content">
+
+
+    <TableRow
+        android:id="@+id/result_row"
+        android:layout_height="match_parent"
+        android:layout_width="wrap_content"
+        android:background="#00000000"
+        >
+
+
+    </TableRow>
+
+</RelativeLayout>

+ 9 - 0
RedAnt Mobile/app/src/main/res/menu/action_bar_menu.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/save_item"
+        android:title="Save"
+        />
+
+</menu>

+ 11 - 0
RedAnt Mobile/app/src/main/res/menu/result_menu.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/result_menu"
+        android:title="Menu"
+        app:showAsAction="always"
+        ></item>
+
+</menu>

+ 10 - 0
RedAnt Mobile/app/src/main/res/menu/set_menu.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+    <item
+        android:id="@+id/set_item"
+        android:title="Set"
+        />
+
+</menu>

+ 15 - 0
RedAnt Mobile/app/src/main/res/menu/signature_action_bar_menu.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+    <item
+        android:id="@+id/clear_signature_item"
+        android:title="Clear"
+        />
+
+    <item
+        android:id="@+id/save_signature_item"
+        android:title="Save"
+        />
+
+</menu>

+ 250 - 0
RedAnt Mobile/app/src/main/res/raw/result.json

@@ -0,0 +1,250 @@
+{
+  "result": 2,
+  "menu": [
+    {
+      "title": "Export 1",
+      "action": "download",
+      "url": "xxx"
+    },
+    {
+      "title": "Export 2",
+      "action": "download",
+      "url": "xxx"
+    },
+    {
+      "title": "Save",
+      "action": "save"
+    }
+  ],
+  "row_action": [
+    {
+      "title": "demo title",
+      "module0": "quick_look",
+      "module1": "kv_detail",
+      "module": "order_detail",
+      "url": "http://1.1.1.1",
+      "params": {
+        "order#": 0
+      }
+    }
+  ],
+  "data": {
+    "count": 5,
+    "item_0": [
+      "1",
+      "8533-UPK",
+      "$ 123.45",
+      "43",
+      "metal table with 4 chairs"
+    ],
+    "item_1": [
+      "2",
+      "315318",
+      "$ 99.49",
+      "13",
+      "WOOD table with 4 chairs"
+    ],
+    "item_2": [
+      "3",
+      "7033566",
+      "$ 13.45",
+      "57",
+      "bed"
+    ],
+    "item_3": [
+      "4",
+      "8533-UVR",
+      "$ 1123.45",
+      "143",
+      "Desk & chair UILongPressGestureRecognizer *longPress"
+    ],
+    "item_4": [
+      "1",
+      "8533-UPK",
+      "$ 123.45",
+      "43",
+      "metal table with 4 chairs"
+    ],
+    "item_5": [
+      "2",
+      "315318",
+      "$ 99.49",
+      "13",
+      "WOOD table with 4 chairs"
+    ],
+    "item_6": [
+      "3",
+      "7033566",
+      "$ 13.45",
+      "57",
+      "bed"
+    ],
+    "item_7": [
+      "4",
+      "8533-UVR",
+      "$ 1123.45",
+      "143",
+      "Desk & chair UILongPressGestureRecognizer *longPress"
+    ],
+    "item_8": [
+      "1",
+      "8533-UPK",
+      "$ 123.45",
+      "43",
+      "metal table with 4 chairs"
+    ],
+    "item_9": [
+      "2",
+      "315318",
+      "$ 99.49",
+      "13",
+      "WOOD table with 4 chairs"
+    ],
+    "item_10": [
+      "3",
+      "7033566",
+      "$ 13.45",
+      "57",
+      "bed"
+    ],
+    "item_11": [
+      "1",
+      "8533-UPK",
+      "$ 123.45",
+      "43",
+      "metal table with 4 chairs"
+    ],
+    "item_12": [
+      "2",
+      "315318",
+      "$ 99.49",
+      "13",
+      "WOOD table with 4 chairs"
+    ],
+    "item_13": [
+      "3",
+      "7033566",
+      "$ 13.45",
+      "57",
+      "bed"
+    ],
+    "item_14": [
+      "1",
+      "8533-UPK",
+      "$ 123.45",
+      "43",
+      "metal table with 4 chairs"
+    ],
+    "item_15": [
+      "2",
+      "315318",
+      "$ 99.49",
+      "13",
+      "WOOD table with 4 chairs"
+    ],
+    "item_16": [
+      "3",
+      "7033566",
+      "$ 13.45",
+      "57",
+      "bed"
+    ]
+  },
+  "layout": {
+    "header": {
+      "width": 810,
+      "height": 44,
+      "margin_r": 10,
+      "margin_l": 10,
+      "margin_t": 10,
+      "margin_b": 10,
+      "bg_color": "0x123456",
+      "f_color": "0x987654",
+      "col": [
+        {
+          "width": 100,
+          "name": "id",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "width": 160,
+          "name": "model",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "width": 180,
+          "name": "price",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "width": 120,
+          "name": "stock",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "width": 250,
+          "name": "description",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        }
+      ]
+    },
+    "row": {
+      "height": 44,
+      "f_color": "0x654321",
+      "color_0": "0xffffff",
+      "color_1": "0x666666",
+      "val": [
+        {
+          "type": "image",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "type": "text",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "type": "text",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "type": "text",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        },
+        {
+          "type": "text",
+          "h_align": "center",
+          "v_center": "center",
+          "bg_color": "0x123456",
+          "f_color": "0x654321"
+        }
+      ]
+    }
+  }
+}

+ 3 - 2
RedAnt Mobile/local.properties

@@ -1,10 +1,11 @@
 ## This file is automatically generated by Android Studio.
 # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
 #
-# This file should *NOT* be checked into Version Control Systems,
+# This file must *NOT* be checked into Version Control Systems,
 # as it contains information specific to your local configuration.
 #
 # Location of the SDK. This is only used by Gradle.
 # For customization when using a Version Control System, please read the
 # header note.
-sdk.dir=/Users/ray/Library/Android/sdk
+#Mon Dec 11 17:10:58 CST 2017
+sdk.dir=/Users/macmini1/Library/Android/sdk

Некоторые файлы не были показаны из-за большого количества измененных файлов