="lines-code">
+        canvas.rotate(mGroupRotation, mTempBounds.centerX(), mTempBounds.centerY());
118
+
119
+        mPaint.setColor(mColor);
120
+        mPaint.setAlpha((int) (MAX_ALPHA * mScale));
121
+        mPaint.setStrokeWidth(mStrokeWidth * mScale);
122
+
123
+        if (mSwipeDegrees != 0) {
124
+            for (int i = 0; i < mGearCount; i++) {
125
+                canvas.drawArc(mTempBounds, mStartDegrees + DEGREE_360 / mGearCount * i, mSwipeDegrees, false, mPaint);
126
+            }
127
+        }
128
+
129
+        canvas.restoreToCount(saveCount);
130
+    }
131
+
132
+    @Override
133
+    protected void computeRender(float renderProgress) {
134
+        // Scaling up the start size only occurs in the first 20% of a single ring animation
135
+        if (renderProgress <= START_SCALE_DURATION_OFFSET) {
136
+            float startScaleProgress = (renderProgress) / START_SCALE_DURATION_OFFSET;
137
+            mScale = DECELERATE_INTERPOLATOR.getInterpolation(startScaleProgress);
138
+        }
139
+
140
+        // Moving the start trim only occurs between 20% to 50% of a single ring animation
141
+        if (renderProgress <= START_TRIM_DURATION_OFFSET && renderProgress > START_SCALE_DURATION_OFFSET) {
142
+            float startTrimProgress = (renderProgress - START_SCALE_DURATION_OFFSET) / (START_TRIM_DURATION_OFFSET - START_SCALE_DURATION_OFFSET);
143
+            mStartDegrees = mOriginStartDegrees + mGearSwipeDegrees * startTrimProgress;
144
+        }
145
+
146
+        // Moving the end trim starts between 50% to 80% of a single ring animation
147
+        if (renderProgress <= END_TRIM_DURATION_OFFSET && renderProgress > START_TRIM_DURATION_OFFSET) {
148
+            float endTrimProgress = (renderProgress - START_TRIM_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_TRIM_DURATION_OFFSET);
149
+            mEndDegrees = mOriginEndDegrees + mGearSwipeDegrees * endTrimProgress;
150
+        }
151
+
152
+        // Scaling down the end size starts after 80% of a single ring animation
153
+        if (renderProgress > END_TRIM_DURATION_OFFSET) {
154
+            float endScaleProgress = (renderProgress - END_TRIM_DURATION_OFFSET) / (END_SCALE_DURATION_OFFSET - END_TRIM_DURATION_OFFSET);
155
+            mScale = 1.0f - ACCELERATE_INTERPOLATOR.getInterpolation(endScaleProgress);
156
+        }
157
+
158
+        if (renderProgress <= END_TRIM_DURATION_OFFSET && renderProgress > START_SCALE_DURATION_OFFSET) {
159
+            float rotateProgress = (renderProgress - START_SCALE_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_SCALE_DURATION_OFFSET);
160
+            mGroupRotation = ((FULL_GROUP_ROTATION / NUM_POINTS) * rotateProgress) + (FULL_GROUP_ROTATION * (mRotationCount / NUM_POINTS));
161
+        }
162
+
163
+        if (Math.abs(mEndDegrees - mStartDegrees) > 0) {
164
+            mSwipeDegrees = mEndDegrees - mStartDegrees;
165
+        }
166
+    }
167
+
168
+    @Override
169
+    protected void setAlpha(int alpha) {
170
+        mPaint.setAlpha(alpha);
171
+    }
172
+
173
+    @Override
174
+    protected void setColorFilter(ColorFilter cf) {
175
+        mPaint.setColorFilter(cf);
176
+    }
177
+
178
+    @Override
179
+    protected void reset() {
180
+        resetOriginals();
181
+    }
182
+
183
+    private void initStrokeInset(float width, float height) {
184
+        float minSize = Math.min(width, height);
185
+        float strokeInset = minSize / 2.0f - mCenterRadius;
186
+        float minStrokeInset = (float) Math.ceil(mStrokeWidth / 2.0f);
187
+        mStrokeInset = strokeInset < minStrokeInset ? minStrokeInset : strokeInset;
188
+    }
189
+
190
+    private void storeOriginals() {
191
+        mOriginEndDegrees = mEndDegrees;
192
+        mOriginStartDegrees = mEndDegrees;
193
+    }
194
+
195
+    private void resetOriginals() {
196
+        mOriginEndDegrees = 0;
197
+        mOriginStartDegrees = 0;
198
+
199
+        mEndDegrees = 0;
200
+        mStartDegrees = 0;
201
+
202
+        mSwipeDegrees = 1;
203
+    }
204
+
205
+    private void apply(Builder builder) {
206
+        this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
207
+        this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
208
+        this.mStrokeWidth = builder.mStrokeWidth > 0 ? builder.mStrokeWidth : this.mStrokeWidth;
209
+        this.mCenterRadius = builder.mCenterRadius > 0 ? builder.mCenterRadius : this.mCenterRadius;
210
+
211
+        this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
212
+
213
+        this.mColor = builder.mColor != 0 ? builder.mColor : this.mColor;
214
+
215
+        this.mGearCount = builder.mGearCount > 0 ? builder.mGearCount : this.mGearCount;
216
+        this.mGearSwipeDegrees = builder.mGearSwipeDegrees > 0 ? builder.mGearSwipeDegrees : this.mGearSwipeDegrees;
217
+
218
+        setupPaint();
219
+        initStrokeInset(this.mWidth, this.mHeight);
220
+    }
221
+
222
+    public static class Builder {
223
+        private Context mContext;
224
+
225
+        private int mWidth;
226
+        private int mHeight;
227
+        private int mStrokeWidth;
228
+        private int mCenterRadius;
229
+
230
+        private int mDuration;
231
+
232
+        private int mColor;
233
+
234
+        private int mGearCount;
235
+        private int mGearSwipeDegrees;
236
+
237
+        public Builder(Context mContext) {
238
+            this.mContext = mContext;
239
+        }
240
+
241
+        public Builder setWidth(int width) {
242
+            this.mWidth = width;
243
+            return this;
244
+        }
245
+
246
+        public Builder setHeight(int height) {
247
+            this.mHeight = height;
248
+            return this;
249
+        }
250
+
251
+        public Builder setStrokeWidth(int strokeWidth) {
252
+            this.mStrokeWidth = strokeWidth;
253
+            return this;
254
+        }
255
+
256
+        public Builder setCenterRadius(int centerRadius) {
257
+            this.mCenterRadius = centerRadius;
258
+            return this;
259
+        }
260
+
261
+        public Builder setDuration(int duration) {
262
+            this.mDuration = duration;
263
+            return this;
264
+        }
265
+
266
+        public Builder setColor(int color) {
267
+            this.mColor = color;
268
+            return this;
269
+        }
270
+
271
+        public Builder setGearCount(int gearCount) {
272
+            this.mGearCount = gearCount;
273
+            return this;
274
+        }
275
+
276
+        public Builder setGearSwipeDegrees(@IntRange(from = 0, to = 360) int gearSwipeDegrees) {
277
+            this.mGearSwipeDegrees = gearSwipeDegrees;
278
+            return this;
279
+        }
280
+
281
+        public GearLoadingRenderer build() {
282
+            GearLoadingRenderer loadingRenderer = new GearLoadingRenderer(mContext);
283
+            loadingRenderer.apply(this);
284
+            return loadingRenderer;
285
+        }
286
+    }
287
+}

+ 27 - 0
views/src/main/res/values/attrs.xml

@@ -121,4 +121,31 @@
121 121
         <attr name="hasStickyHeaders" format="boolean" />
122 122
         <attr name="isDrawingListUnderStickyHeader" format="boolean" />
123 123
     </declare-styleable>
124
+
125
+    <declare-styleable name="LoadingView">
126
+        <attr name="loading_renderer">
127
+            <!--circle rotate-->
128
+            <enum name="MaterialLoadingRenderer" value="0"/>
129
+            <enum name="LevelLoadingRenderer" value="1"/>
130
+            <enum name="WhorlLoadingRenderer" value="2"/>
131
+            <enum name="GearLoadingRenderer" value="3"/>
132
+            <!--circle jump-->
133
+            <enum name="SwapLoadingRenderer" value="4"/>
134
+            <enum name="GuardLoadingRenderer" value="5"/>
135
+            <enum name="DanceLoadingRenderer" value="6"/>
136
+            <enum name="CollisionLoadingRenderer" value="7"/>
137
+            <!--Scenery-->
138
+            <enum name="DayNightLoadingRenderer" value="8"/>
139
+            <enum name="ElectricFanLoadingRenderer" value="9"/>
140
+            <!--Animal-->
141
+            <enum name="FishLoadingRenderer" value="10"/>
142
+            <enum name="GhostsEyeLoadingRenderer" value="11"/>
143
+            <!--Goods-->
144
+            <enum name="BalloonLoadingRenderer" value="12"/>
145
+            <enum name="WaterBottleLoadingRenderer" value="13"/>
146
+            <!--ShapeChange-->
147
+            <enum name="CircleBroodLoadingRenderer" value="14"/>
148
+            <enum name="CoolWaitLoadingRenderer" value="15"/>
149
+        </attr>
150
+    </declare-styleable>
124 151
 </resources>

kodo - Gogs: Go Git Service

No Description

tenancy_views.py 7.1KB

    # -*- coding: utf-8 -*- from __future__ import division import json from django.conf import settings from django.db import transaction from django_logit import logit from django_query import get_query_value from django_response import response from json_response import JsonResponse from paginator import pagination from TimeConvert import TimeConvert as tc from mch.models import ModelInfo from tenancy.models import TenancyShotInfo, TenancyShotRequestInfo from utils.error.errno_utils import TenancyStatusCode from utils.kuaidi.subscribe import KuaiDi100 as KuaiDi100Subscribe @logit def shot_list(request): shots = TenancyShotInfo.objects.values_list('model_id', flat=True).filter(tenancy_status=0, status=True).order_by('model_id') shots = set(shots) shots = ModelInfo.objects.filter(model_id__in=shots) shots = [shot.admindata for shot in shots] return response(data={ 'shots': shots, }) @logit def shot_detail(request): shot_id = request.POST.get('shot_id', '') try: shot = TenancyShotInfo.objects.get(shot_id=shot_id, status=True) except TenancyShotInfo.DoesNotExist: return response(TenancyStatusCode.TENANCY_SHOT_NOT_FOUND) return response(data={ 'shot': shot.data, }) @logit def shot_request_create(request): model_id = request.POST.get('model_id', '') user_id = request.POST.get('user_id', '') name = request.POST.get('name', '') phone = request.POST.get('phone', '') postcode = request.POST.get('postcode', '') location = request.POST.get('location', '') purpose = request.POST.get('purpose', '') return_date = tc.to_date(request.POST.get('return_date', '') or settings.DEFAULT_START_DATE) req = TenancyShotRequestInfo.objects.create( model_id=model_id, user_id=user_id, name=name, phone=phone, postcode=postcode, location=location, purpose=purpose, return_date=return_date, ) return response(data={ 'req': req.data, }) @logit def shot_request_list(request): user_id = request.POST.get('user_id', '') page = request.POST.get('page', 1) num = request.POST.get('num', 20) reqs = TenancyShotRequestInfo.objects.filter(user_id=user_id, status=True).order_by('-pk') reqs = [req.data for req in reqs] reqs, left = pagination(reqs, page, num) return response(data={ 'reqs': reqs, 'left': left, }) @logit def shot_request_detail(request): req_id = request.POST.get('req_id') or request.POST.get('request_id') user_id = request.POST.get('user_id', '') try: req = TenancyShotRequestInfo.objects.get(request_id=req_id, user_id=user_id, status=True) except TenancyShotRequestInfo.DoesNotExist: return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) return response(data={ 'req': req.data, }) @logit @transaction.atomic def shot_request_signed(request): req_id = request.POST.get('req_id') or request.POST.get('request_id') user_id = request.POST.get('user_id', '') signed_images = get_query_value(request, 'signed_images', val_cast_type='listjson') try: req = TenancyShotRequestInfo.objects.select_for_update().get(request_id=req_id, user_id=user_id, status=True) except TenancyShotRequestInfo.DoesNotExist: return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) req.tracking_signed_images = signed_images req.request_status = TenancyShotRequestInfo.TENANCY_TRACKING_SEND_SIGNED request_status_at = req.request_status_at request_status_at[TenancyShotRequestInfo.TENANCY_TRACKING_SEND_SIGNED] = tc.utc_string() req.request_status_at = request_status_at req.save() return response(data={ 'req': req.data, }) @logit @transaction.atomic def shot_request_sendback(request): req_id = request.POST.get('req_id') or request.POST.get('request_id') user_id = request.POST.get('user_id', '') back_express_com = request.POST.get('back_express_com', '') back_express_name = request.POST.get('back_express_name', '') back_tracking_number = request.POST.get('back_tracking_number', '') try: req = TenancyShotRequestInfo.objects.select_for_update().get(request_id=req_id, user_id=user_id, status=True) except TenancyShotRequestInfo.DoesNotExist: return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) old_back_tracking_number = req.back_tracking_number req.back_express_com = back_express_com req.back_express_name = back_express_name req.back_tracking_number = back_tracking_number req.request_status = TenancyShotRequestInfo.TENANCY_TRACKING_BACK request_status_at = req.request_status_at request_status_at[TenancyShotRequestInfo.TENANCY_TRACKING_BACK] = tc.utc_string() req.request_status_at = request_status_at req.save() if back_tracking_number and back_tracking_number != old_back_tracking_number: tenancy_tracking_info_subscribe(req, 'back_tracking') return response(data={ 'req': req.data, }) def is_tenancy_tracking_signed(tracking_info): if not tracking_info: return False items = tracking_info.get('data', []) if not items: return False return items[0].get('status') == u'签收' @transaction.atomic def tenancy_tracking_info_update(req, type_, tracking_info): is_tracking_signed = is_tenancy_tracking_signed(tracking_info) if type_ == 'tracking': req.tracking_info = tracking_info req.tracking_signed = is_tracking_signed else: req.back_tracking_info = tracking_info req.back_tracking_signed = is_tracking_signed req.save() def tenancy_tracking_info_subscribe(req, type_): callbackurl = '{}/api/tenancy/tracking/info/callback?reqpk={}&type={}'.format(settings.DOMAIN, req.pk, type_) if type_ == 'tracking': express_com = req.express_com tracking_number = req.tracking_number phone = req.phone else: express_com = req.back_express_com tracking_number = req.back_tracking_number phone = req.phone return KuaiDi100Subscribe().submit(express_com, tracking_number, phone=phone, callbackurl=callbackurl) @logit(body=True) @transaction.atomic def tenancy_tracking_info_callback(request): reqpk = request.GET.get('reqpk', '') type_ = request.GET.get('type', 'tracking') # tracking / back_tracking param = request.POST.get('param', '') if not param: return response(message='Not Param') try: callback_json = json.loads(param) except Exception: return response(message='JSON Loads Error') tracking_info = callback_json.get('lastResult', {}) if not tracking_info: return response(message='Not Tracking Info') try: req = TenancyShotRequestInfo.objects.select_for_update().get(pk=reqpk, status=True) except TenancyShotRequestInfo.DoesNotExist: return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) tenancy_tracking_info_update(req, type_, tracking_info) return JsonResponse({ 'result': True, 'returnCode': '200', 'message': '成功' }, safe=False)