143
    private TextView publishtopic_choose_topic, mPublishtopicChooseTopic, publishtopic_word_num;
144
145
    private String topicId = "";
146
    //空间名
147
    public static String SPACE = "d1evcom01-fs";
148
    private String policy = "";
149
    private String OPERATER = "d1evvideo01";
150
    @SuppressLint("SdCardPath")
151
    private ParallelUploader parallelUploader;
152
    private ProgressDialog uploadDialog;
153
    private PublishItemSerializable intentData;
154
155
    public static final int REQUEST_CODE_CHOOSE = 342;
156
157
    private List<LocalMedia> mSelectionData =new ArrayList<LocalMedia>();
158
    @Override
159
    protected void onCreate(Bundle savedInstanceState) {
160
        super.onCreate(savedInstanceState);
161
        setContentView(R.layout.activity_publish_picture_content);
162
        BarColorUtil.initStatusBarColor(PublishPicTopicActivity.this);
163
164
        initView();
165
        Res.init(this);
166
        PublicWay.activityList.add(this);
167
        dialog = new LoadingDialog(this);
168
        dialog.setCanceledOnTouchOutside(false);
169
        Init();
170
171
        initYouPaiYun();
172
173
    }
174
175
    /**
176
     * 初始化 又拍云
177
     */
178
    private void initYouPaiYun() {
179
180
        //初始化断点续传 (服务端签名可用)
181
        if (parallelUploader == null) {
182
            parallelUploader = new ParallelUploader();
183
        }
184
    }
185
186
    private void initView() {
187
        intentData = (PublishItemSerializable) getIntent().getSerializableExtra("intent_data");
188
        screenWidth = ScreenUtils.getScreenWidth(this);
189
        itemWidth = (int) ((screenWidth - DensityUtil.dip2px(this, 15 * 2 + 10 * 2)) / 3f);
190
        uploadDialog = new ProgressDialog(this);
191
        uploadDialog.setMessage("图片上传中...");
192
        uploadDialog.setCanceledOnTouchOutside(false);
193
        mPublishTopicDe = (ImageView) findViewById(R.id.publishtopic_choose_topic_de);
194
        mPublishTopicDe.setOnClickListener(this);
195
        mPublishtopicChooseTopic = (TextView) findViewById(R.id.publishtopic_choose_topic);
196
        publishtopic_choose_topic = (TextView) findViewById(R.id.publishtopic_choose_topic);
197
        publishtopic_word_num = (TextView) findViewById(R.id.publishtopic_word_num);
198
        publishtopic_choose_topic.setOnClickListener(this);
199
        insertDialog = new ProgressDialog(this);
200
        insertDialog.setMessage("正在插入图片...");
201
        insertDialog.setCanceledOnTouchOutside(false);
202
        tv_right = (TextView) findViewById(R.id.tv_right);
203
        tv_right.setOnClickListener(new OnClickListener() {
204
            @Override
205
            public void onClick(View view) {
206
                if (imm.isActive()) {
207
                    view = getWindow().peekDecorView();
208
                    if (view != null) {
209
                        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
210
                    }
211
                }
212
213
                MobclickAgent.onEvent(getApplicationContext(), "1035");
214
                uploadDialog.show();
215
                //获取又拍云数据
216
                getYouPaiData();
217
            }
218
        });
219
        rl_point = (RelativeLayout) findViewById(R.id.rl_point);
220
        tv_point = (TextView) findViewById(R.id.tv_point);
221
        animation = AnimationUtils.loadAnimation(PublishPicTopicActivity.this, R.anim.nn);
222
        point = (ImageView) findViewById(R.id.tv_one);
223
        ivBack = (ImageView) findViewById(R.id.iv_back);
224
        ivBack.setOnClickListener(this);
225
        et_context = (EditText) findViewById(R.id.et_context);
226
        et_context.setOnFocusChangeListener(new View.OnFocusChangeListener() {
227
            @Override
228
            public void onFocusChange(View view, boolean b) {
229
                if (b) {
230
                    MobclickAgent.onEvent(getApplicationContext(), "1023");
231
                }
232
            }
233
        });
234
235
236
        et_context.addTextChangedListener(new TextWatcher() {
237
            @Override
238
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
239
240
            }
241
242
            @Override
243
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
244
245
            }
246
247
            @Override
248
            public void afterTextChanged(Editable editable) {
249
                String s = et_context.getText().toString().trim();
250
                if (s.length() > 500) {
251
                    et_context.setText(s.subSequence(0, 500));
252
                    et_context.setSelection(500);
253
                }
254
255
                if (TextUtils.isEmpty(s))
256
                    publishtopic_word_num.setText("0");
257
                else
258
                    publishtopic_word_num.setText(s.length() + "");
259
            }
260
        });
261
        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
262
263
        if (intentData.getFrom().equals(PublishItemsActivity.FROM_TOPIC_DETAIL)) {
264
            chatRecommendBean = new ChatRecommendBean();
265
            chatRecommendBean.topicId = Long.parseLong(intentData.getTopicId());
266
            mPublishtopicChooseTopic.setText(intentData.getName());
267
            mPublishTopicDe.setVisibility(View.VISIBLE);
268
        }
269
    }
270
271
    private void getYouPaiData() {
272
273
        if (null == Bimp.tempSelectBitmap)
274
            return;
275
        String fileNames = "";
276
        for (int i = 0; i < Bimp.tempSelectBitmap.size(); i++) {
277
278
            ImageItem imageItem = Bimp.tempSelectBitmap.get(i);
279
            if (TextUtils.isEmpty(fileNames)) {
280
                fileNames = imageItem.fName;
281
            } else {
282
                fileNames += "," + imageItem.fName;
283
            }
284
        }
285
286
        String url = MainApplication.urlNew + "/topic/sign.do";
287
        Map<String, String> map = new HashMap<>();
288
        map.put("fileNames", fileNames);
289
        map.put("targetType", ChatRecommendBean.TARGET_TYPE_IMAGE_TEXT + "");
290
        CommonParams.addCommonParams(map);
291
        OkHttpUtils.post().params(map).url(url).build().connTimeOut(6000).readTimeOut(6000).execute(new StringCallback() {
292
            @Override
293
            public void onError(Call call, Exception e) {
294
                MobclickAgent.onEvent(getApplicationContext(), "1037");
295
                uploadDialog.dismiss();
296
                ToastUtil.showToast(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT);
297
            }
298
299
            @Override
300
            public void onResponse(String response) {
301
                String code = JsonUtils.getKeyResult(response, "code");
302
                String desc = JsonUtils.getKeyResult(response, "desc");
303
                if ("1000".equals(code)) {
304
                    String data = JsonUtils.getKeyResult(response, "data");
305
                    ArrayList<AuthSignBean> signBeans = (ArrayList<AuthSignBean>) JsonUtils.parseToObjectList(data, AuthSignBean.class);
306
                    if (null != signBeans && signBeans.size() > 0) {
307
                        publishCount = signBeans.size();
308
                        for (int i = 0; i < publishCount; i++) {
309
                            String sign = signBeans.get(i).sign;
310
                            String policy = signBeans.get(i).policy;
311
                            formUpload(Bimp.tempSelectBitmap.get(i).getFile(), sign, policy);
312
                        }
313
                    }
314
                } else if ("8010".equals(code)) {
315
                    MobclickAgent.onEvent(getApplicationContext(), "1037");
316
                    uploadDialog.dismiss();
317
                    startActivity(new Intent(getApplicationContext(), LoginActivity.class));
318
                    ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
319
                } else {
320
                    MobclickAgent.onEvent(getApplicationContext(), "1037");
321
                    uploadDialog.dismiss();
322
                    ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
323
                }
324
            }
325
        });
326
327
    }
328
329
    private ArrayList<String> publishArray = new ArrayList<>();
330
    private int publishCount = 0;
331
    final int reqTopic = 100;
332
333
    @Override
334
    public void onClick(View v) {
335
        switch (v.getId()) {
336
            case R.id.publishtopic_choose_topic_de: // 取消选择的话题
337
                MobclickAgent.onEvent(getApplicationContext(), "1034");
338
                mPublishtopicChooseTopic.setText("# 选择话题");
339
                mPublishTopicDe.setVisibility(View.GONE);
340
                chatRecommendBean = null;
341
                break;
342
            case R.id.publishtopic_choose_topic: // 选择话题
343
                MobclickAgent.onEvent(getApplicationContext(), "1031");
344
                et_context.clearFocus();
345
                startActivityForResult(new Intent(this, TopicActivity.class), reqTopic);
346
                break;
347
            case R.id.iv_back:
348
                if (imm.isActive()) {
349
                    View view = getWindow().peekDecorView();
350
                    if (view != null) {
351
                        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
352
                    }
353
                }
354
                showDialogToExit();
355
                break;
356
        }
357
    }
358
359
    ChatRecommendBean chatRecommendBean = null;
360
361
    @Override
362
    protected void onPause() {
363
        super.onPause();
364
//		requestManager.removeOnRequestFinishedListener(this);
365
        MobclickAgent.onPause(this);
366
    }
367
368
    @Override
369
    protected void onResume() {
370
        super.onResume();
371
//		requestManager.addOnRequestFinishedListener(this);
372
        MobclickAgent.onResume(this);
373
    }
374
375
    private File getFile(String path) {
376
        File f = new File(path);
377
        if (!f.exists()) {
378
            try {
379
                f.createNewFile();
380
            } catch (IOException e) {
381
                e.printStackTrace();
382
            }
383
        }
384
        return f;
385
    }
386
387
388
    public void Init() {
389
        noScrollgridview = (GridView) findViewById(R.id.noScrollgridview);
390
        noScrollgridview.setSelector(new ColorDrawable(Color.TRANSPARENT));
391
        adapter = new GridAdapter(this);
392
        adapter.update();
393
        noScrollgridview.setAdapter(adapter);
394
        noScrollgridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
395
396
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
397
                                    long arg3) {
398
                imm.hideSoftInputFromWindow(arg1.getWindowToken(), 0);
399
                if (arg2 == Bimp.tempSelectBitmap.size()) {
400
                    permissionTask();
401
                } else {
402
                    MobclickAgent.onEvent(getApplicationContext(), "1027");
403
                    Intent intent = new Intent(PublishPicTopicActivity.this,
404
                            GalleryActivityFeedback.class);
405
                    intent.putExtra("position", "1");
406
                    intent.putExtra("type", "1");
407
                    intent.putExtra("ID", arg2);
408
                    startActivity(intent);
409
                }
410
            }
411
        });
412
    }
413
414
    /**
415
     * 调用图库选择
416
     */
417
    private void callGallery() {
418
        MobclickAgent.onEvent(getApplicationContext(), "1024");
419
//        Matisse.from(PublishPicTopicActivity.this)
420
//                .choose(MimeType.of(MimeType.JPEG, MimeType.PNG, MimeType.GIF))
421
//                .showSingleMediaType(true)
422
//                .countable(true)
423
//                .maxSelectable(PIC_NUM - Bimp.tempSelectBitmap.size())
424
//                .capture(true)
425
//                .captureStrategy(new CaptureStrategy(true, "com.electric.chargingpile.provider"))
426
//                .imageEngine(new GlideEngine())
427
//                .forResult(REQUEST_CODE_CHOOSE);
428
        PictureSelector.create(this)
429
                .openGallery(PictureMimeType.ofImage())
430
                .maxSelectNum(PIC_NUM)
431
                .selectionData(mSelectionData)//是否传入已选图片
432
                .selectionMode(PictureConfig.MULTIPLE)
433
                .isCompress(true)//是否压缩
434
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
435
                .isGif(true)//是否显示gif
436
                .isAndroidQTransform(true)
437
                .imageEngine(GlideEngine.createGlideEngine())
438
                .isWeChatStyle(false)// 是否开启微信图片选择风格
439
                .isUseCustomCamera(false)// 是否使用自定义相机
440
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
441
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
442
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
443
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
444
                .imageSpanCount(4)// 每行显示个数
445
                .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
446
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
447
                .forResult(REQUEST_CODE_CHOOSE);
448
449
    }
450
451
    @Override
452
    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
453
        super.onActivityResult(requestCode, resultCode, data);
454
        if (requestCode == reqTopic && resultCode == -100) { // 选择话题完成
455
            chatRecommendBean = (ChatRecommendBean) data.getSerializableExtra("topic");
456
            if (chatRecommendBean != null) {
457
                mPublishtopicChooseTopic.setText(Html.fromHtml(chatRecommendBean.name));
458
                mPublishTopicDe.setVisibility(View.VISIBLE);
459
            }
460
        }
461
462
        if (resultCode == RESULT_OK) {
463
            if (data != null) {
464
                if (requestCode == 1) {
465
                    //处理调用系统图库
466
                } else if (requestCode == REQUEST_CODE_CHOOSE) {
467
                    MobclickAgent.onEvent(getApplicationContext(), "1026");
468
                    //异步方式插入图片
469
                    insertImagesSync(data);
470
                }
471
            }
472
        }
473
    }
474
475
    /**
476
     * 异步方式插入图片
477
     *
478
     * @param data
479
     */
480
    private void insertImagesSync(final Intent data) {
481
        insertDialog.show();
482
        Observable.create(new ObservableOnSubscribe<String>() {
483
            @Override
484
            public void subscribe(ObservableEmitter<String> subscriber) throws Exception {
485
                try {
486
//                    List<Uri> uriList = Matisse.obtainResult(data);
487
                    mSelectionData= PictureSelector.obtainMultipleResult(data);
488
489
                    int i = 0;
490
                    for (LocalMedia localMedia : mSelectionData) {
491
                        i++;
492
//                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
493
//                        File file = FileUtils.from(PublishPicTopicActivity.this, uri);
494
//
495
//                        bitmap = FileUtils.rotateIfRequired(file, bitmap);
496
//                        bitmap = imageZoom(bitmap);
497
                        ImageItem takePhoto = new ImageItem();
498
//                        String deviceId = JPushInterface.getUdid(MainApplication.context);
499
//                        takePhoto.fName = DateUtils.getSimpleCurrentDate();
500
//                        if (TextUtils.isEmpty(deviceId)) {
501
//                            takePhoto.fName += "_" + Util.getRandom(15);
502
//                        } else {
503
//                            takePhoto.fName += "_" + deviceId;
504
//                        }
505
//                        takePhoto.fName += "_00" + i;
506
//
507
//                        String filePath = file.getAbsolutePath();
508
//                        String suffix = filePath.substring(filePath.lastIndexOf(".") + 1);
509
//                        takePhoto.fName += "." + suffix;
510
                        String path="";
511
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
512
                            path= localMedia.getAndroidQToPath();
513
                        }else{
514
                            path=localMedia.getPath();
515
                        }
516
                        takePhoto.setBitmap(imageZoom(BitmapFactory.decodeFile(path)));
517
                        takePhoto.setFile(new File(path));
518
                        Bimp.tempSelectBitmap.add(takePhoto);
519
                        subscriber.onNext("");
520
                    }
521
                    subscriber.onComplete();
522
                } catch (Exception e) {
523
                    e.printStackTrace();
524
                    subscriber.onError(e);
525
                }
526
            }
527
        })
528
                .subscribeOn(Schedulers.io())//生产事件在io
529
                .observeOn(AndroidSchedulers.mainThread())//消费事件在UI线程
530
                .subscribe(new Observer<String>() {
531
                    @Override
532
                    public void onComplete() {
533
                        Log.e(TAG, "onCompleted: -------------");
534
                        insertDialog.dismiss();
535
                        adapter.update();
536
537
                    }
538
539
                    @Override
540
                    public void onError(Throwable e) {
541
                        insertDialog.dismiss();
542
                        Log.e(TAG, "onError: " + "图片插入失败:" + e.getMessage());
543
                        ToastUtil.showToast(getApplicationContext(), "图片插入失败", Toast.LENGTH_SHORT);
544
                    }
545
546
                    @Override
547
                    public void onSubscribe(Disposable d) {
548
549
                    }
550
551
                    @Override
552
                    public void onNext(String imagePath) {
553
554
                    }
555
                });
556
    }
557
558
    public class GridAdapter extends BaseAdapter {
559
        private LayoutInflater inflater;
560
        private int selectedPosition = -1;
561
        private boolean shape;
562
563
        public boolean isShape() {
564
            return shape;
565
        }
566
567
        public void setShape(boolean shape) {
568
            this.shape = shape;
569
        }
570
571
        public GridAdapter(Context context) {
572
            inflater = LayoutInflater.from(context);
573
        }
574
575
        public void update() {
576
            loading();
577
        }
578
579
        public int getCount() {
580
            if (Bimp.tempSelectBitmap.size() == 9) {
581
                return 9;
582
            }
583
            return (Bimp.tempSelectBitmap.size() + 1);
584
        }
585
586
        public Object getItem(int arg0) {
587
            return null;
588
        }
589
590
        public long getItemId(int arg0) {
591
            return 0;
592
        }
593
594
        public void setSelectedPosition(int position) {
595
            selectedPosition = position;
596
        }
597
598
        public int getSelectedPosition() {
599
            return selectedPosition;
600
        }
601
602
        public View getView(final int position, View convertView, ViewGroup parent) {
603
            GridAdapter.ViewHolder holder = null;
604
            if (convertView == null) {
605
                convertView = inflater.inflate(R.layout.item_publish_picture,
606
                        parent, false);
607
                holder = new GridAdapter.ViewHolder();
608
                holder.image = (ImageView) convertView
609
                        .findViewById(R.id.item_publish_image);
610
                holder.imageDelete = convertView.findViewById(R.id.item_publish_image_delete);
611
                convertView.setTag(holder);
612
            } else {
613
                holder = (GridAdapter.ViewHolder) convertView.getTag();
614
            }
615
616
617
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.image.getLayoutParams();
618
            params.width = itemWidth;
619
            params.height = itemWidth;
620
            if (position % 3 != 0) {
621
                params.leftMargin = DensityUtil.dip2px(getApplicationContext(), 10);
622
            }
623
            holder.image.setLayoutParams(params);
624
625
            if (position == Bimp.tempSelectBitmap.size()) {
626
                holder.imageDelete.setVisibility(View.GONE);
627
                holder.image.setImageResource(R.drawable.add_picture);
628
                holder.image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
629
                holder.image.setBackgroundColor(Color.parseColor("#f5f5f5"));
630
                if (position == 9) {
631
                    holder.image.setVisibility(View.GONE);
632
                }
633
            } else {
634
                holder.imageDelete.setVisibility(View.VISIBLE);
635
                holder.image.setImageBitmap(Bimp.tempSelectBitmap.get(position).getBitmap());
636
                holder.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
637
                holder.image.setBackgroundColor(Color.WHITE);
638
            }
639
640
            holder.imageDelete.setOnClickListener(new OnClickListener() {
641
                @Override
642
                public void onClick(View view) {
643
                    MobclickAgent.onEvent(getApplicationContext(), "1030");
644
                    Bimp.tempSelectBitmap.remove(position);
645
                    Bimp.max--;
646
                    Message message = new Message();
647
                    message.what = 1;
648
                    handler.sendMessage(message);
649
                }
650
            });
651
652
            return convertView;
653
        }
654
655
        public class ViewHolder {
656
            public ImageView image;
657
            public ImageView imageDelete;
658
        }
659
660
        Handler handler = new Handler() {
661
            public void handleMessage(Message msg) {
662
                switch (msg.what) {
663
                    case 1:
664
                        if (null != Bimp.tempSelectBitmap && Bimp.tempSelectBitmap.size() > 0) {
665
                            tv_right.setEnabled(true);
666
                            tv_right.setBackgroundColor(Color.parseColor("#02b637"));
667
                        } else {
668
                            tv_right.setEnabled(false);
669
                            tv_right.setBackgroundColor(Color.parseColor("#9ed3ae"));
670
                        }
671
                        adapter.notifyDataSetChanged();
672
                        break;
673
                }
674
                super.handleMessage(msg);
675
            }
676
        };
677
678
        public void loading() {
679
            new Thread(new Runnable() {
680
                public void run() {
681
                    while (true) {
682
                        if (Bimp.max == Bimp.tempSelectBitmap.size()) {
683
                            Message message = new Message();
684
                            message.what = 1;
685
                            handler.sendMessage(message);
686
                            break;
687
                        } else {
688
                            Bimp.max += 1;
689
                            Message message = new Message();
690
                            message.what = 1;
691
                            handler.sendMessage(message);
692
                        }
693
                    }
694
                }
695
            }).start();
696
        }
697
    }
698
699
700
    @Override
701
    protected void onRestart() {
702
        adapter.update();
703
        super.onRestart();
704
    }
705
706
    @Override
707
    protected void onDestroy() {
708
        super.onDestroy();
709
        Bimp.tempSelectBitmap.clear();
710
        Bimp.max = 0;
711
    }
712
713
    private Bitmap imageZoom(Bitmap bm) {
714
        // 图片允许最大空间 单位:KB
715
        double maxSize = 200.00;
716
        // 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)
717
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
718
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
719
        byte[] b = baos.toByteArray();
720
        // 将字节换成KB
721
        double mid = b.length / 1024;
722
        // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
723
        if (mid > maxSize) {
724
            // 获取bitmap大小 是允许最大大小的多少倍
725
            double i = mid / maxSize;
726
            // 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
727
            // (1.保持刻度和高度和原bitmap比率一致,压缩后也达到了最大大小占用空间的大小)
728
            bm = zoomImage(bm, bm.getWidth() / Math.sqrt(i), bm.getHeight() / Math.sqrt(i));
729
        }
730
731
        return bm;
732
    }
733
734
    public Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
735
        // 获取这个图片的宽和高
736
        float width = bgimage.getWidth();
737
        float height = bgimage.getHeight();
738
        // 创建操作图片用的matrix对象
739
        Matrix matrix = new Matrix();
740
        // 计算宽高缩放率
741
        float scaleWidth = ((float) newWidth) / width;
742
        float scaleHeight = ((float) newHeight) / height;
743
        // 缩放图片动作
744
        matrix.postScale(scaleWidth, scaleHeight);
745
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
746
                (int) height, matrix, true);
747
        return bitmap;
748
    }
749
750
751
    /**
752
     * 检测是否有emoji表情
753
     *
754
     * @param source
755
     * @return
756
     */
757
    public static boolean containsEmoji(String source) {
758
        int len = source.length();
759
        for (int i = 0; i < len; i++) {
760
            char codePoint = source.charAt(i);
761
            if (!isEmojiCharacter(codePoint)) { //如果不能匹配,则该字符是Emoji表情
762
                return true;
763
            }
764
        }
765
        return false;
766
    }
767
768
    /**
769
     * 判断是否是Emoji
770
     *
771
     * @param codePoint 比较的单个字符
772
     * @return
773
     */
774
    private static boolean isEmojiCharacter(char codePoint) {
775
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) ||
776
                (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
777
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000)
778
                && (codePoint <= 0x10FFFF));
779
    }
780
781
    @Override
782
    public void onPermissionsGranted(int requestCode, List<String> perms) {
783
784
    }
785
786
    @Override
787
    public void onPermissionsDenied(int requestCode, List<String> perms) {
788
789
    }
790
791
    @AfterPermissionGranted(RC_ALBUM_PERM)
792
    public void permissionTask() {
793
        if (isPermissionOK()) {
794
            callGallery();
795
        } else {
796
            EasyPermissions.requestPermissions(
797
                    this, "充电桩想要获取您的图片读取权限,是否允许?",
798
                    RC_ALBUM_PERM,
799
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
800
                    Manifest.permission.READ_EXTERNAL_STORAGE,
801
                    Manifest.permission.CAMERA
802
            );
803
        }
804
    }
805
806
    private boolean isPermissionOK() {
807
        return EasyPermissions.hasPermissions(this,
808
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
809
                Manifest.permission.READ_EXTERNAL_STORAGE,
810
                Manifest.permission.CAMERA
811
        );
812
    }
813
814
815
    /**
816
     * 表单上传
817
     *
818
     * @param sign
819
     * @param policyServer
820
     */
821
    private void formUpload(File file, String sign, String policyServer) {
822
//        //进度回调,可为空
823
        UpProgressListener progressListener = new UpProgressListener() {
824
            @Override
825
            public void onRequestProgress(long bytesWrite, long contentLength) {
826
//                bp_form.setProgress((int) ((100 * bytesWrite) / contentLength));
827
//                tv_form.setText((100 * bytesWrite) / contentLength + "%");
828
                Log.e(TAG, (100 * bytesWrite) / contentLength + "%");
829
                Log.e(TAG, bytesWrite + "::" + contentLength);
830
                uploadDialog.setProgress((int) (100 * bytesWrite / contentLength));
831
            }
832
        };
833
834
        //结束回调,不可为空
835
        UpCompleteListener completeListener = new UpCompleteListener() {
836
            @Override
837
            public void onComplete(boolean isSuccess, String result) {
838
//                tv_form.setText(isSuccess + ":" + result);
839
                Log.e(TAG, isSuccess + result);
840
                if (isSuccess) {
841
                    PhotoUploadResult photoUploadResult = new PhotoUploadResult(result);
842
                    publishArray.add(photoUploadResult.formatResult());
843
                }
844
845
                if (publishCount == publishArray.size()) {
846
                    String urls = "";
847
                    for (int i = 0; i < publishArray.size(); i++) {
848
                        if (TextUtils.isEmpty(urls))
849
                            urls = publishArray.get(i);
850
                        else
851
                            urls = urls + "," + publishArray.get(i);
852
                    }
853
                    requestPublishServer("[" + urls + "]");
854
                }
855
            }
856
        };
857
858
        //表单上传(服务器签名方式)
859
        UploadEngine.getInstance().formUpload(file, policyServer, OPERATER, sign, completeListener,
860
                progressListener);
861
862
    }
863
864
865
    private void requestPublishServer(String urls) {
866
        String url = MainApplication.urlNew + "/topic/publish.do";
867
        Map<String, String> map = new HashMap<>();
868
        map.put("content", et_context.getText().toString().trim());
869
        map.put("urls", Base64.encode(urls.getBytes()).replaceAll("\\s*", ""));
870
        if (chatRecommendBean != null) {
871
            map.put("topicId", chatRecommendBean.topicId + "");
872
        }
873
        map.put("targetType", ChatRecommendBean.TARGET_TYPE_IMAGE_TEXT + "");
874
        CommonParams.addCommonParams(map);
875
876
        OkHttpUtils.post().params(map).url(url).build().connTimeOut(6000).readTimeOut(6000).execute(new StringCallback() {
877
            @Override
878
            public void onError(Call call, Exception e) {
879
                MobclickAgent.onEvent(getApplicationContext(), "1037");
880
                uploadDialog.dismiss();
881
                dialog.cancel();
882
                publishArray.clear();
883
                publishCount = 0;
884
                ToastUtil.showToast(getApplicationContext(), "发布失败,请重试", Toast.LENGTH_SHORT);
885
            }
886
887
            @Override
888
            public void onResponse(String response) {
889
                uploadDialog.dismiss();
890
                dialog.cancel();
891
                publishArray.clear();
892
                publishCount = 0;
893
                String code = JsonUtils.getKeyResult(response, "code");
894
                String desc = JsonUtils.getKeyResult(response, "desc");
895
                if ("1000".equals(code)) { // 图文发布成功
896
                    MobclickAgent.onEvent(getApplicationContext(), "1036");
897
                    ToastUtil.showToast(getApplicationContext(), "发布成功", Toast.LENGTH_SHORT);
898
                    if (intentData.getFrom().equals(PublishItemsActivity.FROM_CHAT_HOME)) {
899
                        startActivity(new Intent(getApplicationContext(), ChatActivity.class));
900
                    } else {
901
                        startActivity(new Intent(getApplicationContext(), TopicDetailActivity.class));
902
                    }
903
904
                } else {
905
                    MobclickAgent.onEvent(getApplicationContext(), "1037");
906
                    ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
907
                }
908
            }
909
        });
910
    }
911
912
    private void showDialogToExit() {
913
        String s = et_context.getText().toString().trim();
914
        if (s.length() > 0 || Bimp.tempSelectBitmap.size() > 0) {
915
            AlertDialog.Builder builder = new AlertDialog.Builder(PublishPicTopicActivity.this);
916
            builder.setTitle("离开发布页");
917
            builder.setMessage("小主您是否要离开发布页呢?");
918
            builder.setCancelable(false);
919
            builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
920
                @Override
921
                public void onClick(DialogInterface dialog, int which) {
922
                    MobclickAgent.onEvent(getApplicationContext(), "1022");
923
                    finish();
924
                }
925
            });
926
            builder.setNegativeButton("继续编辑", null);
927
            builder.create().show();
928
        } else {
929
            MobclickAgent.onEvent(getApplicationContext(), "1022");
930
            finish();
931
        }
932
    }
933
934
    @Override
935
    public boolean onKeyUp(int keyCode, KeyEvent event) {
936
        if (keyCode == KeyEvent.KEYCODE_BACK) {
937
            showDialogToExit();
938
            return true;
939
        }
940
        return false;
941
    }
942
}

+ 0 - 538
app/src/main/java/com/electric/chargingpile/activity/PublishVideoTopicActivity.java

@ -1,538 +0,0 @@
1
package com.electric.chargingpile.activity;
2
3
import android.app.Activity;
4
import android.app.ProgressDialog;
5
import android.content.BroadcastReceiver;
6
import android.content.Context;
7
import android.content.DialogInterface;
8
import android.content.Intent;
9
import android.content.IntentFilter;
10
import android.content.pm.ActivityInfo;
11
import android.graphics.Color;
12
import android.net.Uri;
13
import android.os.Bundle;
14
import android.text.Editable;
15
import android.text.Html;
16
import android.text.TextUtils;
17
import android.text.TextWatcher;
18
import android.util.Log;
19
import android.view.KeyEvent;
20
import android.view.View;
21
import android.view.View.OnClickListener;
22
import android.widget.EditText;
23
import android.widget.ImageView;
24
import android.widget.RelativeLayout;
25
import android.widget.TextView;
26
import android.widget.Toast;
27
28
import androidx.appcompat.app.AlertDialog;
29
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
30
31
import com.blankj.utilcode.util.ToastUtils;
32
import com.bumptech.glide.Glide;
33
import com.bumptech.glide.request.RequestOptions;
34
import com.electric.chargingpile.R;
35
import com.electric.chargingpile.application.MainApplication;
36
import com.electric.chargingpile.data.AuthSignBean;
37
import com.electric.chargingpile.data.ChatRecommendBean;
38
import com.electric.chargingpile.data.PublishItemSerializable;
39
import com.electric.chargingpile.data.VideoUploadResult;
40
import com.electric.chargingpile.util.BarColorUtil;
41
import com.electric.chargingpile.util.Base64;
42
import com.electric.chargingpile.util.CommonParams;
43
import com.electric.chargingpile.util.DateUtils;
44
import com.electric.chargingpile.util.JsonUtils;
45
import com.electric.chargingpile.util.PhotoUtils;
46
import com.electric.chargingpile.util.ToastUtil;
47
import com.electric.chargingpile.util.Util;
48
import com.luck.picture.lib.PictureSelector;
49
import com.luck.picture.lib.animators.AnimationType;
50
import com.luck.picture.lib.config.PictureConfig;
51
import com.luck.picture.lib.config.PictureMimeType;
52
import com.luck.picture.lib.entity.LocalMedia;
53
import com.electric.chargingpile.engine.GlideEngine;
54
import com.umeng.analytics.MobclickAgent;
55
import com.upyun.library.common.UploadEngine;
56
import com.upyun.library.listener.UpCompleteListener;
57
import com.upyun.library.listener.UpProgressListener;
58
import com.zhy.http.okhttp.OkHttpUtils;
59
import com.zhy.http.okhttp.callback.StringCallback;
60
61
import java.io.File;
62
import java.util.ArrayList;
63
import java.util.HashMap;
64
import java.util.List;
65
import java.util.Map;
66
67
import cn.jpush.android.api.JPushInterface;
68
import okhttp3.Call;
69
@Deprecated
70
public class PublishVideoTopicActivity extends Activity implements OnClickListener {
71
    private static final String TAG = "PublishVideoTopicActivity";
72
    Context mContext;
73
    private ImageView mPublishtopicBack;
74
    private TextView mPublishtopicPublish;
75
    private EditText mPublishtopicCon;
76
    private ImageView mPublishtopicGv;
77
    private TextView mPublishtopicChooseTopic;
78
    private TextView mPublishtopicChoosePreview;
79
    private TextView mPublishtopicWordNum;
80
    private ImageView mPublishTopicDe;
81
82
    private RelativeLayout mItemVideoLl;
83
    private ImageView mItemVideo;
84
    private View mItemVideoDelete;
85
    private String fileName;
86
87
88
    public static final String CACHE_DIR = PhotoUtils.CACHE_DIR;
89
90
91
    public static final String IMAGE_CACHE = CACHE_DIR + "/cache/image/";
92
    LocalMedia media;
93
    ProgressDialog uploadDialog;
94
    private PublishItemSerializable intentData;
95
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
96
97
        @Override
98
        public void onReceive(Context context, Intent intent) {
99
            String message = intent.getStringExtra("message");
100
            if ("take_video".equals(message)) {
101
                MobclickAgent.onEvent(context, "1009");
102
            } else if ("preview_video".equals(message)) {
103
                MobclickAgent.onEvent(context, "1011");
104
            } else if ("finish_preview_video".equals(message)) {
105
                MobclickAgent.onEvent(context, "1012");
106
            } else if ("cancel_choosed_video".equals(message)) {
107
                MobclickAgent.onEvent(context, "1013");
108
            }
109
        }
110
    };
111
112
    @Override
113
    protected void onCreate(Bundle savedInstanceState) {
114
        super.onCreate(savedInstanceState);
115
        setContentView(R.layout.activity_publishtopic);
116
        mContext = this;
117
        uploadDialog = new ProgressDialog(this);
118
        uploadDialog.setMessage("视频上传中...");
119
        uploadDialog.setCanceledOnTouchOutside(false);
120
121
        BarColorUtil.initStatusBarColor(PublishVideoTopicActivity.this);
122
        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("publish-video-topic-activity"));
123
        initView();
124
    }
125
126
127
    private void initView() {
128
        intentData = (PublishItemSerializable) getIntent().getSerializableExtra("intent_data");
129
        mPublishtopicBack = (ImageView) findViewById(R.id.publishtopic_back);
130
        mPublishtopicPublish = (TextView) findViewById(R.id.publishtopic_publish);
131
        mPublishtopicCon = (EditText) findViewById(R.id.publishtopic_con);
132
        mPublishtopicGv = (ImageView) findViewById(R.id.item_choose_video);
133
        mPublishtopicChooseTopic = (TextView) findViewById(R.id.publishtopic_choose_topic);
134
        mPublishtopicChoosePreview = (TextView) findViewById(R.id.publishtopic_choose_preview);
135
        mPublishtopicWordNum = (TextView) findViewById(R.id.publishtopic_word_num);
136
        mPublishTopicDe = (ImageView) findViewById(R.id.publishtopic_choose_topic_de);
137
138
        mItemVideoLl = (RelativeLayout) findViewById(R.id.item_video_ll);
139
        mItemVideo = (ImageView) findViewById(R.id.item_video);
140
        mItemVideoDelete = (View) findViewById(R.id.item_video_delete);
141
142
        if (intentData.getFrom().equals(PublishItemsActivity.FROM_TOPIC_DETAIL)) {
143
            chatRecommendBean = new ChatRecommendBean();
144
            chatRecommendBean.topicId = Long.parseLong(intentData.getTopicId());
145
            mPublishtopicChooseTopic.setText(intentData.getName());
146
            mPublishTopicDe.setVisibility(View.VISIBLE);
147
        }
148
149
        mPublishtopicCon.setOnFocusChangeListener(new View.OnFocusChangeListener() {
150
            @Override
151
            public void onFocusChange(View view, boolean b) {
152
                if (b) { // 获得焦点
153
                    MobclickAgent.onEvent(getApplicationContext(), "1007");
154
                }
155
156
            }
157
        });
158
159
160
        mPublishtopicCon.addTextChangedListener(new TextWatcher() {
161
            @Override
162
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
163
            }
164
165
            @Override
166
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
167
            }
168
169
            @Override
170
            public void afterTextChanged(Editable editable) {
171
                String s = mPublishtopicCon.getText().toString().trim();
172
173
                if (s.length() > 500) {
174
                    mPublishtopicCon.setText(s.subSequence(0, 500));
175
                    mPublishtopicCon.setSelection(500);
176
                }
177
                updatePublishBtn();
178
                if (TextUtils.isEmpty(s)) {
179
                    mPublishtopicWordNum.setText("0/500");
180
                } else {
181
                    mPublishtopicWordNum.setText(s.length() + "/500");
182
                }
183
            }
184
        });
185
186
        mPublishtopicBack.setOnClickListener(this);
187
        mPublishtopicPublish.setOnClickListener(this);
188
        mPublishtopicChoosePreview.setOnClickListener(this);
189
        mPublishtopicChooseTopic.setOnClickListener(this);
190
        mPublishTopicDe.setOnClickListener(this);
191
        mItemVideo.setOnClickListener(this);
192
        mItemVideoDelete.setOnClickListener(this);
193
        mPublishtopicGv.setOnClickListener(this);
194
    }
195
196
    private void updatePublishBtn() {
197
        if (null != media) {
198
            mPublishtopicPublish.setEnabled(true);
199
            mPublishtopicPublish.setBackgroundColor(Color.parseColor("#02b637"));
200
        } else {
201
            mPublishtopicPublish.setEnabled(false);
202
            mPublishtopicPublish.setBackgroundColor(Color.parseColor("#9ed3ae"));
203
        }
204
    }
205
206
207
    @Override
208
    public void onClick(View v) {
209
        switch (v.getId()) {
210
            case R.id.publishtopic_back: // 左上返回按钮事件
211
                showDialogToExit();
212
                break;
213
            case R.id.publishtopic_publish: // 右上发布事件
214
                if (media == null) {
215
                    ToastUtils.showLong("请选择视频!");
216
                    return;
217
                }
218
                MobclickAgent.onEvent(getApplicationContext(), "1035");
219
                uploadDialog.show();
220
                getYouPaiData();
221
                break;
222
            case R.id.publishtopic_choose_topic: // 选择话题事件
223
                MobclickAgent.onEvent(getApplicationContext(), "1031");
224
                mPublishtopicCon.clearFocus();
225
                startActivityForResult(new Intent(this, TopicActivity.class), reqTopic);
226
                break;
227
            case R.id.publishtopic_choose_preview: // 预览事件 暂时隐藏
228
                break;
229
            case R.id.publishtopic_choose_topic_de: // 取消选择话题事件
230
                MobclickAgent.onEvent(getApplicationContext(), "1034");
231
                mPublishtopicChooseTopic.setText("# 选择话题");
232
                mPublishTopicDe.setVisibility(View.GONE);
233
                chatRecommendBean = null;
234
                break;
235
            case R.id.item_choose_video: // 选择视频事件
236
                MobclickAgent.onEvent(getApplicationContext(), "1008");
237
                mPublishtopicCon.clearFocus();
238
239
                PictureSelector.create(PublishVideoTopicActivity.this)
240
                        .openGallery(PictureMimeType.ofVideo())// 全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
241
                        .imageEngine(GlideEngine.createGlideEngine())
242
                        .theme(R.style.picture_white_style)// 主题样式设置 具体参考 values/styles   用法:R.style.picture.white.style v2.3.3后 建议使用setPictureStyle()动态方式
243
                        .isWeChatStyle(false)// 是否开启微信图片选择风格
244
                        .isUseCustomCamera(false)// 是否使用自定义相机
245
                        .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
246
                        .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
247
//                        .setPictureWindowAnimationStyle(mWindowAnimationStyle)// 自定义相册启动退出动画
248
                        .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
249
                        .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
250
//                        .setButtonFeatures(CustomCameraView.BUTTON_STATE_ONLY_RECORDER)// 设置自定义相机按钮状态
251
                        .maxVideoSelectNum(1) // 视频最大选择数量
252
                        .minVideoSelectNum(1)// 视频最小选择数量
253
                        //.closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 关闭在AndroidQ下获取图片或视频宽高相反自动转换
254
                        .imageSpanCount(4)// 每行显示个数
255
                        .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
256
//                        .closeAndroidQChangeWH(true)//如果图片有旋转角度则对换宽高,默认为true
257
//                        .closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 如果视频有旋转角度则对换宽高,默认为false
258
                        .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)// 设置相册Activity方向,不设置默认使用系统
259
                        .selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选
260
                        .isPreviewVideo(true)// 是否可预览视频
261
                        .setOutputCameraPath(IMAGE_CACHE)
262
                        .isCamera(true)// 是否显示拍照按钮
263
                        .isZoomAnim(true)// 图片列表点击 缩放效果 默认true
264
                        .isCompress(true)// 是否压缩
265
                        .synOrAsy(true)//同步true或异步false 压缩 默认同步
266
                        .minimumCompressSize(500)// 小于多少kb的图片不压缩
267
                        .videoMaxSecond(120)
268
                        .videoMinSecond(2)
269
                        .recordVideoSecond(15)
270
                        .forResult(PictureConfig.CHOOSE_REQUEST);
271
                break;
272
            case R.id.item_video:
273
                if (media != null) {
274
                    // 预览视频
275
                    PictureSelector.create(PublishVideoTopicActivity.this)
276
                            .themeStyle(R.style.picture_default_style)
277
                            .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
278
                            .externalPictureVideo(TextUtils.isEmpty(media.getAndroidQToPath()) ? media.getPath() : media.getAndroidQToPath());
279
                }
280
                break;
281
            case R.id.item_video_delete: // 删除视频事件
282
                MobclickAgent.onEvent(getApplicationContext(), "1014");
283
                mItemVideoLl.setVisibility(View.GONE);
284
                mPublishtopicGv.setVisibility(View.VISIBLE);
285
                media = null;
286
                updatePublishBtn();
287
                break;
288
            default:
289
                break;
290
        }
291
    }
292
293
    private void getYouPaiData() {
294
        String url = MainApplication.urlNew + "/topic/sign.do";
295
        if (TextUtils.isEmpty(fileName)) {
296
            ToastUtil.showToast(getApplicationContext(), "请重新选择视频", Toast.LENGTH_SHORT);
297
            return;
298
        }
299
        Map<String, String> map = new HashMap<>();
300
        map.put("fileNames", fileName);
301
        map.put("targetType", ChatRecommendBean.TARGET_TYPE_VIDEO + "");
302
        CommonParams.addCommonParams(map);
303
304
        OkHttpUtils.post().params(map).url(url).build().connTimeOut(6000).readTimeOut(6000).execute(new StringCallback() {
305
            @Override
306
            public void onError(Call call, Exception e) {
307
                ToastUtil.showToast(getApplicationContext(), "发布失败,请重试", Toast.LENGTH_SHORT);
308
                uploadDialog.dismiss();
309
            }
310
311
            @Override
312
            public void onResponse(String response) {
313
                String code = JsonUtils.getKeyResult(response, "code");
314
                String desc = JsonUtils.getKeyResult(response, "desc");
315
                if ("1000".equals(code)) {
316
                    String data = JsonUtils.getKeyResult(response, "data");
317
                    ArrayList<AuthSignBean> signBeans = (ArrayList<AuthSignBean>) JsonUtils.parseToObjectList(data, AuthSignBean.class);
318
                    if (null != signBeans && signBeans.size() > 0) {
319
                        String sign = signBeans.get(0).sign;
320
                        String policy = signBeans.get(0).policy;
321
                        formUpload(TextUtils.isEmpty(media.getAndroidQToPath()) ? media.getPath() : media.getAndroidQToPath(), sign, policy);
322
                    }
323
                } else {
324
                    ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
325
                    uploadDialog.dismiss();
326
                }
327
            }
328
        });
329
330
    }
331
332
    /**
333
     * 表单上传
334
     *
335
     * @param SAMPLE_PIC_FILE
336
     * @param sign
337
     * @param policyServer
338
     */
339
    private void formUpload(String SAMPLE_PIC_FILE, String sign, String policyServer) {
340
        File temp = new File(SAMPLE_PIC_FILE);
341
//        //进度回调,可为空
342
        UpProgressListener progressListener = new UpProgressListener() {
343
            @Override
344
            public void onRequestProgress(long bytesWrite, long contentLength) {
345
            }
346
        };
347
348
        //结束回调,不可为空
349
        UpCompleteListener completeListener = new UpCompleteListener() {
350
            @Override
351
            public void onComplete(boolean isSuccess, String result) {
352
                if (isSuccess) {
353
                    VideoUploadResult videoUploadResult = new VideoUploadResult(result);
354
                    requestPublishServer("[" + videoUploadResult.formatResult() + "]");
355
                } else {
356
                    ToastUtil.showToast(getApplicationContext(), "发布失败,请重试", Toast.LENGTH_SHORT);
357
                    uploadDialog.dismiss();
358
                    MobclickAgent.onEvent(getApplicationContext(), "1037");
359
                }
360
            }
361
        };
362
363
        //表单上传(服务器签名方式)
364
        UploadEngine.getInstance().formUpload(temp, policyServer, "d1evvideo01", sign, completeListener,
365
                progressListener);
366
367
    }
368
369
    private void requestPublishServer(String urls) {
370
371
        String url = MainApplication.urlNew + "/topic/publish.do";
372
        Map<String, String> map = new HashMap<>();
373
        map.put("content", mPublishtopicCon.getText().toString().trim());
374
        map.put("urls", Base64.encode(urls.getBytes()).replaceAll("\\s*", ""));
375
        if (chatRecommendBean != null) {
376
            map.put("topicId", chatRecommendBean.topicId + "");
377
        }
378
        map.put("targetType", ChatRecommendBean.TARGET_TYPE_VIDEO + "");
379
        CommonParams.addCommonParams(map);
380
381
        OkHttpUtils.post().params(map).url(url).build().connTimeOut(6000).readTimeOut(6000).execute(new StringCallback() {
382
            @Override
383
            public void onError(Call call, Exception e) {
384
                ToastUtil.showToast(getApplicationContext(), "发布失败,请重试", Toast.LENGTH_SHORT);
385
                uploadDialog.dismiss();
386
                MobclickAgent.onEvent(getApplicationContext(), "1037");
387
            }
388
389
            @Override
390
            public void onResponse(String response) {
391
                String code = JsonUtils.getKeyResult(response, "code");
392
                if ("1000".equals(code)) { // 视频发布成功
393
                    ToastUtil.showToast(getApplicationContext(), "发布成功", Toast.LENGTH_SHORT);
394
                    if (intentData.getFrom().equals(PublishItemsActivity.FROM_CHAT_HOME)) {
395
                        startActivity(new Intent(getApplicationContext(), ChatActivity.class));
396
                    } else {
397
                        startActivity(new Intent(getApplicationContext(), TopicDetailActivity.class));
398
                    }
399
                    MobclickAgent.onEvent(getApplicationContext(), "1036");
400
                } else {
401
                    String desc = JsonUtils.getKeyResult(response, "desc");
402
                    ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
403
                    MobclickAgent.onEvent(getApplicationContext(), "1037");
404
                }
405
                uploadDialog.dismiss();
406
            }
407
        });
408
    }
409
410
411
    final int reqTopic = 100;
412
    ChatRecommendBean chatRecommendBean = null;
413
414
    @Override
415
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
416
        super.onActivityResult(requestCode, resultCode, data);
417
        if (requestCode == reqTopic && resultCode == -100) { // 选择话题完成
418
            chatRecommendBean = (ChatRecommendBean) data.getSerializableExtra("topic");
419
            if (chatRecommendBean != null) {
420
                mPublishtopicChooseTopic.setText(Html.fromHtml(chatRecommendBean.name));
421
                mPublishTopicDe.setVisibility(View.VISIBLE);
422
            }
423
        } else if (requestCode == PictureConfig.CHOOSE_REQUEST && resultCode == RESULT_OK) {
424
            List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data);
425
            if (selectList != null && selectList.size() > 0) {
426
                MobclickAgent.onEvent(getApplicationContext(), "1010");
427
                media = selectList.get(0);
428
429
                String deviceId = JPushInterface.getUdid(MainApplication.context);
430
                fileName = DateUtils.getSimpleCurrentDate();
431
                if (TextUtils.isEmpty(deviceId)) {
432
                    fileName += "_" + Util.getRandom(15);
433
                } else {
434
                    fileName += "_" + deviceId;
435
                }
436
                String videoPath = TextUtils.isEmpty(media.getAndroidQToPath()) ? media.getPath() : media.getAndroidQToPath();
437
                if (TextUtils.isEmpty(videoPath)) {
438
                    fileName = "";
439
                } else {
440
                    String suffix = videoPath.substring(videoPath.lastIndexOf(".") + 1);
441
                    fileName += "." + suffix;
442
                }
443
444
                if (TextUtils.isEmpty(videoPath)) {
445
                    return;
446
                }
447
448
                if (!fileIsExists(videoPath)) {
449
                    Log.e("yopic", "文件可能不存在了~");
450
                    return;
451
                }
452
                if (isDestroyed()) {
453
                    return;
454
                }
455
456
                Glide.with(this)
457
                        .load(videoPath)
458
                        .apply(new RequestOptions().centerCrop())
459
                        .into(mItemVideo);
460
                mItemVideoLl.setVisibility(View.VISIBLE);
461
                mPublishtopicGv.setVisibility(View.GONE);
462
                updatePublishBtn();
463
                Log.e("yopic", "TEST===> video path = " + media.getPath()
464
                        + ",  compressPath = " + media.getCompressPath()
465
                        + ", height = " + media.getHeight()
466
                        + ", width = " + media.getWidth());
467
            }
468
469
        }
470
    }
471
472
    public static boolean fileIsExists(String strFile) {
473
        if (TextUtils.isEmpty(strFile)) {
474
            return false;
475
        }
476
        try {
477
            File f = new File(strFile);
478
            if (!f.exists()) {
479
                return false;
480
            }
481
482
        } catch (Exception e) {
483
            return false;
484
        }
485
486
        return true;
487
    }
488
489
    @Override
490
    protected void onResume() {
491
        super.onResume();
492
        MobclickAgent.onResume(this);
493
    }
494
495
    @Override
496
    protected void onPause() {
497
        super.onPause();
498
        MobclickAgent.onPause(this);
499
    }
500
501
    @Override
502
    protected void onDestroy() {
503
        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
504
        super.onDestroy();
505
    }
506
507
    private void showDialogToExit() {
508
509
        String s = mPublishtopicCon.getText().toString().trim();
510
        if (s.length() > 0 || media != null) {
511
            AlertDialog.Builder builder = new AlertDialog.Builder(PublishVideoTopicActivity.this);
512
            builder.setTitle("离开发布页");
513
            builder.setMessage("小主您是否要离开发布页呢?");
514
            builder.setCancelable(false);
515
            builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
516
                @Override
517
                public void onClick(DialogInterface dialog, int which) {
518
                    MobclickAgent.onEvent(getApplicationContext(), "1006");
519
                    finish();
520
                }
521
            });
522
            builder.setNegativeButton("继续编辑", null);
523
            builder.create().show();
524
        } else {
525
            MobclickAgent.onEvent(getApplicationContext(), "1006");
526
            finish();
527
        }
528
    }
529
530
    @Override
531
    public boolean onKeyUp(int keyCode, KeyEvent event) {
532
        if (keyCode == KeyEvent.KEYCODE_BACK) {
533
            showDialogToExit();
534
            return true;
535
        }
536
        return false;
537
    }
538
}

+ 71 - 81
app/src/main/java/com/electric/chargingpile/activity/ShareTwoActivity.java

@ -1,5 +1,8 @@
1 1
package com.electric.chargingpile.activity;
2 2
3
import static com.hjq.permissions.Permission.CAMERA;
4
import static com.hjq.permissions.Permission.READ_MEDIA_IMAGES;
5
3 6
import android.Manifest;
4 7
import android.annotation.SuppressLint;
5 8
import android.app.Activity;
@ -17,6 +20,7 @@ import android.os.Build;
17 20
import android.os.Bundle;
18 21
import android.os.Handler;
19 22
import android.os.Message;
23
import android.provider.MediaStore;
20 24
import android.util.Base64;
21 25
import android.util.Log;
22 26
import android.view.KeyEvent;
@ -54,9 +58,13 @@ import com.electric.chargingpile.util.BarColorUtil;
54 58
import com.electric.chargingpile.util.Bimp;
55 59
import com.electric.chargingpile.util.DES3;
56 60
import com.electric.chargingpile.util.DensityUtil;
61
import com.electric.chargingpile.util.ImageFileCompressEngine;
57 62
import com.electric.chargingpile.util.ImageItem;
58 63
import com.electric.chargingpile.util.JsonUtils;
64
import com.electric.chargingpile.util.MeOnCameraInterceptListener;
65
import com.electric.chargingpile.util.MeSandboxFileEngine;
59 66
import com.electric.chargingpile.util.OkHttpUtil;
67
import com.electric.chargingpile.util.PictureUtlis;
60 68
import com.electric.chargingpile.util.PublicWayFour;
61 69
import com.electric.chargingpile.util.Res;
62 70
import com.electric.chargingpile.util.SharedPreferencesUtil;
@ -67,10 +75,15 @@ import com.electric.chargingpile.view.CustomProgressDialog;
67 75
import com.electric.chargingpile.view.ShareDialog;
68 76
import com.google.gson.Gson;
69 77
import com.google.gson.reflect.TypeToken;
70
import com.luck.picture.lib.PictureSelector;
78
79
import com.hjq.permissions.OnPermissionCallback;
80
import com.hjq.permissions.XXPermissions;
71 81
import com.luck.picture.lib.animators.AnimationType;
82
import com.luck.picture.lib.basic.PictureSelector;
72 83
import com.luck.picture.lib.config.PictureConfig;
73 84
import com.luck.picture.lib.config.PictureMimeType;
85
import com.luck.picture.lib.config.SelectMimeType;
86
import com.luck.picture.lib.config.SelectModeConfig;
74 87
import com.luck.picture.lib.entity.LocalMedia;
75 88
import com.squareup.okhttp.Request;
76 89
import com.squareup.okhttp.Response;
@ -102,7 +115,7 @@ import okhttp3.Call;
102 115
import pub.devrel.easypermissions.AfterPermissionGranted;
103 116
import pub.devrel.easypermissions.EasyPermissions;
104 117
105
public class ShareTwoActivity extends Activity implements View.OnClickListener, EasyPermissions.PermissionCallbacks {
118
public class ShareTwoActivity extends Activity implements View.OnClickListener {
106 119
    private static final String TAG = "ShareTwoActivity";
107 120
    private static final int PIC_NUM = 4;
108 121
    private ImageView ivBack, ivType;
@ -344,35 +357,36 @@ public class ShareTwoActivity extends Activity implements View.OnClickListener,
344 357
     * 调用图库选择
345 358
     */
346 359
    private void callGallery() {
347
/*
348
        Matisse.from(ShareTwoActivity.this)
349
                .choose(MimeType.of(MimeType.JPEG, MimeType.PNG, MimeType.GIF))
350
                .showSingleMediaType(true)
351
                .countable(true)
352
                .maxSelectable(1)
353
                .capture(true)
354
                .captureStrategy(new CaptureStrategy(true, "com.electric.chargingpile.provider"))
355
                .imageEngine(new GlideEngine())
356
                .forResult(REQUEST_CODE_CHOOSE);
357
*/
358 360
        PictureSelector.create(this)
359
                .openGallery(PictureMimeType.ofImage())
360
                .selectionMode(PictureConfig.SINGLE)
361
                .isCompress(true)//是否压缩
362
                .isSingleDirectReturn(true)
363
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
364
                .isGif(true)//是否显示gif
365
                .isAndroidQTransform(true)
366
                .imageEngine(GlideEngine.createGlideEngine())
367
                .isWeChatStyle(false)// 是否开启微信图片选择风格
368
                .isUseCustomCamera(false)// 是否使用自定义相机
369
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
370
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
371
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
372
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
373
                .imageSpanCount(4)// 每行显示个数
374
                .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
375
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
361
                .openGallery(SelectMimeType.ofImage())
362
                .setSelectorUIStyle(PictureUtlis.getStyle())
363
                .setImageEngine(GlideEngine.createGlideEngine())
364
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
365
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
366
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
367
                .setSelectionMode(SelectModeConfig.SINGLE)
368
                .setMaxSelectNum(1)
369
                .isEmptyResultReturn(true) //支持未选择返回
370
                .setImageSpanCount(4)
371
                .isPageStrategy(true)   // 是否开启分页模式
372
                .isDisplayCamera(true) //是否显示相机入口
373
                .isPreviewFullScreenMode(true)//预览点击全屏效果
374
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
375
                .isEmptyResultReturn(true)//支持未选择返回
376
                .isWithSelectVideoImage(false)//是否支持视频图片同选
377
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
378
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
379
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
380
                .isGif(false)// 是否显示gif文件
381
                .isWebp(true)// 是否显示webp文件
382
                .isBmp(true)//是否显示bmp文件
383
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
384
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
385
                .isFastSlidingSelect(true) //快速滑动选择
386
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
387
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
388
                .isPreviewImage(true)//是否预览图片
389
                .setFilterMinFileSize(1) //过滤最小文件
376 390
                .forResult(REQUEST_CODE_CHOOSE);
377 391
    }
378 392
@ -403,22 +417,9 @@ public class ShareTwoActivity extends Activity implements View.OnClickListener,
403 417
            public void subscribe(ObservableEmitter<String> subscriber) throws Exception {
404 418
405 419
                try {
406
                    List<LocalMedia> mediaList = PictureSelector.obtainMultipleResult(data);
420
                    List<LocalMedia> mediaList = PictureSelector.obtainSelectorList(data);
407 421
                    if (mediaList!=null && mediaList.size()>0){
408
                       /* List<Uri> uriList = Matisse.obtainResult(data);
409
                        Uri uri = uriList.get(0);
410
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
411
                        File file = FileUtils.from(ShareTwoActivity.this, uri);
412
413
                        bitmap = FileUtils.rotateIfRequired(file, bitmap);
414
                        bitmap = imageZoom(bitmap);
415
*/
416
                        String path="";
417
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
418
                            path= mediaList.get(0).getAndroidQToPath();
419
                        }else{
420
                            path=mediaList.get(0).getPath();
421
                        }
422
                        String path = Util.getCompressAbsolutePath(mediaList.get(0));
422 423
                        ImageItem takePhoto = new ImageItem();
423 424
                        takePhoto.setBitmap(imageZoom(BitmapFactory.decodeFile(path)));
424 425
                        selectBitmap[selectIndex] = takePhoto;
@ -953,48 +954,37 @@ public class ShareTwoActivity extends Activity implements View.OnClickListener,
953 954
        }
954 955
    }
955 956
956
    @Override
957
    public void onRequestPermissionsResult(int requestCode,
958
                                           @NonNull String[] permissions,
959
                                           @NonNull int[] grantResults) {
960
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
961
962
        // EasyPermissions handles the request result.
963
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
964
    }
965
966
    @Override
967
    public void onPermissionsGranted(int requestCode, List<String> perms) {
968 957
969
    }
970 958
971
    @Override
972
    public void onPermissionsDenied(int requestCode, List<String> perms) {
973
974
    }
975 959
976
    @AfterPermissionGranted(RC_ALBUM_PERM)
977 960
    public void permissionTask() {
978
        if (isPermissionOK()) {
979
            callGallery();
980
        } else {
981
            // Ask for one permission
982
            EasyPermissions.requestPermissions(
983
                    this, "充电桩想要获取您的图片读取权限,是否允许?",
984
                    RC_ALBUM_PERM,
985
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
986
                    Manifest.permission.READ_EXTERNAL_STORAGE,
987
                    Manifest.permission.CAMERA);
988
        }
961
        String[] callPhone  =
962
                new String[]{READ_MEDIA_IMAGES, CAMERA};
963
        XXPermissions.with(this)
964
                // 申请单个权限
965
                .permission(callPhone)
966
                .request(new OnPermissionCallback() {
967
                    @Override
968
                    public void onGranted(List<String> permissions, boolean all) {
969
                        if (all) {
970
                            callGallery();
971
                        }else{
972
                            ToastUtil.showToast(getApplicationContext(), "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT);
973
                        }
974
                    }
975
                    @Override
976
                    public void onDenied(List<String> permissions, boolean never) {
977
                        if (never) {
978
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
979
                            XXPermissions.startPermissionActivity(ShareTwoActivity.this, permissions);
980
                        } else {
981
                            ToastUtil.showToast(getApplicationContext(), "获取权限失败", Toast.LENGTH_SHORT);
982
                        }
983
                    }
984
                });
989 985
    }
990 986
991
    private boolean isPermissionOK() {
992
        return EasyPermissions.hasPermissions(this,
993
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
994
                Manifest.permission.READ_EXTERNAL_STORAGE,
995
                Manifest.permission.CAMERA
996
        );
997
    }
987
998 988
999 989
    @SuppressLint("HandlerLeak")
1000 990
    public class GridAdapter extends BaseAdapter {

+ 71 - 73
app/src/main/java/com/electric/chargingpile/activity/ShareTwoEditActivity.java

@ -1,5 +1,8 @@
1 1
package com.electric.chargingpile.activity;
2 2
3
import static com.hjq.permissions.Permission.CAMERA;
4
import static com.hjq.permissions.Permission.READ_MEDIA_IMAGES;
5
3 6
import android.Manifest;
4 7
import android.app.Activity;
5 8
import android.app.ProgressDialog;
@ -50,11 +53,16 @@ import com.electric.chargingpile.application.MainApplication;
50 53
import com.electric.chargingpile.data.Zhan;
51 54
import com.electric.chargingpile.engine.GlideEngine;
52 55
import com.electric.chargingpile.util.BarColorUtil;
56
import com.electric.chargingpile.util.Bimp;
53 57
import com.electric.chargingpile.util.DES3;
54 58
import com.electric.chargingpile.util.DensityUtil;
59
import com.electric.chargingpile.util.ImageFileCompressEngine;
55 60
import com.electric.chargingpile.util.ImageItem;
56 61
import com.electric.chargingpile.util.JsonUtils;
62
import com.electric.chargingpile.util.MeOnCameraInterceptListener;
63
import com.electric.chargingpile.util.MeSandboxFileEngine;
57 64
import com.electric.chargingpile.util.OkHttpUtil;
65
import com.electric.chargingpile.util.PictureUtlis;
58 66
import com.electric.chargingpile.util.PublicWayFour;
59 67
import com.electric.chargingpile.util.Res;
60 68
import com.electric.chargingpile.util.SharedPreferencesUtil;
@ -63,10 +71,15 @@ import com.electric.chargingpile.util.UploadUtil;
63 71
import com.electric.chargingpile.util.Util;
64 72
import com.electric.chargingpile.view.CustomProgressDialog;
65 73
import com.electric.chargingpile.view.ShareDialog;
66
import com.luck.picture.lib.PictureSelector;
74
75
import com.hjq.permissions.OnPermissionCallback;
76
import com.hjq.permissions.XXPermissions;
67 77
import com.luck.picture.lib.animators.AnimationType;
78
import com.luck.picture.lib.basic.PictureSelector;
68 79
import com.luck.picture.lib.config.PictureConfig;
69 80
import com.luck.picture.lib.config.PictureMimeType;
81
import com.luck.picture.lib.config.SelectMimeType;
82
import com.luck.picture.lib.config.SelectModeConfig;
70 83
import com.luck.picture.lib.entity.LocalMedia;
71 84
import com.squareup.okhttp.Request;
72 85
import com.squareup.okhttp.Response;
@ -101,7 +114,7 @@ import okhttp3.Call;
101 114
import pub.devrel.easypermissions.AfterPermissionGranted;
102 115
import pub.devrel.easypermissions.EasyPermissions;
103 116
104
public class ShareTwoEditActivity extends Activity implements View.OnClickListener, EasyPermissions.PermissionCallbacks {
117
public class ShareTwoEditActivity extends Activity implements View.OnClickListener{
105 118
    private static final String TAG = "ShareTwoActivity";
106 119
    private static final int PIC_NUM = 4;
107 120
    private ImageView ivBack, ivType;
@ -299,35 +312,36 @@ public class ShareTwoEditActivity extends Activity implements View.OnClickListen
299 312
     * 调用图库选择
300 313
     */
301 314
    private void callGallery() {
302
/*
303
        Matisse.from(ShareTwoEditActivity.this)
304
                .choose(MimeType.of(MimeType.JPEG, MimeType.PNG, MimeType.GIF))
305
                .showSingleMediaType(true)
306
                .countable(true)
307
                .maxSelectable(1)
308
                .capture(true)
309
                .captureStrategy(new CaptureStrategy(true, "com.electric.chargingpile.provider"))
310
                .imageEngine(new GlideEngine())
311
                .forResult(REQUEST_CODE_CHOOSE);
312
*/
313 315
        PictureSelector.create(this)
314
                .openGallery(PictureMimeType.ofImage())
315
                .selectionMode(PictureConfig.SINGLE)
316
                .isSingleDirectReturn(true)
317
                .isCompress(true)//是否压缩
318
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
319
                .isGif(true)//是否显示gif
320
                .isAndroidQTransform(true)
321
                .imageEngine(GlideEngine.createGlideEngine())
322
                .isWeChatStyle(false)// 是否开启微信图片选择风格
323
                .isUseCustomCamera(false)// 是否使用自定义相机
324
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
325
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
326
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
327
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
328
                .imageSpanCount(4)// 每行显示个数
329
                .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
330
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
316
                .openGallery(SelectMimeType.ofImage())
317
                .setSelectorUIStyle(PictureUtlis.getStyle())
318
                .setImageEngine(GlideEngine.createGlideEngine())
319
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
320
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
321
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
322
                .setSelectionMode(SelectModeConfig.SINGLE)
323
                .setMaxSelectNum(1)
324
                .isEmptyResultReturn(true) //支持未选择返回
325
                .setImageSpanCount(4)
326
                .isPageStrategy(true)   // 是否开启分页模式
327
                .isDisplayCamera(true) //是否显示相机入口
328
                .isPreviewFullScreenMode(true)//预览点击全屏效果
329
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
330
                .isEmptyResultReturn(true)//支持未选择返回
331
                .isWithSelectVideoImage(false)//是否支持视频图片同选
332
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
333
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
334
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
335
                .isGif(false)// 是否显示gif文件
336
                .isWebp(true)// 是否显示webp文件
337
                .isBmp(true)//是否显示bmp文件
338
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
339
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
340
                .isFastSlidingSelect(true) //快速滑动选择
341
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
342
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
343
                .isPreviewImage(true)//是否预览图片
344
                .setFilterMinFileSize(1) //过滤最小文件
331 345
                .forResult(REQUEST_CODE_CHOOSE);
332 346
333 347
    }
@ -358,22 +372,9 @@ public class ShareTwoEditActivity extends Activity implements View.OnClickListen
358 372
            @Override
359 373
            public void subscribe(ObservableEmitter<String> subscriber) throws Exception {
360 374
                try {
361
                    List<LocalMedia> mediaList = PictureSelector.obtainMultipleResult(data);
375
                    List<LocalMedia> mediaList = PictureSelector.obtainSelectorList(data);
362 376
                    if (mediaList!=null && mediaList.size()>0){
363
                      /*  List<Uri> uriList = Matisse.obtainResult(data);
364
                        Uri uri = uriList.get(0);
365
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
366
                        File file = FileUtils.from(ShareTwoEditActivity.this, uri);
367
368
                        bitmap = FileUtils.rotateIfRequired(file, bitmap);
369
                        bitmap = imageZoom(bitmap);
370
*/
371
                        String path="";
372
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
373
                            path= mediaList.get(0).getAndroidQToPath();
374
                        }else{
375
                            path=mediaList.get(0).getPath();
376
                        }
377
                        String path = Util.getCompressAbsolutePath(mediaList.get(0));
377 378
                        ImageItem takePhoto = new ImageItem();
378 379
                        takePhoto.setBitmap(imageZoom(BitmapFactory.decodeFile(path)));
379 380
                        selectBitmap[selectIndex] = takePhoto;
@ -922,39 +923,36 @@ public class ShareTwoEditActivity extends Activity implements View.OnClickListen
922 923
        }
923 924
    }
924 925
925
    @Override
926
    public void onRequestPermissionsResult(int requestCode,
927
                                           @NonNull String[] permissions,
928
                                           @NonNull int[] grantResults) {
929
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
930 926
931
        // EasyPermissions handles the request result.
932
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
933
    }
934 927
935
    @Override
936
    public void onPermissionsGranted(int requestCode, List<String> perms) {
937
938
    }
939 928
940
    @Override
941
    public void onPermissionsDenied(int requestCode, List<String> perms) {
929
    public void permissionTask() {
942 930
943
    }
931
        String[] callPhone  =
932
                new String[]{READ_MEDIA_IMAGES, CAMERA};
933
        XXPermissions.with(this)
934
                // 申请单个权限
935
                .permission(callPhone)
936
                .request(new OnPermissionCallback() {
937
                    @Override
938
                    public void onGranted(List<String> permissions, boolean all) {
939
                        if (all) {
940
                            callGallery();
941
                        }else{
942
                            ToastUtil.showToast(getApplicationContext(), "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT);
943
                        }
944
                    }
945
                    @Override
946
                    public void onDenied(List<String> permissions, boolean never) {
947
                        if (never) {
948
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
949
                            XXPermissions.startPermissionActivity(ShareTwoEditActivity.this, permissions);
950
                        } else {
951
                            ToastUtil.showToast(getApplicationContext(), "获取权限失败", Toast.LENGTH_SHORT);
952
                        }
953
                    }
954
                });
944 955
945
    @AfterPermissionGranted(RC_ALBUM_PERM)
946
    public void permissionTask() {
947
        if (isPermissionOK()) {
948
            callGallery();
949
        } else {
950
            // Ask for one permission
951
            EasyPermissions.requestPermissions(
952
                    this, "充电桩想要获取您的图片读取权限,是否允许?",
953
                    RC_ALBUM_PERM,
954
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
955
                    Manifest.permission.READ_EXTERNAL_STORAGE,
956
                    Manifest.permission.CAMERA);
957
        }
958 956
    }
959 957
960 958
    private boolean isPermissionOK() {

+ 102 - 95
app/src/main/java/com/electric/chargingpile/activity/SkipUserInfoActivity.java

@ -1,5 +1,8 @@
1 1
package com.electric.chargingpile.activity;
2 2
3
import static com.hjq.permissions.Permission.CAMERA;
4
import static com.hjq.permissions.Permission.READ_MEDIA_IMAGES;
5
3 6
import android.Manifest;
4 7
import android.app.Activity;
5 8
import android.content.Context;
@ -54,12 +57,17 @@ import com.electric.chargingpile.manager.ProfileManager;
54 57
import com.electric.chargingpile.util.ActivityManagerApplication;
55 58
import com.electric.chargingpile.util.BarColorUtil;
56 59
import com.electric.chargingpile.util.DES3;
60
import com.electric.chargingpile.util.ImageCropEngine;
61
import com.electric.chargingpile.util.ImageFileCompressEngine;
57 62
import com.electric.chargingpile.util.ImageTools;
58 63
import com.electric.chargingpile.util.JsonUtils;
59 64
import com.electric.chargingpile.util.LoadingDialog;
60 65
import com.electric.chargingpile.util.LogUtils;
66
import com.electric.chargingpile.util.MeOnCameraInterceptListener;
67
import com.electric.chargingpile.util.MeSandboxFileEngine;
61 68
import com.electric.chargingpile.util.OkHttpUtil;
62 69
import com.electric.chargingpile.util.PhotoUtils;
70
import com.electric.chargingpile.util.PictureUtlis;
63 71
import com.electric.chargingpile.util.StatusConstants;
64 72
import com.electric.chargingpile.util.ToastUtil;
65 73
import com.electric.chargingpile.util.UploadUtil;
@ -68,10 +76,15 @@ import com.electric.chargingpile.view.CustomProgressDialog;
68 76
import com.electric.chargingpile.view.RoundImageView;
69 77
import com.electric.chargingpile.view.xrichtext.SDCardUtil;
70 78
import com.google.gson.Gson;
71
import com.luck.picture.lib.PictureSelector;
79
80
import com.hjq.permissions.OnPermissionCallback;
81
import com.hjq.permissions.XXPermissions;
72 82
import com.luck.picture.lib.animators.AnimationType;
83
import com.luck.picture.lib.basic.PictureSelector;
73 84
import com.luck.picture.lib.config.PictureConfig;
74 85
import com.luck.picture.lib.config.PictureMimeType;
86
import com.luck.picture.lib.config.SelectMimeType;
87
import com.luck.picture.lib.config.SelectModeConfig;
75 88
import com.luck.picture.lib.entity.LocalMedia;
76 89
import com.squareup.okhttp.Request;
77 90
import com.squareup.okhttp.Response;
@ -102,7 +115,7 @@ import pub.devrel.easypermissions.AfterPermissionGranted;
102 115
import pub.devrel.easypermissions.EasyPermissions;
103 116
104 117
105
public class SkipUserInfoActivity extends Activity implements View.OnClickListener, EasyPermissions.PermissionCallbacks {
118
public class SkipUserInfoActivity extends Activity implements View.OnClickListener {
106 119
    private ImageView back;
107 120
    private EditText et_nickName;
108 121
    private EditText et_realName;
@ -293,15 +306,6 @@ public class SkipUserInfoActivity extends Activity implements View.OnClickListen
293 306
        spinnerCity.setOnItemSelectedListener(new CityAdapter());
294 307
    }
295 308
296
    @Override
297
    public void onPermissionsGranted(int requestCode, List<String> perms) {
298
299
    }
300
301
    @Override
302
    public void onPermissionsDenied(int requestCode, List<String> perms) {
303
304
    }
305 309
306 310
    private void showWindow() {
307 311
        LayoutInflater inflater = (LayoutInflater) getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
@ -369,31 +373,35 @@ public class SkipUserInfoActivity extends Activity implements View.OnClickListen
369 373
        popupWindow.showAtLocation(cancleButton, Gravity.CENTER, 0, 0);
370 374
    }
371 375
372
    @AfterPermissionGranted(RC_CAMERA_PERM)
376
373 377
    public void cameraTask() {
374
        if (hasCameraPermission()) {
375
            // Have permission, do the thing!
376
//            Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show();
377
            showWindow();
378
        } else {
379
            // Ask for one permission
380
            EasyPermissions.requestPermissions(
381
                    this,
382
                    "充电桩需要获取您相关权限,是否允许?",
383
                    RC_CAMERA_PERM,
384
                    Manifest.permission.CAMERA,
385
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
386
                    Manifest.permission.READ_EXTERNAL_STORAGE);
387
        }
378
        String[] callPhone  =
379
                new String[]{READ_MEDIA_IMAGES, CAMERA};
380
        XXPermissions.with(this)
381
                // 申请单个权限
382
                .permission(callPhone)
383
                .request(new OnPermissionCallback() {
384
                    @Override
385
                    public void onGranted(List<String> permissions, boolean all) {
386
                        if (all) {
387
                            showWindow();
388
                        }else{
389
                            ToastUtil.showToast(getApplicationContext(), "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT);
390
                        }
391
                    }
392
                    @Override
393
                    public void onDenied(List<String> permissions, boolean never) {
394
                        if (never) {
395
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
396
                            XXPermissions.startPermissionActivity(SkipUserInfoActivity.this, permissions);
397
                        } else {
398
                            ToastUtil.showToast(getApplicationContext(), "获取权限失败", Toast.LENGTH_SHORT);
399
                        }
400
                    }
401
                });
388 402
    }
389 403
390
    private boolean hasCameraPermission() {
391
        return EasyPermissions.hasPermissions(this,
392
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
393
                Manifest.permission.READ_EXTERNAL_STORAGE,
394
                Manifest.permission.CAMERA
395
        );
396
    }
404
397 405
398 406
    class ProvinceAdapter implements AdapterView.OnItemSelectedListener {
399 407
@ -515,65 +523,69 @@ public class SkipUserInfoActivity extends Activity implements View.OnClickListen
515 523
     */
516 524
    public void takePhoto(View view) {
517 525
        PictureSelector.create(this)
518
                .openCamera(PictureMimeType.ofImage())
519
                .selectionMode(PictureConfig.SINGLE)
520
                .isSingleDirectReturn(true)
521
                .isCompress(true)//是否压缩
522
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
523
                .isGif(false)//是否显示gif
524
                .isAndroidQTransform(true)
525
                .imageEngine(GlideEngine.createGlideEngine())
526
                .isWeChatStyle(false)// 是否开启微信图片选择风格
527
                .isUseCustomCamera(false)// 是否使用自定义相机
528
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
529
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
530
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
531
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
532
                .imageSpanCount(4)// 每行显示个数
533
                .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
534
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
535
                .isEnableCrop(true)
536
                .rotateEnabled(false)//裁剪是否可旋转图片
537
                .setCircleStrokeWidth(8)//设置圆形裁剪边框粗细
538
                .freeStyleCropEnabled(true)// 裁剪框拖动模式
539
                //.isCropDragSmoothToCenter(true)// 裁剪框拖动时图片自动跟随居中
540
                .circleDimmedLayer(true)// 是否开启圆形裁剪
541
                .isDragFrame(true)//是否可拖动裁剪框(固定)
542
                .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false
543
                .showCropGrid(false)//是否显示裁剪矩形网格 圆形裁剪时建议设为false
526
                .openGallery(SelectMimeType.ofImage())
527
                .setSelectorUIStyle(PictureUtlis.getStyle())
528
                .setImageEngine(GlideEngine.createGlideEngine())
529
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
530
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
531
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
532
                .setSelectionMode(SelectModeConfig.SINGLE)
533
                .setMaxSelectNum(1)
534
                .isEmptyResultReturn(true) //支持未选择返回
535
                .setImageSpanCount(4)
536
                .isPageStrategy(true)   // 是否开启分页模式
537
                .isDisplayCamera(true) //是否显示相机入口
538
                .isPreviewFullScreenMode(true)//预览点击全屏效果
539
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
540
                .isEmptyResultReturn(true)//支持未选择返回
541
                .isWithSelectVideoImage(false)//是否支持视频图片同选
542
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
543
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
544
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
545
                .isGif(false)// 是否显示gif文件
546
                .isWebp(true)// 是否显示webp文件
547
                .isBmp(true)//是否显示bmp文件
548
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
549
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
550
                .isFastSlidingSelect(true) //快速滑动选择
551
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
552
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
553
                .isPreviewImage(true)//是否预览图片
554
                .setCropEngine(new ImageCropEngine(1F,1F,true))
555
                .setFilterMinFileSize(1) //过滤最小文件
544 556
                .forResult(2);
545
546 557
    }
547 558
    private void openPhotoAlbum() {
548 559
        PictureSelector.create(this)
549
                .openGallery(PictureMimeType.ofImage())
550
                .isCamera(false)//列表是否显示拍照按钮
551
                .selectionMode(PictureConfig.SINGLE)
552
                .isSingleDirectReturn(true)//PictureConfig.SINGLE模式下是否直接返回
553
                .isCompress(true)//是否压缩
554
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
555
                .isGif(false)//是否显示gif
556
                .isAndroidQTransform(true)
557
                .imageEngine(GlideEngine.createGlideEngine())
558
                .isWeChatStyle(false)// 是否开启微信图片选择风格
559
                .isUseCustomCamera(false)// 是否使用自定义相机
560
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
561
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
562
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
563
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
564
                .imageSpanCount(4)// 每行显示个数
565
                .isReturnEmpty(false)// 选择数据时点击按钮是否可以返回
566
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
567
                .rotateEnabled(false)//裁剪是否可旋转图片
568
                .isEnableCrop(true)
569
                .rotateEnabled(false)//裁剪是否可旋转图片
570
                .setCircleStrokeWidth(8)//设置圆形裁剪边框粗细
571
                .freeStyleCropEnabled(true)// 裁剪框拖动模式
572
                //.isCropDragSmoothToCenter(true)// 裁剪框拖动时图片自动跟随居中
573
                .circleDimmedLayer(true)// 是否开启圆形裁剪
574
                .isDragFrame(true)//是否可拖动裁剪框(固定)
575
                .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false
576
                .showCropGrid(false)//是否显示裁剪矩形网格 圆形裁剪时建议设为false
560
                .openGallery(SelectMimeType.ofImage())
561
                .setSelectorUIStyle(PictureUtlis.getStyle())
562
                .setImageEngine(GlideEngine.createGlideEngine())
563
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
564
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
565
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
566
                .setSelectionMode(SelectModeConfig.SINGLE)
567
                .setMaxSelectNum(1)
568
                .isEmptyResultReturn(true) //支持未选择返回
569
                .setImageSpanCount(4)
570
                .isPageStrategy(true)   // 是否开启分页模式
571
                .isDisplayCamera(true) //是否显示相机入口
572
                .isPreviewFullScreenMode(true)//预览点击全屏效果
573
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
574
                .isEmptyResultReturn(true)//支持未选择返回
575
                .isWithSelectVideoImage(false)//是否支持视频图片同选
576
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
577
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
578
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
579
                .isGif(false)// 是否显示gif文件
580
                .isWebp(true)// 是否显示webp文件
581
                .isBmp(true)//是否显示bmp文件
582
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
583
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
584
                .isFastSlidingSelect(true) //快速滑动选择
585
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
586
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
587
                .isPreviewImage(true)//是否预览图片
588
                .setCropEngine(new ImageCropEngine(1F,1F,true))
577 589
                .forResult(1);
578 590
    }
579 591
@ -735,14 +747,9 @@ public class SkipUserInfoActivity extends Activity implements View.OnClickListen
735 747
        ;
736 748
    }
737 749
    private void activityResult(Intent data) {
738
        List<LocalMedia> medias = PictureSelector.obtainMultipleResult(data);
750
        List<LocalMedia> medias = PictureSelector.obtainSelectorList(data);
739 751
        if (medias != null && medias.size() > 0) {
740
            String path = "";
741
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
742
                path = medias.get(0).getAndroidQToPath();
743
            } else {
744
                path = medias.get(0).getPath();
745
            }
752
            String path = Util.getCompressAbsolutePath(medias.get(0));
746 753
            photo = imageZoom(BitmapFactory.decodeFile(path));
747 754
            if (photo != null) {
748 755
                iconPic.setImageBitmap(photo);

+ 7 - 7
app/src/main/java/com/electric/chargingpile/activity/TopicDetailActivity.java

@ -263,13 +263,13 @@ public class TopicDetailActivity extends AppCompatActivity implements View.OnCli
263 263
                String code = JsonUtils.getKeyResult(response, "code");
264 264
                String desc = JsonUtils.getKeyResult(response, "desc");
265 265
                if ("1000".equals(code)) {
266
                    Intent intent = new Intent(getApplicationContext(), PublishItemsActivity.class);
267
                    PublishItemSerializable intentData = new PublishItemSerializable();
268
                    intentData.setFrom(PublishItemsActivity.FROM_TOPIC_DETAIL);
269
                    intentData.setTopicId(homePageBean.topicVo.topicId);
270
                    intentData.setName(homePageBean.topicVo.name);
271
                    intent.putExtra("intent_data", intentData);
272
                    startActivity(intent);
266
//                    Intent intent = new Intent(getApplicationContext(), PublishItemsActivity.class);
267
//                    PublishItemSerializable intentData = new PublishItemSerializable();
268
//                    intentData.setFrom(PublishItemsActivity.FROM_TOPIC_DETAIL);
269
//                    intentData.setTopicId(homePageBean.topicVo.topicId);
270
//                    intentData.setName(homePageBean.topicVo.name);
271
//                    intent.putExtra("intent_data", intentData);
272
//                    startActivity(intent);
273 273
                } else if ("8010".equals(code)) {
274 274
                    startActivity(new Intent(getApplicationContext(), LoginActivity.class));
275 275
                    ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_LONG);

+ 104 - 74
app/src/main/java/com/electric/chargingpile/activity/UserInfoActivity.java

@ -1,5 +1,8 @@
1 1
package com.electric.chargingpile.activity;
2 2
3
import static com.hjq.permissions.Permission.CAMERA;
4
import static com.hjq.permissions.Permission.READ_MEDIA_IMAGES;
5
3 6
import android.Manifest;
4 7
import android.app.Activity;
5 8
import android.content.Context;
@ -22,6 +25,7 @@ import android.os.Bundle;
22 25
import android.os.Handler;
23 26
import android.os.Looper;
24 27
import android.os.Message;
28
import android.provider.MediaStore;
25 29
import android.text.TextUtils;
26 30
import android.util.Log;
27 31
import android.view.Gravity;
@ -57,11 +61,16 @@ import com.electric.chargingpile.event.CarIntentModelEvent;
57 61
import com.electric.chargingpile.manager.ProfileManager;
58 62
import com.electric.chargingpile.util.BarColorUtil;
59 63
import com.electric.chargingpile.util.DES3;
64
import com.electric.chargingpile.util.ImageCropEngine;
65
import com.electric.chargingpile.util.ImageFileCompressEngine;
60 66
import com.electric.chargingpile.util.JsonUtils;
61 67
import com.electric.chargingpile.util.LoadingDialog;
62 68
import com.electric.chargingpile.util.LogUtils;
69
import com.electric.chargingpile.util.MeOnCameraInterceptListener;
70
import com.electric.chargingpile.util.MeSandboxFileEngine;
63 71
import com.electric.chargingpile.util.OkHttpUtil;
64 72
import com.electric.chargingpile.util.PhotoUtils;
73
import com.electric.chargingpile.util.PictureUtlis;
65 74
import com.electric.chargingpile.util.StatusConstants;
66 75
import com.electric.chargingpile.util.ToastUtil;
67 76
import com.electric.chargingpile.util.UploadUtil;
@ -69,10 +78,15 @@ import com.electric.chargingpile.util.Util;
69 78
import com.electric.chargingpile.view.CustomProgressDialog;
70 79
import com.electric.chargingpile.view.RoundImageView;
71 80
import com.google.gson.Gson;
72
import com.luck.picture.lib.PictureSelector;
81
82
import com.hjq.permissions.OnPermissionCallback;
83
import com.hjq.permissions.XXPermissions;
73 84
import com.luck.picture.lib.animators.AnimationType;
85
import com.luck.picture.lib.basic.PictureSelector;
74 86
import com.luck.picture.lib.config.PictureConfig;
75 87
import com.luck.picture.lib.config.PictureMimeType;
88
import com.luck.picture.lib.config.SelectMimeType;
89
import com.luck.picture.lib.config.SelectModeConfig;
76 90
import com.luck.picture.lib.entity.LocalMedia;
77 91
import com.squareup.okhttp.Request;
78 92
import com.squareup.okhttp.Response;
@ -104,7 +118,7 @@ import pub.devrel.easypermissions.AfterPermissionGranted;
104 118
import pub.devrel.easypermissions.EasyPermissions;
105 119
106 120
107
public class UserInfoActivity extends Activity implements View.OnClickListener, EasyPermissions.PermissionCallbacks {
121
public class UserInfoActivity extends Activity implements View.OnClickListener {
108 122
    private static final String TAG = "UserInfoActivity";
109 123
    private ImageView back;
110 124
    private EditText et_nickName;
@ -322,15 +336,6 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
322 336
        spinnerCity.setOnItemSelectedListener(new CityAdapter());
323 337
    }
324 338
325
    @Override
326
    public void onPermissionsGranted(int requestCode, List<String> perms) {
327
328
    }
329
330
    @Override
331
    public void onPermissionsDenied(int requestCode, List<String> perms) {
332
333
    }
334 339
335 340
    class ProvinceAdapter implements AdapterView.OnItemSelectedListener {
336 341
@ -579,71 +584,101 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
579 584
     * @param view
580 585
     */
581 586
    public void takePhoto(View view) {
582
583 587
        PictureSelector.create(this)
584
                .openCamera(PictureMimeType.ofImage())
585
                .selectionMode(PictureConfig.SINGLE)
586
                .isSingleDirectReturn(true)
587
                .isCompress(true)//是否压缩
588
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
589
                .isGif(false)//是否显示gif
590
                .isAndroidQTransform(true)
591
                .imageEngine(GlideEngine.createGlideEngine())
592
                .isWeChatStyle(false)// 是否开启微信图片选择风格
593
                .isUseCustomCamera(false)// 是否使用自定义相机
594
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
595
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
596
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
597
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
598
                .imageSpanCount(4)// 每行显示个数
599
                .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
600
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
601
                .isEnableCrop(true)
602
                .rotateEnabled(false)//裁剪是否可旋转图片
603
                .setCircleStrokeWidth(8)//设置圆形裁剪边框粗细
604
                 .freeStyleCropEnabled(true)// 裁剪框拖动模式
605
                //.isCropDragSmoothToCenter(true)// 裁剪框拖动时图片自动跟随居中
606
                .circleDimmedLayer(true)// 是否开启圆形裁剪
607
                .isDragFrame(true)//是否可拖动裁剪框(固定)
608
                .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false
609
                .showCropGrid(false)//是否显示裁剪矩形网格 圆形裁剪时建议设为false
588
                .openGallery(SelectMimeType.ofImage())
589
                .setSelectorUIStyle(PictureUtlis.getStyle())
590
                .setImageEngine(GlideEngine.createGlideEngine())
591
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
592
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
593
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
594
                .setSelectionMode(SelectModeConfig.SINGLE)
595
                .setMaxSelectNum(1)
596
                .isEmptyResultReturn(true) //支持未选择返回
597
                .setImageSpanCount(4)
598
                .isPageStrategy(true)   // 是否开启分页模式
599
                .isDisplayCamera(true) //是否显示相机入口
600
                .isPreviewFullScreenMode(true)//预览点击全屏效果
601
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
602
                .isEmptyResultReturn(true)//支持未选择返回
603
                .isWithSelectVideoImage(false)//是否支持视频图片同选
604
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
605
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
606
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
607
                .isGif(false)// 是否显示gif文件
608
                .isWebp(true)// 是否显示webp文件
609
                .isBmp(true)//是否显示bmp文件
610
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
611
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
612
                .isFastSlidingSelect(true) //快速滑动选择
613
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
614
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
615
                .isPreviewImage(true)//是否预览图片
616
                .setCropEngine(new ImageCropEngine(1F,1F,true))
617
                .setFilterMinFileSize(1) //过滤最小文件
610 618
                .forResult(2);
611 619
    }
612 620
    private void openPhotoAlbum() {
613
        PictureSelector.create(UserInfoActivity.this)
614
                .openGallery(PictureMimeType.ofImage())
615
                .isCamera(false)//列表是否显示拍照按钮
616
                .selectionMode(PictureConfig.SINGLE)
617
                .isSingleDirectReturn(true)//PictureConfig.SINGLE模式下是否直接返回
618
                .isCompress(true)//是否压缩
619
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
620
                .isGif(false)//是否显示gif
621
                .isAndroidQTransform(true)
622
                .imageEngine(GlideEngine.createGlideEngine())
623
                .isWeChatStyle(false)// 是否开启微信图片选择风格
624
                .isUseCustomCamera(false)// 是否使用自定义相机
625
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
626
                .setPictureStyle(Util.getWhiteStyle(UserInfoActivity.this))// 动态自定义相册主题
627
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
628
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
629
                .imageSpanCount(4)// 每行显示个数
630
                .isReturnEmpty(false)// 选择数据时点击按钮是否可以返回
631
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
632
                .rotateEnabled(false)//裁剪是否可旋转图片
633
                .isEnableCrop(true)
634
                .rotateEnabled(false)//裁剪是否可旋转图片
635
                .setCircleStrokeWidth(8)//设置圆形裁剪边框粗细
636
                 .freeStyleCropEnabled(true)// 裁剪框拖动模式
637
                //.isCropDragSmoothToCenter(true)// 裁剪框拖动时图片自动跟随居中
638
                .circleDimmedLayer(true)// 是否开启圆形裁剪
639
                .isDragFrame(true)//是否可拖动裁剪框(固定)
640
                .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false
641
                .showCropGrid(false)//是否显示裁剪矩形网格 圆形裁剪时建议设为false
621
        PictureSelector.create(this)
622
                .openGallery(SelectMimeType.ofImage())
623
                .setSelectorUIStyle(PictureUtlis.getStyle())
624
                .setImageEngine(GlideEngine.createGlideEngine())
625
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
626
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
627
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
628
                .setSelectionMode(SelectModeConfig.SINGLE)
629
                .setMaxSelectNum(1)
630
                .isEmptyResultReturn(true) //支持未选择返回
631
                .setImageSpanCount(4)
632
                .isPageStrategy(true)   // 是否开启分页模式
633
                .isDisplayCamera(true) //是否显示相机入口
634
                .isPreviewFullScreenMode(true)//预览点击全屏效果
635
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
636
                .isEmptyResultReturn(true)//支持未选择返回
637
                .isWithSelectVideoImage(false)//是否支持视频图片同选
638
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
639
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
640
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
641
                .isGif(false)// 是否显示gif文件
642
                .isWebp(true)// 是否显示webp文件
643
                .isBmp(true)//是否显示bmp文件
644
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
645
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
646
                .isFastSlidingSelect(true) //快速滑动选择
647
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
648
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
649
                .isPreviewImage(true)//是否预览图片
650
                .setFilterMinFileSize(1) //过滤最小文件
651
                .setCropEngine(new ImageCropEngine(1F,1F,true))
642 652
                .forResult(1);
643 653
    }
644 654
645 655
    @AfterPermissionGranted(RC_CAMERA_PERM)
646 656
    public void cameraTask() {
657
        String[] callPhone  =
658
                new String[]{READ_MEDIA_IMAGES, CAMERA};
659
        XXPermissions.with(this)
660
                // 申请单个权限
661
                .permission(callPhone)
662
                .request(new OnPermissionCallback() {
663
                    @Override
664
                    public void onGranted(List<String> permissions, boolean all) {
665
                        if (all) {
666
                            showWindow();
667
                        }else{
668
                            ToastUtil.showToast(getApplicationContext(), "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT);
669
                        }
670
                    }
671
                    @Override
672
                    public void onDenied(List<String> permissions, boolean never) {
673
                        if (never) {
674
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
675
                            XXPermissions.startPermissionActivity(UserInfoActivity.this, permissions);
676
                        } else {
677
                            ToastUtil.showToast(getApplicationContext(), "获取权限失败", Toast.LENGTH_SHORT);
678
                        }
679
                    }
680
                });
681
647 682
        if (hasCameraPermission()) {
648 683
            showWindow();
649 684
        } else {
@ -769,14 +804,9 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
769 804
    }
770 805
771 806
    private void activityResult(Intent data) {
772
        List<LocalMedia> medias = PictureSelector.obtainMultipleResult(data);
807
        List<LocalMedia> medias = PictureSelector.obtainSelectorList(data);
773 808
        if (medias != null && medias.size() > 0) {
774
            String path = "";
775
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
776
                path = medias.get(0).getAndroidQToPath();
777
            } else {
778
                path = medias.get(0).getPath();
779
            }
809
            String path = Util.getCompressAbsolutePath(medias.get(0));
780 810
            photo = imageZoom(BitmapFactory.decodeFile(path));
781 811
            if (photo != null) {
782 812
                iconPic.setImageBitmap(photo);

+ 0 - 232
app/src/main/java/com/electric/chargingpile/activity/VideoCompressionActivity.java

@ -1,232 +0,0 @@
1
package com.electric.chargingpile.activity;
2
3
4
import android.view.View;
5
import androidx.appcompat.app.AppCompatActivity;
6
7
8
/*
9
public class VideoCompressionActivity extends AppCompatActivity implements View.OnClickListener {
10
11
    private TextView viewById;
12
    public static final int REQUEST_CODE_CHOOSE = 339;
13
    @Override
14
    protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
15
        super.onCreate(savedInstanceState);
16
        setContentView(R.layout.activity_video_compression);
17
        findViewById(R.id.openPhoto).setOnClickListener(this);
18
        findViewById(R.id.videoZip).setOnClickListener(this);
19
        findViewById(R.id.startVideoZip).setOnClickListener(this);
20
        viewById = findViewById(R.id.progress);
21
    }
22
23
    @Override
24
    public void onClick(View v) {
25
        switch (v.getId()){
26
            case R.id.openPhoto:
27
                PictureSelector.create(this)
28
                        .openGallery(PictureMimeType.ofVideo())
29
                        .selectionMode(PictureConfig.SINGLE)
30
                        .isCompress(true)//是否压缩
31
                        .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
32
                        .isGif(true)//是否显示gif
33
                        .isAndroidQTransform(true)
34
                        .imageEngine(GlideEngine.createGlideEngine())
35
                        .isWeChatStyle(false)// 是否开启微信图片选择风格
36
                        .isUseCustomCamera(false)// 是否使用自定义相机
37
                        .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
38
                        .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
39
                        .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
40
                        .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
41
                        .imageSpanCount(4)// 每行显示个数
42
                        .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
43
                        .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
44
                        .forResult(REQUEST_CODE_CHOOSE);
45
46
                break;
47
48
            case R.id.videoZip:
49
                Log.e("TAG", "开始");
50
                runFFmpegRxJava();
51
                break;
52
53
            case R.id.startVideoZip:
54
                PictureSelector.create(this)
55
                        .setPictureStyle(Util.getWhiteStyle(this))
56
                        .externalPictureVideo(mResultPath);
57
58
                break;
59
        }
60
    }
61
    private String mPath="";
62
    @Override
63
    protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
64
        super.onActivityResult(requestCode, resultCode, data);
65
        LocalMedia media = PictureSelector.obtainMultipleResult(data).get(0);
66
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
67
            mPath= media.getAndroidQToPath();
68
        }else{
69
            mPath=media.getPath();
70
        }
71
    }
72
73
    private  MyRxFFmpegSubscriber myRxFFmpegSubscriber=null;
74
    private  static String mResultPath=null;
75
    private void runFFmpegRxJava() {
76
77
        MediaMetadataRetriever retriever =new MediaMetadataRetriever();
78
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
79
            Uri newUri  = FileProvider.getUriForFile(
80
                    this,
81
                    getPackageName() + ".provider",
82
                    new File(mPath)
83
            );
84
            retriever.setDataSource(this, newUri);
85
        } else {
86
            retriever.setDataSource(mPath, new HashMap<String, String>());
87
        }
88
        retriever.setDataSource(mPath);
89
90
91
        String duration_s = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
92
        long duration = Long.parseLong(duration_s);
93
94
//获取视频帧数
95
        String count_s = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT);
96
97
        long bitrate = Long.parseLong(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
98
        long count = Long.parseLong(count_s);
99
100
//计算帧率
101
        long dt = duration/count; // 平均每帧的时间间隔,35ms
102
103
104
105
        Log.e("TAG", "runFFmpegRxJava帧率为: "+dt);
106
107
        DecimalFormat df = new DecimalFormat("#.00");
108
        String size="";
109
        if (bitrate < 1024) {
110
            size = df.format((double) bitrate) + "BT";
111
        } else if (bitrate < 1048576) {
112
            size = df.format((double) bitrate / 1024) + "KB";
113
        } else if (bitrate < 1073741824) {
114
            size = df.format((double) bitrate / 1048576) + "MB";
115
        } else {
116
            size = df.format((double) bitrate / 1073741824) +"GB";
117
        }
118
119
        Log.e("TAG", "runFFmpegRxJava比特率为: "+size);
120
121
122
123
124
        mResultPath = PhotoUtils.CACHE_DIR + System.currentTimeMillis() + getFileExtension(mPath);
125
        Log.e("TAG", "runFFmpegRxJava: "+GetFileSize(mPath));
126
        if (bitrate < 21299200){//21299200 bit 即 2600k  如果小于2600K则
127
            return;
128
        }
129
//        String text = "ffmpeg -y -i "+mPath+" -vf boxblur=25:5 -preset superfast "+mResultPath;
130
        String text = "ffmpeg -y -i "+mPath+" -b 2600k -r 25 -vcodec libx264 -preset superfast "+mResultPath;
131
132
        String[] commands = text.split(" ");
133
134
        myRxFFmpegSubscriber = new MyRxFFmpegSubscriber(this);
135
136
        //开始执行FFmpeg命令
137
        RxFFmpegInvoke.getInstance()
138
                .runCommandRxJava(commands)
139
                .subscribe(myRxFFmpegSubscriber);
140
141
    }
142
143
    public static class MyRxFFmpegSubscriber extends RxFFmpegSubscriber {
144
145
        private WeakReference<VideoCompressionActivity> mWeakReference;
146
147
        public MyRxFFmpegSubscriber(VideoCompressionActivity homeFragment) {
148
            mWeakReference = new WeakReference<>(homeFragment);
149
        }
150
151
        @Override
152
        public void onFinish() {
153
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
154
            if (mHomeFragment != null) {
155
                Log.e("TAG", "处理成功"+GetFileSize(mResultPath));
156
157
            }
158
        }
159
160
        @Override
161
        public void onProgress(int progress, long progressTime) {
162
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
163
            if (mHomeFragment != null) {
164
                //progressTime 可以在结合视频总时长去计算合适的进度值
165
                Log.e("TAG", "onProgress progress:"+progress+"  progressTime:"+progressTime);
166
            }
167
        }
168
169
        @Override
170
        public void onCancel() {
171
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
172
            if (mHomeFragment != null) {
173
                Log.e("TAG", "已取消");
174
175
            }
176
        }
177
178
        @Override
179
        public void onError(String message) {
180
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
181
            if (mHomeFragment != null) {
182
                Log.e("TAG", "出错了 onError:" + message);
183
            }
184
        }
185
    }
186
187
    @Override
188
    public void onDestroy() {
189
        super.onDestroy();
190
        if (myRxFFmpegSubscriber != null) {
191
            myRxFFmpegSubscriber.dispose();
192
        }
193
    }
194
195
    public String getFileExtension(String path) {
196
        String extension = "";
197
        File file = new File(path);
198
        try {
199
            if (file != null && file.exists()) {
200
                String name = file.getName();
201
                extension = name.substring(name.lastIndexOf("."));
202
            }
203
        } catch (Exception e) {
204
            extension = "";
205
        }
206
        return extension;
207
    }
208
209
    public static String GetFileSize(String path){
210
        String size = "";
211
        File file = new File(path);
212
        if(file.exists() && file.isFile()){
213
            long fileS = file.length();
214
            DecimalFormat df = new DecimalFormat("#.00");
215
            if (fileS < 1024) {
216
                size = df.format((double) fileS) + "BT";
217
            } else if (fileS < 1048576) {
218
                size = df.format((double) fileS / 1024) + "KB";
219
            } else if (fileS < 1073741824) {
220
                size = df.format((double) fileS / 1048576) + "MB";
221
            } else {
222
                size = df.format((double) fileS / 1073741824) +"GB";
223
            }
224
        }else if(file.exists() && file.isDirectory()){
225
            size = "";
226
        }else{
227
            size = "0BT";
228
        }
229
        return size;
230
    }
231
}
232
*/

+ 137 - 131
app/src/main/java/com/electric/chargingpile/activity/ZhanCommentActivity.java

@ -13,6 +13,7 @@ import android.os.Bundle;
13 13
14 14
import android.os.Handler;
15 15
import android.os.Message;
16
import android.provider.MediaStore;
16 17
import android.text.Editable;
17 18
import android.text.Html;
18 19
import android.text.TextUtils;
@ -31,6 +32,7 @@ import android.widget.Toast;
31 32
32 33
import androidx.annotation.NonNull;
33 34
import androidx.appcompat.app.AppCompatActivity;
35
import androidx.fragment.app.Fragment;
34 36
import androidx.recyclerview.widget.GridLayoutManager;
35 37
import androidx.recyclerview.widget.RecyclerView;
36 38
@ -52,9 +54,14 @@ import com.electric.chargingpile.util.CommonParams;
52 54
import com.electric.chargingpile.util.DES3;
53 55
import com.electric.chargingpile.util.DateUtils;
54 56
import com.electric.chargingpile.util.DensityUtil;
57
import com.electric.chargingpile.util.IjkPlayerEngine;
58
import com.electric.chargingpile.util.ImageFileCompressEngine;
55 59
import com.electric.chargingpile.util.JsonUtils;
56 60
import com.electric.chargingpile.util.LoadingDialog;
57 61
import com.electric.chargingpile.util.Md5Util;
62
import com.electric.chargingpile.util.MeOnCameraInterceptListener;
63
import com.electric.chargingpile.util.MeSandboxFileEngine;
64
import com.electric.chargingpile.util.PictureUtlis;
58 65
import com.electric.chargingpile.util.PublicWayONE;
59 66
import com.electric.chargingpile.util.Res;
60 67
import com.electric.chargingpile.util.ScreenUtils;
@ -68,13 +75,18 @@ import com.electric.chargingpile.view.RatingBarView;
68 75
69 76
import com.google.gson.Gson;
70 77
import com.google.gson.reflect.TypeToken;
71
import com.luck.picture.lib.PictureSelector;
78
import com.hjq.permissions.OnPermissionCallback;
79
import com.hjq.permissions.XXPermissions;
80
import com.luck.lib.camerax.CameraImageEngine;
81
import com.luck.lib.camerax.SimpleCameraX;
72 82
import com.luck.picture.lib.animators.AnimationType;
73 83
74 84
75
import com.luck.picture.lib.camera.CustomCameraView;
85
import com.luck.picture.lib.basic.PictureSelector;
76 86
import com.luck.picture.lib.config.PictureConfig;
77 87
import com.luck.picture.lib.config.PictureMimeType;
88
import com.luck.picture.lib.config.SelectMimeType;
89
import com.luck.picture.lib.config.SelectModeConfig;
78 90
import com.luck.picture.lib.entity.LocalMedia;
79 91
import com.upyun.library.common.SerialUploader;
80 92
import com.upyun.library.listener.UpCompleteListener;
@ -105,11 +117,16 @@ import pub.devrel.easypermissions.AfterPermissionGranted;
105 117
import pub.devrel.easypermissions.EasyPermissions;
106 118
107 119
import static android.text.Html.FROM_HTML_MODE_LEGACY;
120
import static com.hjq.permissions.Permission.CAMERA;
121
import static com.hjq.permissions.Permission.READ_MEDIA_IMAGES;
122
import static com.hjq.permissions.Permission.READ_MEDIA_VIDEO;
123
import static com.luck.lib.camerax.CustomCameraConfig.BUTTON_STATE_ONLY_RECORDER;
124
108 125
/**
109 126
 * 如果更改此页面,则需要同步更改 ChargingCommentActivity,
110 127
 * ZhanCommentActivity 该页面为从地图充电icon-> 列表 ->去评论
111 128
 * */
112
public class ZhanCommentActivity extends AppCompatActivity implements View.OnClickListener, EasyPermissions.PermissionCallbacks, GridImageAdapter.GridImgListener {
129
public class ZhanCommentActivity extends AppCompatActivity implements View.OnClickListener,  GridImageAdapter.GridImgListener {
113 130
    private static final String TAG = "ZhanCommentActivity";
114 131
    private static final int PIC_NUM = 3;
115 132
    private ProgressDialog insertDialog;
@ -462,12 +479,8 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
462 479
        for (int i = 0; i < Bimp.tempSelectMedia.size(); i++) {
463 480
464 481
            LocalMedia media = Bimp.tempSelectMedia.get(i);
465
            String path = "";
466
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q)
467
                path = media.getAndroidQToPath();
468
            else {
469
                path = media.getPath();
470
            }
482
            String path = Util.getCompressAbsolutePath(media);
483
471 484
            bm = imageZoom(BitmapFactory.decodeFile(path));
472 485
            String file = bitmapToBase64(bm);
473 486
            Map<String, String> par = new HashMap<String, String>();
@ -518,7 +531,7 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
518 531
                    setLayoutHintVisible(1);
519 532
                    //异步方式插入图片
520 533
//                    insertImagesSync(data);
521
                    Bimp.tempSelectMedia = PictureSelector.obtainMultipleResult(data);
534
                    Bimp.tempSelectMedia = PictureSelector.obtainSelectorList(data);
522 535
                    mAdapter.setMaxCount(3);
523 536
                    mInsterType = 1;
524 537
@ -530,7 +543,7 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
530 543
                    setLayoutHintVisible(2);
531 544
                    mInsterType = 2;
532 545
                    mAdapter.setMaxCount(1);
533
                    Bimp.tempSelectMedia = PictureSelector.obtainMultipleResult(data);
546
                    Bimp.tempSelectMedia = PictureSelector.obtainSelectorList(data);
534 547
                    mAdapter.setDatas(Bimp.tempSelectMedia);
535 548
                }
536 549
            }
@ -591,19 +604,16 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
591 604
                return tv;
592 605
            }
593 606
        });
594
        mFlowLayout.setOnTagClickListener(new TagFlowLayout.OnTagClickListener() {
595
            @Override
596
            public boolean onTagClick(View view, int position, FlowLayout parent) {
597
                if (select_s.contains(stringArr[position])) {
598
                    String s = stringArr[position] + ",";
599
                    select_s = select_s.replaceAll(s, "");
600
                } else {
601
                    select_s += stringArr[position] + ",";
602
                }
603
                Log.e("select===", select_s);
604
605
                return true;
607
        mFlowLayout.setOnTagClickListener((view, position, parent) -> {
608
            if (select_s.contains(stringArr[position])) {
609
                String s = stringArr[position] + ",";
610
                select_s = select_s.replaceAll(s, "");
611
            } else {
612
                select_s += stringArr[position] + ",";
606 613
            }
614
            Log.e("select===", select_s);
615
616
            return true;
607 617
        });
608 618
    }
609 619
@ -769,14 +779,7 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
769 779
                        } else if (Bimp.tempSelectMedia.size() > 0 && mInsterType == 2) {
770 780
                            //进行视频验证
771 781
                            LocalMedia media = Bimp.tempSelectMedia.get(0);
772
                            String path = "";
773
                            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q)
774
                                path = media.getAndroidQToPath();
775
                            else {
776
                                path = media.getPath();
777
                            }
778
779
782
                            String path = Util.getCompressAbsolutePath(media);
780 783
                            getYouPaiData(path);
781 784
                        } else {
782 785
                            if (containsEmoji(et_pinglun.getText().toString())) {
@ -915,118 +918,112 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
915 918
        String saveKey = jsonObject.optString("save-key");
916 919
917 920
        serialUploader.upload(
918
                temp, uri, date, "UPYUN " + operator + ":" + sign, null, new UpCompleteListener() {
919
                    @Override
920
                    public void onComplete(boolean isSuccess, String result) {
921
                        if (isSuccess) {
922
                            try {
923
                                ArrayList<String> list = new ArrayList<>();
924
                                list.add(saveKey);
925
                                addComment(list, saveKey);
926
                            } catch (Exception e) {
927
                                e.printStackTrace();
928
                            }
929
                        } else {
930
                            ToastUtil.showToast(getApplicationContext(), "发布失败,请重试", Toast.LENGTH_SHORT);
931
                            dialog.dismiss();
921
                temp, uri, date, "UPYUN " + operator + ":" + sign, null, (isSuccess, result) -> {
922
                    if (isSuccess) {
923
                        try {
924
                            ArrayList<String> list = new ArrayList<>();
925
                            list.add(saveKey);
926
                            addComment(list, saveKey);
927
                        } catch (Exception e) {
928
                            e.printStackTrace();
932 929
                        }
933
930
                    } else {
931
                        ToastUtil.showToast(getApplicationContext(), "发布失败,请重试", Toast.LENGTH_SHORT);
932
                        dialog.dismiss();
934 933
                    }
934
935 935
                });
936 936
    }
937 937
938 938
    private void addImg() {
939 939
        PictureSelector.create(this)
940
                .openGallery(PictureMimeType.ofImage())
941
                .maxSelectNum(PIC_NUM)
942
                .selectionMode(PictureConfig.MULTIPLE)
943
                .selectionData(Bimp.tempSelectMedia)//是否传入已选图片
944
                .isCompress(true)//是否压缩
945
                .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
946
                .isGif(true)//是否显示gif
947
                .isAndroidQTransform(true)
948
                .imageEngine(GlideEngine.createGlideEngine())
949
                .isWeChatStyle(false)// 是否开启微信图片选择风格
950
                .isUseCustomCamera(false)// 是否使用自定义相机
951
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
952
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
953
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
954
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
955
                .imageSpanCount(4)// 每行显示个数
956
                .isReturnEmpty(false)// 选择数据时点击按钮是否可以返回
957
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
940
                .openGallery(SelectMimeType.ofImage())
941
                .setSelectorUIStyle(PictureUtlis.getStyle())
942
                .setImageEngine(GlideEngine.createGlideEngine())
943
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
944
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
945
                .setCameraInterceptListener(new MeOnCameraInterceptListener())
946
                .setSelectionMode(SelectModeConfig.MULTIPLE)
947
                .setMaxSelectNum(PIC_NUM)
948
                .isEmptyResultReturn(true) //支持未选择返回
949
                .setImageSpanCount(4)
950
                .isPageStrategy(true)   // 是否开启分页模式
951
                .isDisplayCamera(true) //是否显示相机入口
952
                .isPreviewFullScreenMode(true)//预览点击全屏效果
953
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
954
                .isEmptyResultReturn(true)//支持未选择返回
955
                .isWithSelectVideoImage(false)//是否支持视频图片同选
956
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
957
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
958
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
959
                .isGif(true)// 是否显示gif文件
960
                .isWebp(true)// 是否显示webp文件
961
                .isBmp(true)//是否显示bmp文件
962
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
963
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
964
                .isFastSlidingSelect(true) //快速滑动选择
965
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
966
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
967
                .isPreviewImage(true)//是否预览图片
968
                .setFilterMinFileSize(1) //过滤最小文件
958 969
                .forResult(REQUEST_CODE_CHOOSE);
959 970
    }
960 971
961 972
    private void addVideo() {
962 973
        PictureSelector.create(this)
963
                .openGallery(PictureMimeType.ofVideo())
964
               // .selectionMode(PictureConfig.SINGLE)
965
                .isCompress(true)//是否压缩
966
                .maxSelectNum(1)
967
                .isPreviewEggs(true)//图片时是否增强左右滑动图片体验
968
                .isAndroidQTransform(true)
969
                .imageEngine(GlideEngine.createGlideEngine())
970
                .isWeChatStyle(false)// 是否开启微信图片选择风格
971
                .isUseCustomCamera(false)// 是否使用自定义相机
972
                .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
973
                .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
974
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
975
                .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
976
                .imageSpanCount(4)// 每行显示个数
977
                .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
978
                .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
979
                .videoMaxSecond(16)   // 查询多少秒以内的视频
980
                .videoMinSecond(2)   // 查询多少秒以内的视频
981
                .recordVideoSecond(16)//录制视频秒数 默认60s
982
                .isPreviewVideo(true)//是否预览视频
983
                .setButtonFeatures(CustomCameraView.BUTTON_STATE_ONLY_RECORDER) //自定义按钮样式
984
                .isUseCustomCamera(true)// 开启自定义相机
985
               // .isSingleDirectReturn(true)//PictureConfig.SINGLE模式下是否直接返回
986
                .filterMaxFileSize( 100 * 1024 )//查询指定大小内的图片、视频、音频大小,单位 KB
974
                .openGallery(SelectMimeType.ofVideo())
975
                .setSelectorUIStyle(PictureUtlis.getStyle())
976
                .setImageEngine(GlideEngine.createGlideEngine())
977
                .setCompressEngine(new ImageFileCompressEngine()) //设置压缩
978
                .setSandboxFileEngine(new MeSandboxFileEngine()) //设置相册沙盒目录拷贝引擎
979
                .setSelectionMode(SelectModeConfig.SINGLE) //设置单选
980
                .isEmptyResultReturn(true) //支持未选择返回
981
                .setImageSpanCount(3)
982
                .isPageStrategy(true)   // 是否开启分页模式
983
                .isDisplayCamera(true) //是否显示相机入口
984
                .isPreviewFullScreenMode(true)//预览点击全屏效果
985
                .isEmptyResultReturn(true)//支持未选择返回
986
                .isWithSelectVideoImage(false)//是否支持视频图片同选
987
                .isSelectZoomAnim(true)// 选择缩略图缩放效果
988
                .isCameraAroundState(false)// 是否开启前置摄像头;系统相机 只支持部分机型
989
                .isCameraRotateImage(true) //拍照是否纠正旋转图片
990
                .isGif(true)// 是否显示gif文件
991
                .isWebp(true)// 是否显示webp文件
992
                .isBmp(true)//是否显示bmp文件
993
                .isMaxSelectEnabledMask(true)// 达到最大选择数是否开启禁选蒙层
994
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
995
                .isFastSlidingSelect(true) //快速滑动选择
996
                .isDirectReturnSingle(true)//PictureConfig.SINGLE模式下是否直接返回
997
                .setQuerySortOrder(MediaStore.MediaColumns.DATE_MODIFIED + " DESC")//由远-近 MediaStore.MediaColumns.DATE_MODIFIED + " ASC"
998
                .isPreviewImage(true)//是否预览图片
999
                .setMaxSelectNum(1)//最大选择数量,默认9张
1000
                .setMinSelectNum(1)// 最小选择数量
1001
                .setRecordVideoMaxSecond(16) //视频录制最大时长
1002
                .setRecordVideoMinSecond(2) //视频录制最小时长
1003
                .setFilterVideoMaxSecond(16) //过滤视频最大时长
1004
                .setFilterVideoMinSecond(2) //过滤视频最小时长
1005
                .setFilterMinFileSize(1) //过滤最小文件
1006
                .setVideoQuality(1)
1007
                .setCameraInterceptListener(new MeOnCameraInterceptListener(){
1008
                    @Override
1009
                    public void openCamera(Fragment fragment, int cameraMode, int requestCode) {
1010
                        SimpleCameraX camera = SimpleCameraX.of();
1011
                        camera.isAutoRotation(true);
1012
                        camera.setCameraMode(BUTTON_STATE_ONLY_RECORDER);
1013
                        camera.setVideoFrameRate(25);
1014
                        camera.setVideoBitRate(3 * 1024 * 1024);
1015
                        camera.isDisplayRecordChangeTime(true);
1016
                        camera.isManualFocusCameraPreview(true);
1017
                        camera.isZoomCameraPreview(true);
1018
                        camera.setImageEngine((context, url, imageView) -> Glide.with(context).load(url).into(imageView));
1019
                        camera.start(fragment.requireActivity(), fragment, requestCode);
1020
                    }
1021
                })
1022
                .isVideoPauseResumePlay(true) //视频支持暂停与播放
987 1023
                .forResult(REQUEST_VIDEO_CODE_CHOOSE);
988 1024
    }
989 1025
990 1026
    @Override
991
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
992
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
993
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
994
    }
995
996
    @Override
997
    public void onPermissionsGranted(int requestCode, List<String> perms) {
998
999
    }
1000
1001
    @Override
1002
    public void onPermissionsDenied(int requestCode, List<String> perms) {
1003
1004
    }
1005
1006
    @AfterPermissionGranted(RC_ALBUM_PERM)
1007
    public void permissionTask() {
1008
        if (isPermissionOK()) {
1009
            addImg();
1010
        } else {
1011
            // Ask for one permission
1012
            EasyPermissions.requestPermissions(
1013
                    this, "充电桩想要获取您的图片读取权限,是否允许?",
1014
                    RC_ALBUM_PERM,
1015
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
1016
                    Manifest.permission.READ_EXTERNAL_STORAGE,
1017
                    Manifest.permission.CAMERA);
1018
        }
1019
    }
1020
1021
    private boolean isPermissionOK() {
1022
        return EasyPermissions.hasPermissions(this,
1023
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
1024
                Manifest.permission.READ_EXTERNAL_STORAGE,
1025
                Manifest.permission.CAMERA
1026
        );
1027
    }
1028
1029
    @Override
1030 1027
    public void add() {
1031 1028
        if (mInsterType == 1) {
1032 1029
            addImg();
@ -1049,10 +1046,19 @@ public class ZhanCommentActivity extends AppCompatActivity implements View.OnCli
1049 1046
        if (mInsterType == 1) {
1050 1047
            ImageDisplayActivity.actionStart(this, position);
1051 1048
        } else if (mInsterType == 2) {
1052
            PictureSelector.create(ZhanCommentActivity.this)
1053
                    .themeStyle(com.luck.picture.lib.R.style.picture_default_style)
1054
                    .setPictureStyle(Util.getWhiteStyle(ZhanCommentActivity.this))// 动态自定义相册主题
1055
                    .externalPictureVideo(TextUtils.isEmpty(mLocalMedia.getAndroidQToPath()) ? mLocalMedia.getPath() : mLocalMedia.getAndroidQToPath());
1049
1050
            ArrayList<LocalMedia> list = new ArrayList<>();
1051
            list.add(mLocalMedia);
1052
            PictureSelector.create(this)
1053
                    .openPreview()
1054
                    .setImageEngine(GlideEngine.createGlideEngine())
1055
                    .setVideoPlayerEngine(new IjkPlayerEngine())
1056
                    .setSelectorUIStyle(PictureUtlis.getStyle())
1057
                    .isPreviewFullScreenMode(false)
1058
                    .isVideoPauseResumePlay(true)
1059
                    .isAutoVideoPlay(true)
1060
                    .isLoopAutoVideoPlay(true)
1061
                    .startActivityPreview(0,false, list);
1056 1062
        }
1057 1063
    }
1058 1064

+ 3 - 7
app/src/main/java/com/electric/chargingpile/adapter/GridImageAdapter.java

@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView;
12 12
13 13
import com.bumptech.glide.Glide;
14 14
import com.electric.chargingpile.R;
15
import com.electric.chargingpile.util.Util;
15 16
import com.luck.picture.lib.entity.LocalMedia;
16 17
import com.luck.picture.lib.entity.MediaData;
17 18
@ -90,14 +91,9 @@ public class GridImageAdapter extends RecyclerView.Adapter<GridImageAdapter.View
90 91
//            holder.imageView.setImageResource(R.drawable.addpic65);
91 92
            holder.remove.setVisibility( View.GONE);
92 93
        } else {
93
94
            String path="";
95 94
            LocalMedia data = mDatas.get(position);
96
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q)
97
                path= data.getAndroidQToPath();
98
            else {
99
                path= data.getPath();
100
            }
95
96
            String path = Util.getCompressAbsolutePath(data);
101 97
102 98
103 99
            Glide.with(context)

+ 6 - 6
app/src/main/java/com/electric/chargingpile/application/MainApplication.java

@ -103,13 +103,13 @@ public class MainApplication extends MultiDexApplication implements CameraXConfi
103 103
    public static String firstPoint = "";
104 104
    public static Boolean firstSsyd;
105 105
    public static String password = "";
106
//    public static String url = "http://59.110.68.162";// 充电桩测试环境
107
//    public static String pic_url = "http://59.110.68.162/zhannew/uploadfile/";
108
    public static String url = "http://cdz.evcharge.cc";// 充电桩正式环境
109
    public static String pic_url = "http://cdz.evcharge.cc/zhannew/uploadfile/";
106
    public static String url = "http://59.110.68.162";// 充电桩测试环境
107
    public static String pic_url = "http://59.110.68.162/zhannew/uploadfile/";
108
//    public static String url = "http://cdz.evcharge.cc";// 充电桩正式环境
109
//    public static String pic_url = "http://cdz.evcharge.cc/zhannew/uploadfile/";
110 110

111
//        public static String urlNew = "http://123.56.67.7:83/api/0300";// 一电测试环境
112
    public static String urlNew = "https://api.touchev.com:83/api/0300";// 一电正式环境
111
        public static String urlNew = "http://123.56.67.7:83/api/0300";// 一电测试环境
112
//    public static String urlNew = "https://api.touchev.com:83/api/0300";// 一电正式环境
113 113

114 114
    public static String d1evUrl = "https://d1ev-new.yiduyongche.com";// 评论上传视频
115 115
    public static String CDN = "https://cdn-fs.d1ev.com";

+ 49 - 169
app/src/main/java/com/electric/chargingpile/engine/GlideEngine.java

@ -1,197 +1,68 @@
1 1
package com.electric.chargingpile.engine;
2 2
3 3
import android.content.Context;
4
import android.graphics.Bitmap;
5
import android.graphics.PointF;
6
import android.graphics.drawable.Drawable;
7
import android.view.View;
8 4
import android.widget.ImageView;
9 5
10
import androidx.annotation.NonNull;
11
import androidx.annotation.Nullable;
12
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
13
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
14
15 6
import com.bumptech.glide.Glide;
16
import com.bumptech.glide.request.RequestOptions;
17
import com.bumptech.glide.request.target.BitmapImageViewTarget;
18
import com.bumptech.glide.request.target.ImageViewTarget;
7
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
8
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
19 9
import com.electric.chargingpile.R;
20 10
import com.luck.picture.lib.engine.ImageEngine;
21
import com.luck.picture.lib.listener.OnImageCompleteCallback;
22
import com.luck.picture.lib.tools.MediaUtils;
23
import com.luck.picture.lib.widget.longimage.ImageSource;
24
import com.luck.picture.lib.widget.longimage.ImageViewState;
25
import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView;
11
import com.luck.picture.lib.utils.ActivityCompatHelper;
26 12
27
/**
28
 * @author:luck
29
 * @date:2019-11-13 17:02
30
 * @describe:Glide加载引擎
31
 */
32 13
public class GlideEngine implements ImageEngine {
33 14
15
    public static GlideEngine createGlideEngine() {
16
        return InstanceHolder.instance;
17
    }
18
34 19
    /**
35 20
     * 加载图片
36 21
     *
37
     * @param context
38
     * @param url
39
     * @param imageView
22
     * @param context   上下文
23
     * @param url       资源url
24
     * @param imageView 图片承载控件
40 25
     */
41 26
    @Override
42
    public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
27
    public void loadImage(Context context, String url, ImageView imageView) {
28
        if (!ActivityCompatHelper.assertValidRequest(context)) {
29
            return;
30
        }
43 31
        Glide.with(context)
44 32
                .load(url)
45 33
                .into(imageView);
46 34
    }
47 35
48
    /**
49
     * 加载网络图片适配长图方案
50
     * # 注意:此方法只有加载网络图片才会回调
51
     *
52
     * @param context
53
     * @param url
54
     * @param imageView
55
     * @param longImageView
56
     * @param callback      网络图片加载回调监听 {link after version 2.5.1 Please use the #OnImageCompleteCallback#}
57
     */
58 36
    @Override
59
    public void loadImage(@NonNull Context context, @NonNull String url,
60
                          @NonNull ImageView imageView,
61
                          SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) {
62
        Glide.with(context)
63
                .asBitmap()
64
                .load(url)
65
                .into(new ImageViewTarget<Bitmap>(imageView) {
66
                    @Override
67
                    public void onLoadStarted(@Nullable Drawable placeholder) {
68
                        super.onLoadStarted(placeholder);
69
                        if (callback != null) {
70
                            callback.onShowLoading();
71
                        }
72
                    }
73
74
                    @Override
75
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
76
                        super.onLoadFailed(errorDrawable);
77
                        if (callback != null) {
78
                            callback.onHideLoading();
79
                        }
80
                    }
81
82
                    @Override
83
                    protected void setResource(@Nullable Bitmap resource) {
84
                        if (callback != null) {
85
                            callback.onHideLoading();
86
                        }
87
                        if (resource != null) {
88
                            boolean eqLongImage = MediaUtils.isLongImg(resource.getWidth(),
89
                                    resource.getHeight());
90
                            longImageView.setVisibility(eqLongImage ? View.VISIBLE : View.GONE);
91
                            imageView.setVisibility(eqLongImage ? View.GONE : View.VISIBLE);
92
                            if (eqLongImage) {
93
                                // 加载长图
94
                                longImageView.setQuickScaleEnabled(true);
95
                                longImageView.setZoomEnabled(true);
96
                                longImageView.setPanEnabled(true);
97
                                longImageView.setDoubleTapZoomDuration(100);
98
                                longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP);
99
                                longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER);
100
                                longImageView.setImage(ImageSource.bitmap(resource),
101
                                        new ImageViewState(0, new PointF(0, 0), 0));
102
                            } else {
103
                                // 普通图片
104
                                imageView.setImageBitmap(resource);
105
                            }
106
                        }
107
                    }
108
                });
109
    }
110
111
    /**
112
     * 加载网络图片适配长图方案
113
     * # 注意:此方法只有加载网络图片才会回调
114
     *
115
     * @param context
116
     * @param url
117
     * @param imageView
118
     * @param longImageView
119
     * @ 已废弃
120
     */
121
    public void loadImage(@NonNull Context context, @NonNull String url,
122
                          @NonNull ImageView imageView,
123
                          SubsamplingScaleImageView longImageView) {
37
    public void loadImage(Context context, ImageView imageView, String url, int maxWidth, int maxHeight) {
38
        if (!ActivityCompatHelper.assertValidRequest(context)) {
39
            return;
40
        }
124 41
        Glide.with(context)
125
                .asBitmap()
126 42
                .load(url)
127
                .into(new ImageViewTarget<Bitmap>(imageView) {
128
                    @Override
129
                    protected void setResource(@Nullable Bitmap resource) {
130
                        if (resource != null) {
131
                            boolean eqLongImage = MediaUtils.isLongImg(resource.getWidth(),
132
                                    resource.getHeight());
133
                            longImageView.setVisibility(eqLongImage ? View.VISIBLE : View.GONE);
134
                            imageView.setVisibility(eqLongImage ? View.GONE : View.VISIBLE);
135
                            if (eqLongImage) {
136
                                // 加载长图
137
                                longImageView.setQuickScaleEnabled(true);
138
                                longImageView.setZoomEnabled(true);
139
                                longImageView.setPanEnabled(true);
140
                                longImageView.setDoubleTapZoomDuration(100);
141
                                longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP);
142
                                longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER);
143
                                longImageView.setImage(ImageSource.bitmap(resource),
144
                                        new ImageViewState(0, new PointF(0, 0), 0));
145
                            } else {
146
                                // 普通图片
147
                                imageView.setImageBitmap(resource);
148
                            }
149
                        }
150
                    }
151
                });
43
                .override(maxWidth, maxHeight)
44
                .into(imageView);
152 45
    }
153 46
154 47
    /**
155
     * 加载相册目录
48
     * 加载相册目录封面
156 49
     *
157 50
     * @param context   上下文
158 51
     * @param url       图片路径
159 52
     * @param imageView 承载图片ImageView
160 53
     */
161 54
    @Override
162
    public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
55
    public void loadAlbumCover(Context context, String url, ImageView imageView) {
56
        if (!ActivityCompatHelper.assertValidRequest(context)) {
57
            return;
58
        }
163 59
        Glide.with(context)
164 60
                .asBitmap()
165 61
                .load(url)
166 62
                .override(180, 180)
167
                .centerCrop()
168 63
                .sizeMultiplier(0.5f)
169
                .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder))
170
                .into(new BitmapImageViewTarget(imageView) {
171
                    @Override
172
                    protected void setResource(Bitmap resource) {
173
                        RoundedBitmapDrawable circularBitmapDrawable =
174
                                RoundedBitmapDrawableFactory.
175
                                        create(context.getResources(), resource);
176
                        circularBitmapDrawable.setCornerRadius(8);
177
                        imageView.setImageDrawable(circularBitmapDrawable);
178
                    }
179
                });
180
    }
181
182
183
    /**
184
     * 加载gif
185
     *
186
     * @param context   上下文
187
     * @param url       图片路径
188
     * @param imageView 承载图片ImageView
189
     */
190
    public void loadAsGifImage(@NonNull Context context, @NonNull String url,
191
                               @NonNull ImageView imageView) {
192
        Glide.with(context)
193
                .asGif()
194
                .load(url)
64
                .transform(new CenterCrop(), new RoundedCorners(8))
65
                .placeholder(R.drawable.ps_image_placeholder)
195 66
                .into(imageView);
196 67
    }
197 68
@ -203,29 +74,38 @@ public class GlideEngine implements ImageEngine {
203 74
     * @param imageView 承载图片ImageView
204 75
     */
205 76
    @Override
206
    public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
77
    public void loadGridImage(Context context, String url, ImageView imageView) {
78
        if (!ActivityCompatHelper.assertValidRequest(context)) {
79
            return;
80
        }
207 81
        Glide.with(context)
208 82
                .load(url)
209 83
                .override(200, 200)
210 84
                .centerCrop()
211
                .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder))
85
                .placeholder(R.drawable.ps_image_placeholder)
212 86
                .into(imageView);
213 87
    }
214 88
89
    @Override
90
    public void pauseRequests(Context context) {
91
        if (!ActivityCompatHelper.assertValidRequest(context)) {
92
            return;
93
        }
94
        Glide.with(context).pauseRequests();
95
    }
215 96
216 97
    private GlideEngine() {
217 98
    }
218 99
219
    private static GlideEngine instance;
220
221
    public static GlideEngine createGlideEngine() {
222
        if (null == instance) {
223
            synchronized (GlideEngine.class) {
224
                if (null == instance) {
225
                    instance = new GlideEngine();
226
                }
227
            }
100
    @Override
101
    public void resumeRequests(Context context) {
102
        if (!ActivityCompatHelper.assertValidRequest(context)) {
103
            return;
228 104
        }
229
        return instance;
105
        Glide.with(context).resumeRequests();
106
    }
107
108
    private static final class InstanceHolder {
109
        static final GlideEngine instance = new GlideEngine();
230 110
    }
231
}
111
}

+ 7 - 8
app/src/main/java/com/electric/chargingpile/fragment/ChatRecommendFragment.java

@ -19,7 +19,6 @@ import com.andview.refreshview.XRefreshView;
19 19
import com.electric.chargingpile.R;
20 20
import com.electric.chargingpile.activity.ChatContentListActivity;
21 21
import com.electric.chargingpile.activity.LoginActivity;
22
import com.electric.chargingpile.activity.PublishItemsActivity;
23 22
import com.electric.chargingpile.adapter.ChatRecommendAdapter;
24 23
import com.electric.chargingpile.adapter.TopicDetailAdapter;
25 24
import com.electric.chargingpile.application.MainApplication;
@ -42,7 +41,7 @@ import java.util.HashMap;
42 41
import java.util.Map;
43 42
44 43
import okhttp3.Call;
45
44
@Deprecated
46 45
public class ChatRecommendFragment extends Fragment implements View.OnClickListener {
47 46
    private static final String TAG = "ChatRecommendFragment";
48 47
    private View view;
@ -228,12 +227,12 @@ public class ChatRecommendFragment extends Fragment implements View.OnClickListe
228 227
                String code = JsonUtils.getKeyResult(response, "code");
229 228
                String desc = JsonUtils.getKeyResult(response, "desc");
230 229
                if ("1000".equals(code)) {
231
                    MobclickAgent.onEvent(getContext(), "1004");
232
                    Intent intent = new Intent(getActivity(), PublishItemsActivity.class);
233
                    PublishItemSerializable intentData = new PublishItemSerializable();
234
                    intentData.setFrom(PublishItemsActivity.FROM_CHAT_HOME);
235
                    intent.putExtra("intent_data", intentData);
236
                    startActivity(intent);
230
//                    MobclickAgent.onEvent(getContext(), "1004");
231
//                    Intent intent = new Intent(getActivity(), PublishItemsActivity.class);
232
//                    PublishItemSerializable intentData = new PublishItemSerializable();
233
//                    intentData.setFrom(PublishItemsActivity.FROM_CHAT_HOME);
234
//                    intent.putExtra("intent_data", intentData);
235
//                    startActivity(intent);
237 236
                } else if ("8010".equals(code)) {
238 237
                    startActivity(new Intent(getContext(), LoginActivity.class));
239 238
                    ToastUtil.showToast(getContext(), desc, Toast.LENGTH_LONG);

+ 2 - 3
app/src/main/java/com/electric/chargingpile/fragment/TalkRecommendFragment.java

@ -19,7 +19,6 @@ import com.andview.refreshview.XRefreshView;
19 19
import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
20 20
import com.electric.chargingpile.R;
21 21
import com.electric.chargingpile.activity.PersonalPageActivity;
22
import com.electric.chargingpile.activity.PublishItemsActivity;
23 22
import com.electric.chargingpile.activity.TopicDetailActivity;
24 23
import com.electric.chargingpile.activity.VideoDetaislActivity;
25 24
import com.electric.chargingpile.adapter.LayoutAdapter;
@ -47,7 +46,7 @@ import io.reactivex.functions.Consumer;
47 46
import io.reactivex.functions.Predicate;
48 47
import io.reactivex.schedulers.Schedulers;
49 48
import okhttp3.Call;
50
49
@Deprecated
51 50
public class TalkRecommendFragment extends Fragment implements View.OnClickListener {
52 51
    RecyclerView recyclerView;
53 52
    LayoutAdapter layoutAdapter;
@ -249,7 +248,7 @@ public class TalkRecommendFragment extends Fragment implements View.OnClickListe
249 248
    public void onClick(View v) {
250 249
        switch (v.getId()) {
251 250
            case R.id.iv_ask:
252
                startActivity(new Intent(getActivity(), PublishItemsActivity.class));
251
//                startActivity(new Intent(getActivity(), PublishItemsActivity.class));
253 252
//                Toast.makeText(getActivity(), "分享", Toast.LENGTH_SHORT).show();
254 253
                break;
255 254
        }

+ 114 - 0
app/src/main/java/com/electric/chargingpile/util/IjkPlayerEngine.java

@ -0,0 +1,114 @@
1
package com.electric.chargingpile.util;
2
3
import android.content.Context;
4
import android.view.View;
5
6
import com.electric.chargingpile.view.IjkPlayerView;
7
8
import com.luck.picture.lib.config.SelectorConfig;
9
import com.luck.picture.lib.config.SelectorProviders;
10
import com.luck.picture.lib.engine.VideoPlayerEngine;
11
import com.luck.picture.lib.entity.LocalMedia;
12
import com.luck.picture.lib.interfaces.OnPlayerListener;
13
14
import java.util.concurrent.CopyOnWriteArrayList;
15
16
17
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
18
19
public class IjkPlayerEngine implements VideoPlayerEngine<IjkPlayerView> {
20
    /**
21
     * 播放状态监听器集
22
     */
23
    private final CopyOnWriteArrayList<OnPlayerListener> listeners = new CopyOnWriteArrayList<>();
24
25
26
    @Override
27
    public View onCreateVideoPlayer(Context context) {
28
        return new IjkPlayerView(context);
29
    }
30
31
    @Override
32
    public void onStarPlayer(IjkPlayerView player, LocalMedia media) {
33
        IjkMediaPlayer mediaPlayer = player.getMediaPlayer();
34
        SelectorConfig config = SelectorProviders.getInstance().getSelectorConfig();
35
        mediaPlayer.setLooping(config.isLoopAutoPlay);
36
        player.start(media.getAvailablePath());
37
    }
38
39
    @Override
40
    public void onResume(IjkPlayerView player) {
41
        IjkMediaPlayer mediaPlayer = player.getMediaPlayer();
42
        if (mediaPlayer != null) {
43
            mediaPlayer.start();
44
        }
45
    }
46
47
    @Override
48
    public void onPause(IjkPlayerView player) {
49
        IjkMediaPlayer mediaPlayer = player.getMediaPlayer();
50
        if (mediaPlayer != null) {
51
            mediaPlayer.pause();
52
        }
53
    }
54
55
    @Override
56
    public boolean isPlaying(IjkPlayerView player) {
57
        IjkMediaPlayer mediaPlayer = player.getMediaPlayer();
58
        return mediaPlayer != null && mediaPlayer.isPlaying();
59
    }
60
61
    @Override
62
    public void addPlayListener(OnPlayerListener playerListener) {
63
        if (!listeners.contains(playerListener)) {
64
            listeners.add(playerListener);
65
        }
66
    }
67
68
    @Override
69
    public void removePlayListener(OnPlayerListener playerListener) {
70
        if (playerListener != null) {
71
            listeners.remove(playerListener);
72
        } else {
73
            listeners.clear();
74
        }
75
    }
76
77
    @Override
78
    public void onPlayerAttachedToWindow(IjkPlayerView player) {
79
        IjkMediaPlayer mediaPlayer = player.initMediaPlayer();
80
        mediaPlayer.setOnPreparedListener(it -> {
81
            it.start();
82
            for (int i = 0; i < listeners.size(); i++) {
83
                OnPlayerListener playerListener = listeners.get(i);
84
                playerListener.onPlayerReady();
85
            }
86
        });
87
        mediaPlayer.setOnCompletionListener(it -> {
88
            it.reset();
89
            for (int i = 0; i < listeners.size(); i++) {
90
                OnPlayerListener playerListener = listeners.get(i);
91
                playerListener.onPlayerEnd();
92
            }
93
            player.clearCanvas();
94
        });
95
96
        mediaPlayer.setOnErrorListener((it, what, extra) -> {
97
            for (int i = 0; i < listeners.size(); i++) {
98
                OnPlayerListener playerListener = listeners.get(i);
99
                playerListener.onPlayerError();
100
            }
101
            return false;
102
        });
103
    }
104
105
    @Override
106
    public void onPlayerDetachedFromWindow(IjkPlayerView player) {
107
        player.release();
108
    }
109
110
    @Override
111
    public void destroy(IjkPlayerView player) {
112
        player.release();
113
    }
114
}

+ 111 - 0
app/src/main/java/com/electric/chargingpile/util/ImageCropEngine.java

@ -0,0 +1,111 @@
1
package com.electric.chargingpile.util;
2
3
import static com.electric.chargingpile.util.PhotoUtils.CACHE_DIR;
4
5
import android.content.Context;
6
import android.graphics.Bitmap;
7
import android.net.Uri;
8
import android.widget.ImageView;
9
10
import androidx.fragment.app.Fragment;
11
12
import com.bumptech.glide.Glide;
13
import com.luck.picture.lib.config.PictureMimeType;
14
import com.luck.picture.lib.engine.CropEngine;
15
import com.luck.picture.lib.entity.LocalMedia;
16
import com.yalantis.ucrop.UCrop;
17
import com.yalantis.ucrop.UCropImageEngine;
18
import com.luck.picture.lib.utils.DateUtils;
19
import java.io.File;
20
import java.util.ArrayList;
21
22
public class ImageCropEngine implements CropEngine {
23
    //长宽比
24
    private float x = 0F;
25
    //长宽比
26
    private float y = 0F;
27
    //是否为圆
28
    private boolean isCirCle = false;
29
30
    public ImageCropEngine(float x, float y, boolean isCirCle) {
31
        this.x = x;
32
        this.y = y;
33
        this.isCirCle = isCirCle;
34
    }
35
36
    @Override
37
    public void onStartCrop(Fragment fragment, LocalMedia currentLocalMedia, ArrayList<LocalMedia> dataSource, int requestCode) {
38
        String currentCropPath = currentLocalMedia.getAvailablePath();
39
        Uri inputUri ;
40
        if (PictureMimeType.isContent(currentCropPath) || PictureMimeType.isHasHttp(currentCropPath)) {
41
            inputUri= Uri.parse(currentCropPath);
42
        } else {
43
            inputUri = Uri.fromFile(new File(currentCropPath));
44
        }
45
        String fileName = DateUtils.getCreateFileName("CROP_") + ".jpg";
46
        Uri destinationUri = Uri.fromFile(new File(PhotoUtils.CACHE_DIR, fileName));
47
        UCrop.Options options;
48
         if (isCirCle){
49
             options = buildCircleOptions();
50
        }else{
51
             options = buildRatioOptions();
52
        }
53
        ArrayList<String> dataCropSource =new ArrayList<String>();
54
55
        for (LocalMedia media : dataSource) {
56
            dataCropSource.add(media.getAvailablePath());
57
        }
58
59
        UCrop uCrop = UCrop.of(inputUri, destinationUri, dataCropSource);
60
        uCrop.withOptions(options);
61
        uCrop.setImageEngine(new UCropImageEngine(){
62
63
            @Override
64
            public void loadImage(Context context, String url, ImageView imageView) {
65
                Glide.with(context).load(url).into(imageView);
66
67
            }
68
69
            @Override
70
            public void loadImage(Context context, Uri url, int maxWidth, int maxHeight, OnCallbackListener<Bitmap> call) {
71
72
            }
73
        });
74
        uCrop.start(fragment.requireActivity(), fragment, requestCode);
75
    }
76
77
    private UCrop.Options buildRatioOptions()  {
78
        UCrop.Options options = new UCrop.Options();
79
        // 长宽比
80
        options.withAspectRatio(x, y);
81
        //是否为圆
82
        options.setCircleDimmedLayer(false);
83
84
        // 是否让用户调整范围(默认false),如果开启,可能会造成剪切的图片的长宽比不是设定的
85
        // 如果不开启,用户不能拖动选框,只能缩放图片
86
        options.setFreeStyleCropEnabled(true);
87
88
        options.isCropDragSmoothToCenter(false);
89
        options.setSkipCropMimeType(PictureMimeType.ofGIF(), PictureMimeType.ofWEBP());
90
        options.isForbidCropGifWebp(false);
91
        options.isForbidSkipMultipleCrop(true);
92
        options.setMaxScaleMultiplier(100f);
93
        return options;
94
    }
95
    private UCrop.Options buildCircleOptions() {
96
        UCrop.Options options = new UCrop.Options();
97
        // 长宽比
98
        options.withAspectRatio(x, y);
99
        //是否为圆
100
        options.setCircleDimmedLayer(true);
101
        // 是否让用户调整范围(默认false),如果开启,可能会造成剪切的图片的长宽比不是设定的
102
        // 如果不开启,用户不能拖动选框,只能缩放图片
103
        options.setFreeStyleCropEnabled(true);
104
        options.isCropDragSmoothToCenter(false);
105
        options.setSkipCropMimeType(PictureMimeType.ofGIF(), PictureMimeType.ofWEBP());
106
        options.isForbidCropGifWebp(false);
107
        options.isForbidSkipMultipleCrop(true);
108
        options.setMaxScaleMultiplier(100f);
109
        return options;
110
    }
111
}

+ 56 - 0
app/src/main/java/com/electric/chargingpile/util/ImageFileCompressEngine.java

@ -0,0 +1,56 @@
1
package com.electric.chargingpile.util;
2
3
import android.content.Context;
4
import android.net.Uri;
5
6
import com.luck.picture.lib.config.PictureMimeType;
7
import com.luck.picture.lib.engine.CompressFileEngine;
8
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener;
9
import com.luck.picture.lib.utils.DateUtils;
10
11
import java.io.File;
12
import java.util.ArrayList;
13
14
import top.zibin.luban.Luban;
15
import top.zibin.luban.OnCompressListener;
16
import top.zibin.luban.OnNewCompressListener;
17
18
19
/**
20
 * 自定义压缩
21
 */
22
public class ImageFileCompressEngine implements CompressFileEngine {
23
24
    @Override
25
    public void onStartCompress(Context context, ArrayList<Uri> source, OnKeyValueResultCallbackListener call) {
26
        Luban.with(context).load(source).ignoreBy(0).setRenameListener(filePath -> {
27
            int indexOf = filePath.lastIndexOf(".");
28
            String postfix = indexOf != -1 ? filePath.substring(indexOf) : ".jpg";
29
            return DateUtils.getCreateFileName("CMP_") + postfix;
30
        }).filter(path -> {
31
            if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) {
32
                return true;
33
            }
34
            return !PictureMimeType.isUrlHasGif(path);
35
        }).setCompressListener(new OnNewCompressListener() {
36
            @Override
37
            public void onStart() {
38
39
            }
40
41
            @Override
42
            public void onSuccess(String source, File compressFile) {
43
                if (call != null) {
44
                    call.onCallback(source, compressFile.getAbsolutePath());
45
                }
46
            }
47
48
            @Override
49
            public void onError(String source, Throwable e) {
50
                if (call != null) {
51
                    call.onCallback(source, null);
52
                }
53
            }
54
        }).launch();
55
    }
56
}

+ 35 - 0
app/src/main/java/com/electric/chargingpile/util/MeOnCameraInterceptListener.java

@ -0,0 +1,35 @@
1
package com.electric.chargingpile.util;
2
3
import android.content.Context;
4
import android.widget.ImageView;
5
6
import androidx.fragment.app.Fragment;
7
8
import com.bumptech.glide.Glide;
9
import com.luck.lib.camerax.CameraImageEngine;
10
import com.luck.lib.camerax.SimpleCameraX;
11
import com.luck.picture.lib.interfaces.OnCameraInterceptListener;
12
13
public class MeOnCameraInterceptListener implements OnCameraInterceptListener {
14
    @Override
15
    public void openCamera(Fragment fragment, int cameraMode, int requestCode) {
16
        SimpleCameraX camera = SimpleCameraX.of();
17
        camera.isAutoRotation(true);
18
        camera.setCameraMode(cameraMode);
19
        camera.setVideoFrameRate(25);
20
        camera.setVideoBitRate(3 * 1024 * 1024);
21
        camera.isDisplayRecordChangeTime(true);
22
        camera.isManualFocusCameraPreview(true);
23
        camera.isZoomCameraPreview(true);
24
//        camera.setOutputPathDir(getSandboxCameraOutputPath())
25
//        camera.setPermissionDeniedListener(getSimpleXPermissionDeniedListener())
26
//        camera.setPermissionDescriptionListener(getSimpleXPermissionDescriptionListener())
27
        camera.setImageEngine(new CameraImageEngine() {
28
            @Override
29
            public void loadImage(Context context, String url, ImageView imageView) {
30
                Glide.with(context).load(url).into(imageView);
31
            }
32
        });
33
        camera.start(fragment.requireActivity(),fragment, requestCode);
34
    }
35
}

+ 16 - 0
app/src/main/java/com/electric/chargingpile/util/MeSandboxFileEngine.java

@ -0,0 +1,16 @@
1
package com.electric.chargingpile.util;
2
3
import android.content.Context;
4
5
import com.luck.picture.lib.engine.UriToFileTransformEngine;
6
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener;
7
import com.luck.picture.lib.utils.SandboxTransformUtils;
8
9
public class MeSandboxFileEngine implements UriToFileTransformEngine {
10
    @Override
11
    public void onUriToFileAsyncTransform(Context context, String srcPath, String mineType, OnKeyValueResultCallbackListener call) {
12
        if (call != null) {
13
            call.onCallback(srcPath, SandboxTransformUtils.copyPathToSandbox(context, srcPath, mineType));
14
        }
15
    }
16
}

+ 116 - 0
app/src/main/java/com/electric/chargingpile/util/PictureUtlis.java

@ -0,0 +1,116 @@
1
package com.electric.chargingpile.util;
2
3
import androidx.core.content.ContextCompat;
4
5
import com.electric.chargingpile.R;
6
import com.electric.chargingpile.application.MainApplication;
7
import com.luck.picture.lib.style.BottomNavBarStyle;
8
import com.luck.picture.lib.style.PictureSelectorStyle;
9
import com.luck.picture.lib.style.SelectMainStyle;
10
import com.luck.picture.lib.style.TitleBarStyle;
11
12
public class PictureUtlis {
13
14
    public static PictureSelectorStyle getStyle(){
15
        TitleBarStyle blueTitleBarStyle = new TitleBarStyle();
16
17
18
        //标题栏左边关闭样式
19
        blueTitleBarStyle.setTitleLeftBackResource(R.drawable.ps_ic_black_back);
20
        //预览标题栏左边关闭样式
21
        blueTitleBarStyle.setPreviewTitleLeftBackResource(R.drawable.ps_ic_black_back);
22
        //标题栏字体色值
23
        blueTitleBarStyle.setTitleTextColor(ContextCompat.getColor(MainApplication.context, R.color.color_black));
24
        //标题栏右边文本字体色值
25
        blueTitleBarStyle.setTitleCancelTextColor(ContextCompat.getColor(MainApplication.context, R.color.color_black));
26
        blueTitleBarStyle.setTitleBackgroundColor(ContextCompat.getColor(MainApplication.context, R.color.color_white));
27
        //预览标题栏背景
28
        blueTitleBarStyle.setPreviewTitleBackgroundColor(ContextCompat.getColor(MainApplication.context, R.color.color_white));
29
        //标题栏高度
30
        blueTitleBarStyle.setTitleBarHeight(DensityUtil.dip2px(MainApplication.context,48));
31
        // 标题栏右边向上图标
32
        blueTitleBarStyle.setTitleDrawableRightResource(R.drawable.ic_orange_arrow_up);
33
        // 是否隐藏取消按钮
34
        blueTitleBarStyle.setHideCancelButton(false);
35
36
37
        BottomNavBarStyle numberBlueBottomNavBarStyle = new BottomNavBarStyle();
38
        //预览颜色
39
        numberBlueBottomNavBarStyle.setBottomPreviewNormalTextColor(ContextCompat.getColor(MainApplication.context, R.color.ps_color_9b));
40
        //预览颜色选中
41
        numberBlueBottomNavBarStyle.setBottomPreviewSelectTextColor(ContextCompat.getColor(MainApplication.context, R.color.color_accent));
42
43
        //底部导航栏背景色
44
        numberBlueBottomNavBarStyle.setBottomNarBarBackgroundColor(ContextCompat.getColor(MainApplication.context, R.color.color_white));
45
        //已选数量背景样式
46
        numberBlueBottomNavBarStyle.setBottomSelectNumResources( R.drawable.pic_select);
47
        //底部编辑文字色值
48
        numberBlueBottomNavBarStyle.setBottomEditorTextColor(ContextCompat.getColor(MainApplication.context, R.color.color_accent));
49
50
        //底部原图文字色值
51
        numberBlueBottomNavBarStyle.setBottomOriginalTextColor( ContextCompat.getColor(MainApplication.context, R.color.color_accent));
52
53
54
55
        SelectMainStyle numberBlueSelectMainStyle =new  SelectMainStyle();
56
        //状态栏背景色
57
        numberBlueSelectMainStyle.setStatusBarColor(ContextCompat.getColor(MainApplication.context, R.color.color_white));
58
59
        //导航栏背景色
60
        numberBlueSelectMainStyle.setNavigationBarColor(ContextCompat.getColor(MainApplication.context, R.color.color_white));
61
62
        //状态栏字体颜色,非黑即白
63
        numberBlueSelectMainStyle.setDarkStatusBarBlack(true);
64
        //完成按钮从底部放在右上角
65
        numberBlueSelectMainStyle.setCompleteSelectRelativeTop(false);
66
        //预览页选择按钮从顶部放在右下角
67
        numberBlueSelectMainStyle.setPreviewSelectRelativeBottom(false);
68
        //预览页是否显示选择画廊
69
        numberBlueSelectMainStyle.setPreviewDisplaySelectGallery(true);
70
        //预览页选择按钮MarginRight
71
//        numberBlueSelectMainStyle.previewSelectMarginRight = true
72
        //预览背景色
73
        numberBlueSelectMainStyle.setPreviewBackgroundColor( ContextCompat.getColor(MainApplication.context, R.color.color_white));
74
        //预览页选择按钮字体颜色
75
        numberBlueSelectMainStyle.setPreviewSelectTextColor(ContextCompat.getColor(MainApplication.context, R.color.color_black));
76
        //预览页选择按钮文本
77
        numberBlueSelectMainStyle.setPreviewSelectText("");
78
        //预览页勾选样式是否使用数量类型
79
        numberBlueSelectMainStyle.setPreviewSelectNumberStyle(true);
80
        //预览页勾选样式
81
        numberBlueSelectMainStyle.setPreviewSelectBackground(R.drawable.pic_select);
82
83
        //画廊大小
84
        numberBlueSelectMainStyle.setAdapterPreviewGalleryItemSize(DensityUtil.dip2px(MainApplication.context,60));
85
        //勾选样式
86
        numberBlueSelectMainStyle.setSelectBackground(R.drawable.app_preview_select);
87
88
        //勾选样式是否使用数量类型
89
        numberBlueSelectMainStyle.setSelectNumberStyle(true);
90
91
        //列表背景色
92
        numberBlueSelectMainStyle.setMainListBackgroundColor( ContextCompat.getColor(MainApplication.context, R.color.color_white));
93
        //选择按钮默认文本字体色值
94
//        numberBlueSelectMainStyle.selectNormalTextColor = true
95
        //选择按钮默认背景
96
//        numberBlueSelectMainStyle.selectNormalBackgroundResources = R.drawable.app_preview_select
97
98
        // 列表背景色
99
        numberBlueSelectMainStyle.setMainListBackgroundColor(ContextCompat.getColor(MainApplication.context, R.color.ps_color_white));
100
101
        //选择按钮默认文本字体色值
102
        numberBlueSelectMainStyle.setSelectNormalTextColor(ContextCompat.getColor(MainApplication.context, R.color.ps_color_9b));
103
104
        //选择按钮文本字体色值
105
        numberBlueSelectMainStyle.setSelectTextColor(ContextCompat.getColor(MainApplication.context, R.color.color_accent));
106
107
        numberBlueSelectMainStyle.setSelectText(R.string.ps_completed);
108
109
110
        PictureSelectorStyle selectorStyle = new PictureSelectorStyle();
111
        selectorStyle.setTitleBarStyle(blueTitleBarStyle);
112
        selectorStyle.setBottomBarStyle(numberBlueBottomNavBarStyle);
113
        selectorStyle.setSelectMainStyle(numberBlueSelectMainStyle);
114
        return selectorStyle;
115
    }
116
}

+ 30 - 75
app/src/main/java/com/electric/chargingpile/util/Util.java

@ -21,7 +21,8 @@ import com.electric.chargingpile.data.RedEnvelopeBean;
21 21
import com.electric.chargingpile.data.Zhan;
22 22
import com.electric.chargingpile.data.Zhuang;
23 23
import com.electric.chargingpile.manager.ProfileManager;
24
import com.luck.picture.lib.style.PictureParameterStyle;
24

25
import com.luck.picture.lib.entity.LocalMedia;
25 26
import com.tencent.mm.opensdk.openapi.IWXAPI;
26 27
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
27 28

@ -492,80 +493,6 @@ public class Util {
492 493
//    }
493 494
//
494 495

495
    public static PictureParameterStyle getWhiteStyle(Context context) {
496
        // 相册主题
497
        PictureParameterStyle style = new PictureParameterStyle();
498
        // 是否改变状态栏字体颜色(黑白切换)
499
        style.isChangeStatusBarFontColor = true;
500
        // 是否开启右下角已完成(0/9)风格
501
        style.isOpenCompletedNumStyle = false;
502
        // 是否开启类似QQ相册带数字选择风格
503
        style.isOpenCheckNumStyle = false;
504
        // 相册状态栏背景色
505
        style.pictureStatusBarColor = Color.parseColor("#FFFFFF");
506
        // 相册列表标题栏背景色
507
        style.pictureTitleBarBackgroundColor = Color.parseColor("#FFFFFF");
508
        // 相册列表标题栏右侧上拉箭头
509
        style.pictureTitleUpResId = R.drawable.ic_orange_arrow_up;
510
        // 相册列表标题栏右侧下拉箭头
511
        style.pictureTitleDownResId = R.drawable.ic_orange_arrow_down;
512
        // 相册文件夹列表选中圆点
513
        style.pictureFolderCheckedDotStyle = com.luck.picture.lib.R.drawable.picture_orange_oval;
514
        // 相册返回箭头
515
        style.pictureLeftBackIcon = R.drawable.ic_back_orange;
516
        // 标题栏字体颜色
517
        style.pictureTitleTextColor = ContextCompat.getColor(context, R.color.app_color_black);
518
        // 相册右侧取消按钮字体颜色  废弃 改用.pictureRightDefaultTextColor和.pictureRightDefaultTextColor
519
        style.pictureCancelTextColor = ContextCompat.getColor(context, R.color.app_color_black);
520
        // 选择相册目录背景样式
521
        style.pictureAlbumStyle = R.drawable.picture_new_item_select_bg;
522
        // 相册列表勾选图片样式
523
        style.pictureCheckedStyle = com.luck.picture.lib.R.drawable.picture_checkbox_selector;
524
        // 相册列表底部背景色
525
        style.pictureBottomBgColor = ContextCompat.getColor(context, com.luck.picture.lib.R.color.picture_color_fa);
526
        // 已选数量圆点背景样式
527
        style.pictureCheckNumBgStyle = com.luck.picture.lib.R.drawable.picture_num_oval;
528
        // 相册列表底下预览文字色值(预览按钮可点击时的色值)
529
        style.picturePreviewTextColor = ContextCompat.getColor(context, com.luck.picture.lib.R.color.picture_color_fa632d);
530
        // 相册列表底下不可预览文字色值(预览按钮不可点击时的色值)
531
        style.pictureUnPreviewTextColor = ContextCompat.getColor(context, com.luck.picture.lib.R.color.picture_color_9b);
532
        // 相册列表已完成色值(已完成 可点击色值)
533
        style.pictureCompleteTextColor = ContextCompat.getColor(context, com.luck.picture.lib.R.color.picture_color_fa632d);
534
        // 相册列表未完成色值(请选择 不可点击色值)
535
        style.pictureUnCompleteTextColor = ContextCompat.getColor(context, com.luck.picture.lib.R.color.picture_color_9b);
536
        // 预览界面底部背景色
537
        style.picturePreviewBottomBgColor = ContextCompat.getColor(context, com.luck.picture.lib.R.color.picture_color_white);
538
        // 原图按钮勾选样式  需设置.isOriginalImageControl(true); 才有效
539
        style.pictureOriginalControlStyle = com.luck.picture.lib.R.drawable.picture_original_checkbox;
540
        // 原图文字颜色 需设置.isOriginalImageControl(true); 才有效
541
        style.pictureOriginalFontColor = ContextCompat.getColor(context, R.color.app_color_53575e);
542
        // 外部预览界面删除按钮样式
543
        style.pictureExternalPreviewDeleteStyle = com.luck.picture.lib.R.drawable.picture_icon_black_delete;
544
        // 外部预览界面是否显示删除按钮
545
        style.pictureExternalPreviewGonePreviewDelete = true;
546
//        // 自定义相册右侧文本内容设置
547
//        mPictureParameterStyle.pictureRightDefaultText = "";
548
//        // 自定义相册未完成文本内容
549
//        mPictureParameterStyle.pictureUnCompleteText = "";
550
//        // 自定义相册完成文本内容
551
//        mPictureParameterStyle.pictureCompleteText = "";
552
//        // 自定义相册列表不可预览文字
553
//        mPictureParameterStyle.pictureUnPreviewText = "";
554
//        // 自定义相册列表预览文字
555
//        mPictureParameterStyle.picturePreviewText = "";
556

557
//        // 自定义相册标题字体大小
558
//        mPictureParameterStyle.pictureTitleTextSize = 18;
559
//        // 自定义相册右侧文字大小
560
//        mPictureParameterStyle.pictureRightTextSize = 14;
561
//        // 自定义相册预览文字大小
562
//        mPictureParameterStyle.picturePreviewTextSize = 14;
563
//        // 自定义相册完成文字大小
564
//        mPictureParameterStyle.pictureCompleteTextSize = 14;
565
//        // 自定义原图文字大小
566
//        mPictureParameterStyle.pictureOriginalTextSize = 14;
567
        return style;
568
    }
569 496

570 497
    /**
571 498
     * 判断手机是否安装微信
@ -660,4 +587,32 @@ public class Util {
660 587
        }
661 588
        return builder.toString();
662 589
    }
590

591
    public static String getCompressAbsolutePath(LocalMedia localMedia){
592
        String path = "";
593
         if (localMedia.isCompressed()){
594
            String compressPath = localMedia.getCompressPath();
595
            if (compressPath == null || compressPath .equals("") ){
596
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
597
                    path = localMedia.getSandboxPath();
598
                } else {
599
                    path = localMedia.getRealPath();
600
                }
601
            }else{
602
                path = compressPath;
603
            }
604
        }else{
605
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
606
                path = localMedia.getSandboxPath();
607
            } else {
608
                path =  localMedia.getRealPath();
609
            }
610
        }
611
        if (path == null || path.equals("")){
612
            path = localMedia.getAvailablePath();
613
        }
614
        return path;
615

616
    }
617

663 618
}

+ 220 - 0
app/src/main/java/com/electric/chargingpile/view/IjkPlayerView.java

@ -0,0 +1,220 @@
1
package com.electric.chargingpile.view;
2
3
import android.content.Context;
4
import android.graphics.SurfaceTexture;
5
import android.net.Uri;
6
import android.util.AttributeSet;
7
import android.view.Gravity;
8
import android.view.Surface;
9
import android.view.TextureView;
10
import android.widget.FrameLayout;
11
12
import androidx.annotation.NonNull;
13
14
import com.luck.picture.lib.config.PictureMimeType;
15
16
import java.io.IOException;
17
18
import tv.danmaku.ijk.media.player.IMediaPlayer;
19
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
20
21
public class IjkPlayerView extends FrameLayout implements TextureView.SurfaceTextureListener {
22
    private IjkVideoTextureView textureView;
23
    private IjkMediaPlayer mediaPlayer;
24
    private int mVideoRotation;
25
26
    public IjkPlayerView(@NonNull Context context) {
27
        super(context);
28
        init();
29
    }
30
31
    public IjkPlayerView(@NonNull Context context, AttributeSet attrs) {
32
        super(context, attrs);
33
        init();
34
    }
35
36
    public IjkPlayerView(@NonNull Context context, AttributeSet attrs, int defStyleAttr) {
37
        super(context, attrs, defStyleAttr);
38
        init();
39
    }
40
41
    public static int[] scaleSize(int textureWidth, int textureHeight, int realWidth, int realHeight) {
42
        float deviceRate = (float) textureWidth / (float) textureHeight;
43
        float rate = (float) realWidth / (float) realHeight;
44
        int width;
45
        int height;
46
        if (rate < deviceRate) {
47
            height = textureHeight;
48
            width = (int) (textureHeight * rate);
49
        } else {
50
            width = textureWidth;
51
            height = (int) (textureWidth / rate);
52
        }
53
        return new int[]{width, height};
54
    }
55
56
    private void init() {
57
        textureView = new IjkVideoTextureView(getContext());
58
        textureView.setSurfaceTextureListener(this);
59
        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
60
        layoutParams.gravity = Gravity.CENTER;
61
        textureView.setLayoutParams(layoutParams);
62
        addView(textureView);
63
    }
64
65
    public IjkMediaPlayer initMediaPlayer() {
66
        if (mediaPlayer == null) {
67
            mediaPlayer = new IjkMediaPlayer();
68
        }
69
        mediaPlayer.setOnVideoSizeChangedListener(new IMediaPlayer.OnVideoSizeChangedListener() {
70
            @Override
71
            public void onVideoSizeChanged(IMediaPlayer mediaPlayer, int width, int height, int sar_num, int sar_den) {
72
                textureView.adjustVideoSize(width, height, mVideoRotation);
73
            }
74
        });
75
        mediaPlayer.setOnInfoListener(new IMediaPlayer.OnInfoListener() {
76
            @Override
77
            public boolean onInfo(IMediaPlayer mp, int what, int extra) {
78
                if (what == 10001) {
79
                    mVideoRotation = extra;
80
                }
81
                return false;
82
            }
83
        });
84
        mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
85
        return mediaPlayer;
86
    }
87
88
    public IjkMediaPlayer getMediaPlayer() {
89
        return mediaPlayer;
90
    }
91
92
    public void start(String path) {
93
        try {
94
            if (PictureMimeType.isContent(path)) {
95
                mediaPlayer.setDataSource(getContext(), Uri.parse(path));
96
            } else {
97
                mediaPlayer.setDataSource(path);
98
            }
99
            SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
100
            if (surfaceTexture != null) {
101
                mediaPlayer.setSurface(new Surface(surfaceTexture));
102
            }
103
            mediaPlayer.prepareAsync();
104
        } catch (IOException e) {
105
            e.printStackTrace();
106
        }
107
    }
108
109
    @Override
110
    public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
111
        mediaPlayer.setSurface(new Surface(surface));
112
    }
113
114
    @Override
115
    public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
116
    }
117
118
    @Override
119
    public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
120
        return false;
121
    }
122
123
    @Override
124
    public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
125
126
    }
127
128
    public void release() {
129
        if (mediaPlayer != null) {
130
            mediaPlayer.release();
131
            mediaPlayer.setOnPreparedListener(null);
132
            mediaPlayer.setOnCompletionListener(null);
133
            mediaPlayer.setOnErrorListener(null);
134
            mediaPlayer.setOnInfoListener(null);
135
            mediaPlayer = null;
136
        }
137
    }
138
139
    public void clearCanvas() {
140
    }
141
142
    public static class IjkVideoTextureView extends TextureView {
143
        /**
144
         * 视频宽度
145
         */
146
        private int mVideoWidth;
147
        /**
148
         * 视频高度
149
         */
150
        private int mVideoHeight;
151
152
        /**
153
         * 视频旋转角度
154
         */
155
        private int mVideoRotation;
156
157
        public IjkVideoTextureView(@NonNull Context context) {
158
            super(context);
159
        }
160
161
        public void adjustVideoSize(int videoWidth, int videoHeight, int videoRotation) {
162
            this.mVideoWidth = videoWidth;
163
            this.mVideoHeight = videoHeight;
164
            this.mVideoRotation = videoRotation;
165
            this.setRotation(mVideoRotation);
166
            this.requestLayout();
167
        }
168
169
        @Override
170
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
171
            int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
172
            int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
173
            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
174
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
175
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
176
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
177
            if (mVideoWidth > 0 && mVideoHeight > 0) {
178
                if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
179
                    width = widthSpecSize;
180
                    height = heightSpecSize;
181
182
                    if (mVideoWidth * height < width * mVideoHeight) {
183
                        width = height * mVideoWidth / mVideoHeight;
184
                    } else if (mVideoWidth * height > width * mVideoHeight) {
185
                        height = width * mVideoHeight / mVideoWidth;
186
                    }
187
                } else if (widthSpecMode == MeasureSpec.EXACTLY) {
188
                    width = widthSpecSize;
189
                    height = width * mVideoHeight / mVideoWidth;
190
                    if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
191
                        height = heightSpecSize;
192
                    }
193
                } else if (heightSpecMode == MeasureSpec.EXACTLY) {
194
                    height = heightSpecSize;
195
                    width = height * mVideoWidth / mVideoHeight;
196
                    if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
197
                        width = widthSpecSize;
198
                    }
199
                } else {
200
                    width = mVideoWidth;
201
                    height = mVideoHeight;
202
                    if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
203
                        height = heightSpecSize;
204
                        width = height * mVideoWidth / mVideoHeight;
205
                    }
206
                    if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
207
                        width = widthSpecSize;
208
                        height = width * mVideoHeight / mVideoWidth;
209
                    }
210
                }
211
            }
212
            setMeasuredDimension(width, height);
213
            if ((mVideoRotation + 180) % 180 != 0) {
214
                int[] size = scaleSize(widthSpecSize, heightSpecSize, height, width);
215
                setScaleX(size[0] / ((float) height));
216
                setScaleY(size[1] / ((float) width));
217
            }
218
        }
219
    }
220
}

BIN
app/src/main/res/drawable-xxhdpi/app_back_black.png


+ 11 - 0
app/src/main/res/drawable/app_preview_select.xml

@ -0,0 +1,11 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<shape xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:shape="oval"
4
    android:useLevel="false">
5
6
    <solid android:color="@color/color_transparent" />
7
    <size
8
        android:width="18dp"
9
        android:height="18dp" />
10
    <stroke android:width="1dp" android:color="@color/color_accent"/>
11
</shape>

BIN
app/src/main/res/drawable/img.png


BIN
app/src/main/res/drawable/img_1.png


+ 11 - 0
app/src/main/res/drawable/pic_select.xml

@ -0,0 +1,11 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<shape xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:shape="oval"
4
    android:useLevel="false">
5
6
    <solid android:color="@color/color_accent" />
7
    <size
8
        android:width="18dp"
9
        android:height="18dp" />
10
    <stroke android:width="1dp" android:color="@color/color_accent"/>
11
</shape>

+ 2 - 1
app/src/main/res/values/color.xml

@ -18,7 +18,8 @@
18 18
    <color name="bkg_button_green">#39c663</color>
19 19
    <color name="ui_green">#39C663</color>
20 20
    <color name="title_background">#FCFCFC</color>
21

21
    <color name="color_accent">#ff6600</color>
22
    <color name="color_transparent">#00FFFFFF</color>
22 23
    <!-- PictureSelector -->
23 24
    <color name="app_color_grey">#393a3e</color>
24 25
    <color name="app_color_black">#000000</color>

+ 0 - 52
app/src/main/res/values/styles.xml

@ -303,58 +303,6 @@
303 303

304 304
    <style name="BaseNoActionBarTheme" parent="Theme.AppCompat.Light.NoActionBar" />
305 305
    <!--白色主题样式,,注意每一项都不能少-->
306
    <style name="picture.white.style" parent="BaseNoActionBarTheme">
307
        <!-- Customize your theme here. -->
308
        <!--标题栏背景色-->
309
        <item name="colorPrimary">@color/app_color_white</item>
310
        <!--状态栏背景色-->
311
        <item name="colorPrimaryDark">@color/app_color_white</item>
312
        <!--是否改变图片列表界面状态栏字体颜色为黑色-->
313
        <item name="picture.statusFontColor">true</item>
314
        <!--返回键图标-->
315
        <item name="picture.leftBack.icon">@drawable/ic_back_arrow</item>
316
        <!--标题下拉箭头-->
317
        <item name="picture.arrow_down.icon">@drawable/ic_orange_arrow_down</item>
318
        <!--标题上拉箭头-->
319
        <item name="picture.arrow_up.icon">@drawable/ic_orange_arrow_up</item>
320
        <!--标题文字颜色-->
321
        <item name="picture.title.textColor">@color/app_color_black</item>
322
        <!--标题栏右边文字-->
323
        <item name="picture.right.textColor">@color/app_color_black</item>
324
        <!--图片列表勾选样式-->
325
        <item name="picture.checked.style">@drawable/picture_checkbox_selector</item>
326
        <!--开启图片列表勾选数字模式,开启的话勾选样式要换-->
327
        <item name="picture.style.checkNumMode">false</item>
328
        <!--选择图片样式0/9-->
329
        <item name="picture.style.numComplete">true</item>
330
        <!--图片列表底部背景色-->
331
        <item name="picture.bottom.bg">@color/app_color_fa</item>
332
        <!--图片列表预览文字颜色-->
333
        <item name="picture.preview.textColor">@color/picture_list_sina_text_color</item>
334
        <!--图片列表已完成文字颜色-->
335
        <item name="picture.complete.textColor">@color/picture_list_sina_text_color</item>
336
        <!--图片已选数量圆点背景色-->
337
        <item name="picture.num.style">@drawable/picture_num_oval</item>
338
        <!--预览界面标题栏背景色-->
339
        <item name="picture.ac_preview.title.bg">@color/app_color_white</item>
340
        <!--预览界面标题文字颜色-->
341
        <item name="picture.ac_preview.title.textColor">@color/app_color_black</item>
342
        <!--预览界面已完成文字颜色-->
343
        <item name="picture.ac_preview.complete.textColor">@color/picture_list_sina_text_color
344
        </item>
345
        <!--预览界面底部背景色-->
346
        <item name="picture.ac_preview.bottom.bg">@color/picture_color_fa</item>
347
        <!--预览界面返回箭头-->
348
        <item name="picture.preview.leftBack.icon">@drawable/ic_back_arrow</item>
349
        <!--裁剪页面标题背景色-->
350
        <item name="picture.crop.toolbar.bg">@color/app_color_white</item>
351
        <!--裁剪页面状态栏颜色-->
352
        <item name="picture.crop.status.color">@color/app_color_white</item>
353
        <!--裁剪页面标题文字颜色-->
354
        <item name="picture.crop.title.color">@color/app_color_black</item>
355
        <!--相册文件夹列表选中图标-->
356
        <item name="picture.folder_checked_dot">@drawable/picture_orange_oval</item>
357
    </style>
358 306

359 307
    <declare-styleable name="TextImageView">
360 308
        <attr name="drawableLeftWidth" format="dimension" />

+ 2 - 2
config.gradle

@ -1,9 +1,9 @@
1 1
ext{
2 2
    android = [
3
            compileSdkVersion: 31,
3
            compileSdkVersion: 33,
4 4
            applicationId    : "com.electric.chargingpile",
5 5
            minSdkVersion    : 24,
6
            targetSdkVersion : 31,
6
            targetSdkVersion : 33,
7 7
    ]
8 8
9 9
    manifestPlaceholders= [

代码修改 · 041a09647c - Gogs: Go Git Service
huyuguo 5 lat temu
rodzic
commit
041a09647c
37 zmienionych plików z 994 dodań i 498 usunięć
  1. 4 0
      app/src/main/AndroidManifest.xml
  2. 2 5
      app/src/main/java/com/electric/chargingpile/activity/CarBrandActivity.java
  3. 83 9
      app/src/main/java/com/electric/chargingpile/activity/CarModelActivity.java
  4. 26 31
      app/src/main/java/com/electric/chargingpile/activity/CarOwnerCertificateActivity.java
  5. 3 0
      app/src/main/java/com/electric/chargingpile/activity/CarOwnerCertificateListActivity.java
  6. 75 0
      app/src/main/java/com/electric/chargingpile/activity/CarSeriesActivity.java
  7. 1 1
      app/src/main/java/com/electric/chargingpile/activity/RegisterActivity.java
  8. 6 6
      app/src/main/java/com/electric/chargingpile/activity/UserCenterActivity.java
  9. 19 4
      app/src/main/java/com/electric/chargingpile/activity/UserInfoActivity.java
  10. 11 2
      app/src/main/java/com/electric/chargingpile/adapter/CarBrandGroupedListAdapter.java
  11. 20 12
      app/src/main/java/com/electric/chargingpile/adapter/CarModelGroupedListAdapter.java
  12. 16 19
      app/src/main/java/com/electric/chargingpile/adapter/CarOwnerCertificateListAdapter.java
  13. 97 0
      app/src/main/java/com/electric/chargingpile/adapter/CarSeriesGroupedListAdapter.java
  14. 9 2
      app/src/main/java/com/electric/chargingpile/adapter/ZhanCommentsAapter.java
  15. 10 8
      app/src/main/java/com/electric/chargingpile/entity/CarCompanyEntity.java
  16. 30 0
      app/src/main/java/com/electric/chargingpile/entity/CarModelChildEntity.java
  17. 141 0
      app/src/main/java/com/electric/chargingpile/entity/CarModelEntity.java
  18. 32 0
      app/src/main/java/com/electric/chargingpile/entity/CarModelGroupEntity.java
  19. 19 0
      app/src/main/java/com/electric/chargingpile/event/CarModelEvent.java
  20. 2 2
      app/src/main/java/com/electric/chargingpile/event/CarSerieEvent.java
  21. 0 29
      app/src/main/java/com/electric/chargingpile/fragment/ZhanCommentFragment.java
  22. 2 0
      app/src/main/java/com/electric/chargingpile/util/CarTypeUtil.java
  23. 25 8
      app/src/main/java/com/electric/chargingpile/view/MyReceiver.java
  24. BIN
      app/src/main/res/drawable-hdpi/certified_icon.png
  25. BIN
      app/src/main/res/drawable-mdpi/certified_icon.png
  26. BIN
      app/src/main/res/drawable-xhdpi/certified_icon.png
  27. BIN
      app/src/main/res/drawable-xxhdpi/certified_icon.png
  28. BIN
      app/src/main/res/drawable-xxxhdpi/certified_icon.png
  29. 14 1
      app/src/main/res/layout/activity_car_model.xml
  30. 17 10
      app/src/main/res/layout/activity_car_owner_certificate.xml
  31. 57 0
      app/src/main/res/layout/activity_car_series.xml
  32. 1 1
      app/src/main/res/layout/activity_user_center.xml
  33. 37 0
      app/src/main/res/layout/activity_user_info.xml
  34. 7 42
      app/src/main/res/layout/adapter_child_car_model.xml
  35. 78 0
      app/src/main/res/layout/adapter_child_car_series.xml
  36. 19 0
      app/src/main/res/layout/adapter_header_car_series.xml
  37. 131 306
      app/src/main/res/layout/item_zhancomments.xml

+ 4 - 0
app/src/main/AndroidManifest.xml

@ -86,6 +86,10 @@
86 86
            android:launchMode="singleTop"
87 87
            android:screenOrientation="portrait" />
88 88
        <activity
89
            android:name=".activity.CarSeriesActivity"
90
            android:launchMode="singleTop"
91
            android:screenOrientation="portrait" />
92
        <activity
89 93
            android:name=".activity.CarBrandActivity"
90 94
            android:launchMode="singleTop"
91 95
            android:screenOrientation="portrait" />

+ 2 - 5
app/src/main/java/com/electric/chargingpile/activity/CarBrandActivity.java

@ -6,7 +6,6 @@ import androidx.recyclerview.widget.RecyclerView;
6 6
7 7
import android.content.Intent;
8 8
import android.os.Bundle;
9
import android.util.Log;
10 9
import android.view.View;
11 10
import android.widget.TextView;
12 11
@ -49,13 +48,11 @@ public class CarBrandActivity extends AppCompatActivity implements View.OnClickL
49 48
        CarBrandEvent event = EventBus.getDefault().removeStickyEvent(CarBrandEvent.class);
50 49
        if (event != null) {
51 50
            groups = event.getGroups();
52
            Log.e("abs======================",   groups.size() + "");
53 51
            String[] letters = new String[groups.size()];
54 52
            for (int i = 0; i < groups.size(); i++) {
55 53
                letters[i] = groups.get(i).getInitial();
56
                Log.e("abs======================",   letters[i] + "+" + groups.get(i).getInitial());
57 54
            }
58
//            LetterSideView.letters = letters;
55
            LetterSideView.letters = letters;
59 56
        }
60 57
        findViewById(R.id.iv_back).setOnClickListener(this::onClick);
61 58
        letter_side_view = findViewById(R.id.letter_side_view);
@ -94,7 +91,7 @@ public class CarBrandActivity extends AppCompatActivity implements View.OnClickL
94 91
            public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition, int childPosition) {
95 92
                ArrayList<CarCompanyEntity> companyList = groups.get(groupPosition).getBrandList().get(childPosition).getCompanyList();
96 93
                EventBus.getDefault().postSticky(new CarCompanyEvent(companyList));
97
                startActivity(new Intent(CarBrandActivity.this, CarModelActivity.class));
94
                startActivity(new Intent(CarBrandActivity.this, CarSeriesActivity.class));
98 95
            }
99 96
        });
100 97

+ 83 - 9
app/src/main/java/com/electric/chargingpile/activity/CarModelActivity.java

@ -7,28 +7,44 @@ import androidx.recyclerview.widget.RecyclerView;
7 7
import android.content.Intent;
8 8
import android.os.Bundle;
9 9
import android.view.View;
10
import android.widget.TextView;
11
import android.widget.Toast;
10 12
11 13
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
12 14
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
13 15
import com.donkingliang.groupedadapter.widget.StickyHeaderLayout;
14 16
import com.electric.chargingpile.R;
15 17
import com.electric.chargingpile.adapter.CarModelGroupedListAdapter;
16
import com.electric.chargingpile.entity.CarCompanyEntity;
18
import com.electric.chargingpile.entity.CarModelChildEntity;
19
import com.electric.chargingpile.entity.CarModelEntity;
20
import com.electric.chargingpile.entity.CarModelGroupEntity;
17 21
import com.electric.chargingpile.entity.CarSeriesEntity;
18
import com.electric.chargingpile.event.CarCompanyEvent;
19
import com.electric.chargingpile.event.CarSerieEvent;
22
import com.electric.chargingpile.event.CarModelEvent;
23
import com.electric.chargingpile.event.CarSeriesEvent;
20 24
import com.electric.chargingpile.util.BarColorUtil;
25
import com.electric.chargingpile.util.JsonUtils;
26
import com.electric.chargingpile.util.LoadingDialog;
27
import com.electric.chargingpile.util.ToastUtil;
28
import com.google.gson.Gson;
29
import com.google.gson.reflect.TypeToken;
30
import com.zhy.http.okhttp.OkHttpUtils;
31
import com.zhy.http.okhttp.callback.StringCallback;
21 32
22 33
import org.greenrobot.eventbus.EventBus;
23 34
24 35
import java.util.ArrayList;
25 36
37
import okhttp3.Call;
38
26 39
public class CarModelActivity extends AppCompatActivity implements View.OnClickListener {
27 40
28 41
    private RecyclerView recycler_view;
29 42
    private StickyHeaderLayout sticky_header_layout;
30 43
    private CarModelGroupedListAdapter adapter;
31
    private ArrayList<CarCompanyEntity> companyList;
44
    private CarSeriesEntity carSeriesEntity;
45
    private ArrayList<CarModelGroupEntity> groups = new ArrayList<>();
46
    private LoadingDialog loadDialog;
47
    private TextView no_data;
32 48
33 49
    @Override
34 50
    protected void onCreate(Bundle savedInstanceState) {
@ -39,22 +55,44 @@ public class CarModelActivity extends AppCompatActivity implements View.OnClickL
39 55
    }
40 56
41 57
    private void initViews() {
58
        loadDialog = new LoadingDialog(this);
59
        loadDialog.setCanceledOnTouchOutside(false);
42 60
        findViewById(R.id.nav_bar).setOnClickListener(this::onClick);
43
        CarCompanyEvent event = EventBus.getDefault().removeStickyEvent(CarCompanyEvent.class);
61
        CarSeriesEvent event = EventBus.getDefault().removeStickyEvent(CarSeriesEvent.class);
44 62
        if (event != null) {
45
            companyList = event.getCompanyList();
63
            carSeriesEntity = event.getCarSeriesEntity();
64
            loadDialog.show();
65
            getModelList();
46 66
        }
47 67
68
        no_data = findViewById(R.id.no_data);
69
48 70
        recycler_view = (RecyclerView) findViewById(R.id.recycler_view);
49 71
        sticky_header_layout = (StickyHeaderLayout) findViewById(R.id.sticky_header_layout);
50 72
51 73
        recycler_view.setLayoutManager(new LinearLayoutManager(this));
52
        adapter = new CarModelGroupedListAdapter(this, companyList);
74
        adapter = new CarModelGroupedListAdapter(this, groups, carSeriesEntity.getMasterPic());
53 75
        adapter.setOnChildClickListener(new GroupedRecyclerViewAdapter.OnChildClickListener() {
54 76
            @Override
55 77
            public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition, int childPosition) {
56
                CarSeriesEntity carSeriesEntity = companyList.get(groupPosition).getSerieslist().get(childPosition);
57
                EventBus.getDefault().post(new CarSerieEvent(carSeriesEntity));
78
                CarModelChildEntity carModelChildEntity = groups.get(groupPosition).getList().get(childPosition);
79
                CarModelEntity carModelEntity = new CarModelEntity();
80
81
                carModelEntity.setBrandName(carSeriesEntity.getBrandName());
82
                carModelEntity.setCompanyId(carSeriesEntity.getCompanyId());
83
                carModelEntity.setCompanyName(carSeriesEntity.getCompanyName());
84
                carModelEntity.setSeriesId(carSeriesEntity.getSeriesId());
85
                carModelEntity.setSeriesName(carSeriesEntity.getSeriesName());
86
                carModelEntity.setSalePrice(carSeriesEntity.getSalePrice());
87
                carModelEntity.setIcon(carSeriesEntity.getIcon());
88
                carModelEntity.setMasterPic(carSeriesEntity.getMasterPic());
89
                carModelEntity.setMaxSalePrice(carSeriesEntity.getMaxSalePrice());
90
                carModelEntity.setMinSalePrice(carSeriesEntity.getMinSalePrice());
91
92
                carModelEntity.setModelId(carModelChildEntity.getModelId());
93
                carModelEntity.setModelName(carModelChildEntity.getModelName());
94
95
                EventBus.getDefault().post(new CarModelEvent(carModelEntity));
58 96
                startActivity(new Intent(CarModelActivity.this, CarOwnerCertificateActivity.class));
59 97
            }
60 98
        });
@ -64,6 +102,42 @@ public class CarModelActivity extends AppCompatActivity implements View.OnClickL
64 102
        sticky_header_layout.setSticky(true);
65 103
    }
66 104
105
    private void getModelList() {
106
        String url = "https://www.d1ev.com/car/api/v1000/series/model/list.do?seriesId=" + carSeriesEntity.getSeriesId();
107
        OkHttpUtils.get().url(url).build().connTimeOut(6000).readTimeOut(6000).execute(new StringCallback() {
108
            @Override
109
            public void onError(Call call, Exception e) {
110
                e.printStackTrace();
111
                loadDialog.dismiss();
112
                Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
113
            }
114
115
            @Override
116
            public void onResponse(String response) {
117
                loadDialog.dismiss();
118
                String code = JsonUtils.getKeyResult(response, "code");
119
                String desc = JsonUtils.getKeyResult(response, "desc");
120
                if ("1000".equals(code)) {
121
                    if ("1000".equals(code)) {
122
                        String data = JsonUtils.getKeyResult(response, "data");
123
                        Gson gson = new Gson();
124
                        groups = gson.fromJson(data, new TypeToken<ArrayList<CarModelGroupEntity>>() {
125
                        }.getType());
126
                        if (groups == null || groups.size() == 0) {
127
                            ToastUtil.showToast(getApplicationContext(), "暂无车型", Toast.LENGTH_SHORT);
128
                            no_data.setVisibility(View.VISIBLE);
129
                        } else {
130
                            adapter.setGroups(groups);
131
                            no_data.setVisibility(View.GONE);
132
                        }
133
                    } else {
134
                        ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
135
                    }
136
                }
137
            }
138
        });
139
    }
140
67 141
    @Override
68 142
    public void onClick(View v) {
69 143
        switch (v.getId()) {

+ 26 - 31
app/src/main/java/com/electric/chargingpile/activity/CarOwnerCertificateActivity.java

@ -16,7 +16,6 @@ import android.net.Uri;
16 16
import android.os.Bundle;
17 17
import android.text.TextUtils;
18 18
import android.util.Base64;
19
import android.util.Log;
20 19
import android.view.View;
21 20
import android.view.WindowManager;
22 21
import android.widget.Button;
@ -28,28 +27,24 @@ import android.widget.Toast;
28 27
29 28
import com.bumptech.glide.Glide;
30 29
import com.bumptech.glide.load.engine.DiskCacheStrategy;
31
import com.bumptech.glide.request.Request;
32 30
import com.bumptech.glide.request.target.CustomTarget;
33
import com.bumptech.glide.request.target.SizeReadyCallback;
34
import com.bumptech.glide.request.target.Target;
35 31
import com.bumptech.glide.request.transition.Transition;
36 32
import com.electric.chargingpile.R;
37 33
import com.electric.chargingpile.application.MainApplication;
38 34
import com.electric.chargingpile.data.CarOwnerCertificateBean;
39 35
import com.electric.chargingpile.entity.CarBrandGroupEntity;
36
import com.electric.chargingpile.entity.CarModelEntity;
40 37
import com.electric.chargingpile.entity.CarSeriesEntity;
41 38
import com.electric.chargingpile.event.CarBrandEvent;
42
import com.electric.chargingpile.event.CarSerieEvent;
39
import com.electric.chargingpile.event.CarModelEvent;
40
import com.electric.chargingpile.event.CarSeriesEvent;
43 41
import com.electric.chargingpile.util.BarColorUtil;
44
import com.electric.chargingpile.util.Base64Util;
45 42
import com.electric.chargingpile.util.DES3;
46 43
import com.electric.chargingpile.util.FileUtils;
47
import com.electric.chargingpile.util.ImageUitl;
48 44
import com.electric.chargingpile.util.JsonUtils;
49 45
import com.electric.chargingpile.util.LoadingDialog;
50 46
import com.electric.chargingpile.util.ToastUtil;
51 47
import com.electric.chargingpile.view.TextImageView;
52
import com.electric.chargingpile.view.xrichtext.SDCardUtil;
53 48
import com.google.gson.Gson;
54 49
import com.google.gson.reflect.TypeToken;
55 50
import com.zhihu.matisse.Matisse;
@ -65,10 +60,7 @@ import org.greenrobot.eventbus.ThreadMode;
65 60
66 61
import java.io.ByteArrayOutputStream;
67 62
import java.io.File;
68
import java.io.FileInputStream;
69 63
import java.io.IOException;
70
import java.io.InputStream;
71
import java.net.URLEncoder;
72 64
import java.util.ArrayList;
73 65
import java.util.HashMap;
74 66
import java.util.List;
@ -82,7 +74,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
82 74
import io.reactivex.disposables.Disposable;
83 75
import io.reactivex.schedulers.Schedulers;
84 76
import okhttp3.Call;
85
import okhttp3.MediaType;
86 77
import pub.devrel.easypermissions.AfterPermissionGranted;
87 78
import pub.devrel.easypermissions.EasyPermissions;
88 79
@ -106,12 +97,12 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
106 97
    private TextView add_car_model_btn;
107 98
    private LoadingDialog loadDialog;
108 99
    private ArrayList<CarBrandGroupEntity> groups;
109
    private CarSeriesEntity carSeriesEntity;
100
    private CarModelEntity carModelEntity;
110 101
    private ConstraintLayout car_model_constraint_layout;
111 102
    private ConstraintLayout car_model_selected_constraint_layout;
112 103
    private ImageView car_icon;
113
    private TextView car_name;
114 104
    private TextView car_series;
105
    private TextView car_model;
115 106
    private ConstraintLayout driving_license;
116 107
    private ImageView driving_license_icon;
117 108
    private ImageView driving_license_upload_icon;
@ -170,7 +161,7 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
170 161
        car_model_selected_constraint_layout.setOnClickListener(this);
171 162
172 163
        car_icon = findViewById(R.id.car_icon);
173
        car_name = findViewById(R.id.car_name);
164
        car_model = findViewById(R.id.car_model);
174 165
        car_series = findViewById(R.id.car_series);
175 166
176 167
        driving_license = findViewById(R.id.driving_license);
@ -202,8 +193,8 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
202 193
203 194
        if (edit) {
204 195
            Gson gson = new Gson();
205
            CarSerieEvent event = new CarSerieEvent(gson.fromJson(carOwnerCertificateBean.getChexing(), CarSeriesEntity.class));
206
            onCarSeriesMessage(event);
196
            CarModelEvent event = new CarModelEvent(gson.fromJson(carOwnerCertificateBean.getChexing(), CarModelEntity.class));
197
            onCarModelMessage(event);
207 198
208 199
            if (!TextUtils.isEmpty(carOwnerCertificateBean.getLicense_img1())) {
209 200
@ -220,7 +211,6 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
220 211
221 212
                    }
222 213
                });
223
//                Glide.with(this).load(MainApplication.pic_url + carOwnerCertificateBean.getLicense_img1()).into(driving_license_icon);
224 214
                driving_license_upload_icon.setVisibility(View.GONE);
225 215
                driving_license_text_view.setVisibility(View.GONE);
226 216
                driving_license_info.setVisibility(View.VISIBLE);
@ -254,7 +244,7 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
254 244
            loadDialog.show();
255 245
        // https://www.jianshu.com/p/10382cc71127
256 246
//        String url = "https://api.touchev.com:83/car/api/v1000/brand/list.do";
257
        String url = "http://car.d1ev.com/car/api/v1000/brand/list.do";
247
        String url = "http://car.d1ev.com/car/api/v1000/brand/list.do?from=cdz";
258 248
        OkHttpUtils.get().url(url).build().connTimeOut(30000).readTimeOut(30000).execute(new StringCallback() {
259 249
            @Override
260 250
            public void onError(Call call, Exception e) {
@ -337,16 +327,22 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
337 327
    }
338 328
339 329
    @Subscribe(threadMode = ThreadMode.MAIN)
340
    public void onCarSeriesMessage(CarSerieEvent event) {
341
        if (event != null && event.getCarSeriesEntity() != null) {
342
            carSeriesEntity = event.getCarSeriesEntity();
330
    public void onCarModelMessage(CarModelEvent event) {
331
        if (event != null && event.getCarModelEntity() != null) {
332
            carModelEntity = event.getCarModelEntity();
343 333
            car_model_constraint_layout.setVisibility(View.GONE);
344 334
            car_model_selected_constraint_layout.setVisibility(View.VISIBLE);
345
            car_name.setText(carSeriesEntity.getBrandName());
346
            car_series.setText(carSeriesEntity.getSeriesName());
347
            Glide.with(CarOwnerCertificateActivity.this).load(carSeriesEntity.getMasterPic()).placeholder(android.R.color.white).fitCenter().into(car_icon);
335
            car_series.setText(carModelEntity.getSeriesName());
336
            car_model.setText(carModelEntity.getModelName());
337
            try {
338
                String[] imgNames = carModelEntity.getMasterPic().split("!w");
339
                imgNames[1] = imgNames[1].replace("480", "240");
340
                Glide.with(CarOwnerCertificateActivity.this).load(imgNames[0] + "!w" + imgNames[1]).placeholder(android.R.color.white).dontAnimate().diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(car_icon);
341
            } catch (Exception e) {
342
                e.printStackTrace();
343
            }
348 344
        } else {
349
            carSeriesEntity = null;
345
            carModelEntity = null;
350 346
            car_model_constraint_layout.setVisibility(View.VISIBLE);
351 347
            car_model_selected_constraint_layout.setVisibility(View.GONE);
352 348
        }
@ -538,7 +534,7 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
538 534
    }
539 535
540 536
    private void addCarOwnerCertification() {
541
        if (carSeriesEntity == null) {
537
        if (carModelEntity == null) {
542 538
            ToastUtil.showToast(this, "请添加车型", Toast.LENGTH_SHORT);
543 539
            return;
544 540
        }
@ -573,7 +569,7 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
573 569
        }
574 570
        Map<String, String> map = new HashMap<>();
575 571
        Gson gson = new Gson();
576
        String chexing = gson.toJson(carSeriesEntity);
572
        String chexing = gson.toJson(carModelEntity);
577 573
        map.put("chexing", chexing);
578 574
579 575
        if (drivingLicenseBase64Data != null) {
@ -609,11 +605,10 @@ public class CarOwnerCertificateActivity extends AppCompatActivity implements Vi
609 605
                // {"Code":0,"Message":"成功","RequestId":"F84FF659-1D65-48E1-8C12-B253CEFCC4F8","Data":{"plate_num":"京Q52DR5","vehicle_type":"小型轿车","owner":"北京一度用车信息科技有限公司","address":"北京市海淀区中关村东路18号1号楼C日609-1","useCharacter":"葙赁","model":"北京牌BJ7000B3D5-BEV","vin":"LNBSCB3F4HD101254","engine_num":"AD33DH03040031","register_date":"20170525","issueDate":"00170525"}}
610 606
                String rtnCode = JsonUtils.getKeyResult(response, "rtnCode");
611 607
                if ("01".equals(rtnCode)) {
612
                    ToastUtil.showToast(getApplicationContext(), "数据提交成功", Toast.LENGTH_SHORT);
608
                    ToastUtil.showToast(getApplicationContext(), "认证信息提交成功,请等待审核", Toast.LENGTH_SHORT);
613 609
                    finish();
614 610
                } else {
615
                    String rtnMsg = JsonUtils.getKeyResult(response, "rtnMsg");
616
                    ToastUtil.showToast(getApplicationContext(), rtnMsg, Toast.LENGTH_SHORT);
611
                    ToastUtil.showToast(getApplicationContext(), "认证信息提交超时,请重新提交", Toast.LENGTH_SHORT);
617 612
                }
618 613
            }
619 614
        });

+ 3 - 0
app/src/main/java/com/electric/chargingpile/activity/CarOwnerCertificateListActivity.java

@ -114,6 +114,7 @@ public class CarOwnerCertificateListActivity extends AppCompatActivity {
114 114
        String token = null;
115 115
        try {
116 116
            token = DES3.encode(String.valueOf(tokenTime));
117
            token = URLEncoder.encode(token, "UTF-8");
117 118
        } catch (Exception e) {
118 119
            e.printStackTrace();
119 120
        }
@ -151,6 +152,7 @@ public class CarOwnerCertificateListActivity extends AppCompatActivity {
151 152
        String token = null;
152 153
        try {
153 154
            token = DES3.encode(String.valueOf(tokenTime));
155
            token = URLEncoder.encode(token, "UTF-8");
154 156
        } catch (Exception e) {
155 157
            e.printStackTrace();
156 158
        }
@ -183,6 +185,7 @@ public class CarOwnerCertificateListActivity extends AppCompatActivity {
183 185
        String token = null;
184 186
        try {
185 187
            token = DES3.encode(String.valueOf(tokenTime));
188
            token = URLEncoder.encode(token, "UTF-8");
186 189
        } catch (Exception e) {
187 190
            e.printStackTrace();
188 191
        }

+ 75 - 0
app/src/main/java/com/electric/chargingpile/activity/CarSeriesActivity.java

@ -0,0 +1,75 @@
1
package com.electric.chargingpile.activity;
2
3
import androidx.appcompat.app.AppCompatActivity;
4
import androidx.recyclerview.widget.LinearLayoutManager;
5
import androidx.recyclerview.widget.RecyclerView;
6
7
import android.content.Intent;
8
import android.os.Bundle;
9
import android.view.View;
10
11
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
12
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
13
import com.donkingliang.groupedadapter.widget.StickyHeaderLayout;
14
import com.electric.chargingpile.R;
15
import com.electric.chargingpile.adapter.CarSeriesGroupedListAdapter;
16
import com.electric.chargingpile.entity.CarCompanyEntity;
17
import com.electric.chargingpile.entity.CarSeriesEntity;
18
import com.electric.chargingpile.event.CarCompanyEvent;
19
import com.electric.chargingpile.event.CarSeriesEvent;
20
import com.electric.chargingpile.util.BarColorUtil;
21
22
import org.greenrobot.eventbus.EventBus;
23
24
import java.util.ArrayList;
25
26
public class CarSeriesActivity extends AppCompatActivity implements View.OnClickListener {
27
28
    private RecyclerView recycler_view;
29
    private StickyHeaderLayout sticky_header_layout;
30
    private CarSeriesGroupedListAdapter adapter;
31
    private ArrayList<CarCompanyEntity> companyList;
32
33
    @Override
34
    protected void onCreate(Bundle savedInstanceState) {
35
        super.onCreate(savedInstanceState);
36
        setContentView(R.layout.activity_car_series);
37
        BarColorUtil.initStatusBarColor(CarSeriesActivity.this);
38
        initViews();
39
    }
40
41
    private void initViews() {
42
        findViewById(R.id.nav_bar).setOnClickListener(this::onClick);
43
        CarCompanyEvent event = EventBus.getDefault().removeStickyEvent(CarCompanyEvent.class);
44
        if (event != null) {
45
            companyList = event.getCompanyList();
46
        }
47
48
        recycler_view = (RecyclerView) findViewById(R.id.recycler_view);
49
        sticky_header_layout = (StickyHeaderLayout) findViewById(R.id.sticky_header_layout);
50
51
        recycler_view.setLayoutManager(new LinearLayoutManager(this));
52
        adapter = new CarSeriesGroupedListAdapter(this, companyList);
53
        adapter.setOnChildClickListener(new GroupedRecyclerViewAdapter.OnChildClickListener() {
54
            @Override
55
            public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition, int childPosition) {
56
                CarSeriesEntity carSeriesEntity = companyList.get(groupPosition).getSerieslist().get(childPosition);
57
                EventBus.getDefault().postSticky(new CarSeriesEvent(carSeriesEntity));
58
                startActivity(new Intent(CarSeriesActivity.this, CarModelActivity.class));
59
            }
60
        });
61
62
        recycler_view.setAdapter(adapter);
63
        // 设置是否吸顶。
64
        sticky_header_layout.setSticky(true);
65
    }
66
67
    @Override
68
    public void onClick(View v) {
69
        switch (v.getId()) {
70
            case R.id.nav_bar:
71
                finish();
72
                break;
73
        }
74
    }
75
}

+ 1 - 1
app/src/main/java/com/electric/chargingpile/activity/RegisterActivity.java

@ -631,7 +631,7 @@ public class RegisterActivity extends Activity implements OnClickListener {
631 631
                        new Handler().postDelayed(new Runnable() {
632 632
                            public void run() {
633 633
                                ActivityManagerApplication.destoryActivity("login");
634
                                startActivity(new Intent(RegisterActivity.this, SkipUserInfoActivity.class));
634
//                                startActivity(new Intent(RegisterActivity.this, SkipUserInfoActivity.class));
635 635
                                finish();
636 636
                            }
637 637
                        }, 1200);

+ 6 - 6
app/src/main/java/com/electric/chargingpile/activity/UserCenterActivity.java

@ -435,9 +435,6 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
435 435
436 436
437 437
        set_loginShow();
438
439
        getCarOwnerCertificateList("init");
440
441 438
    }
442 439
443 440
    private void getSharePrompt(String user_id) {
@ -795,6 +792,7 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
795 792
                    Toast.makeText(getApplication(), "请先登录", Toast.LENGTH_SHORT).show();
796 793
                    startActivity(new Intent(getApplication(), LoginActivity.class));
797 794
                } else {
795
                    loadDialog.show();
798 796
                    getCarOwnerCertificateList("certificate");
799 797
                }
800 798
                break;
@ -803,6 +801,7 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
803 801
                    Toast.makeText(getApplication(), "请先登录", Toast.LENGTH_SHORT).show();
804 802
                    startActivity(new Intent(getApplication(), LoginActivity.class));
805 803
                } else {
804
                    loadDialog.show();
806 805
                    getCarOwnerCertificateList("price");
807 806
                }
808 807
                break;
@ -1065,11 +1064,11 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
1065 1064
    }
1066 1065
1067 1066
    private void getCarOwnerCertificateList(String from) {
1068
        loadDialog.show();
1069 1067
        long tokenTime = System.currentTimeMillis() / 1000 - MainMapActivity.cha - 1;
1070 1068
        String token = null;
1071 1069
        try {
1072 1070
            token = DES3.encode(String.valueOf(tokenTime));
1071
            token = URLEncoder.encode(token, "UTF-8");
1073 1072
        } catch (Exception e) {
1074 1073
            e.printStackTrace();
1075 1074
        }
@ -1176,8 +1175,9 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
1176 1175
                userIcon.setImageResource(R.drawable.icon_face2_0);
1177 1176
            }
1178 1177
        }
1179
1180
1178
        if (MainApplication.isLogin()) {
1179
            getCarOwnerCertificateList("init");
1180
        }
1181 1181
    }
1182 1182
1183 1183

+ 19 - 4
app/src/main/java/com/electric/chargingpile/activity/UserInfoActivity.java

@ -86,6 +86,7 @@ import java.io.ByteArrayOutputStream;
86 86
import java.io.File;
87 87
import java.io.FileOutputStream;
88 88
import java.io.IOException;
89
import java.net.URLEncoder;
89 90
import java.util.ArrayList;
90 91
import java.util.HashMap;
91 92
import java.util.List;
@ -243,6 +244,12 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
243 244
        go_title = findViewById(R.id.go_title);
244 245
        go_desc = findViewById(R.id.go_desc);
245 246
        go_cursor = findViewById(R.id.go_cursor);
247
248
        TextView phone = findViewById(R.id.phone);
249
        String userPhone = MainApplication.userPhone;
250
        if (userPhone.length() == 11) {
251
            phone.setText(userPhone.substring(0, 3) + "****" + userPhone.substring(7, userPhone.length()));
252
        }
246 253
    }
247 254
248 255
    private void setIcon() {
@ -258,12 +265,10 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
258 265
259 266
                        @Override
260 267
                        public void onBitmapFailed(Drawable drawable) {
261
262 268
                        }
263 269
264 270
                        @Override
265 271
                        public void onPrepareLoad(Drawable drawable) {
266
267 272
                        }
268 273
                    });
269 274
        } else {
@ -1053,7 +1058,17 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
1053 1058
        if (showLoading) {
1054 1059
            loadDialog.show();
1055 1060
        }
1056
        String url = MainApplication.url + "/zhannew/basic/web/index.php/car/my?userid=" + MainApplication.userId;
1061
1062
        long tokenTime = System.currentTimeMillis() / 1000 - MainMapActivity.cha - 1;
1063
        String token = null;
1064
        try {
1065
            token = DES3.encode(String.valueOf(tokenTime));
1066
            token = URLEncoder.encode(token, "UTF-8");
1067
        } catch (Exception e) {
1068
            e.printStackTrace();
1069
        }
1070
1071
        String url = MainApplication.url + "/zhannew/basic/web/index.php/car/my?userid=" + MainApplication.userId + "&token=" + token;
1057 1072
        OkHttpUtils.get().url(url).build().connTimeOut(6000).readTimeOut(6000).execute(new StringCallback() {
1058 1073
            @Override
1059 1074
            public void onError(Call call, Exception e) {
@ -1104,7 +1119,7 @@ public class UserInfoActivity extends Activity implements View.OnClickListener,
1104 1119
                        go_cursor.setVisibility(View.VISIBLE);
1105 1120
                    }
1106 1121
1107
                    if (certificateStatus == 1) {
1122
                    if (certificateStatus == 1 && showLoading) {
1108 1123
                        startActivity(new Intent(getApplication(), CarOwnerCertificateActivity.class));
1109 1124
                    }
1110 1125

+ 11 - 2
app/src/main/java/com/electric/chargingpile/adapter/CarBrandGroupedListAdapter.java

@ -1,14 +1,18 @@
1 1
package com.electric.chargingpile.adapter;
2 2
3 3
import android.content.Context;
4
import android.graphics.Bitmap;
4 5
import android.view.LayoutInflater;
5 6
import android.view.View;
6 7
import android.view.ViewGroup;
7 8
import android.widget.Button;
8 9
import android.widget.ImageView;
9 10
11
import androidx.annotation.Nullable;
12
10 13
import com.bumptech.glide.Glide;
11 14
import com.bumptech.glide.load.engine.DiskCacheStrategy;
15
import com.bumptech.glide.request.target.ImageViewTarget;
12 16
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
13 17
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
14 18
import com.electric.chargingpile.R;
@ -92,7 +96,12 @@ public class CarBrandGroupedListAdapter extends GroupedRecyclerViewAdapter {
92 96
            holder.setVisible(R.id.line, View.VISIBLE);
93 97
        }
94 98
        ImageView icon = holder.getImageView(R.id.icon);
95
        final float scale = mContext.getResources().getDisplayMetrics().density;
96
        Glide.with(mContext).load(entity.getIcon()).placeholder(android.R.color.white).dontAnimate().override((int)(40*scale), (int)(40*scale)).fitCenter().into(icon);
99
        try {
100
            String[] imgNames = entity.getIcon().split("!w");
101
            imgNames[1] = imgNames[1].replace("480", "144");
102
            Glide.with(mContext).load(imgNames[0] + "!w" + imgNames[1]).placeholder(android.R.color.white).dontAnimate().diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(icon);
103
        } catch (Exception e) {
104
            e.printStackTrace();
105
        }
97 106
    }
98 107
}

+ 20 - 12
app/src/main/java/com/electric/chargingpile/adapter/CarModelGroupedListAdapter.java

@ -11,16 +11,20 @@ import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
11 11
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
12 12
import com.electric.chargingpile.R;
13 13
import com.electric.chargingpile.entity.CarCompanyEntity;
14
import com.electric.chargingpile.entity.CarModelChildEntity;
15
import com.electric.chargingpile.entity.CarModelGroupEntity;
14 16
import com.electric.chargingpile.entity.CarSeriesEntity;
15 17
16 18
import java.util.ArrayList;
17 19
18 20
public class CarModelGroupedListAdapter extends GroupedRecyclerViewAdapter {
19
    protected ArrayList<CarCompanyEntity> groups;
21
    protected ArrayList<CarModelGroupEntity> groups;
22
    private String masterPic = "";
20 23
21
    public CarModelGroupedListAdapter(Context context, ArrayList<CarCompanyEntity> groups) {
24
    public CarModelGroupedListAdapter(Context context, ArrayList<CarModelGroupEntity> groups, String masterPic) {
22 25
        super(context);
23 26
        this.groups = groups;
27
        this.masterPic = masterPic;
24 28
    }
25 29
26 30
    public void clear() {
@ -28,7 +32,7 @@ public class CarModelGroupedListAdapter extends GroupedRecyclerViewAdapter {
28 32
        notifyDataChanged();
29 33
    }
30 34
31
    public void setGroups(ArrayList<CarCompanyEntity> groups) {
35
    public void setGroups(ArrayList<CarModelGroupEntity> groups) {
32 36
        this.groups = groups;
33 37
        notifyDataChanged();
34 38
    }
@ -40,7 +44,7 @@ public class CarModelGroupedListAdapter extends GroupedRecyclerViewAdapter {
40 44
41 45
    @Override
42 46
    public int getChildrenCount(int groupPosition) {
43
        ArrayList<CarSeriesEntity> children = groups.get(groupPosition).getSerieslist();
47
        ArrayList<CarModelChildEntity> children = groups.get(groupPosition).getList();
44 48
        return children == null ? 0 : children.size();
45 49
    }
46 50
@ -71,8 +75,8 @@ public class CarModelGroupedListAdapter extends GroupedRecyclerViewAdapter {
71 75
72 76
    @Override
73 77
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
74
        CarCompanyEntity entity = groups.get(groupPosition);
75
        holder.setText(R.id.title, entity.getCompanyName());
78
        CarModelGroupEntity entity = groups.get(groupPosition);
79
        holder.setText(R.id.title, entity.getYear());
76 80
    }
77 81
78 82
    @Override
@ -82,17 +86,21 @@ public class CarModelGroupedListAdapter extends GroupedRecyclerViewAdapter {
82 86
83 87
    @Override
84 88
    public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
85
        CarSeriesEntity entity = groups.get(groupPosition).getSerieslist().get(childPosition);
86
        holder.setText(R.id.title, entity.getSeriesName());
89
        CarModelChildEntity entity = groups.get(groupPosition).getList().get(childPosition);
90
        holder.setText(R.id.model_name, entity.getModelName());
87 91
        if (childPosition == 0) {
88 92
            holder.setVisible(R.id.line, View.GONE);
89 93
        } else {
90 94
            holder.setVisible(R.id.line, View.VISIBLE);
91 95
        }
92 96
        ImageView master_pic = holder.getImageView(R.id.master_pic);
93
        final float scale = mContext.getResources().getDisplayMetrics().density;
94
        Glide.with(mContext).load(entity.getMasterPic()).placeholder(android.R.color.white).dontAnimate().override((int)(scale*120), (int)(scale*80)).diskCacheStrategy(DiskCacheStrategy.RESOURCE).fitCenter().into(master_pic);
95
        holder.setText(R.id.sale_price, entity.getSalePrice());
96
    }
97 97
98
        try {
99
            String[] imgNames = masterPic.split("!w");
100
            imgNames[1] = imgNames[1].replace("480", "240");
101
            Glide.with(mContext).load(imgNames[0] + "!w" + imgNames[1]).placeholder(android.R.color.white).dontAnimate().diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(master_pic);
102
        } catch (Exception e) {
103
            e.printStackTrace();
104
        }
105
    }
98 106
}

+ 16 - 19
app/src/main/java/com/electric/chargingpile/adapter/CarOwnerCertificateListAdapter.java

@ -14,8 +14,11 @@ import androidx.annotation.NonNull;
14 14
import androidx.recyclerview.widget.RecyclerView;
15 15
16 16
import com.bumptech.glide.Glide;
17
import com.bumptech.glide.load.engine.DiskCacheStrategy;
17 18
import com.electric.chargingpile.R;
19
import com.electric.chargingpile.activity.CarOwnerCertificateActivity;
18 20
import com.electric.chargingpile.data.CarOwnerCertificateBean;
21
import com.electric.chargingpile.entity.CarModelEntity;
19 22
import com.electric.chargingpile.entity.CarSeriesEntity;
20 23
import com.electric.chargingpile.iview.RecyclerItemTypeClickListener;
21 24
import com.electric.chargingpile.util.DateUtils;
@ -48,10 +51,16 @@ public class CarOwnerCertificateListAdapter extends RecyclerView.Adapter<CarOwne
48 51
    public void onBindViewHolder(@NonNull CarOwnerCertificateListHolder holder, int position) {
49 52
        CarOwnerCertificateBean bean = mList.get(position);
50 53
        Gson gson = new Gson();
51
        CarSeriesEntity carSeriesEntity = gson.fromJson(bean.getChexing(), CarSeriesEntity.class);
52
        Glide.with(mContext).load(carSeriesEntity.getIcon()).into(holder.master_pic);
53
        holder.name.setText(carSeriesEntity.getCompanyName());
54
        holder.detail_name.setText(carSeriesEntity.getSeriesName());
54
        CarModelEntity carModelEntity = gson.fromJson(bean.getChexing(), CarModelEntity.class);
55
        try {
56
            String[] imgNames = carModelEntity.getMasterPic().split("!w");
57
            imgNames[1] = imgNames[1].replace("480", "240");
58
            Glide.with(mContext).load(imgNames[0] + "!w" + imgNames[1]).placeholder(android.R.color.white).dontAnimate().diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(holder.master_pic);
59
        } catch (Exception e) {
60
            e.printStackTrace();
61
        }
62
        holder.name.setText(carModelEntity.getSeriesName());
63
        holder.detail_name.setText(carModelEntity.getModelName());
55 64
56 65
        holder.main.setVisibility(View.GONE);
57 66
        holder.set_main.setVisibility(View.GONE);
@ -104,7 +113,7 @@ public class CarOwnerCertificateListAdapter extends RecyclerView.Adapter<CarOwne
104 113
            @Override
105 114
            public void onClick(View v) {
106 115
                new AlertDialogTwo(mContext).builder()
107
                        .setMsg("是否设置为主车型" + carSeriesEntity.getSeriesName() + "?")
116
                        .setMsg("是否设置为主车型" + carModelEntity.getSeriesName() + " " + carModelEntity.getModelName() + "?")
108 117
                        .setPositiveButton("是", new View.OnClickListener() {
109 118
                            @Override
110 119
                            public void onClick(View v) {
@ -122,7 +131,7 @@ public class CarOwnerCertificateListAdapter extends RecyclerView.Adapter<CarOwne
122 131
            @Override
123 132
            public void onClick(View v) {
124 133
                new AlertDialogTwo(mContext).builder()
125
                        .setMsg("是否删除" + carSeriesEntity.getSeriesName() + "?")
134
                        .setMsg("是否删除" + carModelEntity.getSeriesName() + " " + carModelEntity.getModelName() + "?")
126 135
                        .setPositiveButton("是", new View.OnClickListener() {
127 136
                            @Override
128 137
                            public void onClick(View v) {
@ -139,19 +148,7 @@ public class CarOwnerCertificateListAdapter extends RecyclerView.Adapter<CarOwne
139 148
        holder.edit.setOnClickListener(new View.OnClickListener() {
140 149
            @Override
141 150
            public void onClick(View v) {
142
                new AlertDialogTwo(mContext).builder()
143
                        .setMsg("是否编辑" + carSeriesEntity.getSeriesName() + "?")
144
                        .setPositiveButton("是", new View.OnClickListener() {
145
                            @Override
146
                            public void onClick(View v) {
147
                                recyclerItemTypeClickListener.onItemClickListener(position, 2);
148
                            }
149
                        }).setNegativeButton("否", new View.OnClickListener() {
150
                    @Override
151
                    public void onClick(View v) {
152
153
                    }
154
                }).show();
151
                recyclerItemTypeClickListener.onItemClickListener(position, 2);
155 152
            }
156 153
        });
157 154
    }

+ 97 - 0
app/src/main/java/com/electric/chargingpile/adapter/CarSeriesGroupedListAdapter.java

@ -0,0 +1,97 @@
1
package com.electric.chargingpile.adapter;
2
3
import android.content.Context;
4
import android.view.View;
5
import android.widget.ImageView;
6
7
import com.bumptech.glide.Glide;
8
import com.bumptech.glide.load.engine.DiskCacheStrategy;
9
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
10
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
11
import com.electric.chargingpile.R;
12
import com.electric.chargingpile.entity.CarCompanyEntity;
13
import com.electric.chargingpile.entity.CarSeriesEntity;
14
15
import java.util.ArrayList;
16
17
public class CarSeriesGroupedListAdapter extends GroupedRecyclerViewAdapter {
18
    protected ArrayList<CarCompanyEntity> groups;
19
20
    public CarSeriesGroupedListAdapter(Context context, ArrayList<CarCompanyEntity> groups) {
21
        super(context);
22
        this.groups = groups;
23
    }
24
25
    public void clear() {
26
        groups.clear();
27
        notifyDataChanged();
28
    }
29
30
    public void setGroups(ArrayList<CarCompanyEntity> groups) {
31
        this.groups = groups;
32
        notifyDataChanged();
33
    }
34
35
    @Override
36
    public int getGroupCount() {
37
        return groups == null ? 0 : groups.size();
38
    }
39
40
    @Override
41
    public int getChildrenCount(int groupPosition) {
42
        ArrayList<CarSeriesEntity> children = groups.get(groupPosition).getSerieslist();
43
        return children == null ? 0 : children.size();
44
    }
45
46
    @Override
47
    public boolean hasHeader(int groupPosition) {
48
        return true;
49
    }
50
51
    @Override
52
    public boolean hasFooter(int groupPosition) {
53
        return false;
54
    }
55
56
    @Override
57
    public int getHeaderLayout(int viewType) {
58
        return R.layout.adapter_header_car_series;
59
    }
60
61
    @Override
62
    public int getFooterLayout(int viewType) {
63
        return 0;
64
    }
65
66
    @Override
67
    public int getChildLayout(int viewType) {
68
        return R.layout.adapter_child_car_series;
69
    }
70
71
    @Override
72
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
73
        CarCompanyEntity entity = groups.get(groupPosition);
74
        holder.setText(R.id.title, entity.getCompanyName());
75
    }
76
77
    @Override
78
    public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {
79
80
    }
81
82
    @Override
83
    public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
84
        CarSeriesEntity entity = groups.get(groupPosition).getSerieslist().get(childPosition);
85
        holder.setText(R.id.title, entity.getSeriesName());
86
        if (childPosition == 0) {
87
            holder.setVisible(R.id.line, View.GONE);
88
        } else {
89
            holder.setVisible(R.id.line, View.VISIBLE);
90
        }
91
        ImageView master_pic = holder.getImageView(R.id.master_pic);
92
        final float scale = mContext.getResources().getDisplayMetrics().density;
93
//        Glide.with(mContext).load(entity.getMasterPic()).placeholder(android.R.color.white).dontAnimate().override(216, 144).diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(master_pic);
94
        Glide.with(mContext).load(entity.getMasterPic().replace("480", "144")).diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(master_pic);
95
        holder.setText(R.id.sale_price, entity.getSalePrice());
96
    }
97
}

+ 9 - 2
app/src/main/java/com/electric/chargingpile/adapter/ZhanCommentsAapter.java

@ -136,6 +136,7 @@ public class ZhanCommentsAapter extends BaseAdapter {
136 136
            holder.lv_scomment = (ListView) convertView.findViewById(R.id.lv_scomment);
137 137
138 138
            holder.iv_picon = (ImageView) convertView.findViewById(R.id.iv_picon);
139
            holder.certified_icon = (ImageView)convertView.findViewById(R.id.certified_icon);
139 140
            holder.iv_pgrade = (ImageView) convertView.findViewById(R.id.iv_pgrade);
140 141
            holder.iv_commentPic = (ImageView) convertView.findViewById(R.id.iv_commentPic);
141 142
            holder.iv_level_img = (ImageView) convertView.findViewById(R.id.iv_level_img);
@ -237,8 +238,14 @@ public class ZhanCommentsAapter extends BaseAdapter {
237 238
                holder.tv_ptime.setText(TimeStamp2Date(datas.get(position).getString("addtime"), "yyyy-MM-dd"));
238 239
                //父级评论人车型
239 240
                String chexing = datas.get(position).getString("hascar");
240
241
                int isCertifiedOwner = datas.get(position).getInt("is_certified_owner");
241 242
                holder.tv_pcar.setText(CarTypeUtil.getCarType(chexing));
243
//                holder.tv_pcar.setText(carSeries);
244
                if (isCertifiedOwner == 1) {
245
                    holder.certified_icon.setVisibility(View.VISIBLE);
246
                } else {
247
                    holder.certified_icon.setVisibility(View.GONE);
248
                }
242 249
243 250
                //父级回复
244 251
                holder.tv_preply.setOnClickListener(new View.OnClickListener() {
@ -518,7 +525,7 @@ public class ZhanCommentsAapter extends BaseAdapter {
518 525
519 526
    private class ViewHolder {
520 527
        TextView tv_pdelete, tv_pname, tv_sname, tv_ptime, tv_stime, tv_pcontext, tv_scontext, tv_preply, tv_pcar, tv_more, tv_pzan;
521
        ImageView iv_picon;
528
        ImageView iv_picon, certified_icon;
522 529
        LinearLayout ll_pzan;
523 530
        ImageView iv_havemessage, iv_commentPic;
524 531
        ImageView iv_pgrade, iv_pzan, iv_level_img;

+ 10 - 8
app/src/main/java/com/electric/chargingpile/entity/CarCompanyEntity.java

@ -8,14 +8,6 @@ public class CarCompanyEntity {
8 8
    private int brandId;
9 9
    private ArrayList<CarSeriesEntity> serieslist;
10 10
11
    public CarCompanyEntity(int companyId, String companyName, int brandId, ArrayList<CarSeriesEntity> serieslist) {
12
        this.companyId = companyId;
13
        this.companyName = companyName;
14
        this.brandId = brandId;
15
        this.serieslist = serieslist;
16
    }
17
18
19 11
    public int getCompanyId() {
20 12
        return companyId;
21 13
    }
@ -47,4 +39,14 @@ public class CarCompanyEntity {
47 39
    public void setSerieslist(ArrayList<CarSeriesEntity> serieslist) {
48 40
        this.serieslist = serieslist;
49 41
    }
42
43
    @Override
44
    public String toString() {
45
        return "CarCompanyEntity{" +
46
                "companyId=" + companyId +
47
                ", companyName='" + companyName + '\'' +
48
                ", brandId=" + brandId +
49
                ", serieslist=" + serieslist +
50
                '}';
51
    }
50 52
}

+ 30 - 0
app/src/main/java/com/electric/chargingpile/entity/CarModelChildEntity.java

@ -0,0 +1,30 @@
1
package com.electric.chargingpile.entity;
2
3
public class CarModelChildEntity {
4
    private int modelId;
5
    private String modelName;
6
7
    public int getModelId() {
8
        return modelId;
9
    }
10
11
    public void setModelId(int modelId) {
12
        this.modelId = modelId;
13
    }
14
15
    public String getModelName() {
16
        return modelName;
17
    }
18
19
    public void setModelName(String modelName) {
20
        this.modelName = modelName;
21
    }
22
23
    @Override
24
    public String toString() {
25
        return "CarModelEntity{" +
26
                "modelId=" + modelId +
27
                ", modelName='" + modelName + '\'' +
28
                '}';
29
    }
30
}

+ 141 - 0
app/src/main/java/com/electric/chargingpile/entity/CarModelEntity.java

@ -0,0 +1,141 @@
1
package com.electric.chargingpile.entity;
2
3
public class CarModelEntity {
4
    private String brandId;
5
    private String brandName;
6
    private String companyId;
7
    private String companyName;
8
    private String seriesId;
9
    private String seriesName;
10
    private String salePrice;
11
    private String icon;
12
    private String masterPic;
13
    private String maxSalePrice;
14
    private String minSalePrice;
15
16
    private int modelId;
17
    private String modelName;
18
19
    public String getBrandId() {
20
        return brandId;
21
    }
22
23
    public void setBrandId(String brandId) {
24
        this.brandId = brandId;
25
    }
26
27
    public String getBrandName() {
28
        return brandName;
29
    }
30
31
    public void setBrandName(String brandName) {
32
        this.brandName = brandName;
33
    }
34
35
    public String getCompanyId() {
36
        return companyId;
37
    }
38
39
    public void setCompanyId(String companyId) {
40
        this.companyId = companyId;
41
    }
42
43
    public String getCompanyName() {
44
        return companyName;
45
    }
46
47
    public void setCompanyName(String companyName) {
48
        this.companyName = companyName;
49
    }
50
51
    public String getSeriesId() {
52
        return seriesId;
53
    }
54
55
    public void setSeriesId(String seriesId) {
56
        this.seriesId = seriesId;
57
    }
58
59
    public String getSeriesName() {
60
        return seriesName;
61
    }
62
63
    public void setSeriesName(String seriesName) {
64
        this.seriesName = seriesName;
65
    }
66
67
    public String getSalePrice() {
68
        return salePrice;
69
    }
70
71
    public void setSalePrice(String salePrice) {
72
        this.salePrice = salePrice;
73
    }
74
75
    public String getIcon() {
76
        return icon;
77
    }
78
79
    public void setIcon(String icon) {
80
        this.icon = icon;
81
    }
82
83
    public String getMasterPic() {
84
        return masterPic;
85
    }
86
87
    public void setMasterPic(String masterPic) {
88
        this.masterPic = masterPic;
89
    }
90
91
    public String getMaxSalePrice() {
92
        return maxSalePrice;
93
    }
94
95
    public void setMaxSalePrice(String maxSalePrice) {
96
        this.maxSalePrice = maxSalePrice;
97
    }
98
99
    public String getMinSalePrice() {
100
        return minSalePrice;
101
    }
102
103
    public void setMinSalePrice(String minSalePrice) {
104
        this.minSalePrice = minSalePrice;
105
    }
106
107
    public int getModelId() {
108
        return modelId;
109
    }
110
111
    public void setModelId(int modelId) {
112
        this.modelId = modelId;
113
    }
114
115
    public String getModelName() {
116
        return modelName;
117
    }
118
119
    public void setModelName(String modelName) {
120
        this.modelName = modelName;
121
    }
122
123
    @Override
124
    public String toString() {
125
        return "CarModelEntity{" +
126
                "brandId='" + brandId + '\'' +
127
                ", brandName='" + brandName + '\'' +
128
                ", companyId='" + companyId + '\'' +
129
                ", companyName='" + companyName + '\'' +
130
                ", seriesId='" + seriesId + '\'' +
131
                ", seriesName='" + seriesName + '\'' +
132
                ", salePrice='" + salePrice + '\'' +
133
                ", icon='" + icon + '\'' +
134
                ", masterPic='" + masterPic + '\'' +
135
                ", maxSalePrice='" + maxSalePrice + '\'' +
136
                ", minSalePrice='" + minSalePrice + '\'' +
137
                ", modelId=" + modelId +
138
                ", modelName='" + modelName + '\'' +
139
                '}';
140
    }
141
}

+ 32 - 0
app/src/main/java/com/electric/chargingpile/entity/CarModelGroupEntity.java

@ -0,0 +1,32 @@
1
package com.electric.chargingpile.entity;
2
3
import java.util.ArrayList;
4
5
public class CarModelGroupEntity {
6
    private String year;
7
    private ArrayList<CarModelChildEntity> list;
8
9
    public String getYear() {
10
        return year;
11
    }
12
13
    public void setYear(String year) {
14
        this.year = year;
15
    }
16
17
    public ArrayList<CarModelChildEntity> getList() {
18
        return list;
19
    }
20
21
    public void setList(ArrayList<CarModelChildEntity> list) {
22
        this.list = list;
23
    }
24
25
    @Override
26
    public String toString() {
27
        return "CarModelGroupEntity{" +
28
                "year='" + year + '\'' +
29
                ", list=" + list +
30
                '}';
31
    }
32
}

+ 19 - 0
app/src/main/java/com/electric/chargingpile/event/CarModelEvent.java

@ -0,0 +1,19 @@
1
package com.electric.chargingpile.event;
2
3
import com.electric.chargingpile.entity.CarModelEntity;
4
5
public class CarModelEvent {
6
    private CarModelEntity carModelEntity;
7
8
    public CarModelEvent(CarModelEntity carModelEntity) {
9
        this.carModelEntity = carModelEntity;
10
    }
11
12
    public CarModelEntity getCarModelEntity() {
13
        return carModelEntity;
14
    }
15
16
    public void setCarModelEntity(CarModelEntity carModelEntity) {
17
        this.carModelEntity = carModelEntity;
18
    }
19
}

+ 2 - 2
app/src/main/java/com/electric/chargingpile/event/CarSerieEvent.java

@ -2,10 +2,10 @@ package com.electric.chargingpile.event;
2 2
3 3
import com.electric.chargingpile.entity.CarSeriesEntity;
4 4
5
public class CarSerieEvent {
5
public class CarSeriesEvent {
6 6
    private CarSeriesEntity carSeriesEntity;
7 7
8
    public CarSerieEvent(CarSeriesEntity carSeriesEntity) {
8
    public CarSeriesEvent(CarSeriesEntity carSeriesEntity) {
9 9
        this.carSeriesEntity = carSeriesEntity;
10 10
    }
11 11

+ 0 - 29
app/src/main/java/com/electric/chargingpile/fragment/ZhanCommentFragment.java

@ -285,8 +285,6 @@ public class ZhanCommentFragment extends Fragment {
285 285
286 286
    public void getCommentsData() {
287 287
        String url = MainApplication.url + "/zhannew/basic/web/index.php/tpappcomments/get-comments?zhanid=" + NewZhanDetailsActivity.zhan_id + "&page=1";
288
//        String url = MainApplication.url+"/zhannew/basic/web/index.php/tpappcomments/get-comments?zhanid=" + NewZhanDetailsActivity.zhan_id + "&page=1";
289
//        Log.e(TAG, "getCommentsData=" + url);
290 288
        OkHttpUtils.get().url(url)
291 289
                .build().connTimeOut(6000).readTimeOut(6000)
292 290
                .execute(new StringCallback() {
@ -297,19 +295,16 @@ public class ZhanCommentFragment extends Fragment {
297 295
298 296
                    @Override
299 297
                    public void onResponse(String response) {
300
//                        Log.e(TAG, "response=" + response);
301 298
                        String rtnCode = JsonUtils.getKeyResult(response, "rtnCode");
302 299
                        if (null != rtnCode && rtnCode.equals("01")) {
303 300
                            try {
304 301
                                JSONObject jsonObj = new JSONObject(response);
305 302
                                String commentData = jsonObj.getString("data");
306 303
                                JSONArray jsonArray = new JSONArray(commentData);
307
//                                datas.clear();
308 304
                                for (int j = 0; j < jsonArray.length(); j++) {
309 305
                                    JSONObject jsonObject = (JSONObject) jsonArray.opt(j);
310 306
                                    datas.add(jsonObject);
311 307
                                }
312
//                                Log.e(TAG, "dealData: size=" + datas.size());
313 308
                                if (datas.size() == 0) {
314 309
                                    ll_tishi.setVisibility(View.VISIBLE);
315 310
                                    lv_comment.setVisibility(View.GONE);
@ -324,7 +319,6 @@ public class ZhanCommentFragment extends Fragment {
324 319
                                e.printStackTrace();
325 320
                            }
326 321
                        } else {
327
//                            Log.e(TAG, "error");
328 322
                        }
329 323
                    }
330 324
                });
@ -332,8 +326,6 @@ public class ZhanCommentFragment extends Fragment {
332 326
333 327
    private void getPullToRefreshData(final boolean isClear) {
334 328
        String url = MainApplication.url + "/zhannew/basic/web/index.php/tpappcomments/get-comments?zhanid=" + NewZhanDetailsActivity.zhan_id + "&page=" + index;
335
//        String url = MainApplication.url+"/zhannew/basic/web/index.php/tpappcomments/get-comments?zhanid=" + NewZhanDetailsActivity.zhan_id + "&page=1";
336
//        Log.e(TAG, "getPullToRefreshData=" + url);
337 329
        OkHttpUtils.get().url(url)
338 330
                .build().connTimeOut(6000).readTimeOut(6000)
339 331
                .execute(new StringCallback() {
@ -344,7 +336,6 @@ public class ZhanCommentFragment extends Fragment {
344 336
345 337
                    @Override
346 338
                    public void onResponse(String response) {
347
//                        Log.e(TAG, "response=" + response);
348 339
                        String rtnCode = JsonUtils.getKeyResult(response, "rtnCode");
349 340
                        if (null != rtnCode && rtnCode.equals("01")) {
350 341
//                            Gson gson = new Gson();
@ -360,7 +351,6 @@ public class ZhanCommentFragment extends Fragment {
360 351
                                if (isClear == true) {
361 352
                                    datas.clear();
362 353
                                }
363
//                                Log.e(TAG,"datas.size="+datas.size()+"");
364 354
365 355
                                for (int j = 0; j < jsonArray.length(); j++) {
366 356
                                    JSONObject jsonObject = (JSONObject) jsonArray.opt(j);
@ -372,15 +362,12 @@ public class ZhanCommentFragment extends Fragment {
372 362
                                        Toast.makeText(MainApplication.context, "已经全部加载完毕", Toast.LENGTH_SHORT).show();
373 363
                                    }
374 364
                                }
375
//                                Log.e(TAG, "dealData: size=" + datas.size());
376 365
                                if (datas.size() == 0) {
377 366
                                    ll_tishi.setVisibility(View.VISIBLE);
378 367
                                    lv_comment.setVisibility(View.GONE);
379
//                                    tv_tips.setVisibility(View.GONE);
380 368
                                } else {
381 369
                                    ll_tishi.setVisibility(View.GONE);
382 370
                                    lv_comment.setVisibility(View.VISIBLE);
383
//                                    tv_tips.setVisibility(View.VISIBLE);
384 371
                                }
385 372
386 373
                                if (null != datas) {
@ -390,7 +377,6 @@ public class ZhanCommentFragment extends Fragment {
390 377
                                        adapter.changeData(datas);
391 378
                                    }
392 379
                                }
393
//                                adapter = new ZhanCommentsAapter(datas, getActivity(), mContext);
394 380
                                lv_comment.setAdapter(adapter);
395 381
396 382
                                adapter.notifyDataSetChanged();
@ -405,7 +391,6 @@ public class ZhanCommentFragment extends Fragment {
405 391
                            }
406 392
407 393
                        } else {
408
//                            Log.e(TAG, "error");
409 394
                        }
410 395
                    }
411 396
                });
@ -416,8 +401,6 @@ public class ZhanCommentFragment extends Fragment {
416 401
        Gson gson = new Gson();
417 402
        PCommentBean pCommentBean = (PCommentBean) gson.fromJson(data, PCommentBean.class);
418 403
        List<PCommentBean.DataBean> list = pCommentBean.getData();
419
//        Log.e(TAG, "list==="+list.size() );
420
421 404
422 405
        JSONObject jsonObj = new JSONObject(data);
423 406
        String commentData = jsonObj.getString("data");
@ -427,7 +410,6 @@ public class ZhanCommentFragment extends Fragment {
427 410
            JSONObject jsonObject = (JSONObject) jsonArray.opt(j);
428 411
            datas.add(jsonObject);
429 412
        }
430
//        Log.e(TAG, "dealData: size=" + datas.size());
431 413
        if (datas.size() == 0) {
432 414
            ll_tishi.setVisibility(View.VISIBLE);
433 415
            lv_comment.setVisibility(View.GONE);
@ -435,8 +417,6 @@ public class ZhanCommentFragment extends Fragment {
435 417
            ll_tishi.setVisibility(View.GONE);
436 418
            lv_comment.setVisibility(View.VISIBLE);
437 419
        }
438
439
440 420
    }
441 421
442 422
@ -444,8 +424,6 @@ public class ZhanCommentFragment extends Fragment {
444 424
    public void setUserVisibleHint(boolean isVisibleToUser) {
445 425
        super.setUserVisibleHint(isVisibleToUser);
446 426
        if (isVisibleToUser) {
447
//            Log.e("123","123");
448
//            getCommentsData(null);
449 427
        }
450 428
    }
451 429
@ -462,7 +440,6 @@ public class ZhanCommentFragment extends Fragment {
462 440
463 441
464 442
    private void addItemToFloatLayout(QMUIFloatLayout floatLayout, CommentTag commentTag) {
465
//        int currentChildCount = floatLayout.getChildCount();
466 443
467 444
        TextView textView = new TextView(getActivity());
468 445
@ -471,7 +448,6 @@ public class ZhanCommentFragment extends Fragment {
471 448
        textView.setPadding(textViewHPadding, textViewVPadding, textViewHPadding, textViewVPadding);
472 449
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
473 450
        textView.setTextColor(ContextCompat.getColor(getContext(), R.color.lvse));
474
//        textView.setText(String.valueOf(currentChildCount));
475 451
        textView.setText(commentTag.getName());
476 452
        textView.setBackgroundResource(R.drawable.bg_comment_tag);
477 453
@ -479,10 +455,6 @@ public class ZhanCommentFragment extends Fragment {
479 455
480 456
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, textViewSize);
481 457
        floatLayout.addView(textView, lp);
482
483
484
//        lineHeiht = textView.getMeasuredHeight();
485
//        LogUtils.e(lineHeiht);
486 458
    }
487 459
488 460
    private void removeItemFromFloatLayout(QMUIFloatLayout floatLayout) {
@ -491,5 +463,4 @@ public class ZhanCommentFragment extends Fragment {
491 463
        }
492 464
        floatLayout.removeView(floatLayout.getChildAt(floatLayout.getChildCount() - 1));
493 465
    }
494
495 466
}

+ 2 - 0
app/src/main/java/com/electric/chargingpile/util/CarTypeUtil.java

@ -14,6 +14,8 @@ public class CarTypeUtil {
14 14
        if (strarray.length > 1) {
15 15
            name0 = strarray[0];//江淮
16 16
            name1 = strarray[1];//iEV3
17
        } else {
18
            name0 = strarray[0];
17 19
        }
18 20
        if (chexing.equals("$$") || chexing == null || chexing.equals("") || chexing.equals("null") || chexing.equals("品牌$$车型") || chexing.equals("null$$null")) {
19 21
            car = "";

+ 25 - 8
app/src/main/java/com/electric/chargingpile/view/MyReceiver.java

@ -7,13 +7,18 @@ import android.os.Bundle;
7 7
import android.util.Log;
8 8
9 9
import com.electric.chargingpile.activity.MainActicity;
10
import com.electric.chargingpile.activity.MainMapActivity;
11
import com.electric.chargingpile.activity.MyWebViewActivity;
10 12
import com.electric.chargingpile.activity.WelcomeActivity;
11 13
import com.electric.chargingpile.application.MainApplication;
14
import com.electric.chargingpile.util.DES3;
12 15
import com.electric.chargingpile.util.ExampleUtil;
16
import com.umeng.analytics.MobclickAgent;
13 17
14 18
import org.json.JSONException;
15 19
import org.json.JSONObject;
16 20
21
import java.net.URLEncoder;
17 22
import java.util.Iterator;
18 23
19 24
import cn.jpush.android.api.JPushInterface;
@ -84,14 +89,26 @@ public class MyReceiver extends BroadcastReceiver {
84 89
            }
85 90
//			Log.e("articleUrl:", articleUrl);
86 91
            //打开自定义的Activity
87
            Intent i = new Intent(context, WelcomeActivity.class);
88
            i.putExtras(bundle);
89
            //i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
90
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
91
//			i.putExtra("url","https://www.baidu.com/");
92
//			i.putExtra("tag","5");
93
            context.startActivity(i);
94
92
            if ("PushRedBag".equals(type)) {
93
                long appTime4 = System.currentTimeMillis() / 1000;
94
                long updatetime4 = appTime4 - MainMapActivity.cha - 1;
95
                String token4 = String.valueOf(updatetime4);
96
                Intent intent4 = new Intent(context, MyWebViewActivity.class);
97
                String web1 = null;
98
                try {
99
                    web1 = MainApplication.url + "/zhannew/basic/web/index.php/discount/redlist?userid=" + MainApplication.userId + "&token=" + URLEncoder.encode(DES3.encode(token4));
100
                } catch (Exception e) {
101
                    e.printStackTrace();
102
                }
103
                intent4.putExtra("url", web1);
104
                context.startActivity(intent4);
105
                MobclickAgent.onEvent(context, "0808");
106
            } else {
107
                Intent i = new Intent(context, WelcomeActivity.class);
108
                i.putExtras(bundle);
109
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
110
                context.startActivity(i);
111
            }
95 112
        } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
96 113
            Log.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
97 114
            //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..

BIN
app/src/main/res/drawable-hdpi/certified_icon.png


BIN
app/src/main/res/drawable-mdpi/certified_icon.png


BIN
app/src/main/res/drawable-xhdpi/certified_icon.png


BIN
app/src/main/res/drawable-xxhdpi/certified_icon.png


BIN
app/src/main/res/drawable-xxxhdpi/certified_icon.png


+ 14 - 1
app/src/main/res/layout/activity_car_model.xml

@ -5,7 +5,7 @@
5 5
    android:layout_width="match_parent"
6 6
    android:layout_height="match_parent"
7 7
    android:background="@color/white"
8
    tools:context=".activity.CarModelActivity">
8
    tools:context=".activity.CarSeriesActivity">
9 9
10 10
    <androidx.constraintlayout.widget.ConstraintLayout
11 11
        android:id="@+id/nav_bar"
@ -54,4 +54,17 @@
54 54
            android:layout_width="match_parent"
55 55
            android:layout_height="match_parent" />
56 56
    </com.donkingliang.groupedadapter.widget.StickyHeaderLayout>
57
58
    <TextView
59
        android:id="@+id/no_data"
60
        android:layout_width="match_parent"
61
        android:layout_height="wrap_content"
62
        android:gravity="center"
63
        android:text="暂无车型"
64
        android:textColor="#999999"
65
        android:textSize="14sp"
66
        android:visibility="gone"
67
        app:layout_constraintBottom_toBottomOf="parent"
68
        app:layout_constraintTop_toBottomOf="@+id/nav_bar"
69
        tools:visibility="visible" />
57 70
</androidx.constraintlayout.widget.ConstraintLayout>

+ 17 - 10
app/src/main/res/layout/activity_car_owner_certificate.xml

@ -111,30 +111,37 @@
111 111
                    tools:background="#00ff00" />
112 112
113 113
                <TextView
114
                    android:id="@+id/car_name"
115
                    android:layout_width="wrap_content"
114
                    android:id="@+id/car_series"
115
                    android:layout_width="0dp"
116 116
                    android:layout_height="wrap_content"
117 117
                    android:layout_marginLeft="10dp"
118 118
                    android:layout_marginTop="12dp"
119
                    android:layout_marginRight="15dp"
119 120
                    android:textColor="#FF222222"
120 121
                    android:textSize="14sp"
121 122
                    app:layout_constraintLeft_toRightOf="@+id/car_icon"
123
                    app:layout_constraintRight_toLeftOf="@+id/model_cursor"
122 124
                    app:layout_constraintTop_toTopOf="parent"
123
                    tools:text="蔚来ES6" />
125
                    tools:text="本田 CR-V" />
124 126
125 127
                <TextView
126
                    android:id="@+id/car_series"
127
                    android:layout_width="wrap_content"
128
                    android:id="@+id/car_model"
129
                    android:layout_width="0dp"
128 130
                    android:layout_height="wrap_content"
131
                    android:layout_marginLeft="10dp"
132
                    android:layout_marginTop="5dp"
133
                    android:layout_marginRight="15dp"
129 134
                    android:layout_marginBottom="10dp"
130 135
                    android:textColor="#FF0D1120"
131 136
                    android:textSize="14sp"
132 137
                    app:layout_constraintBottom_toBottomOf="parent"
133
                    app:layout_constraintLeft_toLeftOf="@+id/car_name"
134
138
                    app:layout_constraintLeft_toRightOf="@+id/car_icon"
139
                    app:layout_constraintRight_toLeftOf="@+id/model_cursor"
140
                    app:layout_constraintTop_toBottomOf="@+id/car_series"
135 141
                    tools:text="2020款 420KM 运动版" />
136 142
137 143
                <ImageView
144
                    android:id="@+id/model_cursor"
138 145
                    android:layout_width="wrap_content"
139 146
                    android:layout_height="wrap_content"
140 147
                    android:src="@drawable/icon_right_cursor"
@ -191,11 +198,11 @@
191 198
                android:layout_width="match_parent"
192 199
                android:layout_height="wrap_content"
193 200
                android:layout_marginTop="5dp"
194
                android:visibility="gone"
195
                tools:visibility="visible"
196 201
                android:layout_marginBottom="50dp"
197 202
                android:orientation="vertical"
198
                app:layout_constraintTop_toBottomOf="@+id/driving_license">
203
                android:visibility="gone"
204
                app:layout_constraintTop_toBottomOf="@+id/driving_license"
205
                tools:visibility="visible">
199 206
200 207
                <LinearLayout
201 208
                    android:layout_width="match_parent"

+ 57 - 0
app/src/main/res/layout/activity_car_series.xml

@ -0,0 +1,57 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="match_parent"
7
    android:background="@color/white"
8
    tools:context=".activity.CarSeriesActivity">
9
10
    <androidx.constraintlayout.widget.ConstraintLayout
11
        android:id="@+id/nav_bar"
12
        android:layout_width="match_parent"
13
        android:layout_height="44dp"
14
        app:layout_constraintTop_toTopOf="parent">
15
16
        <TextView
17
            android:id="@+id/nav_title"
18
            android:layout_width="match_parent"
19
            android:layout_height="match_parent"
20
            android:gravity="center"
21
            android:text="车系"
22
            android:textColor="#444444"
23
            android:textSize="18sp" />
24
25
        <ImageView
26
            android:id="@+id/iv_back"
27
            android:layout_width="wrap_content"
28
            android:layout_height="match_parent"
29
            android:layout_alignParentLeft="true"
30
            android:layout_centerVertical="true"
31
            android:contentDescription="@null"
32
            android:paddingLeft="15dp"
33
            android:paddingRight="15dp"
34
            android:src="@drawable/icon_lvback1119"
35
            app:layout_constraintLeft_toLeftOf="parent" />
36
37
        <View
38
            android:layout_width="match_parent"
39
            android:layout_height="0.5dp"
40
            android:background="@color/ui_titleline"
41
            app:layout_constraintBottom_toBottomOf="parent" />
42
    </androidx.constraintlayout.widget.ConstraintLayout>
43
44
    <com.donkingliang.groupedadapter.widget.StickyHeaderLayout
45
        android:id="@+id/sticky_header_layout"
46
        android:layout_width="match_parent"
47
        android:layout_height="0dp"
48
        android:background="#FFF2F6F9"
49
        app:layout_constraintBottom_toBottomOf="parent"
50
        app:layout_constraintTop_toBottomOf="@+id/nav_bar">
51
52
        <androidx.recyclerview.widget.RecyclerView
53
            android:id="@+id/recycler_view"
54
            android:layout_width="match_parent"
55
            android:layout_height="match_parent" />
56
    </com.donkingliang.groupedadapter.widget.StickyHeaderLayout>
57
</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
app/src/main/res/layout/activity_user_center.xml

@ -505,7 +505,7 @@
505 505
                            android:layout_width="wrap_content"
506 506
                            android:layout_height="match_parent"
507 507
                            android:layout_toLeftOf="@+id/iv_certificate_cursor"
508
                            android:text=""
508
                            android:text="认证车主得充电红包"
509 509
                            android:textSize="14sp"
510 510
                            android:gravity="center_vertical"
511 511
                            android:layout_marginRight="12dp"

+ 37 - 0
app/src/main/res/layout/activity_user_info.xml

@ -153,6 +153,43 @@
153 153
                android:background="@color/ui_line"
154 154
                android:visibility="visible" />
155 155
156
            <RelativeLayout
157
                android:layout_width="fill_parent"
158
                android:layout_height="45dp"
159
                android:background="@color/white">
160
161
                <TextView
162
                    android:layout_width="wrap_content"
163
                    android:layout_height="match_parent"
164
                    android:gravity="center"
165
                    android:paddingLeft="15dp"
166
                    android:text="手机号"
167
                    android:textColor="@color/title_row"
168
                    android:textSize="15sp" />
169
170
                <TextView
171
                    android:id="@+id/phone"
172
                    android:layout_width="wrap_content"
173
                    android:layout_height="130px"
174
                    android:layout_alignParentTop="true"
175
                    android:layout_alignParentEnd="true"
176
                    android:layout_alignParentRight="true"
177
                    android:layout_marginEnd="15dp"
178
                    android:layout_marginRight="15dp"
179
                    android:background="@color/white"
180
                    android:gravity="center|right"
181
                    android:textColor="@color/ui_62"
182
                    android:textSize="15sp" />
183
184
            </RelativeLayout>
185
186
            <View
187
                android:layout_width="match_parent"
188
                android:layout_height="0.5dp"
189
                android:layout_marginLeft="15dp"
190
                android:background="@color/ui_line"
191
                android:visibility="visible" />
192
156 193
157 194
            <RelativeLayout
158 195
                android:id="@+id/go_certificate"

+ 7 - 42
app/src/main/res/layout/adapter_child_car_model.xml

@ -4,8 +4,8 @@
4 4
    xmlns:tools="http://schemas.android.com/tools"
5 5
    android:layout_width="match_parent"
6 6
    android:layout_height="100dp"
7
    android:paddingLeft="15dp"
8 7
    android:background="@color/white"
8
    android:paddingLeft="15dp"
9 9
    tools:background="#cccccc">
10 10
11 11
    <View
@ -26,53 +26,18 @@
26 26
        tools:background="#00ff00" />
27 27
28 28
    <TextView
29
        android:id="@+id/title"
30
        android:layout_width="wrap_content"
29
        android:id="@+id/model_name"
30
        android:layout_width="0dp"
31 31
        android:layout_height="wrap_content"
32 32
        android:layout_gravity="center_vertical"
33 33
        android:layout_marginLeft="10dp"
34
        android:layout_marginTop="27dp"
34
        android:layout_marginRight="15dp"
35 35
        android:textColor="#FF222222"
36 36
        android:textSize="14sp"
37
        app:layout_constraintBottom_toBottomOf="parent"
37 38
        app:layout_constraintLeft_toRightOf="@+id/master_pic"
39
        app:layout_constraintRight_toRightOf="parent"
38 40
        app:layout_constraintTop_toTopOf="parent"
39
        tools:text="奥迪" />
40
41
    <LinearLayout
42
        android:layout_width="wrap_content"
43
        android:layout_height="wrap_content"
44
        android:layout_marginLeft="10dp"
45
        android:layout_marginBottom="28dp"
46
        android:orientation="horizontal"
47
        app:layout_constraintBottom_toBottomOf="parent"
48
        app:layout_constraintLeft_toRightOf="@+id/master_pic">
49
50
        <TextView
51
            android:id="@+id/sale_price"
52
            android:layout_width="wrap_content"
53
            android:layout_height="wrap_content"
54
            android:textColor="#FFE02020"
55
            android:textSize="14sp"
56
            tools:text="33.8-52.3" />
57
58
        <TextView
59
            android:id="@+id/price"
60
            android:layout_width="wrap_content"
61
            android:layout_height="wrap_content"
62
            android:layout_gravity="center_vertical"
63
            android:layout_marginLeft="5dp"
64
            android:text="万"
65
            android:textColor="#FF222222"
66
            android:textSize="12sp" />
67
68
        <TextView
69
            android:id="@+id/endurance"
70
            android:layout_width="wrap_content"
71
            android:layout_height="wrap_content"
72
            android:layout_marginLeft="20dp"
73
            android:textColor="#FF222222"
74
            android:textSize="12sp"
75
            tools:text="续航:300km" />
76
    </LinearLayout>
41
        tools:text="2019款 锐·混动 2.0L 两驱净速版 国V" />
77 42
78 43
</androidx.constraintlayout.widget.ConstraintLayout>

+ 78 - 0
app/src/main/res/layout/adapter_child_car_series.xml

@ -0,0 +1,78 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="100dp"
7
    android:paddingLeft="15dp"
8
    android:background="@color/white"
9
    tools:background="#cccccc">
10
11
    <View
12
        android:id="@+id/line"
13
        android:layout_width="match_parent"
14
        android:layout_height="1dp"
15
        android:background="#E6E6E6"
16
        app:layout_constraintTop_toTopOf="parent" />
17
18
    <ImageView
19
        android:id="@+id/master_pic"
20
        android:layout_width="120dp"
21
        android:layout_height="80dp"
22
        android:scaleType="fitCenter"
23
        app:layout_constraintBottom_toBottomOf="parent"
24
        app:layout_constraintLeft_toLeftOf="parent"
25
        app:layout_constraintTop_toTopOf="parent"
26
        tools:background="#00ff00" />
27
28
    <TextView
29
        android:id="@+id/title"
30
        android:layout_width="wrap_content"
31
        android:layout_height="wrap_content"
32
        android:layout_gravity="center_vertical"
33
        android:layout_marginLeft="10dp"
34
        android:layout_marginTop="27dp"
35
        android:textColor="#FF222222"
36
        android:textSize="14sp"
37
        app:layout_constraintLeft_toRightOf="@+id/master_pic"
38
        app:layout_constraintTop_toTopOf="parent"
39
        tools:text="奥迪" />
40
41
    <LinearLayout
42
        android:layout_width="wrap_content"
43
        android:layout_height="wrap_content"
44
        android:layout_marginLeft="10dp"
45
        android:layout_marginBottom="28dp"
46
        android:orientation="horizontal"
47
        app:layout_constraintBottom_toBottomOf="parent"
48
        app:layout_constraintLeft_toRightOf="@+id/master_pic">
49
50
        <TextView
51
            android:id="@+id/sale_price"
52
            android:layout_width="wrap_content"
53
            android:layout_height="wrap_content"
54
            android:textColor="#FFE02020"
55
            android:textSize="14sp"
56
            tools:text="33.8-52.3" />
57
58
        <TextView
59
            android:id="@+id/price"
60
            android:layout_width="wrap_content"
61
            android:layout_height="wrap_content"
62
            android:layout_gravity="center_vertical"
63
            android:layout_marginLeft="5dp"
64
            android:text="万"
65
            android:textColor="#FF222222"
66
            android:textSize="12sp" />
67
68
        <TextView
69
            android:id="@+id/endurance"
70
            android:layout_width="wrap_content"
71
            android:layout_height="wrap_content"
72
            android:layout_marginLeft="20dp"
73
            android:textColor="#FF222222"
74
            android:textSize="12sp"
75
            tools:text="续航:300km" />
76
    </LinearLayout>
77
78
</androidx.constraintlayout.widget.ConstraintLayout>

+ 19 - 0
app/src/main/res/layout/adapter_header_car_series.xml

@ -0,0 +1,19 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:tools="http://schemas.android.com/tools"
4
    android:layout_width="match_parent"
5
    android:layout_height="25dp"
6
    android:background="#FFF2F6F9"
7
    android:paddingLeft="15dp"
8
    android:paddingRight="15dp">
9
    
10
    <TextView
11
        android:id="@+id/title"
12
        android:layout_width="match_parent"
13
        android:layout_height="match_parent"
14
        android:gravity="center_vertical"
15
        android:lines="1"
16
        android:textColor="#FF6F6F7D"
17
        android:textSize="12sp"
18
        tools:text="A" />
19
</LinearLayout>

+ 131 - 306
app/src/main/res/layout/item_zhancomments.xml

@ -1,10 +1,10 @@
1 1
<?xml version="1.0" encoding="utf-8"?>
2 2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
3 4
    xmlns:zhy="http://schemas.android.com/tools"
4 5
    android:id="@+id/ll_zhan_comments"
5 6
    android:layout_width="match_parent"
6 7
    android:layout_height="match_parent"
7
    xmlns:app="http://schemas.android.com/apk/res-auto"
8 8
    android:background="@color/bg_row"
9 9
    android:orientation="vertical">
10 10
@ -18,89 +18,99 @@
18 18
            android:id="@+id/rl_icon"
19 19
            android:layout_width="35dp"
20 20
            android:layout_height="35dp"
21
            android:layout_alignParentTop="true"
22
            android:layout_alignParentLeft="true"
23 21
            android:layout_alignParentStart="true"
24
            android:layout_marginTop="12dp"
22
            android:layout_alignParentLeft="true"
23
            android:layout_alignParentTop="true"
24
            android:layout_gravity="center_vertical"
25 25
            android:layout_marginLeft="15dp"
26
            android:layout_gravity="center_vertical">
26
            android:layout_marginTop="12dp">
27 27
28 28
            <ImageView
29
                android:id="@+id/iv_picon"
29 30
                android:layout_width="35dp"
30 31
                android:layout_height="35dp"
31
                android:id="@+id/iv_picon"
32
                android:src="@drawable/icon_touxiang0128"/>
32
                android:src="@drawable/icon_touxiang0128" />
33 33
34 34
            <ImageView
35 35
                android:id="@+id/iv_level_img"
36 36
                android:layout_width="15dp"
37 37
                android:layout_height="15dp"
38
                android:layout_alignParentBottom="true"
39
                android:layout_alignParentRight="true"/>
38
                android:layout_alignParentRight="true"
39
                android:layout_alignParentBottom="true" />
40 40
41 41
42 42
        </RelativeLayout>
43 43
44 44
45
46 45
        <TextView
46
            android:id="@+id/tv_pname"
47 47
            android:layout_width="wrap_content"
48 48
            android:layout_height="wrap_content"
49
            android:textAppearance="?android:attr/textAppearanceSmall"
50
            android:text="EV200车主"
51
            android:textSize="13sp"
52
            android:id="@+id/tv_pname"
53
            android:textColor="@color/ui_65"
54
            android:maxEms="8"
55
            android:ellipsize="end"
56
            android:singleLine="true"
57
            android:layout_marginLeft="10dp"
58
            android:layout_gravity="center_vertical"
59 49
            android:layout_alignTop="@+id/rl_icon"
50
            android:layout_gravity="center_vertical"
51
            android:layout_marginLeft="10dp"
52
            android:layout_toEndOf="@+id/rl_icon"
60 53
            android:layout_toRightOf="@+id/rl_icon"
61
            android:layout_toEndOf="@+id/rl_icon" />
54
            android:ellipsize="end"
55
            android:maxEms="8"
56
            android:singleLine="true"
57
            android:text="EV200车主"
58
            android:textAppearance="?android:attr/textAppearanceSmall"
59
            android:textColor="@color/ui_65"
60
            android:textSize="13sp" />
61
62
        <ImageView
63
            android:id="@+id/certified_icon"
64
            android:layout_width="18dp"
65
            android:layout_height="18dp"
66
            android:layout_alignTop="@+id/tv_pname"
67
            android:layout_marginTop="2dp"
68
            android:layout_alignBottom="@+id/tv_pname"
69
            android:layout_marginLeft="5dp"
70
            android:layout_toRightOf="@+id/tv_pname"
71
            android:src="@drawable/certified_icon" />
62 72
63 73
        <TextView
74
            android:id="@+id/tv_pcar"
64 75
            android:layout_width="match_parent"
65 76
            android:layout_height="wrap_content"
66
            android:textAppearance="?android:attr/textAppearanceSmall"
67
            android:text="北京市"
68
            android:textSize="13sp"
69
            android:textColor="#888888"
70
            android:id="@+id/tv_pcar"
71
            android:layout_marginLeft="5dp"
72
            android:layout_gravity="center_vertical"
73 77
            android:layout_alignTop="@+id/tv_pname"
74
            android:layout_toRightOf="@+id/tv_pname"
75
            android:layout_toLeftOf="@+id/iv_pgrade"
78
            android:layout_gravity="center_vertical"
79
            android:layout_marginLeft="5dp"
76 80
            android:layout_marginRight="5dp"
81
            android:layout_toLeftOf="@+id/iv_pgrade"
82
            android:layout_toRightOf="@+id/certified_icon"
83
            android:ellipsize="end"
77 84
            android:singleLine="true"
78
            android:ellipsize="end"/>
85
            android:text="北京市"
86
            android:textAppearance="?android:attr/textAppearanceSmall"
87
            android:textColor="#888888"
88
            android:textSize="13sp" />
79 89
80 90
        <ImageView
91
            android:id="@+id/iv_pgrade"
81 92
            android:layout_width="wrap_content"
82 93
            android:layout_height="wrap_content"
83
            android:textAppearance="?android:attr/textAppearanceSmall"
84
            android:id="@+id/iv_pgrade"
85
            android:layout_gravity="center_vertical"
86 94
            android:layout_alignTop="@+id/tv_pname"
87 95
            android:layout_alignParentRight="true"
96
            android:layout_gravity="center_vertical"
88 97
            android:layout_marginRight="15dp"
89
            android:src="@drawable/icon_5xing"/>
98
            android:src="@drawable/icon_5xing"
99
            android:textAppearance="?android:attr/textAppearanceSmall" />
90 100
91 101
        <TextView
102
            android:id="@+id/tv_pcontext"
92 103
            android:layout_width="wrap_content"
93 104
            android:layout_height="wrap_content"
94
            android:textAppearance="?android:attr/textAppearanceSmall"
95
            android:text=""
96
            android:id="@+id/tv_pcontext"
97
            android:textSize="15sp"
98
            android:layout_marginTop="10dp"
99
            android:layout_marginRight="15dp"
100 105
            android:layout_below="@+id/tv_pname"
101
            android:layout_alignLeft="@+id/tv_pname"
102 106
            android:layout_alignStart="@+id/tv_pname"
103
            android:visibility="visible"/>
107
            android:layout_alignLeft="@+id/tv_pname"
108
            android:layout_marginTop="10dp"
109
            android:layout_marginRight="15dp"
110
            android:text=""
111
            android:textAppearance="?android:attr/textAppearanceSmall"
112
            android:textSize="15sp"
113
            android:visibility="visible" />
104 114
105 115
        <com.zhy.view.flowlayout.TagFlowLayout
106 116
            android:id="@+id/fl_ptag"
@ -109,45 +119,45 @@
109 119
            android:layout_below="@+id/tv_pcontext"
110 120
            android:layout_alignLeft="@+id/tv_pcontext"
111 121
            android:layout_marginTop="10dp"
112
            zhy:max_select="-1"
113
            android:visibility="visible"/>
122
            android:visibility="visible"
123
            zhy:max_select="-1" />
114 124
115 125
        <ImageView
126
            android:id="@+id/iv_commentPic"
116 127
            android:layout_width="65dp"
117 128
            android:layout_height="65dp"
118
            android:id="@+id/iv_commentPic"
119
            android:layout_marginTop="10dp"
120 129
            android:layout_below="@+id/fl_ptag"
121 130
            android:layout_alignLeft="@+id/tv_pcontext"
131
            android:layout_marginTop="10dp"
122 132
            android:scaleType="centerCrop"
123
            android:visibility="gone"/>
133
            android:visibility="gone" />
124 134
125 135
        <TextView
136
            android:id="@+id/tv_ptime"
126 137
            android:layout_width="wrap_content"
127 138
            android:layout_height="wrap_content"
128
            android:textAppearance="?android:attr/textAppearanceSmall"
129
            android:text="15分钟前"
130
            android:textSize="12sp"
131
            android:textColor="#c8c8c8"
132
            android:id="@+id/tv_ptime"
133
            android:layout_marginTop="10dp"
134
            android:layout_marginBottom="8dp"
135 139
            android:layout_below="@+id/iv_commentPic"
140
            android:layout_alignStart="@+id/tv_pcontext"
136 141
            android:layout_alignLeft="@+id/tv_pcontext"
137
            android:layout_alignStart="@+id/tv_pcontext" />
142
            android:layout_marginTop="10dp"
143
            android:layout_marginBottom="8dp"
144
            android:text="15分钟前"
145
            android:textAppearance="?android:attr/textAppearanceSmall"
146
            android:textColor="#c8c8c8"
147
            android:textSize="12sp" />
138 148
139 149
        <TextView
140 150
            android:id="@+id/tv_pdelete"
141 151
            android:layout_width="wrap_content"
142 152
            android:layout_height="wrap_content"
143
            android:layout_toRightOf="@+id/tv_ptime"
144 153
            android:layout_alignTop="@+id/tv_ptime"
154
            android:layout_toRightOf="@+id/tv_ptime"
145 155
            android:paddingLeft="12dp"
146 156
            android:paddingRight="12dp"
147 157
            android:text="删除"
148
            android:textSize="12sp"
149 158
            android:textColor="@color/ui_68"
150
            android:visibility="gone"/>
159
            android:textSize="12sp"
160
            android:visibility="gone" />
151 161
152 162
153 163
        <LinearLayout
@ -156,128 +166,125 @@
156 166
            android:layout_height="wrap_content"
157 167
            android:layout_below="@+id/iv_commentPic"
158 168
            android:layout_toLeftOf="@+id/tv_preply"
159
            android:paddingRight="13dp"
169
            android:paddingLeft="10dp"
160 170
            android:paddingTop="10dp"
161
            android:paddingBottom="8dp"
162
            android:paddingLeft="10dp">
171
            android:paddingRight="13dp"
172
            android:paddingBottom="8dp">
163 173
164 174
            <ImageView
175
                android:id="@+id/iv_pzan"
165 176
                android:layout_width="wrap_content"
166 177
                android:layout_height="wrap_content"
167
                android:id="@+id/iv_pzan"
168 178
                android:layout_gravity="center"
169
                android:src="@drawable/icon_comment_zan"/>
179
                android:src="@drawable/icon_comment_zan" />
170 180
171 181
            <TextView
182
                android:id="@+id/tv_pzan"
172 183
                android:layout_width="wrap_content"
173 184
                android:layout_height="wrap_content"
174
                android:textAppearance="?android:attr/textAppearanceSmall"
185
                android:layout_marginLeft="8dp"
186
                android:gravity="center"
175 187
                android:text="0"
176
                android:textSize="12sp"
188
                android:textAppearance="?android:attr/textAppearanceSmall"
177 189
                android:textColor="@color/ui_68"
178
                android:id="@+id/tv_pzan"
179
                android:visibility="visible"
180
                android:layout_marginLeft="8dp"
181
                android:gravity="center" />
190
                android:textSize="12sp"
191
                android:visibility="visible" />
182 192
183 193
        </LinearLayout>
184 194
185 195
186 196
        <TextView
197
            android:id="@+id/tv_preply"
187 198
            android:layout_width="wrap_content"
188 199
            android:layout_height="wrap_content"
189
            android:textAppearance="?android:attr/textAppearanceSmall"
190
            android:text="回复"
191
            android:textSize="12sp"
192
            android:textColor="#2fb3ff"
193
            android:id="@+id/tv_preply"
194
            android:visibility="visible"
195 200
            android:layout_below="@+id/iv_commentPic"
196
            android:layout_alignRight="@+id/tv_pcontext"
197 201
            android:layout_alignEnd="@+id/tv_pcontext"
202
            android:layout_alignRight="@+id/tv_pcontext"
198 203
            android:layout_alignParentRight="true"
199
            android:paddingRight="15dp"
200
            android:paddingTop="10dp"
201 204
            android:paddingLeft="12dp"
202
            android:paddingBottom="8dp"/>
205
            android:paddingTop="10dp"
206
            android:paddingRight="15dp"
207
            android:paddingBottom="8dp"
208
            android:text="回复"
209
            android:textAppearance="?android:attr/textAppearanceSmall"
210
            android:textColor="#2fb3ff"
211
            android:textSize="12sp"
212
            android:visibility="visible" />
203 213
204 214
205 215
        <TextView
216
            android:id="@+id/tv_childName"
206 217
            android:layout_width="wrap_content"
207 218
            android:layout_height="wrap_content"
208
            android:textAppearance="?android:attr/textAppearanceSmall"
209
            android:text="IEV5车主"
210
            android:layout_marginTop="10dp"
211
            android:id="@+id/tv_childName"
212 219
            android:layout_below="@+id/tv_ptime"
213
            android:layout_alignLeft="@+id/tv_ptime"
214 220
            android:layout_alignStart="@+id/tv_ptime"
215
            android:visibility="gone"/>
221
            android:layout_alignLeft="@+id/tv_ptime"
222
            android:layout_marginTop="10dp"
223
            android:text="IEV5车主"
224
            android:textAppearance="?android:attr/textAppearanceSmall"
225
            android:visibility="gone" />
216 226
217 227
        <TextView
228
            android:id="@+id/textView14"
218 229
            android:layout_width="wrap_content"
219 230
            android:layout_height="wrap_content"
220
            android:textAppearance="?android:attr/textAppearanceSmall"
221
            android:text="回复"
222
            android:id="@+id/textView14"
223
            android:layout_marginLeft="8dp"
224 231
            android:layout_alignBaseline="@+id/tv_childName"
225 232
            android:layout_alignBottom="@+id/tv_childName"
233
            android:layout_marginLeft="8dp"
226 234
            android:layout_toRightOf="@+id/tv_childName"
227
            android:visibility="gone"/>
235
            android:text="回复"
236
            android:textAppearance="?android:attr/textAppearanceSmall"
237
            android:visibility="gone" />
228 238
229 239
        <TextView
240
            android:id="@+id/tv_parentName"
230 241
            android:layout_width="wrap_content"
231 242
            android:layout_height="wrap_content"
232
            android:textAppearance="?android:attr/textAppearanceSmall"
233
            android:text="EV200车主:"
234
            android:id="@+id/tv_parentName"
235
            android:layout_marginLeft="8dp"
236 243
            android:layout_alignBottom="@+id/textView14"
237
            android:layout_toRightOf="@+id/textView14"
244
            android:layout_marginLeft="8dp"
238 245
            android:layout_toEndOf="@+id/textView14"
239
            android:visibility="gone"/>
246
            android:layout_toRightOf="@+id/textView14"
247
            android:text="EV200车主:"
248
            android:textAppearance="?android:attr/textAppearanceSmall"
249
            android:visibility="gone" />
240 250
241 251
        <TextView
252
            android:id="@+id/tv_commentDetail"
242 253
            android:layout_width="wrap_content"
243 254
            android:layout_height="wrap_content"
244
            android:textAppearance="?android:attr/textAppearanceSmall"
245
            android:text="有故障!"
246
            android:id="@+id/tv_commentDetail"
247 255
            android:layout_alignBottom="@+id/tv_parentName"
248
            android:layout_toRightOf="@+id/tv_parentName"
249
            android:layout_toEndOf="@+id/tv_parentName"
250 256
            android:layout_marginLeft="8dp"
251
            android:visibility="gone"/>
257
            android:layout_toEndOf="@+id/tv_parentName"
258
            android:layout_toRightOf="@+id/tv_parentName"
259
            android:text="有故障!"
260
            android:textAppearance="?android:attr/textAppearanceSmall"
261
            android:visibility="gone" />
252 262
253 263
        <com.electric.chargingpile.view.MyListView
254 264
            android:id="@+id/lv_scomment"
255 265
            android:layout_width="match_parent"
256 266
            android:layout_height="wrap_content"
257
            android:divider="#dddddd"
258
            android:dividerHeight="0.5dp"
259 267
            android:layout_below="@+id/tv_ptime"
260
            android:background="#fafafa"
261 268
            android:layout_alignLeft="@+id/tv_ptime"
262
            android:paddingLeft="15dp"
263
            android:layout_marginRight="15dp"/>
269
            android:layout_marginRight="15dp"
270
            android:background="#fafafa"
271
            android:divider="#dddddd"
272
            android:dividerHeight="0.5dp"
273
            android:paddingLeft="15dp" />
264 274
265 275
        <TextView
266
        android:id="@+id/tv_more"
267
        android:layout_width="match_parent"
268
        android:layout_height="40dp"
276
            android:id="@+id/tv_more"
277
            android:layout_width="match_parent"
278
            android:layout_height="40dp"
269 279
            android:layout_below="@+id/lv_scomment"
270 280
            android:layout_alignLeft="@+id/lv_scomment"
271 281
            android:layout_alignRight="@+id/lv_scomment"
272
        android:text="查看剩余*条评论 >"
273
        android:textColor="@color/lvse"
274
        android:gravity="center"
275
        android:background="@drawable/bg_03"
276
        android:textSize="14sp"
277
        android:visibility="gone"/>
278
279
280
282
            android:background="@drawable/bg_03"
283
            android:gravity="center"
284
            android:text="查看剩余*条评论 >"
285
            android:textColor="@color/lvse"
286
            android:textSize="14sp"
287
            android:visibility="gone" />
281 288
282 289
283 290
        <!--<LinearLayout-->
@ -325,201 +332,19 @@
325 332
326 333
            android:layout_width="match_parent"
327 334
            android:layout_height="0.5dp"
328
            android:background="@color/Line"
329 335
            android:layout_below="@+id/tv_ptime"
330
            android:visibility="gone"/>
336
            android:background="@color/Line"
337
            android:visibility="gone" />
331 338
332 339
    </RelativeLayout>
333 340
334
    <!--<LinearLayout-->
335
        <!--android:id="@+id/ll_out"-->
336
        <!--android:layout_width="match_parent"-->
337
        <!--android:layout_height="wrap_content"-->
338
        <!--android:visibility="gone">-->
339
340
        <!--<RelativeLayout-->
341
            <!--android:id="@+id/son"-->
342
            <!--android:layout_width="match_parent"-->
343
            <!--android:layout_height="wrap_content"-->
344
            <!--android:background="#fafafa"-->
345
            <!--android:layout_marginLeft="45dp"-->
346
            <!--android:layout_marginRight="15dp">-->
347
348
            <!--<com.electric.chargingpile.view.CircleImageView-->
349
                <!--android:layout_width="35dp"-->
350
                <!--android:layout_height="35dp"-->
351
                <!--android:id="@+id/iv_icon_son"-->
352
                <!--android:layout_alignParentTop="true"-->
353
                <!--android:layout_alignParentLeft="true"-->
354
                <!--android:layout_alignParentStart="true"-->
355
                <!--android:layout_marginTop="12dp"-->
356
                <!--android:layout_marginLeft="10dp"-->
357
                <!--app:border_color="@color/white"-->
358
                <!--android:layout_gravity="center_vertical"-->
359
                <!--android:src="@drawable/icon_touxiang0128"-->
360
                <!--android:visibility="gone"/>-->
361
362
            <!--<TextView-->
363
                <!--android:layout_width="wrap_content"-->
364
                <!--android:layout_height="wrap_content"-->
365
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
366
                <!--android:text="EV200车主"-->
367
                <!--android:textSize="13sp"-->
368
                <!--android:id="@+id/tv_carType_son"-->
369
                <!--android:textColor="@color/ui_65"-->
370
371
                <!--android:layout_gravity="center_vertical"-->
372
                <!--android:layout_alignParentLeft="true"-->
373
                <!--android:layout_marginTop="12dp"-->
374
                <!--android:layout_marginLeft="15dp"/>-->
375
376
            <!--<TextView-->
377
                <!--android:layout_width="wrap_content"-->
378
                <!--android:layout_height="wrap_content"-->
379
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
380
                <!--android:text="北京市"-->
381
                <!--android:textSize="13sp"-->
382
                <!--android:textColor="#888888"-->
383
                <!--android:id="@+id/tv_city_son"-->
384
                <!--android:layout_marginLeft="5dp"-->
385
                <!--android:layout_gravity="center_vertical"-->
386
                <!--android:layout_alignTop="@+id/tv_carType_son"-->
387
                <!--android:layout_toRightOf="@+id/tv_carType_son"-->
388
                <!--android:layout_toEndOf="@+id/tv_carType_son"-->
389
                <!--android:visibility="gone"/>-->
390
391
392
393
            <!--<TextView-->
394
                <!--android:layout_width="wrap_content"-->
395
                <!--android:layout_height="wrap_content"-->
396
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
397
                <!--android:text="桩在哪里呢?桩在哪里呢?桩在哪里呢?桩在哪里呢?桩在哪里呢?桩在哪里呢?桩在哪里呢?桩在哪里呢?桩在哪里呢?"-->
398
                <!--android:id="@+id/tv_comment_son"-->
399
                <!--android:textSize="15sp"-->
400
                <!--android:layout_marginTop="10dp"-->
401
                <!--android:layout_marginRight="10dp"-->
402
                <!--android:layout_marginBottom="10dp"-->
403
                <!--android:layout_below="@+id/tv_carType_son"-->
404
                <!--android:layout_alignLeft="@+id/tv_carType_son"-->
405
                <!--android:layout_alignStart="@+id/tv_carType_son" />-->
406
407
408
409
410
            <!--<TextView-->
411
                <!--android:layout_width="wrap_content"-->
412
                <!--android:layout_height="wrap_content"-->
413
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
414
                <!--android:text="15分钟前"-->
415
                <!--android:textSize="12sp"-->
416
                <!--android:textColor="#c8c8c8"-->
417
                <!--android:id="@+id/tv_time_son"-->
418
                <!--android:layout_marginRight="10dp"-->
419
                <!--android:layout_alignTop="@+id/tv_city_son"-->
420
                <!--android:layout_alignParentRight="true"-->
421
                <!--android:layout_alignParentEnd="true" />-->
422
423
            <!--<TextView-->
424
                <!--android:layout_width="wrap_content"-->
425
                <!--android:layout_height="wrap_content"-->
426
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
427
                <!--android:text="回复"-->
428
                <!--android:id="@+id/tv_reply_son"-->
429
                <!--android:layout_marginLeft="20dp"-->
430
                <!--android:layout_alignTop="@+id/tv_time_son"-->
431
                <!--android:layout_toRightOf="@+id/tv_time_son"-->
432
                <!--android:layout_toEndOf="@+id/tv_time_son"-->
433
                <!--android:visibility="gone"/>-->
434
435
436
            <!--<TextView-->
437
                <!--android:layout_width="wrap_content"-->
438
                <!--android:layout_height="wrap_content"-->
439
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
440
                <!--android:text="IEV5车主"-->
441
                <!--android:layout_marginTop="10dp"-->
442
                <!--android:id="@+id/tv_childName_son"-->
443
                <!--android:layout_below="@+id/tv_time_son"-->
444
                <!--android:layout_alignLeft="@+id/tv_time_son"-->
445
                <!--android:layout_alignStart="@+id/tv_time_son"-->
446
                <!--android:visibility="gone"/>-->
447
448
            <!--<TextView-->
449
                <!--android:layout_width="wrap_content"-->
450
                <!--android:layout_height="wrap_content"-->
451
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
452
                <!--android:text="回复"-->
453
                <!--android:id="@+id/textView15"-->
454
                <!--android:layout_marginLeft="8dp"-->
455
                <!--android:layout_alignBaseline="@+id/tv_childName_son"-->
456
                <!--android:layout_alignBottom="@+id/tv_childName_son"-->
457
                <!--android:layout_toRightOf="@+id/tv_childName_son"-->
458
                <!--android:visibility="gone"/>-->
459
460
            <!--<TextView-->
461
                <!--android:layout_width="wrap_content"-->
462
                <!--android:layout_height="wrap_content"-->
463
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
464
                <!--android:text="EV200车主:"-->
465
                <!--android:id="@+id/tv_parentName_son"-->
466
                <!--android:layout_marginLeft="8dp"-->
467
                <!--android:layout_alignBottom="@+id/textView15"-->
468
                <!--android:layout_toRightOf="@+id/textView15"-->
469
                <!--android:layout_toEndOf="@+id/textView15"-->
470
                <!--android:visibility="gone"/>-->
471
472
            <!--<TextView-->
473
                <!--android:layout_width="wrap_content"-->
474
                <!--android:layout_height="wrap_content"-->
475
                <!--android:textAppearance="?android:attr/textAppearanceSmall"-->
476
                <!--android:text="有故障!"-->
477
                <!--android:id="@+id/tv_commentDetail_son"-->
478
                <!--android:layout_alignBottom="@+id/tv_parentName_son"-->
479
                <!--android:layout_toRightOf="@+id/tv_parentName_son"-->
480
                <!--android:layout_toEndOf="@+id/tv_parentName_son"-->
481
                <!--android:layout_marginLeft="8dp"-->
482
                <!--android:visibility="gone"/>-->
483
484
            <!--<View-->
485
                <!--android:id="@+id/vvvv"-->
486
                <!--android:layout_width="match_parent"-->
487
                <!--android:layout_height="0.5dp"-->
488
                <!--android:background="@color/Line"-->
489
                <!--android:layout_marginLeft="15dp"-->
490
                <!--android:layout_below="@+id/tv_comment_son"/>-->
491
492
        <!--</RelativeLayout>-->
493
494
    <!--</LinearLayout>-->
495
496
    <!--<TextView-->
497
        <!--android:id="@+id/tv_more"-->
498
        <!--android:layout_width="match_parent"-->
499
        <!--android:layout_height="40dp"-->
500
        <!--android:text="查看剩余*条评论 >"-->
501
        <!--android:textColor="@color/lvse"-->
502
        <!--android:gravity="center"-->
503
        <!--android:background="#fafafa"-->
504
        <!--android:textSize="14sp"-->
505
        <!--android:layout_marginLeft="45dp"-->
506
        <!--android:layout_marginRight="15dp"-->
507
        <!--android:visibility="gone"/>-->
508
    <!--<ListView-->
509
        <!--android:layout_width="wrap_content"-->
510
        <!--android:layout_height="wrap_content"-->
511
        <!--android:layout_below="@+id/tv_ptime"-->
512
        <!--android:layout_alignLeft="@+id/tv_ptime"-->
513
        <!--android:layout_alignStart="@+id/tv_ptime"-->
514
        <!--android:layout_marginRight="15dp"/>-->
515
516 341
    <View
517 342
        android:id="@+id/vvv"
518 343
        android:layout_width="match_parent"
519 344
        android:layout_height="0.5dp"
520
        android:background="@color/Line"
521 345
        android:layout_below="@+id/lv_scomment"
522
        android:layout_marginTop="10dp" />
346
        android:layout_marginTop="10dp"
347
        android:background="@color/Line" />
523 348
524 349
525 350
</LinearLayout>

车主认证开发 · c2143716ef - Gogs: Go Git Service
浏览代码

车主认证开发

huyuguo 5 年之前
父节点
当前提交
c2143716ef
共有 48 个文件被更改,包括 3963 次插入134 次删除
  1. 二进制
      app/.DS_Store
  2. 4 0
      app/build.gradle
  3. 12 1
      app/src/main/AndroidManifest.xml
  4. 1154 0
      app/src/main/java/com/donkingliang/groupedadapter/adapter/GroupedRecyclerViewAdapter.java
  5. 126 0
      app/src/main/java/com/donkingliang/groupedadapter/holder/BaseViewHolder.java
  6. 77 0
      app/src/main/java/com/donkingliang/groupedadapter/layoutmanger/GroupedGridLayoutManager.java
  7. 43 0
      app/src/main/java/com/donkingliang/groupedadapter/structure/GroupStructure.java
  8. 439 0
      app/src/main/java/com/donkingliang/groupedadapter/widget/StickyHeaderLayout.java
  9. 5 0
      app/src/main/java/com/donkingliang/groupedadapter/widget/StickyHeaderPositionListener.java
  10. 120 0
      app/src/main/java/com/electric/chargingpile/activity/CarBrandActivity.java
  11. 75 0
      app/src/main/java/com/electric/chargingpile/activity/CarModelActivity.java
  12. 385 0
      app/src/main/java/com/electric/chargingpile/activity/CarOwnerCertificateActivity.java
  13. 29 133
      app/src/main/java/com/electric/chargingpile/activity/UserCenterActivity.java
  14. 97 0
      app/src/main/java/com/electric/chargingpile/adapter/CarBrandGroupedListAdapter.java
  15. 95 0
      app/src/main/java/com/electric/chargingpile/adapter/CarModelGroupedListAdapter.java
  16. 59 0
      app/src/main/java/com/electric/chargingpile/entity/CarBrandChildEntity.java
  17. 30 0
      app/src/main/java/com/electric/chargingpile/entity/CarBrandGroupEntity.java
  18. 50 0
      app/src/main/java/com/electric/chargingpile/entity/CarCompanyEntity.java
  19. 67 0
      app/src/main/java/com/electric/chargingpile/entity/CarSeriesEntity.java
  20. 21 0
      app/src/main/java/com/electric/chargingpile/event/CarBrandEvent.java
  21. 20 0
      app/src/main/java/com/electric/chargingpile/event/CarCompanyEvent.java
  22. 19 0
      app/src/main/java/com/electric/chargingpile/event/CarSerieEvent.java
  23. 12 0
      app/src/main/java/com/electric/chargingpile/util/DensityUtil.java
  24. 154 0
      app/src/main/java/com/electric/chargingpile/view/LetterSideView.java
  25. 92 0
      app/src/main/java/com/electric/chargingpile/view/TextImageView.java
  26. 二进制
      app/src/main/res/drawable-hdpi/icon_radio_normal.png
  27. 二进制
      app/src/main/res/drawable-hdpi/icon_radio_selected.png
  28. 二进制
      app/src/main/res/drawable-mdpi/icon_radio_normal.png
  29. 二进制
      app/src/main/res/drawable-mdpi/icon_radio_selected.png
  30. 二进制
      app/src/main/res/drawable-xhdpi/icon_radio_normal.png
  31. 二进制
      app/src/main/res/drawable-xhdpi/icon_radio_selected.png
  32. 二进制
      app/src/main/res/drawable-xxhdpi/icon_radio_normal.png
  33. 二进制
      app/src/main/res/drawable-xxhdpi/icon_radio_selected.png
  34. 二进制
      app/src/main/res/drawable-xxxhdpi/icon_radio_normal.png
  35. 二进制
      app/src/main/res/drawable-xxxhdpi/icon_radio_selected.png
  36. 8 0
      app/src/main/res/drawable/bg_add_car_model_shape.xml
  37. 二进制
      app/src/main/res/drawable/group_adapter_empty_view_image.png
  38. 83 0
      app/src/main/res/layout/activity_car_brand.xml
  39. 57 0
      app/src/main/res/layout/activity_car_model.xml
  40. 363 0
      app/src/main/res/layout/activity_car_owner_certificate.xml
  41. 81 0
      app/src/main/res/layout/activity_user_center.xml
  42. 42 0
      app/src/main/res/layout/adapter_child_car_brand.xml
  43. 77 0
      app/src/main/res/layout/adapter_child_car_model.xml
  44. 19 0
      app/src/main/res/layout/adapter_header_car_brand.xml
  45. 19 0
      app/src/main/res/layout/adapter_header_car_model.xml
  46. 13 0
      app/src/main/res/layout/group_adapter_default_empty_view.xml
  47. 5 0
      app/src/main/res/values/strings.xml
  48. 11 0
      app/src/main/res/values/styles.xml

二进制
app/.DS_Store


+ 4 - 0
app/build.gradle

@ -47,6 +47,10 @@ android {
47 47
//        }
48 48
    }
49 49
50
    dataBinding {
51
        enabled true
52
    }
53
50 54
    sourceSets.main {
51 55
        jniLibs.srcDirs 'src/main/libs'
52 56
        res.srcDirs = ['src/main/res']

+ 12 - 1
app/src/main/AndroidManifest.xml

@ -79,7 +79,18 @@
79 79
                <category android:name="android.intent.category.LAUNCHER" />
80 80
            </intent-filter>
81 81
        </activity>
82
82
        <activity
83
            android:name=".activity.CarModelActivity"
84
            android:launchMode="singleTop"
85
            android:screenOrientation="portrait"></activity>
86
        <activity
87
            android:name=".activity.CarBrandActivity"
88
            android:launchMode="singleTop"
89
            android:screenOrientation="portrait" />
90
        <activity
91
            android:name=".activity.CarOwnerCertificateActivity"
92
            android:launchMode="singleTask"
93
            android:screenOrientation="portrait" />
83 94
        <activity android:name=".activity.SearchAllActivity"></activity>
84 95
        <activity android:name=".activity.ShareTwoPictureActivity" />
85 96
        <activity

+ 1154 - 0
app/src/main/java/com/donkingliang/groupedadapter/adapter/GroupedRecyclerViewAdapter.java

@ -0,0 +1,1154 @@
1
package com.donkingliang.groupedadapter.adapter;
2
3
import android.content.Context;
4
import android.view.LayoutInflater;
5
import android.view.View;
6
import android.view.ViewGroup;
7
import android.view.ViewParent;
8
import android.widget.FrameLayout;
9
10
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
11
import com.donkingliang.groupedadapter.structure.GroupStructure;
12
import com.electric.chargingpile.R;
13
14
import java.util.ArrayList;
15
16
import androidx.databinding.DataBindingUtil;
17
import androidx.databinding.ViewDataBinding;
18
import androidx.recyclerview.widget.RecyclerView;
19
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
20
21
/**
22
 * 通用的分组列表Adapter。通过它可以很方便的实现列表的分组效果。
23
 * 这个类提供了一系列的对列表的更新、删除和插入等操作的方法。
24
 * 使用者要使用这些方法的列表进行操作,而不要直接使用RecyclerView.Adapter的方法。
25
 * 因为当分组列表发生变化时,需要及时更新分组列表的组结构{@link GroupedRecyclerViewAdapter#mStructures}
26
 */
27
public abstract class GroupedRecyclerViewAdapter
28
        extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
29
30
    public static final int TYPE_HEADER = R.integer.type_header;
31
    public static final int TYPE_FOOTER = R.integer.type_footer;
32
    public static final int TYPE_CHILD = R.integer.type_child;
33
    public static final int TYPE_EMPTY = R.integer.type_empty;
34
35
    private OnHeaderClickListener mOnHeaderClickListener;
36
    private OnFooterClickListener mOnFooterClickListener;
37
    private OnChildClickListener mOnChildClickListener;
38
39
    protected Context mContext;
40
    //保存分组列表的组结构
41
    protected ArrayList<GroupStructure> mStructures = new ArrayList<>();
42
    //数据是否发生变化。如果数据发生变化,要及时更新组结构。
43
    private boolean isDataChanged;
44
    private int mTempPosition;
45
46
    private boolean mUseBinding;
47
48
    // 是否显示空布局
49
    private boolean showEmptyView = false;
50
51
    public GroupedRecyclerViewAdapter(Context context) {
52
        this(context, false);
53
    }
54
55
    public GroupedRecyclerViewAdapter(Context context, boolean useBinding) {
56
        mContext = context;
57
        mUseBinding = useBinding;
58
        registerAdapterDataObserver(new GroupDataObserver());
59
    }
60
61
    @Override
62
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
63
        super.onAttachedToRecyclerView(recyclerView);
64
        structureChanged();
65
    }
66
67
    @Override
68
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
69
        super.onViewAttachedToWindow(holder);
70
71
        //处理StaggeredGridLayout,保证组头和组尾占满一行。
72
        if (isStaggeredGridLayout(holder)) {
73
            handleLayoutIfStaggeredGridLayout(holder, holder.getLayoutPosition());
74
        }
75
    }
76
77
    private boolean isStaggeredGridLayout(RecyclerView.ViewHolder holder) {
78
        ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
79
        if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
80
            return true;
81
        }
82
        return false;
83
    }
84
85
    private void handleLayoutIfStaggeredGridLayout(RecyclerView.ViewHolder holder, int position) {
86
        if (isEmptyPosition(position) || judgeType(position) == TYPE_HEADER || judgeType(position) == TYPE_FOOTER) {
87
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams)
88
                    holder.itemView.getLayoutParams();
89
            p.setFullSpan(true);
90
        }
91
    }
92
93
    @Override
94
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
95
        if (viewType == TYPE_EMPTY){
96
            return new BaseViewHolder(getEmptyView(parent));
97
        } else {
98
            if (mUseBinding) {
99
                ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(mContext),
100
                        getLayoutId(mTempPosition, viewType), parent, false);
101
                return new BaseViewHolder(binding.getRoot());
102
            } else {
103
                View view = LayoutInflater.from(mContext).inflate(
104
                        getLayoutId(mTempPosition, viewType), parent, false);
105
                return new BaseViewHolder(view);
106
            }
107
        }
108
    }
109
110
    @Override
111
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
112
        int type = judgeType(position);
113
        final int groupPosition = getGroupPositionForPosition(position);
114
        if (type == TYPE_HEADER) {
115
            if (mOnHeaderClickListener != null) {
116
                holder.itemView.setOnClickListener(new View.OnClickListener() {
117
                    @Override
118
                    public void onClick(View v) {
119
                        if (mOnHeaderClickListener != null) {
120
                            ViewParent parent = holder.itemView.getParent();
121
                            int gPosition = parent instanceof FrameLayout ? groupPosition : getGroupPositionForPosition(holder.getLayoutPosition());
122
                            if (gPosition >= 0 && gPosition < mStructures.size()) {
123
                                mOnHeaderClickListener.onHeaderClick(GroupedRecyclerViewAdapter.this,
124
                                        (BaseViewHolder) holder, gPosition);
125
                            }
126
                        }
127
                    }
128
                });
129
            }
130
            onBindHeaderViewHolder((BaseViewHolder) holder, groupPosition);
131
        } else if (type == TYPE_FOOTER) {
132
            if (mOnFooterClickListener != null) {
133
                holder.itemView.setOnClickListener(new View.OnClickListener() {
134
                    @Override
135
                    public void onClick(View v) {
136
                        if (mOnFooterClickListener != null) {
137
                            int gPosition = getGroupPositionForPosition(holder.getLayoutPosition());
138
                            if (gPosition >= 0 && gPosition < mStructures.size()) {
139
                                mOnFooterClickListener.onFooterClick(GroupedRecyclerViewAdapter.this,
140
                                        (BaseViewHolder) holder, gPosition);
141
                            }
142
                        }
143
                    }
144
                });
145
            }
146
            onBindFooterViewHolder((BaseViewHolder) holder, groupPosition);
147
        } else if (type == TYPE_CHILD) {
148
            int childPosition = getChildPositionForPosition(groupPosition, position);
149
            if (mOnChildClickListener != null) {
150
                holder.itemView.setOnClickListener(new View.OnClickListener() {
151
                    @Override
152
                    public void onClick(View v) {
153
                        if (mOnChildClickListener != null) {
154
                            int gPosition = getGroupPositionForPosition(holder.getLayoutPosition());
155
                            int cPosition = getChildPositionForPosition(gPosition, holder.getLayoutPosition());
156
                            if (gPosition >= 0 && gPosition < mStructures.size() && cPosition >= 0
157
                                    && cPosition < mStructures.get(gPosition).getChildrenCount()) {
158
                                mOnChildClickListener.onChildClick(GroupedRecyclerViewAdapter.this,
159
                                        (BaseViewHolder) holder, gPosition, cPosition);
160
                            }
161
                        }
162
                    }
163
                });
164
            }
165
            onBindChildViewHolder((BaseViewHolder) holder, groupPosition, childPosition);
166
        }
167
    }
168
169
    @Override
170
    public int getItemCount() {
171
        if (isDataChanged) {
172
            structureChanged();
173
        }
174
175
        int count = count();
176
        if (count > 0) {
177
            return count;
178
        } else if (showEmptyView) {
179
            // 显示空布局
180
            return 1;
181
        } else {
182
            return 0;
183
        }
184
    }
185
186
    public boolean isEmptyPosition(int position) {
187
        return position == 0 && showEmptyView && count() == 0;
188
    }
189
190
    @Override
191
    public int getItemViewType(int position) {
192
        if (isEmptyPosition(position)) {
193
            // 空布局
194
            return TYPE_EMPTY;
195
        }
196
        mTempPosition = position;
197
        int groupPosition = getGroupPositionForPosition(position);
198
        int type = judgeType(position);
199
        if (type == TYPE_HEADER) {
200
            return getHeaderViewType(groupPosition);
201
        } else if (type == TYPE_FOOTER) {
202
            return getFooterViewType(groupPosition);
203
        } else if (type == TYPE_CHILD) {
204
            int childPosition = getChildPositionForPosition(groupPosition, position);
205
            return getChildViewType(groupPosition, childPosition);
206
        }
207
        return super.getItemViewType(position);
208
    }
209
210
    public int getHeaderViewType(int groupPosition) {
211
        return TYPE_HEADER;
212
    }
213
214
    public int getFooterViewType(int groupPosition) {
215
        return TYPE_FOOTER;
216
    }
217
218
    public int getChildViewType(int groupPosition, int childPosition) {
219
        return TYPE_CHILD;
220
    }
221
222
    private int getLayoutId(int position, int viewType) {
223
        int type = judgeType(position);
224
        if (type == TYPE_HEADER) {
225
            return getHeaderLayout(viewType);
226
        } else if (type == TYPE_FOOTER) {
227
            return getFooterLayout(viewType);
228
        } else if (type == TYPE_CHILD) {
229
            return getChildLayout(viewType);
230
        }
231
        return 0;
232
    }
233
234
    private int count() {
235
        return countGroupRangeItem(0, mStructures.size());
236
    }
237
238
    /**
239
     * 判断item的type 头部 尾部 和 子项
240
     *
241
     * @param position
242
     * @return
243
     */
244
    public int judgeType(int position) {
245
        int itemCount = 0;
246
        int groupCount = mStructures.size();
247
248
        for (int i = 0; i < groupCount; i++) {
249
            GroupStructure structure = mStructures.get(i);
250
            if (structure.hasHeader()) {
251
                itemCount += 1;
252
                if (position < itemCount) {
253
                    return TYPE_HEADER;
254
                }
255
            }
256
257
            itemCount += structure.getChildrenCount();
258
            if (position < itemCount) {
259
                return TYPE_CHILD;
260
            }
261
262
            if (structure.hasFooter()) {
263
                itemCount += 1;
264
                if (position < itemCount) {
265
                    return TYPE_FOOTER;
266
                }
267
            }
268
        }
269
270
        return TYPE_EMPTY;
271
    }
272
273
    /**
274
     * 重置组结构列表
275
     */
276
    private void structureChanged() {
277
        mStructures.clear();
278
        int groupCount = getGroupCount();
279
        for (int i = 0; i < groupCount; i++) {
280
            mStructures.add(new GroupStructure(hasHeader(i), hasFooter(i), getChildrenCount(i)));
281
        }
282
        isDataChanged = false;
283
    }
284
285
    /**
286
     * 根据下标计算position所在的组(groupPosition)
287
     *
288
     * @param position 下标
289
     * @return 组下标 groupPosition
290
     */
291
    public int getGroupPositionForPosition(int position) {
292
        int count = 0;
293
        int groupCount = mStructures.size();
294
        for (int i = 0; i < groupCount; i++) {
295
            count += countGroupItem(i);
296
            if (position < count) {
297
                return i;
298
            }
299
        }
300
        return -1;
301
    }
302
303
    /**
304
     * 根据下标计算position在组中位置(childPosition)
305
     *
306
     * @param groupPosition 所在的组
307
     * @param position      下标
308
     * @return 子项下标 childPosition
309
     */
310
    public int getChildPositionForPosition(int groupPosition, int position) {
311
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
312
            int itemCount = countGroupRangeItem(0, groupPosition + 1);
313
            GroupStructure structure = mStructures.get(groupPosition);
314
            int p = structure.getChildrenCount() - (itemCount - position)
315
                    + (structure.hasFooter() ? 1 : 0);
316
            if (p >= 0) {
317
                return p;
318
            }
319
        }
320
        return -1;
321
    }
322
323
    /**
324
     * 获取一个组的开始下标,这个下标可能是组头,可能是子项(如果没有组头)或者组尾(如果这个组只有组尾)
325
     *
326
     * @param groupPosition 组下标
327
     * @return
328
     */
329
    public int getPositionForGroup(int groupPosition) {
330
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
331
            return countGroupRangeItem(0, groupPosition);
332
        } else {
333
            return -1;
334
        }
335
336
    }
337
338
    /**
339
     * 获取一个组的组头下标 如果该组没有组头 返回-1
340
     *
341
     * @param groupPosition 组下标
342
     * @return 下标
343
     */
344
    public int getPositionForGroupHeader(int groupPosition) {
345
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
346
            GroupStructure structure = mStructures.get(groupPosition);
347
            if (!structure.hasHeader()) {
348
                return -1;
349
            }
350
            return countGroupRangeItem(0, groupPosition);
351
        }
352
        return -1;
353
    }
354
355
    /**
356
     * 获取一个组的组尾下标 如果该组没有组尾 返回-1
357
     *
358
     * @param groupPosition 组下标
359
     * @return 下标
360
     */
361
    public int getPositionForGroupFooter(int groupPosition) {
362
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
363
            GroupStructure structure = mStructures.get(groupPosition);
364
            if (!structure.hasFooter()) {
365
                return -1;
366
            }
367
            return countGroupRangeItem(0, groupPosition + 1) - 1;
368
        }
369
        return -1;
370
    }
371
372
    /**
373
     * 获取一个组指定的子项下标 如果没有 返回-1
374
     *
375
     * @param groupPosition 组下标
376
     * @param childPosition 子项的组内下标
377
     * @return 下标
378
     */
379
    public int getPositionForChild(int groupPosition, int childPosition) {
380
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
381
            GroupStructure structure = mStructures.get(groupPosition);
382
            if (structure.getChildrenCount() > childPosition) {
383
                int itemCount = countGroupRangeItem(0, groupPosition);
384
                return itemCount + childPosition + (structure.hasHeader() ? 1 : 0);
385
            }
386
        }
387
        return -1;
388
    }
389
390
    /**
391
     * 计算一个组里有多少个Item(头加尾加子项)
392
     *
393
     * @param groupPosition
394
     * @return
395
     */
396
    public int countGroupItem(int groupPosition) {
397
        int itemCount = 0;
398
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
399
            GroupStructure structure = mStructures.get(groupPosition);
400
            if (structure.hasHeader()) {
401
                itemCount += 1;
402
            }
403
            itemCount += structure.getChildrenCount();
404
            if (structure.hasFooter()) {
405
                itemCount += 1;
406
            }
407
        }
408
        return itemCount;
409
    }
410
411
    /**
412
     * 计算多个组的项的总和
413
     *
414
     * @return
415
     */
416
    public int countGroupRangeItem(int start, int count) {
417
        int itemCount = 0;
418
        int size = mStructures.size();
419
        for (int i = start; i < size && i < start + count; i++) {
420
            itemCount += countGroupItem(i);
421
        }
422
        return itemCount;
423
    }
424
425
    /**
426
     * 设置空布局显示。默认不显示
427
     * @param isShow
428
     */
429
    public void showEmptyView(boolean isShow){
430
        if (isShow != showEmptyView){
431
            showEmptyView = isShow;
432
            notifyDataChanged();
433
        }
434
    }
435
436
    public boolean isShowEmptyView(){
437
        return showEmptyView;
438
    }
439
440
    //****** 刷新操作 *****//
441
442
    /**
443
     * Use {@link #notifyDataChanged()} instead.
444
     */
445
    @Deprecated
446
    public void changeDataSet() {
447
        notifyDataChanged();
448
    }
449
450
    /**
451
     * 通知数据列表刷新
452
     */
453
    public void notifyDataChanged() {
454
        isDataChanged = true;
455
        notifyDataSetChanged();
456
    }
457
458
    /**
459
     * Use {@link #notifyGroupChanged(int)} instead.
460
     *
461
     * @param groupPosition
462
     */
463
    @Deprecated
464
    public void changeGroup(int groupPosition) {
465
        notifyGroupChanged(groupPosition);
466
    }
467
468
    /**
469
     * 通知一组数据刷新,包括组头,组尾和子项
470
     *
471
     * @param groupPosition
472
     */
473
    public void notifyGroupChanged(int groupPosition) {
474
        int index = getPositionForGroup(groupPosition);
475
        int itemCount = countGroupItem(groupPosition);
476
        if (index >= 0 && itemCount > 0) {
477
            notifyItemRangeChanged(index, itemCount);
478
        }
479
    }
480
481
    /**
482
     * Use {@link #notifyGroupRangeChanged(int, int)} instead.
483
     *
484
     * @param groupPosition
485
     * @param count
486
     */
487
    @Deprecated
488
    public void changeRangeGroup(int groupPosition, int count) {
489
        notifyGroupRangeChanged(groupPosition, count);
490
    }
491
492
    /**
493
     * 通知多组数据刷新,包括组头,组尾和子项
494
     *
495
     * @param groupPosition
496
     */
497
    public void notifyGroupRangeChanged(int groupPosition, int count) {
498
        int index = getPositionForGroup(groupPosition);
499
        int itemCount = 0;
500
        if (groupPosition + count <= mStructures.size()) {
501
            itemCount = countGroupRangeItem(groupPosition, groupPosition + count);
502
        } else {
503
            itemCount = countGroupRangeItem(groupPosition, mStructures.size());
504
        }
505
        if (index >= 0 && itemCount > 0) {
506
            notifyItemRangeChanged(index, itemCount);
507
        }
508
    }
509
510
    /**
511
     * Use {@link #notifyHeaderChanged(int)} instead.
512
     *
513
     * @param groupPosition
514
     */
515
    @Deprecated
516
    public void changeHeader(int groupPosition) {
517
        notifyHeaderChanged(groupPosition);
518
    }
519
520
    /**
521
     * 通知组头刷新
522
     *
523
     * @param groupPosition
524
     */
525
    public void notifyHeaderChanged(int groupPosition) {
526
        int index = getPositionForGroupHeader(groupPosition);
527
        if (index >= 0) {
528
            notifyItemChanged(index);
529
        }
530
    }
531
532
    /**
533
     * Use {@link #notifyFooterChanged(int)} instead.
534
     *
535
     * @param groupPosition
536
     */
537
    @Deprecated
538
    public void changeFooter(int groupPosition) {
539
        notifyFooterChanged(groupPosition);
540
    }
541
542
    /**
543
     * 通知组尾刷新
544
     *
545
     * @param groupPosition
546
     */
547
    public void notifyFooterChanged(int groupPosition) {
548
        int index = getPositionForGroupFooter(groupPosition);
549
        if (index >= 0) {
550
            notifyItemChanged(index);
551
        }
552
    }
553
554
    /**
555
     * Use {@link #notifyChildChanged(int, int)} instead.
556
     *
557
     * @param groupPosition
558
     * @param childPosition
559
     */
560
    @Deprecated
561
    public void changeChild(int groupPosition, int childPosition) {
562
        notifyChildChanged(groupPosition, childPosition);
563
    }
564
565
    /**
566
     * 通知一组里的某个子项刷新
567
     *
568
     * @param groupPosition
569
     * @param childPosition
570
     */
571
    public void notifyChildChanged(int groupPosition, int childPosition) {
572
        int index = getPositionForChild(groupPosition, childPosition);
573
        if (index >= 0) {
574
            notifyItemChanged(index);
575
        }
576
    }
577
578
    /**
579
     * Use {@link #notifyChildRangeChanged(int, int, int)} instead.
580
     *
581
     * @param groupPosition
582
     * @param childPosition
583
     * @param count
584
     */
585
    @Deprecated
586
    public void changeRangeChild(int groupPosition, int childPosition, int count) {
587
        notifyChildRangeChanged(groupPosition, childPosition, count);
588
    }
589
590
    /**
591
     * 通知一组里的多个子项刷新
592
     *
593
     * @param groupPosition
594
     * @param childPosition
595
     * @param count
596
     */
597
    public void notifyChildRangeChanged(int groupPosition, int childPosition, int count) {
598
        if (groupPosition < mStructures.size()) {
599
            int index = getPositionForChild(groupPosition, childPosition);
600
            if (index >= 0) {
601
                GroupStructure structure = mStructures.get(groupPosition);
602
                if (structure.getChildrenCount() >= childPosition + count) {
603
                    notifyItemRangeChanged(index, count);
604
                } else {
605
                    notifyItemRangeChanged(index, structure.getChildrenCount() - childPosition);
606
                }
607
            }
608
        }
609
    }
610
611
    /**
612
     * Use {@link #notifyChildrenChanged(int)} instead.
613
     *
614
     * @param groupPosition
615
     */
616
    @Deprecated
617
    public void changeChildren(int groupPosition) {
618
        notifyChildrenChanged(groupPosition);
619
    }
620
621
    /**
622
     * 通知一组里的所有子项刷新
623
     *
624
     * @param groupPosition
625
     */
626
    public void notifyChildrenChanged(int groupPosition) {
627
        if (groupPosition >= 0 && groupPosition < mStructures.size()) {
628
            int index = getPositionForChild(groupPosition, 0);
629
            if (index >= 0) {
630
                GroupStructure structure = mStructures.get(groupPosition);
631
                notifyItemRangeChanged(index, structure.getChildrenCount());
632
            }
633
        }
634
    }
635
636
    //****** 删除操作 *****//
637
638
    /**
639
     * Use {@link #notifyDataRemoved()} instead.
640
     */
641
    @Deprecated
642
    public void removeAll() {
643
        notifyDataRemoved();
644
    }
645
646
    /**
647
     * 通知所有数据删除
648
     */
649
    public void notifyDataRemoved() {
650
        int count = countGroupRangeItem(0, mStructures.size());
651
        mStructures.clear();
652
        notifyItemRangeRemoved(0, count);
653
    }
654
655
    /**
656
     * Use {@link #notifyGroupRemoved(int)} instead.
657
     */
658
    @Deprecated
659
    public void removeGroup(int groupPosition) {
660
        notifyGroupRemoved(groupPosition);
661
    }
662
663
    /**
664
     * 通知一组数据删除,包括组头,组尾和子项
665
     *
666
     * @param groupPosition
667
     */
668
    public void notifyGroupRemoved(int groupPosition) {
669
        int index = getPositionForGroup(groupPosition);
670
        int itemCount = countGroupItem(groupPosition);
671
        if (index >= 0 && itemCount > 0) {
672
            mStructures.remove(groupPosition);
673
            notifyItemRangeRemoved(index, itemCount);
674
        }
675
    }
676
677
    /**
678
     * Use {@link #notifyGroupRangeRemoved(int, int)} instead.
679
     */
680
    @Deprecated
681
    public void removeRangeGroup(int groupPosition, int count) {
682
        notifyGroupRangeRemoved(groupPosition, count);
683
    }
684
685
    /**
686
     * 通知多组数据删除,包括组头,组尾和子项
687
     *
688
     * @param groupPosition
689
     */
690
    public void notifyGroupRangeRemoved(int groupPosition, int count) {
691
        int index = getPositionForGroup(groupPosition);
692
        int itemCount = 0;
693
        if (groupPosition + count <= mStructures.size()) {
694
            itemCount = countGroupRangeItem(groupPosition, groupPosition + count);
695
        } else {
696
            itemCount = countGroupRangeItem(groupPosition, mStructures.size());
697
        }
698
        if (index >= 0 && itemCount > 0) {
699
            mStructures.remove(groupPosition);
700
            notifyItemRangeRemoved(index, itemCount);
701
        }
702
    }
703
704
    /**
705
     * Use {@link #notifyHeaderRemoved(int)} instead.
706
     */
707
    @Deprecated
708
    public void removeHeader(int groupPosition) {
709
        notifyHeaderRemoved(groupPosition);
710
    }
711
712
    /**
713
     * 通知组头删除
714
     *
715
     * @param groupPosition
716
     */
717
    public void notifyHeaderRemoved(int groupPosition) {
718
        int index = getPositionForGroupHeader(groupPosition);
719
        if (index >= 0) {
720
            GroupStructure structure = mStructures.get(groupPosition);
721
            structure.setHasHeader(false);
722
            notifyItemRemoved(index);
723
        }
724
    }
725
726
    /**
727
     * Use {@link #notifyFooterRemoved(int)} instead.
728
     *
729
     * @param groupPosition
730
     */
731
    @Deprecated
732
    public void removeFooter(int groupPosition) {
733
        notifyFooterRemoved(groupPosition);
734
    }
735
736
    /**
737
     * 通知组尾删除
738
     *
739
     * @param groupPosition
740
     */
741
    public void notifyFooterRemoved(int groupPosition) {
742
        int index = getPositionForGroupFooter(groupPosition);
743
        if (index >= 0) {
744
            GroupStructure structure = mStructures.get(groupPosition);
745
            structure.setHasFooter(false);
746
            notifyItemRemoved(index);
747
        }
748
    }
749
750
    /**
751
     * Use {@link #notifyChildRemoved(int, int)} instead.
752
     *
753
     * @param groupPosition
754
     * @param childPosition
755
     */
756
    @Deprecated
757
    public void removeChild(int groupPosition, int childPosition) {
758
        notifyChildRemoved(groupPosition, childPosition);
759
    }
760
761
    /**
762
     * 通知一组里的某个子项删除
763
     *
764
     * @param groupPosition
765
     * @param childPosition
766
     */
767
    public void notifyChildRemoved(int groupPosition, int childPosition) {
768
        int index = getPositionForChild(groupPosition, childPosition);
769
        if (index >= 0) {
770
            GroupStructure structure = mStructures.get(groupPosition);
771
            structure.setChildrenCount(structure.getChildrenCount() - 1);
772
            notifyItemRemoved(index);
773
        }
774
    }
775
776
    /**
777
     * Use {@link #notifyChildRangeRemoved(int, int, int)} instead.
778
     *
779
     * @param groupPosition
780
     * @param childPosition
781
     * @param count
782
     */
783
    @Deprecated
784
    public void removeRangeChild(int groupPosition, int childPosition, int count) {
785
        notifyChildRangeRemoved(groupPosition, childPosition, count);
786
    }
787
788
    /**
789
     * 通知一组里的多个子项删除
790
     *
791
     * @param groupPosition
792
     * @param childPosition
793
     * @param count
794
     */
795
    public void notifyChildRangeRemoved(int groupPosition, int childPosition, int count) {
796
        if (groupPosition < mStructures.size()) {
797
            int index = getPositionForChild(groupPosition, childPosition);
798
            if (index >= 0) {
799
                GroupStructure structure = mStructures.get(groupPosition);
800
                int childCount = structure.getChildrenCount();
801
                int removeCount = count;
802
                if (childCount < childPosition + count) {
803
                    removeCount = childCount - childPosition;
804
                }
805
                structure.setChildrenCount(childCount - removeCount);
806
                notifyItemRangeRemoved(index, removeCount);
807
            }
808
        }
809
    }
810
811
    /**
812
     * Use {@link #notifyChildrenRemoved(int)} instead.
813
     *
814
     * @param groupPosition
815
     */
816
    @Deprecated
817
    public void removeChildren(int groupPosition) {
818
        notifyChildrenRemoved(groupPosition);
819
    }
820
821
    /**
822
     * 通知一组里的所有子项删除
823
     *
824
     * @param groupPosition
825
     */
826
    public void notifyChildrenRemoved(int groupPosition) {
827
        if (groupPosition < mStructures.size()) {
828
            int index = getPositionForChild(groupPosition, 0);
829
            if (index >= 0) {
830
                GroupStructure structure = mStructures.get(groupPosition);
831
                int itemCount = structure.getChildrenCount();
832
                structure.setChildrenCount(0);
833
                notifyItemRangeRemoved(index, itemCount);
834
            }
835
        }
836
    }
837
838
    //****** 插入操作 *****//
839
840
    /**
841
     * Use {@link #notifyGroupInserted(int)} instead.
842
     *
843
     * @param groupPosition
844
     */
845
    @Deprecated
846
    public void insertGroup(int groupPosition) {
847
        notifyGroupInserted(groupPosition);
848
    }
849
850
    /**
851
     * 通知一组数据插入
852
     *
853
     * @param groupPosition
854
     */
855
    public void notifyGroupInserted(int groupPosition) {
856
        GroupStructure structure = new GroupStructure(hasHeader(groupPosition),
857
                hasFooter(groupPosition), getChildrenCount(groupPosition));
858
        if (groupPosition < mStructures.size()) {
859
            mStructures.add(groupPosition, structure);
860
        } else {
861
            mStructures.add(structure);
862
            groupPosition = mStructures.size() - 1;
863
        }
864
865
        int index = countGroupRangeItem(0, groupPosition);
866
        int itemCount = countGroupItem(groupPosition);
867
        if (itemCount > 0) {
868
            notifyItemRangeInserted(index, itemCount);
869
        }
870
    }
871
872
    /**
873
     * Use {@link #notifyGroupRangeInserted(int, int)} instead.
874
     *
875
     * @param groupPosition
876
     * @param count
877
     */
878
    @Deprecated
879
    public void insertRangeGroup(int groupPosition, int count) {
880
        notifyGroupRangeInserted(groupPosition, count);
881
    }
882
883
    /**
884
     * 通知多组数据插入
885
     *
886
     * @param groupPosition
887
     * @param count
888
     */
889
    public void notifyGroupRangeInserted(int groupPosition, int count) {
890
        ArrayList<GroupStructure> list = new ArrayList<>();
891
        for (int i = 0; i < count; i++) {
892
            GroupStructure structure = new GroupStructure(hasHeader(i),
893
                    hasFooter(i), getChildrenCount(i));
894
            list.add(structure);
895
        }
896
897
        if (groupPosition < mStructures.size()) {
898
            mStructures.addAll(groupPosition, list);
899
        } else {
900
            mStructures.addAll(list);
901
            groupPosition = mStructures.size() - list.size();
902
        }
903
904
        int index = countGroupRangeItem(0, groupPosition);
905
        int itemCount = countGroupRangeItem(groupPosition, count);
906
        if (itemCount > 0) {
907
            notifyItemRangeInserted(index, itemCount);
908
        }
909
    }
910
911
    /**
912
     * Use {@link #notifyHeaderInserted(int)} instead.
913
     *
914
     * @param groupPosition
915
     */
916
    @Deprecated
917
    public void insertHeader(int groupPosition) {
918
        notifyHeaderInserted(groupPosition);
919
    }
920
921
    /**
922
     * 通知组头插入
923
     *
924
     * @param groupPosition
925
     */
926
    public void notifyHeaderInserted(int groupPosition) {
927
        if (groupPosition < mStructures.size() && 0 > getPositionForGroupHeader(groupPosition)) {
928
            GroupStructure structure = mStructures.get(groupPosition);
929
            structure.setHasHeader(true);
930
            int index = countGroupRangeItem(0, groupPosition);
931
            notifyItemInserted(index);
932
        }
933
    }
934
935
    /**
936
     * Use {@link #notifyFooterInserted(int)} instead.
937
     *
938
     * @param groupPosition
939
     */
940
    @Deprecated
941
    public void insertFooter(int groupPosition) {
942
        notifyFooterInserted(groupPosition);
943
    }
944
945
    /**
946
     * 通知组尾插入
947
     *
948
     * @param groupPosition
949
     */
950
    public void notifyFooterInserted(int groupPosition) {
951
        if (groupPosition < mStructures.size() && 0 > getPositionForGroupFooter(groupPosition)) {
952
            GroupStructure structure = mStructures.get(groupPosition);
953
            structure.setHasFooter(true);
954
            int index = countGroupRangeItem(0, groupPosition + 1);
955
            notifyItemInserted(index);
956
        }
957
    }
958
959
    /**
960
     * Use {@link #notifyChildInserted(int, int)} instead.
961
     *
962
     * @param groupPosition
963
     * @param childPosition
964
     */
965
    @Deprecated
966
    public void insertChild(int groupPosition, int childPosition) {
967
        notifyChildInserted(groupPosition, childPosition);
968
    }
969
970
    /**
971
     * 通知一个子项到组里插入
972
     *
973
     * @param groupPosition
974
     * @param childPosition
975
     */
976
    public void notifyChildInserted(int groupPosition, int childPosition) {
977
        if (groupPosition < mStructures.size()) {
978
            GroupStructure structure = mStructures.get(groupPosition);
979
            int index = getPositionForChild(groupPosition, childPosition);
980
            if (index < 0) {
981
                index = countGroupRangeItem(0, groupPosition);
982
                index += structure.hasHeader() ? 1 : 0;
983
                index += structure.getChildrenCount();
984
            }
985
            structure.setChildrenCount(structure.getChildrenCount() + 1);
986
            notifyItemInserted(index);
987
        }
988
    }
989
990
    /**
991
     * Use {@link #notifyChildRangeInserted(int, int, int)} instead.
992
     *
993
     * @param groupPosition
994
     * @param childPosition
995
     * @param count
996
     */
997
    @Deprecated
998
    public void insertRangeChild(int groupPosition, int childPosition, int count) {
999
        notifyChildRangeInserted(groupPosition, childPosition, count);
1000
    }
1001
1002
    /**
1003
     * 通知一组里的多个子项插入
1004
     *
1005
     * @param groupPosition
1006
     * @param childPosition
1007
     * @param count
1008
     */
1009
    public void notifyChildRangeInserted(int groupPosition, int childPosition, int count) {
1010
        if (groupPosition < mStructures.size()) {
1011
            int index = countGroupRangeItem(0, groupPosition);
1012
            GroupStructure structure = mStructures.get(groupPosition);
1013
            if (structure.hasHeader()) {
1014
                index++;
1015
            }
1016
            if (childPosition < structure.getChildrenCount()) {
1017
                index += childPosition;
1018
            } else {
1019
                index += structure.getChildrenCount();
1020
            }
1021
            if (count > 0) {
1022
                structure.setChildrenCount(structure.getChildrenCount() + count);
1023
                notifyItemRangeInserted(index, count);
1024
            }
1025
        }
1026
    }
1027
1028
    /**
1029
     * Use {@link #notifyChildrenInserted(int)} instead.
1030
     *
1031
     * @param groupPosition
1032
     */
1033
    @Deprecated
1034
    public void insertChildren(int groupPosition) {
1035
        notifyChildrenInserted(groupPosition);
1036
    }
1037
1038
    /**
1039
     * 通知一组里的所有子项插入
1040
     *
1041
     * @param groupPosition
1042
     */
1043
    public void notifyChildrenInserted(int groupPosition) {
1044
        if (groupPosition < mStructures.size()) {
1045
            int index = countGroupRangeItem(0, groupPosition);
1046
            GroupStructure structure = mStructures.get(groupPosition);
1047
            if (structure.hasHeader()) {
1048
                index++;
1049
            }
1050
            int itemCount = getChildrenCount(groupPosition);
1051
            if (itemCount > 0) {
1052
                structure.setChildrenCount(itemCount);
1053
                notifyItemRangeInserted(index, itemCount);
1054
            }
1055
        }
1056
    }
1057
1058
    //****** 设置点击事件 *****//
1059
1060
    /**
1061
     * 设置组头点击事件
1062
     *
1063
     * @param listener
1064
     */
1065
    public void setOnHeaderClickListener(OnHeaderClickListener listener) {
1066
        mOnHeaderClickListener = listener;
1067
    }
1068
1069
    /**
1070
     * 设置组尾点击事件
1071
     *
1072
     * @param listener
1073
     */
1074
    public void setOnFooterClickListener(OnFooterClickListener listener) {
1075
        mOnFooterClickListener = listener;
1076
    }
1077
1078
    /**
1079
     * 设置子项点击事件
1080
     *
1081
     * @param listener
1082
     */
1083
    public void setOnChildClickListener(OnChildClickListener listener) {
1084
        mOnChildClickListener = listener;
1085
    }
1086
1087
    public abstract int getGroupCount();
1088
1089
    public abstract int getChildrenCount(int groupPosition);
1090
1091
    public abstract boolean hasHeader(int groupPosition);
1092
1093
    public abstract boolean hasFooter(int groupPosition);
1094
1095
    public abstract int getHeaderLayout(int viewType);
1096
1097
    public abstract int getFooterLayout(int viewType);
1098
1099
    public abstract int getChildLayout(int viewType);
1100
1101
    public abstract void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition);
1102
1103
    public abstract void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition);
1104
1105
    public abstract void onBindChildViewHolder(BaseViewHolder holder,
1106
                                               int groupPosition, int childPosition);
1107
1108
    /**
1109
     * 获取空布局
1110
     * @param parent
1111
     * @return
1112
     */
1113
    public View getEmptyView(ViewGroup parent){
1114
        View view = LayoutInflater.from(mContext).inflate(R.layout.group_adapter_default_empty_view, parent, false);
1115
        return view;
1116
    }
1117
1118
    class GroupDataObserver extends RecyclerView.AdapterDataObserver {
1119
1120
        @Override
1121
        public void onChanged() {
1122
            isDataChanged = true;
1123
        }
1124
1125
        public void onItemRangeChanged(int positionStart, int itemCount) {
1126
            isDataChanged = true;
1127
        }
1128
1129
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
1130
            onItemRangeChanged(positionStart, itemCount);
1131
        }
1132
1133
        public void onItemRangeInserted(int positionStart, int itemCount) {
1134
            isDataChanged = true;
1135
        }
1136
1137
        public void onItemRangeRemoved(int positionStart, int itemCount) {
1138
            isDataChanged = true;
1139
        }
1140
    }
1141
1142
    public interface OnHeaderClickListener {
1143
        void onHeaderClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition);
1144
    }
1145
1146
    public interface OnFooterClickListener {
1147
        void onFooterClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition);
1148
    }
1149
1150
    public interface OnChildClickListener {
1151
        void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder,
1152
                          int groupPosition, int childPosition);
1153
    }
1154
}

+ 126 - 0
app/src/main/java/com/donkingliang/groupedadapter/holder/BaseViewHolder.java

@ -0,0 +1,126 @@
1
package com.donkingliang.groupedadapter.holder;
2
3
import android.graphics.Bitmap;
4
import android.graphics.drawable.Drawable;
5
import android.util.SparseArray;
6
import android.view.View;
7
import android.widget.ImageView;
8
import android.widget.TextView;
9
10
import androidx.databinding.DataBindingUtil;
11
import androidx.databinding.ViewDataBinding;
12
import androidx.recyclerview.widget.RecyclerView;
13
14
/**
15
 * 通用的RecyclerView.ViewHolder。提供了根据viewId获取View的方法。
16
 * 提供了对View、TextView、ImageView的常用设置方法。
17
 */
18
public class BaseViewHolder extends RecyclerView.ViewHolder {
19
20
    private SparseArray<View> mViews;
21
22
    public BaseViewHolder(View itemView) {
23
        super(itemView);
24
        mViews = new SparseArray<>();
25
    }
26
27
    /**
28
     * 获取item对应的ViewDataBinding对象
29
     *
30
     * @param <T>
31
     * @return
32
     */
33
    public <T extends ViewDataBinding> T getBinding() {
34
        return DataBindingUtil.getBinding(this.itemView);
35
    }
36
37
    /**
38
     * 根据View Id 获取对应的View
39
     *
40
     * @param viewId
41
     * @param <T>
42
     * @return
43
     */
44
    public <T extends View> T get(int viewId) {
45
        View view = mViews.get(viewId);
46
        if (view == null) {
47
            view = this.itemView.findViewById(viewId);
48
            mViews.put(viewId, view);
49
        }
50
        return (T) view;
51
    }
52
53
    //******** 提供对View、TextView、ImageView的常用设置方法 ******//
54
55
    public BaseViewHolder setText(int viewId, String text) {
56
        TextView tv = get(viewId);
57
        tv.setText(text);
58
        return this;
59
    }
60
61
    public BaseViewHolder setText(int viewId, int textRes) {
62
        TextView tv = get(viewId);
63
        tv.setText(textRes);
64
        return this;
65
    }
66
67
    public BaseViewHolder setTextColor(int viewId, int textColor) {
68
        TextView view = get(viewId);
69
        view.setTextColor(textColor);
70
        return this;
71
    }
72
73
    public BaseViewHolder setTextSize(int viewId, int size) {
74
        TextView view = get(viewId);
75
        view.setTextSize(size);
76
        return this;
77
    }
78
79
    public BaseViewHolder setImageResource(int viewId, int resId) {
80
        ImageView view = get(viewId);
81
        view.setImageResource(resId);
82
        return this;
83
    }
84
85
    public BaseViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
86
        ImageView view = get(viewId);
87
        view.setImageBitmap(bitmap);
88
        return this;
89
    }
90
91
92
    public BaseViewHolder setImageDrawable(int viewId, Drawable drawable) {
93
        ImageView view = get(viewId);
94
        view.setImageDrawable(drawable);
95
        return this;
96
    }
97
98
99
    public BaseViewHolder setBackgroundColor(int viewId, int color) {
100
        View view = get(viewId);
101
        view.setBackgroundColor(color);
102
        return this;
103
    }
104
105
    public BaseViewHolder setBackgroundRes(int viewId, int backgroundRes) {
106
        View view = get(viewId);
107
        view.setBackgroundResource(backgroundRes);
108
        return this;
109
    }
110
111
    public BaseViewHolder setVisible(int viewId, boolean visible) {
112
        View view = get(viewId);
113
        view.setVisibility(visible ? View.VISIBLE : View.GONE);
114
        return this;
115
    }
116
117
    public BaseViewHolder setVisible(int viewId, int visible) {
118
        View view = get(viewId);
119
        view.setVisibility(visible);
120
        return this;
121
    }
122
123
    public ImageView getImageView(int viewId) {
124
        return get(viewId);
125
    }
126
}

+ 77 - 0
app/src/main/java/com/donkingliang/groupedadapter/layoutmanger/GroupedGridLayoutManager.java

@ -0,0 +1,77 @@
1
package com.donkingliang.groupedadapter.layoutmanger;
2
3
import android.content.Context;
4
import android.util.AttributeSet;
5
6
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
7
8
import androidx.recyclerview.widget.GridLayoutManager;
9
10
11
/**
12
 * 为分组列表提供的GridLayoutManager。
13
 * 因为分组列表如果要使用GridLayoutManager实现网格布局。要保证组的头部和尾部是要单独占用一行的。
14
 * 否则组的头、尾可能会跟子项混着一起,造成布局混乱。
15
 */
16
public class GroupedGridLayoutManager extends GridLayoutManager {
17
18
    private GroupedRecyclerViewAdapter mAdapter;
19
20
    public GroupedGridLayoutManager(Context context, int spanCount,
21
                                    GroupedRecyclerViewAdapter adapter) {
22
        super(context, spanCount);
23
        mAdapter = adapter;
24
        setSpanSizeLookup();
25
    }
26
27
    public GroupedGridLayoutManager(Context context, int spanCount, int orientation,
28
                                    boolean reverseLayout, GroupedRecyclerViewAdapter adapter) {
29
        super(context, spanCount, orientation, reverseLayout);
30
        this.mAdapter = adapter;
31
        setSpanSizeLookup();
32
    }
33
34
    public GroupedGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
35
                                    int defStyleRes, GroupedRecyclerViewAdapter adapter) {
36
        super(context, attrs, defStyleAttr, defStyleRes);
37
        this.mAdapter = adapter;
38
        setSpanSizeLookup();
39
    }
40
41
    private void setSpanSizeLookup() {
42
        super.setSpanSizeLookup(new SpanSizeLookup() {
43
            @Override
44
            public int getSpanSize(int position) {
45
                int count = getSpanCount();
46
                if (mAdapter != null) {
47
                    int type = mAdapter.judgeType(position);
48
                    //只对子项做Grid效果
49
                    if (type == GroupedRecyclerViewAdapter.TYPE_CHILD) {
50
                        int groupPosition = mAdapter.getGroupPositionForPosition(position);
51
                        int childPosition =
52
                                mAdapter.getChildPositionForPosition(groupPosition, position);
53
                        return getChildSpanSize(groupPosition, childPosition);
54
                    }
55
                }
56
57
                return count;
58
            }
59
        });
60
    }
61
62
    /**
63
     * 提供这个方法可以使外部改变子项的SpanSize。
64
     * 这个方法的作用跟{@link SpanSizeLookup#getSpanSize(int)}一样。
65
     * @param groupPosition
66
     * @param childPosition
67
     * @return
68
     */
69
    public int getChildSpanSize(int groupPosition, int childPosition) {
70
        return 1;
71
    }
72
73
    @Override
74
    public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup) {
75
76
    }
77
}

+ 43 - 0
app/src/main/java/com/donkingliang/groupedadapter/structure/GroupStructure.java

@ -0,0 +1,43 @@
1
package com.donkingliang.groupedadapter.structure;
2
3
/**
4
 * 这个类是用来记录分组列表中组的结构的。
5
 * 通过GroupStructure记录每个组是否有头部,是否有尾部和子项的数量。从而能方便的计算
6
 * 列表的长度和每个组的组头、组尾和子项在列表中的位置。
7
 */
8
public class GroupStructure {
9
10
    private boolean hasHeader;
11
    private boolean hasFooter;
12
    private int childrenCount;
13
14
    public GroupStructure(boolean hasHeader, boolean hasFooter, int childrenCount) {
15
        this.hasHeader = hasHeader;
16
        this.hasFooter = hasFooter;
17
        this.childrenCount = childrenCount;
18
    }
19
20
    public boolean hasHeader() {
21
        return hasHeader;
22
    }
23
24
    public void setHasHeader(boolean hasHeader) {
25
        this.hasHeader = hasHeader;
26
    }
27
28
    public boolean hasFooter() {
29
        return hasFooter;
30
    }
31
32
    public void setHasFooter(boolean hasFooter) {
33
        this.hasFooter = hasFooter;
34
    }
35
36
    public int getChildrenCount() {
37
        return childrenCount;
38
    }
39
40
    public void setChildrenCount(int childrenCount) {
41
        this.childrenCount = childrenCount;
42
    }
43
}

+ 439 - 0
app/src/main/java/com/donkingliang/groupedadapter/widget/StickyHeaderLayout.java

@ -0,0 +1,439 @@
1
package com.donkingliang.groupedadapter.widget;
2
3
import android.content.Context;
4
import android.util.AttributeSet;
5
import android.util.SparseArray;
6
import android.view.View;
7
import android.view.ViewGroup;
8
import android.widget.FrameLayout;
9
10
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
11
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
12
13
import java.lang.reflect.Method;
14
15
import androidx.annotation.AttrRes;
16
import androidx.annotation.NonNull;
17
import androidx.annotation.Nullable;
18
import androidx.recyclerview.widget.GridLayoutManager;
19
import androidx.recyclerview.widget.LinearLayoutManager;
20
import androidx.recyclerview.widget.RecyclerView;
21
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
22
23
/**
24
 * Depiction:头部吸顶布局。只要用StickyHeaderLayout包裹{@link RecyclerView},
25
 * 并且使用{@link GroupedRecyclerViewAdapter},就可以实现列表头部吸顶功能。
26
 * StickyHeaderLayout只能包裹RecyclerView,而且只能包裹一个RecyclerView。
27
 * <p>
28
 * Author:donkingliang  QQ:1043214265
29
 * Dat:2017/11/14
30
 */
31
public class StickyHeaderLayout extends FrameLayout {
32
33
    private Context mContext;
34
    private RecyclerView mRecyclerView;
35
36
    //吸顶容器,用于承载吸顶布局。
37
    private FrameLayout mStickyLayout;
38
39
    //保存吸顶布局的缓存池。它以列表组头的viewType为key,ViewHolder为value对吸顶布局进行保存和回收复用。
40
    private final SparseArray<BaseViewHolder> mStickyViews = new SparseArray<>();
41
42
    //用于在吸顶布局中保存viewType的key。
43
    private final int VIEW_TAG_TYPE = -101;
44
45
    //用于在吸顶布局中保存ViewHolder的key。
46
    private final int VIEW_TAG_HOLDER = -102;
47
48
    //记录当前吸顶的组。
49
    private int mCurrentStickyGroup = -1;
50
51
    //是否吸顶。
52
    private boolean isSticky = true;
53
54
    //是否已经注册了adapter刷新监听
55
    private boolean isRegisterDataObserver = false;
56
57
    public StickyHeaderLayout(@NonNull Context context) {
58
        super(context);
59
        mContext = context;
60
    }
61
62
    public StickyHeaderLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
63
        super(context, attrs);
64
        mContext = context;
65
    }
66
67
    public StickyHeaderLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
68
        super(context, attrs, defStyleAttr);
69
        mContext = context;
70
    }
71
72
    @Override
73
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
74
        if (getChildCount() > 0 || !(child instanceof RecyclerView)) {
75
            //外界只能向StickyHeaderLayout添加一个RecyclerView,而且只能添加RecyclerView。
76
            throw new IllegalArgumentException("StickyHeaderLayout can host only one direct child --> RecyclerView");
77
        }
78
        super.addView(child, index, params);
79
        mRecyclerView = (RecyclerView) child;
80
        addOnScrollListener();
81
        addStickyLayout();
82
    }
83
84
    /**
85
     * 添加滚动监听
86
     */
87
    private void addOnScrollListener() {
88
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
89
            @Override
90
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
91
                // 在滚动的时候,需要不断的更新吸顶布局。
92
                if (isSticky) {
93
                    updateStickyView(false);
94
                }
95
            }
96
        });
97
    }
98
99
    /**
100
     * 添加吸顶容器
101
     */
102
    private void addStickyLayout() {
103
        mStickyLayout = new FrameLayout(mContext);
104
        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
105
                LayoutParams.WRAP_CONTENT);
106
        mStickyLayout.setLayoutParams(lp);
107
        super.addView(mStickyLayout, 1, lp);
108
    }
109
110
    /**
111
     * 强制更新吸顶布局。
112
     */
113
    public void updateStickyView() {
114
        updateStickyView(true);
115
    }
116
117
    /**
118
     * 更新吸顶布局。
119
     *
120
     * @param imperative 是否强制更新。
121
     */
122
    private void updateStickyView(boolean imperative) {
123
        RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
124
        //只有RecyclerView的adapter是GroupedRecyclerViewAdapter的时候,才会添加吸顶布局。
125
        if (adapter instanceof GroupedRecyclerViewAdapter) {
126
            GroupedRecyclerViewAdapter gAdapter = (GroupedRecyclerViewAdapter) adapter;
127
            registerAdapterDataObserver(gAdapter);
128
            //获取列表显示的第一个项。
129
            int firstVisibleItem = getFirstVisibleItem();
130
            //通过显示的第一个项的position获取它所在的组。
131
            int groupPosition = gAdapter.getGroupPositionForPosition(firstVisibleItem);
132
133
            //如果当前吸顶的组头不是我们要吸顶的组头,就更新吸顶布局。这样做可以避免频繁的更新吸顶布局。
134
            if (imperative || mCurrentStickyGroup != groupPosition) {
135
                mCurrentStickyGroup = groupPosition;
136
                if (stickyHeaderPositionListener != null) {
137
                    stickyHeaderPositionListener.onHeaderPositionChange(mCurrentStickyGroup);
138
                }
139
                //通过groupPosition获取当前组的组头position。这个组头就是我们需要吸顶的布局。
140
                int groupHeaderPosition = gAdapter.getPositionForGroupHeader(groupPosition);
141
                if (groupHeaderPosition != -1) {
142
                    //获取吸顶布局的viewType。
143
                    int viewType = gAdapter.getItemViewType(groupHeaderPosition);
144
145
                    //如果当前的吸顶布局的类型和我们需要的一样,就直接获取它的ViewHolder,否则就回收。
146
                    BaseViewHolder holder = recycleStickyView(viewType);
147
148
                    //标志holder是否是从当前吸顶布局取出来的。
149
                    boolean flag = holder != null;
150
151
                    if (holder == null) {
152
                        //从缓存池中获取吸顶布局。
153
                        holder = getStickyViewByType(viewType);
154
                    }
155
156
                    if (holder == null) {
157
                        //如果没有从缓存池中获取到吸顶布局,则通过GroupedRecyclerViewAdapter创建。
158
                        holder = (BaseViewHolder) gAdapter.onCreateViewHolder(mStickyLayout, viewType);
159
                        holder.itemView.setTag(VIEW_TAG_TYPE, viewType);
160
                        holder.itemView.setTag(VIEW_TAG_HOLDER, holder);
161
                    }
162
163
                    //通过GroupedRecyclerViewAdapter更新吸顶布局的数据。
164
                    //这样可以保证吸顶布局的显示效果跟列表中的组头保持一致。
165
                    gAdapter.onBindViewHolder(holder, groupHeaderPosition);
166
167
                    //如果holder不是从当前吸顶布局取出来的,就需要把吸顶布局添加到容器里。
168
                    if (!flag) {
169
                        mStickyLayout.addView(holder.itemView);
170
                    }
171
                } else {
172
                    //如果当前组没有组头,则不显示吸顶布局。
173
                    //回收旧的吸顶布局。
174
                    recycle();
175
                }
176
            }
177
178
            //这是是处理第一次打开时,吸顶布局已经添加到StickyLayout,但StickyLayout的高依然为0的情况。
179
            if (mStickyLayout.getChildCount() > 0 && mStickyLayout.getHeight() == 0) {
180
                mStickyLayout.requestLayout();
181
            }
182
183
            //设置mStickyLayout的Y偏移量。
184
            mStickyLayout.setTranslationY(calculateOffset(gAdapter, firstVisibleItem, groupPosition + 1));
185
        }
186
    }
187
188
    /**
189
     * 注册adapter刷新监听
190
     */
191
    private void registerAdapterDataObserver(GroupedRecyclerViewAdapter adapter) {
192
        if (!isRegisterDataObserver) {
193
            isRegisterDataObserver = true;
194
            adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
195
                @Override
196
                public void onChanged() {
197
                    updateStickyViewDelayed();
198
                }
199
200
                @Override
201
                public void onItemRangeChanged(int positionStart, int itemCount) {
202
                    updateStickyViewDelayed();
203
                }
204
205
                @Override
206
                public void onItemRangeInserted(int positionStart, int itemCount) {
207
                    updateStickyViewDelayed();
208
                }
209
210
                @Override
211
                public void onItemRangeRemoved(int positionStart, int itemCount) {
212
                    updateStickyViewDelayed();
213
                }
214
215
            });
216
        }
217
    }
218
219
    private void updateStickyViewDelayed() {
220
        postDelayed(new Runnable() {
221
            @Override
222
            public void run() {
223
                updateStickyView(true);
224
            }
225
        }, 64);
226
    }
227
228
    /**
229
     * 判断是否需要先回收吸顶布局,如果要回收,则回收吸顶布局并返回null。
230
     * 如果不回收,则返回吸顶布局的ViewHolder。
231
     * 这样做可以避免频繁的添加和移除吸顶布局。
232
     *
233
     * @param viewType
234
     * @return
235
     */
236
    private BaseViewHolder recycleStickyView(int viewType) {
237
        if (mStickyLayout.getChildCount() > 0) {
238
            View view = mStickyLayout.getChildAt(0);
239
            int type = (int) view.getTag(VIEW_TAG_TYPE);
240
            if (type == viewType) {
241
                return (BaseViewHolder) view.getTag(VIEW_TAG_HOLDER);
242
            } else {
243
                recycle();
244
            }
245
        }
246
        return null;
247
    }
248
249
    /**
250
     * 回收并移除吸顶布局
251
     */
252
    private void recycle() {
253
        if (mStickyLayout.getChildCount() > 0) {
254
            View view = mStickyLayout.getChildAt(0);
255
            mStickyViews.put((int) (view.getTag(VIEW_TAG_TYPE)),
256
                    (BaseViewHolder) (view.getTag(VIEW_TAG_HOLDER)));
257
            mStickyLayout.removeAllViews();
258
        }
259
    }
260
261
    /**
262
     * 从缓存池中获取吸顶布局
263
     *
264
     * @param viewType 吸顶布局的viewType
265
     * @return
266
     */
267
    private BaseViewHolder getStickyViewByType(int viewType) {
268
        return mStickyViews.get(viewType);
269
    }
270
271
    /**
272
     * 计算StickyLayout的偏移量。因为如果下一个组的组头顶到了StickyLayout,
273
     * 就要把StickyLayout顶上去,直到下一个组的组头变成吸顶布局。否则会发生两个组头重叠的情况。
274
     *
275
     * @param gAdapter
276
     * @param firstVisibleItem 当前列表显示的第一个项。
277
     * @param groupPosition    下一个组的组下标。
278
     * @return 返回偏移量。
279
     */
280
    private float calculateOffset(GroupedRecyclerViewAdapter gAdapter, int firstVisibleItem, int groupPosition) {
281
        int groupHeaderPosition = gAdapter.getPositionForGroupHeader(groupPosition);
282
        if (groupHeaderPosition != -1) {
283
            int index = groupHeaderPosition - firstVisibleItem;
284
            if (mRecyclerView.getChildCount() > index) {
285
                //获取下一个组的组头的itemView。
286
                View view = mRecyclerView.getChildAt(index);
287
                float off = view.getY() - mStickyLayout.getHeight();
288
                if (off < 0) {
289
                    return off;
290
                }
291
            }
292
        }
293
        return 0;
294
    }
295
296
    /**
297
     * 获取当前第一个显示的item .
298
     */
299
    private int getFirstVisibleItem() {
300
        int firstVisibleItem = -1;
301
        RecyclerView.LayoutManager layout = mRecyclerView.getLayoutManager();
302
        if (layout != null) {
303
            if (layout instanceof GridLayoutManager) {
304
                firstVisibleItem = ((GridLayoutManager) layout).findFirstVisibleItemPosition();
305
            } else if (layout instanceof LinearLayoutManager) {
306
                firstVisibleItem = ((LinearLayoutManager) layout).findFirstVisibleItemPosition();
307
            } else if (layout instanceof StaggeredGridLayoutManager) {
308
                int[] firstPositions = new int[((StaggeredGridLayoutManager) layout).getSpanCount()];
309
                ((StaggeredGridLayoutManager) layout).findFirstVisibleItemPositions(firstPositions);
310
                firstVisibleItem = getMin(firstPositions);
311
            }
312
        }
313
        return firstVisibleItem;
314
    }
315
316
    private int getMin(int[] arr) {
317
        int min = arr[0];
318
        for (int x = 1; x < arr.length; x++) {
319
            if (arr[x] < min)
320
                min = arr[x];
321
        }
322
        return min;
323
    }
324
325
    /**
326
     * 是否吸顶
327
     *
328
     * @return
329
     */
330
    public boolean isSticky() {
331
        return isSticky;
332
    }
333
334
    /**
335
     * 设置是否吸顶。
336
     *
337
     * @param sticky
338
     */
339
    public void setSticky(boolean sticky) {
340
        if (isSticky != sticky) {
341
            isSticky = sticky;
342
            if (mStickyLayout != null) {
343
                if (isSticky) {
344
                    mStickyLayout.setVisibility(VISIBLE);
345
                    updateStickyView(false);
346
                } else {
347
                    recycle();
348
                    mStickyLayout.setVisibility(GONE);
349
                }
350
            }
351
        }
352
    }
353
354
    @Override
355
    protected int computeVerticalScrollOffset() {
356
        if (mRecyclerView != null) {
357
            try {
358
                Method method = View.class.getDeclaredMethod("computeVerticalScrollOffset");
359
                method.setAccessible(true);
360
                return (int) method.invoke(mRecyclerView);
361
            } catch (Exception e) {
362
                e.printStackTrace();
363
            }
364
        }
365
        return super.computeVerticalScrollOffset();
366
    }
367
368
369
    @Override
370
    protected int computeVerticalScrollRange() {
371
        if (mRecyclerView != null) {
372
            try {
373
                Method method = View.class.getDeclaredMethod("computeVerticalScrollRange");
374
                method.setAccessible(true);
375
                return (int) method.invoke(mRecyclerView);
376
            } catch (Exception e) {
377
                e.printStackTrace();
378
            }
379
        }
380
        return super.computeVerticalScrollRange();
381
    }
382
383
    @Override
384
    protected int computeVerticalScrollExtent() {
385
        if (mRecyclerView != null) {
386
            try {
387
                Method method = View.class.getDeclaredMethod("computeVerticalScrollExtent");
388
                method.setAccessible(true);
389
                return (int) method.invoke(mRecyclerView);
390
            } catch (Exception e) {
391
                e.printStackTrace();
392
            }
393
        }
394
        return super.computeVerticalScrollExtent();
395
    }
396
397
    @Override
398
    public void scrollBy(int x, int y) {
399
        if (mRecyclerView != null) {
400
            mRecyclerView.scrollBy(x, y);
401
        } else {
402
            super.scrollBy(x, y);
403
        }
404
    }
405
406
    @Override
407
    public void scrollTo(int x, int y) {
408
        if (mRecyclerView != null) {
409
            mRecyclerView.scrollTo(x, y);
410
        } else {
411
            super.scrollTo(x, y);
412
        }
413
    }
414
415
    private StickyHeaderPositionListener stickyHeaderPositionListener;
416
417
    /**
418
     * 添加监听,监控头部视图滑动到顶部对应的头部视图的position
419
     * add by huyuguo
420
     */
421
    public void setStickyHeaderPositionListener(StickyHeaderPositionListener listener) {
422
        stickyHeaderPositionListener = listener;
423
    }
424
425
    /**
426
     * 滑动到指定位置
427
     * https://blog.csdn.net/shanshan_1117/article/details/78780137
428
     * @param position
429
     */
430
    public void scrollToPosition(int position) {
431
        if (mRecyclerView != null) {
432
            mRecyclerView.scrollToPosition(position);
433
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
434
            linearLayoutManager.scrollToPositionWithOffset(position, 0);
435
            updateStickyView();
436
        }
437
    }
438
439
}

+ 5 - 0
app/src/main/java/com/donkingliang/groupedadapter/widget/StickyHeaderPositionListener.java

@ -0,0 +1,5 @@
1
package com.donkingliang.groupedadapter.widget;
2
3
public interface StickyHeaderPositionListener {
4
    public void onHeaderPositionChange(int groupPosition);
5
}

+ 120 - 0
app/src/main/java/com/electric/chargingpile/activity/CarBrandActivity.java

@ -0,0 +1,120 @@
1
package com.electric.chargingpile.activity;
2
3
import androidx.appcompat.app.AppCompatActivity;
4
import androidx.recyclerview.widget.LinearLayoutManager;
5
import androidx.recyclerview.widget.RecyclerView;
6
7
import android.content.Intent;
8
import android.os.Bundle;
9
import android.view.View;
10
import android.widget.TextView;
11
12
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
13
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
14
import com.donkingliang.groupedadapter.widget.StickyHeaderLayout;
15
import com.donkingliang.groupedadapter.widget.StickyHeaderPositionListener;
16
import com.electric.chargingpile.R;
17
import com.electric.chargingpile.adapter.CarBrandGroupedListAdapter;
18
import com.electric.chargingpile.entity.CarBrandGroupEntity;
19
import com.electric.chargingpile.entity.CarCompanyEntity;
20
import com.electric.chargingpile.event.CarBrandEvent;
21
import com.electric.chargingpile.event.CarCompanyEvent;
22
import com.electric.chargingpile.util.BarColorUtil;
23
import com.electric.chargingpile.view.LetterSideView;
24
25
import org.greenrobot.eventbus.EventBus;
26
27
import java.util.ArrayList;
28
29
public class CarBrandActivity extends AppCompatActivity implements View.OnClickListener {
30
31
    private LetterSideView letter_side_view;
32
    private TextView text_view_dialog;
33
    private StickyHeaderLayout sticky_header_layout;
34
    private RecyclerView recycler_view;
35
    private CarBrandGroupedListAdapter adapter;
36
    private ArrayList<CarBrandGroupEntity> groups;
37
38
    @Override
39
    protected void onCreate(Bundle savedInstanceState) {
40
        super.onCreate(savedInstanceState);
41
        setContentView(R.layout.activity_car_brand);
42
        BarColorUtil.initStatusBarColor(CarBrandActivity.this);
43
        initViews();
44
    }
45
46
    private void initViews() {
47
48
        CarBrandEvent event = EventBus.getDefault().removeStickyEvent(CarBrandEvent.class);
49
        if (event != null) {
50
            groups = event.getGroups();
51
        }
52
53
        findViewById(R.id.iv_back).setOnClickListener(this::onClick);
54
        letter_side_view = findViewById(R.id.letter_side_view);
55
        text_view_dialog = findViewById(R.id.text_view_dialog);
56
        letter_side_view.setTextView(text_view_dialog);
57
        letter_side_view.setOnTouchLetterChangedListener(new LetterSideView.OnTouchLetterChangedListener() {
58
            @Override
59
            public void onTouchLetterChanged(String s) {
60
61
            }
62
63
            @Override
64
            public void onTouchLetterPosition(int position) {
65
                int count = 0;
66
                for (int i = 0; i < groups.size(); i++) {
67
                    if (i < position) {
68
                        count += groups.get(i).getBrandList().size();
69
                    } else {
70
                        break;
71
                    }
72
                }
73
                count += position;
74
                sticky_header_layout.scrollToPosition(count);
75
            }
76
        });
77
78
        String[] letters = new String[groups.size()];
79
        for (int i = 0; i < groups.size(); i++) {
80
            letters[i] = groups.get(i).getInitial();
81
        }
82
        LetterSideView.letters = letters;
83
        letter_side_view.setVisibility(View.VISIBLE);
84
85
        recycler_view = (RecyclerView) findViewById(R.id.recycler_view);
86
        sticky_header_layout = (StickyHeaderLayout) findViewById(R.id.sticky_header_layout);
87
88
        recycler_view.setLayoutManager(new LinearLayoutManager(this));
89
        adapter = new CarBrandGroupedListAdapter(this, groups);
90
        adapter.setOnChildClickListener(new GroupedRecyclerViewAdapter.OnChildClickListener() {
91
            @Override
92
            public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition, int childPosition) {
93
                ArrayList<CarCompanyEntity> companyList = groups.get(groupPosition).getBrandList().get(childPosition).getCompanyList();
94
                EventBus.getDefault().postSticky(new CarCompanyEvent(companyList));
95
                startActivity(new Intent(CarBrandActivity.this, CarModelActivity.class));
96
            }
97
        });
98
99
        recycler_view.setAdapter(adapter);
100
        // 设置是否吸顶。
101
        sticky_header_layout.setSticky(true);
102
        // 头部滑动到视图顶部时,监听头部对应的groupPosition
103
        sticky_header_layout.setStickyHeaderPositionListener(new StickyHeaderPositionListener() {
104
            @Override
105
            public void onHeaderPositionChange(int groupPosition) {
106
                letter_side_view.setPosition(groupPosition);
107
            }
108
        });
109
110
    }
111
112
    @Override
113
    public void onClick(View v) {
114
        switch (v.getId()) {
115
            case R.id.iv_back:
116
                finish();
117
                break;
118
        }
119
    }
120
}

+ 75 - 0
app/src/main/java/com/electric/chargingpile/activity/CarModelActivity.java

@ -0,0 +1,75 @@
1
package com.electric.chargingpile.activity;
2
3
import androidx.appcompat.app.AppCompatActivity;
4
import androidx.recyclerview.widget.LinearLayoutManager;
5
import androidx.recyclerview.widget.RecyclerView;
6
7
import android.content.Intent;
8
import android.os.Bundle;
9
import android.view.View;
10
11
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
12
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
13
import com.donkingliang.groupedadapter.widget.StickyHeaderLayout;
14
import com.electric.chargingpile.R;
15
import com.electric.chargingpile.adapter.CarModelGroupedListAdapter;
16
import com.electric.chargingpile.entity.CarCompanyEntity;
17
import com.electric.chargingpile.entity.CarSeriesEntity;
18
import com.electric.chargingpile.event.CarCompanyEvent;
19
import com.electric.chargingpile.event.CarSerieEvent;
20
import com.electric.chargingpile.util.BarColorUtil;
21
22
import org.greenrobot.eventbus.EventBus;
23
24
import java.util.ArrayList;
25
26
public class CarModelActivity extends AppCompatActivity implements View.OnClickListener {
27
28
    private RecyclerView recycler_view;
29
    private StickyHeaderLayout sticky_header_layout;
30
    private CarModelGroupedListAdapter adapter;
31
    private ArrayList<CarCompanyEntity> companyList;
32
33
    @Override
34
    protected void onCreate(Bundle savedInstanceState) {
35
        super.onCreate(savedInstanceState);
36
        setContentView(R.layout.activity_car_model);
37
        BarColorUtil.initStatusBarColor(CarModelActivity.this);
38
        initViews();
39
    }
40
41
    private void initViews() {
42
        findViewById(R.id.nav_bar).setOnClickListener(this::onClick);
43
        CarCompanyEvent event = EventBus.getDefault().removeStickyEvent(CarCompanyEvent.class);
44
        if (event != null) {
45
            companyList = event.getCompanyList();
46
        }
47
48
        recycler_view = (RecyclerView) findViewById(R.id.recycler_view);
49
        sticky_header_layout = (StickyHeaderLayout) findViewById(R.id.sticky_header_layout);
50
51
        recycler_view.setLayoutManager(new LinearLayoutManager(this));
52
        adapter = new CarModelGroupedListAdapter(this, companyList);
53
        adapter.setOnChildClickListener(new GroupedRecyclerViewAdapter.OnChildClickListener() {
54
            @Override
55
            public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder, int groupPosition, int childPosition) {
56
                CarSeriesEntity carSeriesEntity = companyList.get(groupPosition).getSerieslist().get(childPosition);
57
                EventBus.getDefault().post(new CarSerieEvent(carSeriesEntity));
58
                startActivity(new Intent(CarModelActivity.this, CarOwnerCertificateActivity.class));
59
            }
60
        });
61
62
        recycler_view.setAdapter(adapter);
63
        // 设置是否吸顶。
64
        sticky_header_layout.setSticky(true);
65
    }
66
67
    @Override
68
    public void onClick(View v) {
69
        switch (v.getId()) {
70
            case R.id.nav_bar:
71
                finish();
72
                break;
73
        }
74
    }
75
}

+ 385 - 0
app/src/main/java/com/electric/chargingpile/activity/CarOwnerCertificateActivity.java

@ -0,0 +1,385 @@
1
package com.electric.chargingpile.activity;
2
3
import androidx.appcompat.app.AppCompatActivity;
4
import androidx.constraintlayout.widget.ConstraintLayout;
5
6
import android.app.ProgressDialog;
7
import android.content.Intent;
8
import android.graphics.Bitmap;
9
import android.graphics.BitmapFactory;
10
import android.graphics.Matrix;
11
import android.graphics.drawable.Drawable;
12
import android.net.Uri;
13
import android.os.Bundle;
14
import android.view.View;
15
import android.view.WindowManager;
16
import android.widget.Button;
17
import android.widget.ImageView;
18
import android.widget.TextView;
19
import android.widget.Toast;
20
21
import com.bumptech.glide.Glide;
22
import com.electric.chargingpile.R;
23
import com.electric.chargingpile.entity.CarBrandGroupEntity;
24
import com.electric.chargingpile.entity.CarSeriesEntity;
25
import com.electric.chargingpile.event.CarBrandEvent;
26
import com.electric.chargingpile.event.CarSerieEvent;
27
import com.electric.chargingpile.util.BarColorUtil;
28
import com.electric.chargingpile.util.FileUtils;
29
import com.electric.chargingpile.util.JsonUtils;
30
import com.electric.chargingpile.util.LoadingDialog;
31
import com.electric.chargingpile.util.ToastUtil;
32
import com.electric.chargingpile.view.TextImageView;
33
import com.electric.chargingpile.view.xrichtext.SDCardUtil;
34
import com.google.gson.Gson;
35
import com.google.gson.reflect.TypeToken;
36
import com.zhihu.matisse.Matisse;
37
import com.zhihu.matisse.MimeType;
38
import com.zhihu.matisse.engine.impl.GlideEngine;
39
import com.zhihu.matisse.internal.entity.CaptureStrategy;
40
import com.zhy.http.okhttp.OkHttpUtils;
41
import com.zhy.http.okhttp.callback.StringCallback;
42
43
import org.greenrobot.eventbus.EventBus;
44
import org.greenrobot.eventbus.Subscribe;
45
import org.greenrobot.eventbus.ThreadMode;
46
47
import java.io.ByteArrayOutputStream;
48
import java.io.File;
49
import java.util.ArrayList;
50
import java.util.List;
51
52
import io.reactivex.Observable;
53
import io.reactivex.ObservableEmitter;
54
import io.reactivex.ObservableOnSubscribe;
55
import io.reactivex.Observer;
56
import io.reactivex.android.schedulers.AndroidSchedulers;
57
import io.reactivex.disposables.Disposable;
58
import io.reactivex.schedulers.Schedulers;
59
import okhttp3.Call;
60
61
/**
62
 * 车主认证
63
 */
64
65
public class CarOwnerCertificateActivity extends AppCompatActivity implements View.OnClickListener {
66
67
    private static final int RC_ALBUM_PERM = 123;
68
    private static final int REQUEST_CODE_CHOOSE = 342;
69
    private Bitmap insertBitmap;
70
    private String u_path = "";
71
    private int drivingLicenseType = 1;
72
    private ProgressDialog insertDialog;
73
74
    private TextView nav_title;
75
    private Button submit_btn;
76
    private TextImageView driving_license_type_first;
77
    private TextImageView driving_license_type_second;
78
    private TextImageView driving_license_type_third;
79
    private TextView add_car_model_btn;
80
    private LoadingDialog loadDialog;
81
    private ArrayList<CarBrandGroupEntity> groups;
82
    private CarSeriesEntity carSeriesEntity;
83
    private ConstraintLayout car_model_constraint_layout;
84
    private ConstraintLayout car_model_selected_constraint_layout;
85
    private ImageView car_icon;
86
    private TextView car_name;
87
    private TextView car_series;
88
    private ConstraintLayout driving_license;
89
    private ImageView driving_license_icon;
90
    private ImageView driving_license_upload_icon;
91
    private TextView driving_license_text_view;
92
    private Drawable selected;
93
    private Drawable normal;
94
95
    @Override
96
    protected void onCreate(Bundle savedInstanceState) {
97
        super.onCreate(savedInstanceState);
98
        // 禁止顶部固定部分滑动
99
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
100
        setContentView(R.layout.activity_car_owner_certificate);
101
        BarColorUtil.initStatusBarColor(CarOwnerCertificateActivity.this);
102
        initViews();
103
        brandListRequest(false);
104
        add_car_model_btn.setVisibility(View.GONE);
105
        EventBus.getDefault().register(this);
106
    }
107
108
    private void initViews() {
109
        loadDialog = new LoadingDialog(this);
110
        loadDialog.setCanceledOnTouchOutside(false);
111
112
        insertDialog = new ProgressDialog(this);
113
        insertDialog.setMessage("正在插入图片...");
114
        insertDialog.setCanceledOnTouchOutside(false);
115
116
        nav_title = findViewById(R.id.nav_title);
117
        findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() {
118
            @Override
119
            public void onClick(View v) {
120
                finish();
121
            }
122
        });
123
124
        add_car_model_btn = findViewById(R.id.add_car_model_btn);
125
        car_model_constraint_layout = findViewById(R.id.car_model_constraint_layout);
126
        car_model_selected_constraint_layout = findViewById(R.id.car_model_selected_constraint_layout);
127
        add_car_model_btn.setOnClickListener(this);
128
        car_model_selected_constraint_layout.setOnClickListener(this);
129
130
        car_icon = findViewById(R.id.car_icon);
131
        car_name = findViewById(R.id.car_name);
132
        car_series = findViewById(R.id.car_series);
133
134
        driving_license = findViewById(R.id.driving_license);
135
        driving_license.setOnClickListener(this);
136
        driving_license_icon = findViewById(R.id.driving_license_icon);
137
        driving_license_upload_icon = findViewById(R.id.driving_license_upload_icon);
138
        driving_license_text_view = findViewById(R.id.driving_license_text_view);
139
140
141
        driving_license_type_first = findViewById(R.id.driving_license_type_first);
142
        driving_license_type_second = findViewById(R.id.driving_license_type_second);
143
        driving_license_type_third = findViewById(R.id.driving_license_type_third);
144
        driving_license_type_first.setOnClickListener(this);
145
        driving_license_type_second.setOnClickListener(this);
146
        driving_license_type_third.setOnClickListener(this);
147
148
        selected = getResources().getDrawable(R.drawable.icon_radio_selected, null);
149
        selected.setBounds(0, 0, selected.getMinimumWidth(), selected.getMinimumHeight());
150
        normal = getResources().getDrawable(R.drawable.icon_radio_normal, null);
151
        normal.setBounds(0, 0, normal.getMinimumWidth(), normal.getMinimumHeight());
152
153
        submit_btn = findViewById(R.id.submit_btn);
154
        submit_btn.setOnClickListener(this);
155
    }
156
157
    private void brandListRequest(Boolean showLoading) {
158
        if (showLoading)
159
            loadDialog.show();
160
        // https://www.jianshu.com/p/10382cc71127
161
//        String url = "https://api.touchev.com:83/car/api/v1000/brand/list.do";
162
        String url = "http://car.d1ev.com/car/api/v1000/brand/list.do";
163
//        String url = MainApplication.url + "/zhannew/basic/web/index.php/member/get-score?id=" + MainApplication.userId +
164
//                "&phone=" + MainApplication.userPhone + "&password=" + MainApplication.userPassword + "&token=" + "xxxxxx";
165
        OkHttpUtils.get().url(url).build().connTimeOut(5000).readTimeOut(5000).execute(new StringCallback() {
166
            @Override
167
            public void onError(Call call, Exception e) {
168
                Toast.makeText(getApplicationContext(), "网络不给力,请检查网络状态", Toast.LENGTH_SHORT).show();
169
                loadDialog.dismiss();
170
                add_car_model_btn.setVisibility(View.VISIBLE);
171
            }
172
173
            @Override
174
            public void onResponse(String response) {
175
                loadDialog.dismiss();
176
                add_car_model_btn.setVisibility(View.VISIBLE);
177
                String code = JsonUtils.getKeyResult(response, "code");
178
                String desc = JsonUtils.getKeyResult(response, "desc");
179
                if ("1000".equals(code)) {
180
                    String data = JsonUtils.getKeyResult(response, "data");
181
                    Gson gson = new Gson();
182
                    groups = gson.fromJson(data, new TypeToken<ArrayList<CarBrandGroupEntity>>() {
183
                    }.getType());
184
                    if (groups == null || groups.size() == 0) {
185
                        if (showLoading)
186
                            ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
187
                    } else {
188
                        if (showLoading) {
189
                            EventBus.getDefault().postSticky(new CarBrandEvent(groups));
190
                            startActivity(new Intent(CarOwnerCertificateActivity.this, CarBrandActivity.class));
191
                        }
192
                    }
193
                } else {
194
                    if (showLoading)
195
                        ToastUtil.showToast(getApplicationContext(), desc, Toast.LENGTH_SHORT);
196
                }
197
            }
198
        });
199
    }
200
201
    @Override
202
    public void onClick(View v) {
203
        switch (v.getId()) {
204
            case R.id.add_car_model_btn:
205
            case R.id.car_model_selected_constraint_layout:
206
                if (groups == null || groups.size() == 0) {
207
                    brandListRequest(true);
208
                } else {
209
                    EventBus.getDefault().postSticky(new CarBrandEvent(groups));
210
                    startActivity(new Intent(CarOwnerCertificateActivity.this, CarBrandActivity.class));
211
                }
212
                break;
213
            case R.id.driving_license:
214
                Matisse.from(CarOwnerCertificateActivity.this)
215
                        .choose(MimeType.of(MimeType.JPEG, MimeType.PNG))
216
                        .showSingleMediaType(true)
217
                        .countable(true)
218
                        .maxSelectable(1)
219
                        .capture(true)
220
                        .captureStrategy(new CaptureStrategy(true, "com.electric.chargingpile.provider"))
221
                        .imageEngine(new GlideEngine())
222
                        .forResult(REQUEST_CODE_CHOOSE);
223
                break;
224
            case R.id.driving_license_type_first:
225
                drivingLicenseType = 1;
226
                driving_license_type_first.setCompoundDrawables(selected, null, null, null);
227
                driving_license_type_second.setCompoundDrawables(normal, null, null, null);
228
                driving_license_type_third.setCompoundDrawables(normal, null, null, null);
229
                break;
230
            case R.id.driving_license_type_second:
231
                drivingLicenseType = 2;
232
                driving_license_type_first.setCompoundDrawables(normal, null, null, null);
233
                driving_license_type_second.setCompoundDrawables(selected, null, null, null);
234
                driving_license_type_third.setCompoundDrawables(normal, null, null, null);
235
                break;
236
            case R.id.driving_license_type_third:
237
                drivingLicenseType = 3;
238
                driving_license_type_first.setCompoundDrawables(normal, null, null, null);
239
                driving_license_type_second.setCompoundDrawables(normal, null, null, null);
240
                driving_license_type_third.setCompoundDrawables(selected, null, null, null);
241
                break;
242
            case R.id.submit_btn:
243
                if (carSeriesEntity == null) {
244
                    ToastUtil.showToast(this, "请添加车型" + drivingLicenseType, Toast.LENGTH_SHORT);
245
                    return;
246
                }
247
                break;
248
        }
249
    }
250
251
    @Override
252
    protected void onDestroy() {
253
        super.onDestroy();
254
        EventBus.getDefault().unregister(this);
255
    }
256
257
    @Subscribe(threadMode = ThreadMode.MAIN)
258
    public void onCarSeriesMessage(CarSerieEvent event) {
259
        if (event != null && event.getCarSeriesEntity() != null) {
260
            carSeriesEntity = event.getCarSeriesEntity();
261
            car_model_constraint_layout.setVisibility(View.GONE);
262
            car_model_selected_constraint_layout.setVisibility(View.VISIBLE);
263
            car_name.setText(carSeriesEntity.getBrandName());
264
            car_series.setText(carSeriesEntity.getSeriesName());
265
            Glide.with(CarOwnerCertificateActivity.this).load(carSeriesEntity.getIcon()).placeholder(android.R.color.white).fitCenter().into(car_icon);
266
        } else {
267
            carSeriesEntity = null;
268
            car_model_constraint_layout.setVisibility(View.VISIBLE);
269
            car_model_selected_constraint_layout.setVisibility(View.GONE);
270
        }
271
    }
272
273
    @Override
274
    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
275
        super.onActivityResult(requestCode, resultCode, data);
276
        if (resultCode == RESULT_OK) {
277
            if (data != null) {
278
                if (requestCode == REQUEST_CODE_CHOOSE) {
279
                    insertImagesSync(data);
280
                }
281
            }
282
        }
283
    }
284
285
    private Bitmap imageZoom(Bitmap bm) {
286
        // 图片允许最大空间 单位:KB
287
        double maxSize = 200.00;
288
        // 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)
289
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
290
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
291
        byte[] b = baos.toByteArray();
292
        // 将字节换成KB
293
        double mid = b.length / 1024;
294
        // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
295
        if (mid > maxSize) {
296
            // 获取bitmap大小 是允许最大大小的多少倍
297
            double i = mid / maxSize;
298
            // 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
299
            // (1.保持刻度和高度和原bitmap比率一致,压缩后也达到了最大大小占用空间的大小)
300
            bm = zoomImage(bm, bm.getWidth() / Math.sqrt(i), bm.getHeight()
301
                    / Math.sqrt(i));
302
        }
303
304
305
        return bm;
306
    }
307
308
    public Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
309
        // 获取这个图片的宽和高
310
        float width = bgimage.getWidth();
311
        float height = bgimage.getHeight();
312
        // 创建操作图片用的matrix对象
313
        Matrix matrix = new Matrix();
314
        // 计算宽高缩放率
315
        float scaleWidth = ((float) newWidth) / width;
316
        float scaleHeight = ((float) newHeight) / height;
317
        // 缩放图片动作
318
        matrix.postScale(scaleWidth, scaleHeight);
319
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
320
                (int) height, matrix, true);
321
        return bitmap;
322
    }
323
324
    /**
325
     * 异步方式插入图片
326
     *
327
     * @param data
328
     */
329
    private void insertImagesSync(final Intent data) {
330
        insertDialog.show();
331
332
        Observable.create(new ObservableOnSubscribe<String>() {
333
            @Override
334
            public void subscribe(ObservableEmitter<String> subscriber) throws Exception {
335
336
                try {
337
                    List<Uri> uriList = Matisse.obtainResult(data);
338
                    Uri uri = uriList.get(0);
339
                    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
340
                    File file = FileUtils.from(CarOwnerCertificateActivity.this, uri);
341
342
                    bitmap = FileUtils.rotateIfRequired(file, bitmap);
343
                    bitmap = imageZoom(bitmap);
344
                    insertBitmap = bitmap;
345
346
                    u_path = SDCardUtil.saveToSdCard(bitmap);
347
348
                    subscriber.onNext(u_path);
349
                    subscriber.onComplete();
350
                } catch (Exception e) {
351
                    e.printStackTrace();
352
                    subscriber.onError(e);
353
                }
354
            }
355
        })
356
                .subscribeOn(Schedulers.io())//生产事件在io
357
                .observeOn(AndroidSchedulers.mainThread())//消费事件在UI线程
358
                .subscribe(new Observer<String>() {
359
                    @Override
360
                    public void onComplete() {
361
                        insertDialog.dismiss();
362
                        driving_license_icon.setImageBitmap(insertBitmap);
363
                        driving_license_upload_icon.setVisibility(View.GONE);
364
                        driving_license_text_view.setVisibility(View.GONE);
365
//                        uploadPic(insertBitmap, u_path); // TODO EditAnswerActivity
366
                    }
367
368
                    @Override
369
                    public void onError(Throwable e) {
370
                        insertDialog.dismiss();
371
                        ToastUtil.showToast(getApplicationContext(), "图片插入失败", Toast.LENGTH_SHORT);
372
                    }
373
374
                    @Override
375
                    public void onSubscribe(Disposable d) {
376
377
                    }
378
379
                    @Override
380
                    public void onNext(String imagePath) {
381
382
                    }
383
                });
384
    }
385
}

+ 29 - 133
app/src/main/java/com/electric/chargingpile/activity/UserCenterActivity.java

@ -21,7 +21,9 @@ import android.os.Environment;
21 21
import android.os.Handler;
22 22
import android.os.Message;
23 23
import android.os.Process;
24
24 25
import androidx.annotation.NonNull;
26
25 27
import android.util.Log;
26 28
import android.view.KeyEvent;
27 29
import android.view.View;
@ -98,7 +100,7 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
98 100
    private NetworkChangeReceiver networkChangeReceiver;
99 101
    private ImageView iv_back, iv_message, iv_qiandao, iv_share_prompt, iv_find, iv_main, iv_screening, iv_point;
100 102
    private RelativeLayout rl_addZhan, rl_collection, rl_more,
101
            rl_offline, rl_shop, rl_message, rl_feedback, rl_shareNo, rl_offline_upload, rl_chongzhi, rl_myaccount, rl_yue, rl_chongdianbi, rl_hongbao;
103
            rl_offline, rl_shop, rl_message, rl_feedback, rl_shareNo, rl_offline_upload, rl_chongzhi, rl_myaccount, rl_yue, rl_chongdianbi, rl_hongbao, rl_car_owner_certificate, rl_publish_price;
102 104
    private ToggleButton mTogBtn;
103 105
    private TextView tv_exit, userLogin, userRegister, chongdianbi, yue, hongbao, tv_our;
104 106
    private LinearLayout ll_userLogin;
@ -148,73 +150,11 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
148 150
149 151
                        Log.d("pingLunNum+++", pingLunNum);
150 152
                        MainMapActivity.have_pinglun = Integer.parseInt(pingLunNum);
151
152 153
                        Log.d("pinglun===yonghu", MainMapActivity.have_message + "");
153
//                        if (MainMapActivity.have_message == 0 && MainMapActivity.have_pinglun == 0) {
154
////            ivRight.setImageResource(R.drawable.icon_user2_0);
155
////                        iv_havemessage.setVisibility(View.GONE);
156
//                            iv_message.setVisibility(View.INVISIBLE);
157
//                            if (MainApplication.festival_time.equals("1")){
158
//                                iv_our.setImageResource(R.drawable.icon_cj4);
159
//                            }else if (MainApplication.festival_time.equals("2")){
160
//                                iv_our.setImageResource(R.drawable.icon_yx4);
161
//                            }else {
162
//                                iv_our.setImageResource(R.drawable.tab_our_selected);
163
//                            }
164
////                            iv_our.setImageResource(R.drawable.tab_our_selected);
165
//                        } else if (MainMapActivity.have_message == 1) {
166
//                            if (MainApplication.festival_time.equals("1")){
167
//                                iv_our.setImageResource(R.drawable.icon_cjh4);
168
//                            }else if (MainApplication.festival_time.equals("2")){
169
//                                iv_our.setImageResource(R.drawable.icon_yxh4);
170
//                            }else {
171
//                                iv_our.setImageResource(R.drawable.tab_our_selected_h);
172
//                            }
173
////                            iv_our.setImageResource(R.drawable.tab_our_selected_h);
174
////                        iv_havemessage.setVisibility(View.VISIBLE);
175
//                            iv_message.setVisibility(View.VISIBLE);
176
//                        } else if (MainMapActivity.have_pinglun > 0) {
177
////                        iv_havemessage.setVisibility(View.VISIBLE);
178
//                            iv_message.setVisibility(View.VISIBLE);
179
//                            if (MainApplication.festival_time.equals("1")){
180
//                                iv_our.setImageResource(R.drawable.icon_cjh4);
181
//                            }else if (MainApplication.festival_time.equals("2")){
182
//                                iv_our.setImageResource(R.drawable.icon_yxh4);
183
//                            }else {
184
//                        }
185
//                                iv_our.setImageResource(R.drawable.tab_our_selected_h);
186
//                            }
187
//                        }
188 154
                    } catch (JSONException e) {
189 155
                        e.printStackTrace();
190 156
                    }
191
192 157
                    break;
193
194
//                case 5:
195
////                    Log.e("log",msg.obj.toString());
196
//                    try {
197
//                        JSONArray jsonArray = new JSONArray(msg.obj.toString());
198
//                        Log.e("???",jsonArray.length()+"");
199
//                        Log.e("???",msg.obj.toString());
200
//                        if (jsonArray.length() == 0){
201
//                            Log.e("!!!",jsonArray.length()+"");
202
//                            iv_message.setVisibility(View.INVISIBLE);
203
//                            have_message = 0;
204
//                        }else{
205
//                            Log.e("@@@",jsonArray.length()+"");
206
//                            iv_message.setVisibility(View.VISIBLE);
207
//                            have_message = 1;
208
//                        }
209
//                    } catch (JSONException e) {
210
//                        e.printStackTrace();
211
//                    }
212
////                    if (msg.obj.toString() == null || msg.obj.toString().equals("") ||msg.obj.toString().equals("null")){
213
////                       iv_message.setVisibility(View.INVISIBLE);
214
////                    }
215
//                    break;
216
217
218 158
                default:
219 159
220 160
                    break;
@ -268,21 +208,12 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
268 208
        registerReceiver(networkChangeReceiver, intentFilter);
269 209
        //透明状态栏
270 210
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
271
        //透明导航栏
272
//        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
273
274 211
        initView();
275 212
        activity = this;
276 213
        if (MainApplication.isLogin()) {
277 214
            getPingLun();
278 215
        }
279 216
280
281
//        getMessage();
282
283
//        getIntegration();
284
285
286 217
        // ATTENTION: This was auto-generated to implement the App Indexing API.
287 218
        // See https://g.co/AppIndexing/AndroidStudio for more information.
288 219
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
@ -298,12 +229,7 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
298 229
                    } catch (Exception e) {
299 230
                        e.printStackTrace();
300 231
                    }
301
302
//                    saveBitmap(bm);
303
304 232
                    break;
305
306
307 233
                default:
308 234
                    break;
309 235
            }
@ -364,7 +290,6 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
364 290
        iv_hongbao = (ImageView) findViewById(R.id.iv_hongbao);
365 291
        iv_chongdianbi = (ImageView) findViewById(R.id.iv_chongdianbi);
366 292
        yue = (TextView) findViewById(R.id.tv_yue);
367
//        iv_message = (ImageView) findViewById(R.id.iv_message);
368 293
        iv_message = (ImageView) findViewById(R.id.iv_have_message);
369 294
370 295
        ll_tab_find = (RelativeLayout) findViewById(R.id.ll_tab_find);
@ -379,39 +304,13 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
379 304
380 305
381 306
        iv_our = (ImageView) findViewById(R.id.iv_our);
382
//        if (MainMapActivity.have_message == 1) {
383
//            Log.e("userCenter==",MainMapActivity.have_message+"");
384
//            iv_message.setVisibility(View.VISIBLE);
385
//        } else {
386
//            iv_message.setVisibility(View.INVISIBLE);
387
//        }
388
389
390
//        iv_havemessage = (ImageView) findViewById(R.id.iv_havemessage);
391
//        if (MainFragment.have_message == 1){
392
//            iv_havemessage.setVisibility(View.VISIBLE);
393
//        }else if(MainFragment.have_message == 0){
394
//            iv_havemessage.setVisibility(View.GONE);
395
//        }
396
397
398
//        if (have_message == 1){
399
//            iv_message.setVisibility(View.VISIBLE);
400
//        }else{
401
//            iv_message.setVisibility(View.INVISIBLE);
402
//        }
403 307
404 308
        rl_collection = (RelativeLayout) findViewById(R.id.rl_collection);
405 309
        rl_collection.setOnClickListener(this);
406 310
407
408
//        rl_more = (RelativeLayout) findViewById(R.id.rl_more);
409
//        rl_more.setOnClickListener(this);
410
411 311
        rl_message = (RelativeLayout) findViewById(R.id.rl_message);
412 312
        rl_message.setOnClickListener(this);
413 313
414
415 314
        rl_shareNo = (RelativeLayout) findViewById(R.id.rl_shareNo);
416 315
        rl_shareNo.setOnClickListener(this);
417 316
@ -422,6 +321,11 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
422 321
        chat_share_bar = findViewById(R.id.chat_share_bar);
423 322
        chat_share_bar.setOnClickListener(this);
424 323
324
        rl_car_owner_certificate = findViewById(R.id.rl_car_owner_certificate);
325
        rl_car_owner_certificate.setOnClickListener(this);
326
327
        rl_publish_price = findViewById(R.id.rl_publish_price);
328
        rl_publish_price.setOnClickListener(this);
425 329
426 330
        rl_chongzhi = (RelativeLayout) findViewById(R.id.rl_chongzhi);
427 331
        rl_chongzhi.setOnClickListener(this);
@ -437,30 +341,6 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
437 341
438 342
        rl_yue = (RelativeLayout) findViewById(R.id.rl_yue);
439 343
        rl_yue.setOnClickListener(this);
440
//        mTogBtn = (ToggleButton) findViewById(R.id.iosbutton); // 获取到控件
441
//        if (MainApplication.userTpye == "1") {
442
//            mTogBtn.setChecked(false);
443
//        } else if (MainApplication.userTpye == "2") {
444
//            mTogBtn.setChecked(true);
445
//        }
446
//
447
//        mTogBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
448
//
449
//            @Override
450
//            public void onCheckedChanged(CompoundButton buttonView,
451
//                                         boolean isChecked) {
452
//                // TODO Auto-generated method stub
453
//                if (isChecked) {
454
//                    MainApplication.userTpye = "2";
455
//                    Log.e("suit_car", "特斯拉");
456
//                    MainFragment.firstSelect();
457
//                } else {
458
//                    MainApplication.userTpye = "1";
459
//                    Log.e("suit_car", "国标");
460
//                    MainFragment.firstSelect();
461
//                }
462
//            }
463
//        });
464 344
465 345
        tab_main = (LinearLayout) findViewById(R.id.tab_main);
466 346
        tab_main.setOnClickListener(this);
@ -478,11 +358,6 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
478 358
        llPerson = (RelativeLayout) findViewById(R.id.ll_person);
479 359
        llPerson.setOnClickListener(this);
480 360
481
482
        //退出登录按钮
483
//        tv_exit = (TextView) findViewById(R.id.tv_exit);
484
//        tv_exit.setOnClickListener(this);
485
486 361
        //登陆按钮
487 362
        userLogin = (TextView) findViewById(R.id.userLogin);
488 363
        userLogin.setOnClickListener(this);
@ -901,6 +776,27 @@ public class UserCenterActivity extends Activity implements View.OnClickListener
901 776
                MobclickAgent.onEvent(getApplicationContext(), "0815");
902 777
                break;
903 778
779
            case R.id.rl_car_owner_certificate: // 车主认证
780
                if (!MainApplication.isLogin()) {
781
                    Toast.makeText(getApplication(), "请先登录", Toast.LENGTH_SHORT).show();
782
                    startActivity(new Intent(getApplication(), LoginActivity.class));
783
                } else {
784
                    // 列表接口
785
                    // 1.无认证记录
786
                    startActivity(new Intent(getApplication(), CarOwnerCertificateActivity.class));
787
//                    MobclickAgent.onEvent(getApplicationContext(), "0810"); // TODO
788
                }
789
                break;
790
            case R.id.rl_publish_price: // 发表成交价
791
                if (!MainApplication.isLogin()) {
792
                    Toast.makeText(getApplication(), "请先登录", Toast.LENGTH_SHORT).show();
793
                    startActivity(new Intent(getApplication(), LoginActivity.class));
794
                } else {
795
                    // TODO 跳转html
796
                    System.out.println("come on");
797
                }
798
                break;
799
904 800
            case R.id.rl_chongzhi:
905 801
                if (!MainApplication.isLogin()) {
906 802
                    Toast.makeText(getApplication(), "请先登录", Toast.LENGTH_SHORT).show();

+ 97 - 0
app/src/main/java/com/electric/chargingpile/adapter/CarBrandGroupedListAdapter.java

@ -0,0 +1,97 @@
1
package com.electric.chargingpile.adapter;
2
3
import android.content.Context;
4
import android.view.LayoutInflater;
5
import android.view.View;
6
import android.view.ViewGroup;
7
import android.widget.Button;
8
import android.widget.ImageView;
9
10
import com.bumptech.glide.Glide;
11
import com.bumptech.glide.load.engine.DiskCacheStrategy;
12
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
13
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
14
import com.electric.chargingpile.R;
15
import com.electric.chargingpile.entity.CarBrandChildEntity;
16
import com.electric.chargingpile.entity.CarBrandGroupEntity;
17
18
import java.util.ArrayList;
19
20
public class CarBrandGroupedListAdapter extends GroupedRecyclerViewAdapter {
21
22
    protected ArrayList<CarBrandGroupEntity> groups;
23
24
    public CarBrandGroupedListAdapter(Context context, ArrayList<CarBrandGroupEntity> groups) {
25
        super(context);
26
        this.groups = groups;
27
    }
28
29
    public void clear() {
30
        groups.clear();
31
        notifyDataChanged();
32
    }
33
34
    public void setGroups(ArrayList<CarBrandGroupEntity> groups) {
35
        this.groups = groups;
36
        notifyDataChanged();
37
    }
38
39
    @Override
40
    public int getGroupCount() {
41
        return groups == null ? 0 : groups.size();
42
    }
43
44
    @Override
45
    public int getChildrenCount(int groupPosition) {
46
        ArrayList<CarBrandChildEntity> children = groups.get(groupPosition).getBrandList();
47
        return children == null ? 0 : children.size();
48
    }
49
50
    @Override
51
    public boolean hasHeader(int groupPosition) {
52
        return true;
53
    }
54
55
    @Override
56
    public boolean hasFooter(int groupPosition) {
57
        return false;
58
    }
59
60
    @Override
61
    public int getHeaderLayout(int viewType) {
62
        return R.layout.adapter_header_car_brand;
63
    }
64
65
    @Override
66
    public int getFooterLayout(int viewType) {
67
        return 0;
68
    }
69
70
    @Override
71
    public int getChildLayout(int viewType) {
72
        return R.layout.adapter_child_car_brand;
73
    }
74
75
    @Override
76
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
77
        CarBrandGroupEntity entity = groups.get(groupPosition);
78
        holder.setText(R.id.title, entity.getInitial());
79
    }
80
81
    @Override
82
    public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {
83
    }
84
85
    @Override
86
    public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
87
        CarBrandChildEntity entity = groups.get(groupPosition).getBrandList().get(childPosition);
88
        holder.setText(R.id.title, entity.getBrandName());
89
        if (childPosition == 0) {
90
            holder.setVisible(R.id.line, View.GONE);
91
        } else {
92
            holder.setVisible(R.id.line, View.VISIBLE);
93
        }
94
        ImageView icon = holder.getImageView(R.id.icon);
95
        Glide.with(mContext).load(entity.getIcon()).placeholder(android.R.color.white).fitCenter().into(icon);
96
    }
97
}

+ 95 - 0
app/src/main/java/com/electric/chargingpile/adapter/CarModelGroupedListAdapter.java

@ -0,0 +1,95 @@
1
package com.electric.chargingpile.adapter;
2
3
import android.content.Context;
4
import android.view.View;
5
import android.widget.ImageView;
6
7
import com.bumptech.glide.Glide;
8
import com.bumptech.glide.load.engine.DiskCacheStrategy;
9
import com.donkingliang.groupedadapter.adapter.GroupedRecyclerViewAdapter;
10
import com.donkingliang.groupedadapter.holder.BaseViewHolder;
11
import com.electric.chargingpile.R;
12
import com.electric.chargingpile.entity.CarCompanyEntity;
13
import com.electric.chargingpile.entity.CarSeriesEntity;
14
15
import java.util.ArrayList;
16
17
public class CarModelGroupedListAdapter extends GroupedRecyclerViewAdapter {
18
    protected ArrayList<CarCompanyEntity> groups;
19
20
    public CarModelGroupedListAdapter(Context context, ArrayList<CarCompanyEntity> groups) {
21
        super(context);
22
        this.groups = groups;
23
    }
24
25
    public void clear() {
26
        groups.clear();
27
        notifyDataChanged();
28
    }
29
30
    public void setGroups(ArrayList<CarCompanyEntity> groups) {
31
        this.groups = groups;
32
        notifyDataChanged();
33
    }
34
35
    @Override
36
    public int getGroupCount() {
37
        return groups == null ? 0 : groups.size();
38
    }
39
40
    @Override
41
    public int getChildrenCount(int groupPosition) {
42
        ArrayList<CarSeriesEntity> children = groups.get(groupPosition).getSerieslist();
43
        return children == null ? 0 : children.size();
44
    }
45
46
    @Override
47
    public boolean hasHeader(int groupPosition) {
48
        return true;
49
    }
50
51
    @Override
52
    public boolean hasFooter(int groupPosition) {
53
        return false;
54
    }
55
56
    @Override
57
    public int getHeaderLayout(int viewType) {
58
        return R.layout.adapter_header_car_model;
59
    }
60
61
    @Override
62
    public int getFooterLayout(int viewType) {
63
        return 0;
64
    }
65
66
    @Override
67
    public int getChildLayout(int viewType) {
68
        return R.layout.adapter_child_car_model;
69
    }
70
71
    @Override
72
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
73
        CarCompanyEntity entity = groups.get(groupPosition);
74
        holder.setText(R.id.title, entity.getCompanyName());
75
    }
76
77
    @Override
78
    public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {
79
80
    }
81
82
    @Override
83
    public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
84
        CarSeriesEntity entity = groups.get(groupPosition).getSerieslist().get(childPosition);
85
        holder.setText(R.id.title, entity.getSeriesName());
86
        if (childPosition == 0) {
87
            holder.setVisible(R.id.line, View.GONE);
88
        } else {
89
            holder.setVisible(R.id.line, View.VISIBLE);
90
        }
91
        ImageView icon = holder.getImageView(R.id.icon);
92
        Glide.with(mContext).load(entity.getIcon()).placeholder(android.R.color.white).diskCacheStrategy(DiskCacheStrategy.RESOURCE).fitCenter().into(icon);
93
    }
94
95
}

+ 59 - 0
app/src/main/java/com/electric/chargingpile/entity/CarBrandChildEntity.java

@ -0,0 +1,59 @@
1
package com.electric.chargingpile.entity;
2
3
import java.util.ArrayList;
4
5
public class CarBrandChildEntity {
6
    private int brandId;
7
    private String brandName;
8
    private int seriesNum;
9
    private String icon;
10
    private ArrayList<CarCompanyEntity> companyList;
11
12
    public CarBrandChildEntity(int brandId, String brandName, int seriesNum, String icon, ArrayList<CarCompanyEntity> companyList) {
13
        this.brandId = brandId;
14
        this.brandName = brandName;
15
        this.seriesNum = seriesNum;
16
        this.icon = icon;
17
        this.companyList = companyList;
18
    }
19
20
    public int getBrandId() {
21
        return brandId;
22
    }
23
24
    public void setBrandId(int brandId) {
25
        this.brandId = brandId;
26
    }
27
28
    public String getBrandName() {
29
        return brandName;
30
    }
31
32
    public void setBrandName(String brandName) {
33
        this.brandName = brandName;
34
    }
35
36
    public int getSeriesNum() {
37
        return seriesNum;
38
    }
39
40
    public void setSeriesNum(int seriesNum) {
41
        this.seriesNum = seriesNum;
42
    }
43
44
    public String getIcon() {
45
        return icon;
46
    }
47
48
    public void setIcon(String icon) {
49
        this.icon = icon;
50
    }
51
52
    public ArrayList<CarCompanyEntity> getCompanyList() {
53
        return companyList;
54
    }
55
56
    public void setCompanyList(ArrayList<CarCompanyEntity> companyList) {
57
        this.companyList = companyList;
58
    }
59
}

+ 30 - 0
app/src/main/java/com/electric/chargingpile/entity/CarBrandGroupEntity.java

@ -0,0 +1,30 @@
1
package com.electric.chargingpile.entity;
2
3
4
import java.util.ArrayList;
5
6
public class CarBrandGroupEntity {
7
    private String initial; // header
8
    private ArrayList<CarBrandChildEntity> brandList; // children
9
10
    public CarBrandGroupEntity(String initial, ArrayList<CarBrandChildEntity> brandList) {
11
        this.initial = initial;
12
        this.brandList = brandList;
13
    }
14
15
    public String getInitial() {
16
        return initial;
17
    }
18
19
    public void setInitial(String initial) {
20
        this.initial = initial;
21
    }
22
23
    public ArrayList<CarBrandChildEntity> getBrandList() {
24
        return brandList;
25
    }
26
27
    public void setBrandList(ArrayList<CarBrandChildEntity> brandList) {
28
        this.brandList = brandList;
29
    }
30
}

+ 50 - 0
app/src/main/java/com/electric/chargingpile/entity/CarCompanyEntity.java

@ -0,0 +1,50 @@
1
package com.electric.chargingpile.entity;
2
3
import java.util.ArrayList;
4
5
public class CarCompanyEntity {
6
    private int companyId;
7
    private String companyName;
8
    private int brandId;
9
    private ArrayList<CarSeriesEntity> serieslist;
10
11
    public CarCompanyEntity(int companyId, String companyName, int brandId, ArrayList<CarSeriesEntity> serieslist) {
12
        this.companyId = companyId;
13
        this.companyName = companyName;
14
        this.brandId = brandId;
15
        this.serieslist = serieslist;
16
    }
17
18
19
    public int getCompanyId() {
20
        return companyId;
21
    }
22
23
    public void setCompanyId(int companyId) {
24
        this.companyId = companyId;
25
    }
26
27
    public String getCompanyName() {
28
        return companyName;
29
    }
30
31
    public void setCompanyName(String companyName) {
32
        this.companyName = companyName;
33
    }
34
35
    public int getBrandId() {
36
        return brandId;
37
    }
38
39
    public void setBrandId(int brandId) {
40
        this.brandId = brandId;
41
    }
42
43
    public ArrayList<CarSeriesEntity> getSerieslist() {
44
        return serieslist;
45
    }
46
47
    public void setSerieslist(ArrayList<CarSeriesEntity> serieslist) {
48
        this.serieslist = serieslist;
49
    }
50
}

+ 67 - 0
app/src/main/java/com/electric/chargingpile/entity/CarSeriesEntity.java

@ -0,0 +1,67 @@
1
package com.electric.chargingpile.entity;
2
3
public class CarSeriesEntity {
4
    private int brandId;
5
    private String brandName;
6
    private int companyId;
7
    private int seriesId;
8
    private String seriesName;
9
    private String icon;
10
11
    public CarSeriesEntity(int brandId, String brandName, int companyId, int seriesId, String seriesName, String icon) {
12
        this.brandId = brandId;
13
        this.brandName = brandName;
14
        this.companyId = companyId;
15
        this.seriesId = seriesId;
16
        this.seriesName = seriesName;
17
        this.icon = icon;
18
    }
19
20
    public int getBrandId() {
21
        return brandId;
22
    }
23
24
    public void setBrandId(int brandId) {
25
        this.brandId = brandId;
26
    }
27
28
    public String getBrandName() {
29
        return brandName;
30
    }
31
32
    public void setBrandName(String brandName) {
33
        this.brandName = brandName;
34
    }
35
36
    public int getCompanyId() {
37
        return companyId;
38
    }
39
40
    public void setCompanyId(int companyId) {
41
        this.companyId = companyId;
42
    }
43
44
    public int getSeriesId() {
45
        return seriesId;
46
    }
47
48
    public void setSeriesId(int seriesId) {
49
        this.seriesId = seriesId;
50
    }
51
52
    public String getSeriesName() {
53
        return seriesName;
54
    }
55
56
    public void setSeriesName(String seriesName) {
57
        this.seriesName = seriesName;
58
    }
59
60
    public String getIcon() {
61
        return icon;
62
    }
63
64
    public void setIcon(String icon) {
65
        this.icon = icon;
66
    }
67
}

+ 21 - 0
app/src/main/java/com/electric/chargingpile/event/CarBrandEvent.java

@ -0,0 +1,21 @@
1
package com.electric.chargingpile.event;
2
3
import com.electric.chargingpile.entity.CarBrandGroupEntity;
4
5
import java.util.ArrayList;
6
7
public class CarBrandEvent {
8
    private ArrayList<CarBrandGroupEntity> groups;
9
10
    public CarBrandEvent(ArrayList<CarBrandGroupEntity> groups) {
11
        this.groups = groups;
12
    }
13
14
    public ArrayList<CarBrandGroupEntity> getGroups() {
15
        return groups;
16
    }
17
18
    public void setGroups(ArrayList<CarBrandGroupEntity> groups) {
19
        this.groups = groups;
20
    }
21
}

+ 20 - 0
app/src/main/java/com/electric/chargingpile/event/CarCompanyEvent.java

@ -0,0 +1,20 @@
1
package com.electric.chargingpile.event;
2
3
import com.electric.chargingpile.entity.CarCompanyEntity;
4
5
import java.util.ArrayList;
6
7
public class CarCompanyEvent {
8
    private ArrayList<CarCompanyEntity> companyList;
9
    public ArrayList<CarCompanyEntity> getCompanyList() {
10
        return companyList;
11
    }
12
13
    public void setCompanyList(ArrayList<CarCompanyEntity> companyList) {
14
        this.companyList = companyList;
15
    }
16
17
    public CarCompanyEvent(ArrayList<CarCompanyEntity> companyList) {
18
        this.companyList = companyList;
19
    }
20
}

+ 19 - 0
app/src/main/java/com/electric/chargingpile/event/CarSerieEvent.java

@ -0,0 +1,19 @@
1
package com.electric.chargingpile.event;
2
3
import com.electric.chargingpile.entity.CarSeriesEntity;
4
5
public class CarSerieEvent {
6
    private CarSeriesEntity carSeriesEntity;
7
8
    public CarSerieEvent(CarSeriesEntity carSeriesEntity) {
9
        this.carSeriesEntity = carSeriesEntity;
10
    }
11
12
    public CarSeriesEntity getCarSeriesEntity() {
13
        return carSeriesEntity;
14
    }
15
16
    public void setCarSeriesEntity(CarSeriesEntity carSeriesEntity) {
17
        this.carSeriesEntity = carSeriesEntity;
18
    }
19
}

+ 12 - 0
app/src/main/java/com/electric/chargingpile/util/DensityUtil.java

@ -28,4 +28,16 @@ public class DensityUtil {
28 28
        final float scale = context.getResources().getDisplayMetrics().density;
29 29
        return (int) (pxValue / scale + 0.5f);
30 30
    }
31

32
    /**
33
     * 将sp值转换为px值,保证文字大小不变
34
     *
35
     * @param spValue fontScale(DisplayMetrics类中属性scaledDensity)
36
     * @return
37
     */
38
    public static int sp2px(Context context, float spValue) {
39
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
40
        return (int) (spValue * fontScale + 0.5f);
41
    }
42

31 43
}

+ 154 - 0
app/src/main/java/com/electric/chargingpile/view/LetterSideView.java

@ -0,0 +1,154 @@
1
package com.electric.chargingpile.view;
2
3
import android.content.Context;
4
import android.graphics.Canvas;
5
import android.graphics.Color;
6
import android.graphics.Paint;
7
import android.graphics.Rect;
8
import android.util.AttributeSet;
9
import android.view.MotionEvent;
10
import android.view.View;
11
import android.widget.TextView;
12
13
import com.electric.chargingpile.util.DensityUtil;
14
15
public class LetterSideView extends View {
16
    // 26个字母
17
    public static String[] letters = {
18
            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
19
            "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#"
20
    };
21
    private int choose = -1;  // 选中的字母的y坐标
22
    private int chosen = -1;
23
    private Paint paint = new Paint(); // 字母画笔
24
    private Paint circle = new Paint(); // 选中字符背景
25
    private TextView mTextDialog;  // 显示当前字母的文本框
26
    private int singleHeight;      // 一个字母的空间
27
    Rect rect = new Rect();     // 存放文字的高度
28
29
    public LetterSideView(Context context, AttributeSet attrs) {
30
        super(context, attrs);
31
    }
32
33
    @Override
34
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
35
        super.onLayout(changed, left, top, right, bottom);
36
        paint.setAntiAlias(true); // 设置抗锯齿
37
        paint.setTextSize(DensityUtil.sp2px(getContext(), 12f)); // 设置字母字体大小为12sp
38
        paint.getTextBounds("A", 0, 1, rect);  // 获取一个字母实际的宽高到rect
39
        singleHeight = (getHeight() - (getPaddingTop() + getPaddingBottom())) / letters.length;   // 获取一个字母的空间
40
41
        circle.setAntiAlias(true); // 设置抗锯齿
42
        circle.setColor(Color.parseColor("#C1CCD5"));
43
    }
44
45
    /**
46
     * 为SideBar设置显示字母的TextView
47
     *
48
     * @param mTextDialog 在activity传递过来的textView
49
     */
50
    public void setTextView(TextView mTextDialog) {
51
        this.mTextDialog = mTextDialog;
52
    }
53
54
    public void setPosition(int position) {
55
        chosen = position;
56
        invalidate();
57
    }
58
59
    /**
60
     * 绘制
61
     */
62
    @Override
63
    protected void onDraw(Canvas canvas) {
64
        super.onDraw(canvas);
65
        // 循环绘制字母
66
        for (int i = 0; i < letters.length; i++) {
67
            //paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置默认字体加粗
68
69
70
            // 选中的状态
71
            if (i == chosen) {
72
                paint.setColor(Color.parseColor("#FFFFFF")); // 选中的字母改变颜色
73
                paint.setFakeBoldText(true); // 设置字体为粗体
74
                float yPos = getPaddingTop() + singleHeight * i + rect.height() / 2f;
75
                canvas.drawCircle(getWidth() / 2f, yPos, getWidth() * 0.35f, circle);
76
            } else {
77
                paint.setColor(Color.parseColor("#6F6F7D")); // 设置字体颜色
78
                paint.setFakeBoldText(false); // 设置字体为正常
79
            }
80
81
            // x坐标等于中间-字符宽度的一半.
82
            float xPos = getWidth() / 2 - paint.measureText(letters[i]) / 2;
83
            // Y轴坐标
84
            float yPos = getPaddingTop() + singleHeight * i + rect.height();
85
            canvas.drawText(letters[i], xPos, yPos, paint); // 绘制字母
86
        }
87
    }
88
89
    /**
90
     * 分发触摸事件
91
     *
92
     * @param event
93
     * @return
94
     */
95
    @Override
96
    public boolean dispatchTouchEvent(MotionEvent event) {
97
        final int action = event.getAction();
98
        final float y = event.getY(); // 点击y坐标
99
        chosen = choose;  // 上一个选中的字母
100
        // 点击y坐标所占总高度的比例  *   数组的长度就等于点击了 数组中的位置.
101
        final int c = (int) (y / (getHeight() - getPaddingTop() - getPaddingBottom()) * letters.length);
102
        switch (action) {
103
            case MotionEvent.ACTION_UP:
104
                //抬起来的时候设置背景为透明
105
                //setBackgroundDrawable(new ColorDrawable(0x00000000));
106
                choose = -1;
107
                invalidate();
108
                if (mTextDialog != null) {
109
                    mTextDialog.setVisibility(View.INVISIBLE);
110
                }
111
                break;
112
            default:
113
                //按下,滑动的时候设置背景为灰色
114
                //setBackgroundDrawable(new ColorDrawable(0x44000000));
115
                //setBackgroundResource(R.drawable.sidebar_background);
116
                if (chosen != c) { // 判断选中字母是否发生改变
117
                    if (c >= 0 && c < letters.length) {
118
                        if (listener != null) {
119
                            listener.onTouchLetterChanged(letters[c]);
120
                            listener.onTouchLetterPosition(c);
121
                        }
122
                        if (mTextDialog != null) {
123
                            mTextDialog.setText(letters[c]);
124
                            mTextDialog.setVisibility(View.VISIBLE);
125
                        }
126
                        // 设置选中字母在数组的位置
127
                        choose = c;
128
                        chosen = choose;
129
                        invalidate();
130
                    }
131
                }
132
                break;
133
        }
134
        return true;
135
    }
136
137
    // 触摸回调接口
138
    private OnTouchLetterChangedListener listener;
139
140
141
    public void setOnTouchLetterChangedListener(OnTouchLetterChangedListener onTouchLetterChangedListener) {
142
        this.listener = onTouchLetterChangedListener;
143
    }
144
145
    public interface OnTouchLetterChangedListener {
146
        /**
147
         * 触摸字母回调
148
         *
149
         * @param s 触摸的字符
150
         */
151
        void onTouchLetterChanged(String s);
152
        void onTouchLetterPosition(int position);
153
    }
154
}

+ 92 - 0
app/src/main/java/com/electric/chargingpile/view/TextImageView.java

@ -0,0 +1,92 @@
1
package com.electric.chargingpile.view;
2
3
import android.content.Context;
4
import android.content.res.TypedArray;
5
import android.graphics.Rect;
6
import android.graphics.drawable.Drawable;
7
import android.util.AttributeSet;
8
9
import androidx.appcompat.widget.AppCompatTextView;
10
11
import com.electric.chargingpile.R;
12
13
public class TextImageView extends AppCompatTextView {
14
    private int leftWidth;
15
    private int leftHeight;
16
    private int topWidth;
17
    private int topHeight;
18
    private int rightWidth;
19
    private int rightHeight;
20
    private int bottomWidth;
21
    private int bottomHeight;
22
23
24
    public TextImageView(Context context) {
25
        super(context);
26
    }
27
28
    public TextImageView(Context context, AttributeSet attrs) {
29
        super(context, attrs);
30
        init(context, attrs);
31
    }
32
33
    public TextImageView(Context context, AttributeSet attrs, int defStyleAttr) {
34
        super(context, attrs, defStyleAttr);
35
        init(context, attrs);
36
    }
37
38
    private void init(Context context, AttributeSet attrs) {
39
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextImageView);
40
        leftWidth = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableLeftWidth, 0);
41
        leftHeight = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableLeftHeight, 0);
42
        topWidth = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableTopWidth, 0);
43
        topHeight = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableTopHeight, 0);
44
        rightWidth = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableRightWidth, 0);
45
        rightHeight = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableRightHeight, 0);
46
        bottomWidth = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableBottomWidth, 0);
47
        bottomHeight = typedArray.getDimensionPixelOffset(R.styleable.TextImageView_drawableBottomHeight, 0);
48
        typedArray.recycle();
49
        setDrawablesSize();
50
    }
51
52
    private void setDrawablesSize() {
53
        Drawable[] compoundDrawables = getCompoundDrawables();
54
        for (int i = 0; i < compoundDrawables.length; i++) {
55
            switch (i) {
56
                case 0:
57
                    setDrawableBounds(compoundDrawables[0], leftWidth, leftHeight);
58
                    break;
59
                case 1:
60
                    setDrawableBounds(compoundDrawables[1], topWidth, topHeight);
61
                    break;
62
                case 2:
63
                    setDrawableBounds(compoundDrawables[2], rightWidth, rightHeight);
64
                    break;
65
                case 3:
66
                    setDrawableBounds(compoundDrawables[3], bottomWidth, bottomHeight);
67
                    break;
68
                default:
69
                    break;
70
            }
71
        }
72
        setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], compoundDrawables[2], compoundDrawables[3]);
73
    }
74
75
    private void setDrawableBounds(Drawable drawable, int width, int height) {
76
        if (drawable != null) {
77
            double scale = ((double) drawable.getIntrinsicHeight()) / ((double) drawable.getIntrinsicWidth());
78
            drawable.setBounds(0, 0, width, height);
79
            Rect bounds = drawable.getBounds();
80
            // 高宽只给一个值时,自适应
81
            if (bounds.right != 0 | bounds.bottom != 0) {
82
                bounds.right = (int) (bounds.bottom / scale);
83
                drawable.setBounds(bounds);
84
            }
85
            if (bounds.bottom == 0) {
86
                bounds.bottom = (int) (bounds.right * scale);
87
                drawable.setBounds(bounds);
88
            }
89
        }
90
    }
91
92
}

二进制
app/src/main/res/drawable-hdpi/icon_radio_normal.png


二进制
app/src/main/res/drawable-hdpi/icon_radio_selected.png


二进制
app/src/main/res/drawable-mdpi/icon_radio_normal.png


二进制
app/src/main/res/drawable-mdpi/icon_radio_selected.png


二进制
app/src/main/res/drawable-xhdpi/icon_radio_normal.png


二进制
app/src/main/res/drawable-xhdpi/icon_radio_selected.png


二进制
app/src/main/res/drawable-xxhdpi/icon_radio_normal.png


二进制
app/src/main/res/drawable-xxhdpi/icon_radio_selected.png


二进制
app/src/main/res/drawable-xxxhdpi/icon_radio_normal.png


二进制
app/src/main/res/drawable-xxxhdpi/icon_radio_selected.png


+ 8 - 0
app/src/main/res/drawable/bg_add_car_model_shape.xml

@ -0,0 +1,8 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<shape xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:shape="rectangle">
4
    <corners android:radius="48dp" /> <!-- 圆角大小 -->
5
    <stroke
6
        android:width="1dp"
7
        android:color="#CFE5D6" /> <!-- 边框颜色 -->
8
</shape>

二进制
app/src/main/res/drawable/group_adapter_empty_view_image.png


+ 83 - 0
app/src/main/res/layout/activity_car_brand.xml

@ -0,0 +1,83 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="match_parent"
7
    android:background="@color/white"
8
    tools:context=".activity.CarBrandActivity">
9
10
    <androidx.constraintlayout.widget.ConstraintLayout
11
        android:id="@+id/nav_bar"
12
        android:layout_width="match_parent"
13
        android:layout_height="44dp"
14
        app:layout_constraintTop_toTopOf="parent">
15
16
        <TextView
17
            android:id="@+id/nav_title"
18
            android:layout_width="match_parent"
19
            android:layout_height="match_parent"
20
            android:gravity="center"
21
            android:text="品牌"
22
            android:textColor="#444444"
23
            android:textSize="18sp" />
24
25
        <ImageView
26
            android:id="@+id/iv_back"
27
            android:layout_width="wrap_content"
28
            android:layout_height="match_parent"
29
            android:layout_alignParentLeft="true"
30
            android:layout_centerVertical="true"
31
            android:contentDescription="@null"
32
            android:paddingLeft="15dp"
33
            android:paddingRight="15dp"
34
            android:src="@drawable/icon_lvback1119"
35
            app:layout_constraintLeft_toLeftOf="parent" />
36
37
        <View
38
            android:layout_width="match_parent"
39
            android:layout_height="0.5dp"
40
            android:background="@color/ui_titleline"
41
            app:layout_constraintBottom_toBottomOf="parent" />
42
    </androidx.constraintlayout.widget.ConstraintLayout>
43
44
    <com.donkingliang.groupedadapter.widget.StickyHeaderLayout
45
        android:id="@+id/sticky_header_layout"
46
        android:layout_width="match_parent"
47
        android:layout_height="0dp"
48
        app:layout_constraintBottom_toBottomOf="parent"
49
        app:layout_constraintTop_toBottomOf="@+id/nav_bar">
50
51
        <androidx.recyclerview.widget.RecyclerView
52
            android:id="@+id/recycler_view"
53
            android:layout_width="match_parent"
54
            android:layout_height="match_parent" />
55
    </com.donkingliang.groupedadapter.widget.StickyHeaderLayout>
56
57
    <com.electric.chargingpile.view.LetterSideView
58
        android:id="@+id/letter_side_view"
59
        android:layout_width="30dp"
60
        android:layout_height="0dp"
61
        android:background="#F8FBFE"
62
        android:paddingTop="25dp"
63
        android:paddingBottom="25dp"
64
        android:visibility="gone"
65
        app:layout_constraintBottom_toBottomOf="parent"
66
        app:layout_constraintRight_toRightOf="parent"
67
        app:layout_constraintTop_toBottomOf="@+id/nav_bar"
68
        tools:visibility="visible" />
69
70
    <TextView
71
        android:id="@+id/text_view_dialog"
72
        android:layout_width="match_parent"
73
        android:layout_height="0dp"
74
        android:gravity="center"
75
        android:textColor="#CCCCCC"
76
        android:textSize="40sp"
77
        android:visibility="gone"
78
        app:layout_constraintBottom_toBottomOf="parent"
79
        app:layout_constraintTop_toBottomOf="@+id/nav_bar"
80
        tools:text="X"
81
        tools:visibility="visible" />
82
83
</androidx.constraintlayout.widget.ConstraintLayout>

+ 57 - 0
app/src/main/res/layout/activity_car_model.xml

@ -0,0 +1,57 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="match_parent"
7
    android:background="@color/white"
8
    tools:context=".activity.CarModelActivity">
9
10
    <androidx.constraintlayout.widget.ConstraintLayout
11
        android:id="@+id/nav_bar"
12
        android:layout_width="match_parent"
13
        android:layout_height="44dp"
14
        app:layout_constraintTop_toTopOf="parent">
15
16
        <TextView
17
            android:id="@+id/nav_title"
18
            android:layout_width="match_parent"
19
            android:layout_height="match_parent"
20
            android:gravity="center"
21
            android:text="车型"
22
            android:textColor="#444444"
23
            android:textSize="18sp" />
24
25
        <ImageView
26
            android:id="@+id/iv_back"
27
            android:layout_width="wrap_content"
28
            android:layout_height="match_parent"
29
            android:layout_alignParentLeft="true"
30
            android:layout_centerVertical="true"
31
            android:contentDescription="@null"
32
            android:paddingLeft="15dp"
33
            android:paddingRight="15dp"
34
            android:src="@drawable/icon_lvback1119"
35
            app:layout_constraintLeft_toLeftOf="parent" />
36
37
        <View
38
            android:layout_width="match_parent"
39
            android:layout_height="0.5dp"
40
            android:background="@color/ui_titleline"
41
            app:layout_constraintBottom_toBottomOf="parent" />
42
    </androidx.constraintlayout.widget.ConstraintLayout>
43
44
    <com.donkingliang.groupedadapter.widget.StickyHeaderLayout
45
        android:id="@+id/sticky_header_layout"
46
        android:layout_width="match_parent"
47
        android:layout_height="0dp"
48
        android:background="#FFF2F6F9"
49
        app:layout_constraintBottom_toBottomOf="parent"
50
        app:layout_constraintTop_toBottomOf="@+id/nav_bar">
51
52
        <androidx.recyclerview.widget.RecyclerView
53
            android:id="@+id/recycler_view"
54
            android:layout_width="match_parent"
55
            android:layout_height="match_parent" />
56
    </com.donkingliang.groupedadapter.widget.StickyHeaderLayout>
57
</androidx.constraintlayout.widget.ConstraintLayout>

+ 363 - 0
app/src/main/res/layout/activity_car_owner_certificate.xml

@ -0,0 +1,363 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="match_parent"
7
    android:background="@color/white"
8
    android:focusableInTouchMode="true"
9
    tools:context=".activity.CarOwnerCertificateActivity">
10
11
    <androidx.constraintlayout.widget.ConstraintLayout
12
        android:id="@+id/nav_bar"
13
        android:layout_width="match_parent"
14
        android:layout_height="44dp"
15
        app:layout_constraintTop_toTopOf="parent">
16
17
        <TextView
18
            android:id="@+id/nav_title"
19
            android:layout_width="match_parent"
20
            android:layout_height="match_parent"
21
            android:gravity="center"
22
            android:text="车主认证"
23
            android:textColor="#444444"
24
            android:textSize="18sp" />
25
26
        <ImageView
27
            android:id="@+id/iv_back"
28
            android:layout_width="wrap_content"
29
            android:layout_height="match_parent"
30
            android:layout_alignParentLeft="true"
31
            android:layout_centerVertical="true"
32
            android:contentDescription="@null"
33
            android:paddingLeft="15dp"
34
            android:paddingRight="15dp"
35
            android:src="@drawable/icon_lvback1119"
36
            app:layout_constraintLeft_toLeftOf="parent" />
37
38
        <View
39
            android:layout_width="match_parent"
40
            android:layout_height="0.5dp"
41
            android:background="@color/ui_titleline"
42
            app:layout_constraintBottom_toBottomOf="parent" />
43
    </androidx.constraintlayout.widget.ConstraintLayout>
44
45
    <ScrollView
46
        android:layout_width="match_parent"
47
        android:layout_height="0dp"
48
        android:orientation="vertical"
49
        android:scrollbars="none"
50
        app:layout_constraintBottom_toTopOf="@+id/submit_btn"
51
        app:layout_constraintTop_toBottomOf="@+id/nav_bar">
52
53
        <androidx.constraintlayout.widget.ConstraintLayout
54
            android:layout_width="match_parent"
55
            android:layout_height="wrap_content"
56
            android:paddingLeft="15dp"
57
            android:paddingRight="15dp">
58
59
            <!-- 车型 -->
60
            <androidx.constraintlayout.widget.ConstraintLayout
61
                android:id="@+id/car_model_constraint_layout"
62
                android:layout_width="match_parent"
63
                android:layout_height="0dp"
64
                android:layout_marginTop="15dp"
65
                app:layout_constraintDimensionRatio="h,518:95"
66
                app:layout_constraintTop_toTopOf="parent">
67
68
                <ImageView
69
                    android:id="@+id/add_car_model_icon"
70
                    android:layout_width="match_parent"
71
                    android:layout_height="match_parent"
72
                    android:scaleType="fitXY"
73
                    android:src="@drawable/icon_car_model"
74
                    app:layout_constraintBottom_toBottomOf="parent"
75
                    app:layout_constraintTop_toTopOf="parent" />
76
77
                <TextView
78
                    android:id="@+id/add_car_model_btn"
79
                    android:layout_width="80dp"
80
                    android:layout_height="32dp"
81
                    android:layout_marginRight="15dp"
82
                    android:background="@drawable/bg_add_car_model_shape"
83
                    android:gravity="center"
84
                    android:text="添加车型"
85
                    android:textColor="#506857"
86
                    android:textSize="14sp"
87
                    app:layout_constraintBottom_toBottomOf="parent"
88
                    app:layout_constraintRight_toRightOf="parent"
89
                    app:layout_constraintTop_toTopOf="parent" />
90
            </androidx.constraintlayout.widget.ConstraintLayout>
91
92
            <androidx.constraintlayout.widget.ConstraintLayout
93
                android:id="@+id/car_model_selected_constraint_layout"
94
                android:layout_width="match_parent"
95
                android:layout_height="wrap_content"
96
                android:layout_marginTop="15dp"
97
                android:background="@color/white"
98
                android:visibility="gone"
99
                app:layout_constraintTop_toBottomOf="@+id/car_model_constraint_layout"
100
                tools:background="#cccccc"
101
                tools:visibility="visible">
102
103
                <ImageView
104
                    android:id="@+id/car_icon"
105
                    android:layout_width="95dp"
106
                    android:layout_height="63dp"
107
                    android:scaleType="fitCenter"
108
                    app:layout_constraintBottom_toBottomOf="parent"
109
                    app:layout_constraintLeft_toLeftOf="parent"
110
                    app:layout_constraintTop_toTopOf="parent"
111
                    tools:background="#00ff00" />
112
113
                <TextView
114
                    android:id="@+id/car_name"
115
                    android:layout_width="wrap_content"
116
                    android:layout_height="wrap_content"
117
                    android:layout_marginLeft="10dp"
118
                    android:layout_marginTop="12dp"
119
                    android:textColor="#FF222222"
120
                    android:textSize="14sp"
121
                    app:layout_constraintLeft_toRightOf="@+id/car_icon"
122
                    app:layout_constraintTop_toTopOf="parent"
123
                    tools:text="蔚来ES6" />
124
125
                <TextView
126
                    android:id="@+id/car_series"
127
                    android:layout_width="wrap_content"
128
                    android:layout_height="wrap_content"
129
                    android:layout_marginBottom="10dp"
130
                    android:textColor="#FF0D1120"
131
                    android:textSize="14sp"
132
                    app:layout_constraintBottom_toBottomOf="parent"
133
                    app:layout_constraintLeft_toLeftOf="@+id/car_name"
134
135
                    tools:text="2020款 420KM 运动版" />
136
137
                <ImageView
138
                    android:layout_width="wrap_content"
139
                    android:layout_height="wrap_content"
140
                    android:src="@drawable/icon_right_cursor"
141
                    app:layout_constraintBottom_toBottomOf="parent"
142
                    app:layout_constraintRight_toRightOf="parent"
143
                    app:layout_constraintTop_toTopOf="parent" />
144
145
146
            </androidx.constraintlayout.widget.ConstraintLayout>
147
148
149
            <!-- 行驶证图片 -->
150
            <androidx.constraintlayout.widget.ConstraintLayout
151
                android:id="@+id/driving_license"
152
                android:layout_width="match_parent"
153
                android:layout_height="0dp"
154
                android:layout_marginTop="10dp"
155
                app:layout_constraintDimensionRatio="h,518:315"
156
                app:layout_constraintTop_toBottomOf="@+id/car_model_selected_constraint_layout">
157
158
                <ImageView
159
                    android:id="@+id/driving_license_icon"
160
                    android:layout_width="match_parent"
161
                    android:layout_height="match_parent"
162
                    android:src="@drawable/icon_driving_license" />
163
164
                <TextView
165
                    android:id="@+id/driving_license_text_view"
166
                    android:layout_width="wrap_content"
167
                    android:layout_height="wrap_content"
168
                    android:text="上传行驶证首页(选填)"
169
                    android:textColor="#3D5545"
170
                    android:textSize="14sp"
171
                    app:layout_constraintBottom_toBottomOf="parent"
172
                    app:layout_constraintLeft_toLeftOf="parent"
173
                    app:layout_constraintRight_toRightOf="parent"
174
                    app:layout_constraintTop_toTopOf="parent" />
175
176
                <ImageView
177
                    android:id="@+id/driving_license_upload_icon"
178
                    android:layout_width="wrap_content"
179
                    android:layout_height="wrap_content"
180
                    android:layout_marginBottom="5dp"
181
                    android:src="@drawable/icon_upload"
182
                    app:layout_constraintBottom_toTopOf="@+id/driving_license_text_view"
183
                    app:layout_constraintLeft_toLeftOf="parent"
184
                    app:layout_constraintRight_toRightOf="parent" />
185
186
            </androidx.constraintlayout.widget.ConstraintLayout>
187
188
            <!-- 行驶证信息 -->
189
            <LinearLayout
190
                android:id="@+id/driving_license_info"
191
                android:layout_width="match_parent"
192
                android:layout_height="wrap_content"
193
                android:layout_marginTop="5dp"
194
                android:layout_marginBottom="50dp"
195
                android:orientation="vertical"
196
                app:layout_constraintTop_toBottomOf="@+id/driving_license">
197
198
                <LinearLayout
199
                    android:layout_width="match_parent"
200
                    android:layout_height="50dp"
201
                    android:gravity="center_vertical"
202
                    android:orientation="horizontal">
203
204
                    <TextView
205
                        android:layout_width="90dp"
206
                        android:layout_height="wrap_content"
207
                        android:text="* 车牌号"
208
                        android:textColor="#0D1120"
209
                        android:textSize="14sp"
210
                        android:textStyle="bold" />
211
212
                    <EditText
213
                        android:layout_width="0dp"
214
                        android:layout_height="match_parent"
215
                        android:layout_weight="1"
216
                        android:background="@null"
217
                        android:hint="请输入正确的车牌号"
218
                        android:inputType="text"
219
                        android:textColor="#0D1120"
220
                        android:textColorHint="#CBCBCB"
221
                        android:textSize="14sp" />
222
                </LinearLayout>
223
224
                <View
225
                    android:layout_width="match_parent"
226
                    android:layout_height="1dp"
227
                    android:background="#F8F8F8" />
228
229
                <LinearLayout
230
                    android:layout_width="match_parent"
231
                    android:layout_height="50dp"
232
                    android:gravity="center_vertical"
233
                    android:orientation="horizontal">
234
235
                    <TextView
236
                        android:layout_width="90dp"
237
                        android:layout_height="wrap_content"
238
                        android:text="* 发动机号"
239
                        android:textColor="#0D1120"
240
                        android:textSize="14sp"
241
                        android:textStyle="bold" />
242
243
                    <EditText
244
                        android:layout_width="0dp"
245
                        android:layout_height="match_parent"
246
                        android:layout_weight="1"
247
                        android:background="@null"
248
                        android:hint="请输入发动机号"
249
                        android:inputType="text"
250
                        android:textColor="#0D1120"
251
                        android:textColorHint="#CBCBCB"
252
                        android:textSize="14sp" />
253
                </LinearLayout>
254
255
                <View
256
                    android:layout_width="match_parent"
257
                    android:layout_height="1dp"
258
                    android:background="#F8F8F8" />
259
260
                <LinearLayout
261
                    android:layout_width="match_parent"
262
                    android:layout_height="50dp"
263
                    android:gravity="center_vertical"
264
                    android:orientation="horizontal">
265
266
                    <TextView
267
                        android:layout_width="90dp"
268
                        android:layout_height="wrap_content"
269
                        android:text="注册时间"
270
                        android:textColor="#0D1120"
271
                        android:textSize="14sp"
272
                        android:textStyle="bold" />
273
274
                    <EditText
275
                        android:layout_width="0dp"
276
                        android:layout_height="match_parent"
277
                        android:layout_weight="1"
278
                        android:background="@null"
279
                        android:hint="请输入有效日期"
280
                        android:inputType="text"
281
                        android:textColor="#0D1120"
282
                        android:textColorHint="#CBCBCB"
283
                        android:textSize="14sp" />
284
                </LinearLayout>
285
286
                <View
287
                    android:layout_width="match_parent"
288
                    android:layout_height="1dp"
289
                    android:background="#F8F8F8" />
290
            </LinearLayout>
291
            <!-- 行驶证类型 -->
292
            <LinearLayout
293
                android:id="@+id/driving_license_type"
294
                android:layout_width="match_parent"
295
                android:layout_height="50dp"
296
                android:layout_marginTop="10dp"
297
                android:gravity="center_vertical"
298
                android:orientation="horizontal"
299
                app:layout_constraintTop_toBottomOf="@+id/driving_license_info">
300
301
                <com.electric.chargingpile.view.TextImageView
302
                    android:id="@+id/driving_license_type_first"
303
                    android:layout_width="wrap_content"
304
                    android:layout_height="match_parent"
305
                    android:drawableLeft="@drawable/icon_radio_selected"
306
                    android:drawablePadding="10dp"
307
                    android:gravity="center_vertical"
308
                    android:paddingRight="40dp"
309
                    android:text="自用"
310
                    app:drawableLeftHeight="17dp"
311
                    app:drawableLeftWidth="17dp" />
312
313
                <com.electric.chargingpile.view.TextImageView
314
                    android:id="@+id/driving_license_type_second"
315
                    android:layout_width="wrap_content"
316
                    android:layout_height="match_parent"
317
                    android:drawableLeft="@drawable/icon_radio_normal"
318
                    android:drawablePadding="10dp"
319
                    android:gravity="center_vertical"
320
                    android:paddingRight="40dp"
321
                    android:text="营运"
322
                    app:drawableLeftHeight="17dp"
323
                    app:drawableLeftWidth="17dp" />
324
325
326
                <com.electric.chargingpile.view.TextImageView
327
                    android:id="@+id/driving_license_type_third"
328
                    android:layout_width="wrap_content"
329
                    android:layout_height="match_parent"
330
                    android:drawableLeft="@drawable/icon_radio_normal"
331
                    android:drawablePadding="10dp"
332
                    android:gravity="center_vertical"
333
                    android:paddingRight="40dp"
334
                    android:text="公务"
335
                    app:drawableLeftHeight="17dp"
336
                    app:drawableLeftWidth="17dp" />
337
338
            </LinearLayout>
339
            <!-- 认证说明信息 -->
340
            <TextView
341
                android:layout_width="match_parent"
342
                android:layout_height="wrap_content"
343
                android:layout_marginTop="10dp"
344
                android:layout_marginBottom="30dp"
345
                android:text="认证说明\n\n1.车型信息和行驶证主页为必填项;\n2.最多可认证三款车型;\n3.默认首款认证车型为主车型;\n4.上传行驶证详细页面,并保证所有信息清晰;\n5.认证成功的首个车型可获得50元充电红包。"
346
                android:textColor="#0D1120"
347
                android:textSize="14sp"
348
                app:layout_constraintBottom_toBottomOf="parent"
349
                app:layout_constraintTop_toBottomOf="@+id/driving_license_type" />
350
        </androidx.constraintlayout.widget.ConstraintLayout>
351
    </ScrollView>
352
353
    <Button
354
        android:id="@+id/submit_btn"
355
        android:layout_width="match_parent"
356
        android:layout_height="44dp"
357
        android:background="#00CA42"
358
        android:text="确认提交"
359
        android:textColor="#ffffff"
360
        android:textSize="16sp"
361
        app:layout_constraintBottom_toBottomOf="parent" />
362
363
</androidx.constraintlayout.widget.ConstraintLayout>

+ 81 - 0
app/src/main/res/layout/activity_user_center.xml

@ -479,6 +479,87 @@
479 479
                        android:layout_width="match_parent"
480 480
                        android:layout_height="0.5dp"
481 481
                        android:background="@color/ui_line" />
482
                    <RelativeLayout
483
                        android:id="@+id/rl_car_owner_certificate"
484
                        android:layout_width="fill_parent"
485
                        android:layout_height="44dp"
486
                        android:background="@drawable/item_selector">
487
488
                        <TextView
489
                            android:layout_width="wrap_content"
490
                            android:layout_height="wrap_content"
491
                            android:layout_alignParentStart="true"
492
                            android:layout_alignParentLeft="true"
493
                            android:layout_alignParentTop="true"
494
                            android:layout_alignParentBottom="true"
495
                            android:layout_marginLeft="15dp"
496
                            android:drawableLeft="@drawable/icon_car_user_certificate"
497
                            android:drawablePadding="15dp"
498
                            android:gravity="center_vertical"
499
                            android:text="车主认证"
500
                            android:textColor="@color/ui_62"
501
                            android:textSize="15sp" />
502
503
                        <TextView
504
                            android:layout_width="wrap_content"
505
                            android:layout_height="wrap_content"
506
                            android:layout_alignParentTop="true"
507
                            android:layout_alignParentRight="true"
508
                            android:layout_alignParentBottom="true"
509
                            android:layout_marginRight="15dp"
510
                            android:drawableRight="@drawable/icon_more2_0"
511
                            android:drawablePadding="30px"
512
                            android:gravity="center_vertical"
513
                            android:text=""
514
                            android:textColor="@color/ui_68"
515
                            android:textSize="14sp" />
516
                    </RelativeLayout>
517
                    <View
518
                        android:layout_width="match_parent"
519
                        android:layout_height="0.5dp"
520
                        android:layout_marginLeft="16dp"
521
                        android:background="@color/ui_line" />
522
523
                    <RelativeLayout
524
                        android:id="@+id/rl_publish_price"
525
                        android:layout_width="fill_parent"
526
                        android:layout_height="44dp"
527
                        android:background="@drawable/item_selector">
528
529
                        <TextView
530
                            android:layout_width="wrap_content"
531
                            android:layout_height="wrap_content"
532
                            android:layout_alignParentStart="true"
533
                            android:layout_alignParentLeft="true"
534
                            android:layout_alignParentTop="true"
535
                            android:layout_alignParentBottom="true"
536
                            android:layout_marginLeft="15dp"
537
                            android:drawableLeft="@drawable/icon_publish_price"
538
                            android:drawablePadding="15dp"
539
                            android:gravity="center_vertical"
540
                            android:text="发表成交价"
541
                            android:textColor="@color/ui_62"
542
                            android:textSize="15sp" />
543
544
                        <TextView
545
                            android:layout_width="wrap_content"
546
                            android:layout_height="wrap_content"
547
                            android:layout_alignParentTop="true"
548
                            android:layout_alignParentRight="true"
549
                            android:layout_alignParentBottom="true"
550
                            android:layout_marginRight="15dp"
551
                            android:drawableRight="@drawable/icon_more2_0"
552
                            android:drawablePadding="30px"
553
                            android:gravity="center_vertical"
554
                            android:text=""
555
                            android:textColor="@color/ui_68"
556
                            android:textSize="14sp" />
557
                    </RelativeLayout>
558
                    <View
559
                        android:layout_width="match_parent"
560
                        android:layout_height="0.5dp"
561
                        android:layout_marginLeft="16dp"
562
                        android:background="@color/ui_line" />
482 563
483 564
                    <RelativeLayout
484 565
                        android:id="@+id/rl_chongzhi"

+ 42 - 0
app/src/main/res/layout/adapter_child_car_brand.xml

@ -0,0 +1,42 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="55dp"
7
    android:orientation="vertical"
8
    android:paddingLeft="15dp"
9
    android:background="@color/white"
10
    tools:background="#cccccc">
11
12
    <View
13
        android:id="@+id/line"
14
        android:layout_width="match_parent"
15
        android:layout_height="1dp"
16
        android:background="#E6E6E6"
17
        app:layout_constraintTop_toTopOf="parent" />
18
19
    <ImageView
20
        android:id="@+id/icon"
21
        android:layout_width="40dp"
22
        android:layout_height="40dp"
23
        android:scaleType="fitCenter"
24
        app:layout_constraintBottom_toBottomOf="parent"
25
        app:layout_constraintLeft_toLeftOf="parent"
26
        app:layout_constraintTop_toTopOf="parent"
27
        tools:background="#00ff00" />
28
29
    <TextView
30
        android:id="@+id/title"
31
        android:layout_width="wrap_content"
32
        android:layout_height="wrap_content"
33
        android:layout_gravity="center_vertical"
34
        android:layout_marginLeft="10dp"
35
        android:textColor="#FF222222"
36
        android:textSize="14sp"
37
        app:layout_constraintBottom_toBottomOf="parent"
38
        app:layout_constraintLeft_toRightOf="@+id/icon"
39
        app:layout_constraintTop_toTopOf="parent"
40
        tools:text="奥迪" />
41
42
</androidx.constraintlayout.widget.ConstraintLayout>

+ 77 - 0
app/src/main/res/layout/adapter_child_car_model.xml

@ -0,0 +1,77 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:layout_width="match_parent"
6
    android:layout_height="100dp"
7
    android:paddingLeft="15dp"
8
    android:background="@color/white"
9
    tools:background="#cccccc">
10
11
    <View
12
        android:id="@+id/line"
13
        android:layout_width="match_parent"
14
        android:layout_height="1dp"
15
        android:background="#E6E6E6"
16
        app:layout_constraintTop_toTopOf="parent" />
17
18
    <ImageView
19
        android:id="@+id/icon"
20
        android:layout_width="120dp"
21
        android:layout_height="80dp"
22
        android:scaleType="fitCenter"
23
        app:layout_constraintBottom_toBottomOf="parent"
24
        app:layout_constraintLeft_toLeftOf="parent"
25
        app:layout_constraintTop_toTopOf="parent"
26
        tools:background="#00ff00" />
27
28
    <TextView
29
        android:id="@+id/title"
30
        android:layout_width="wrap_content"
31
        android:layout_height="wrap_content"
32
        android:layout_gravity="center_vertical"
33
        android:layout_marginLeft="10dp"
34
        android:layout_marginTop="27dp"
35
        android:textColor="#FF222222"
36
        android:textSize="14sp"
37
        app:layout_constraintLeft_toRightOf="@+id/icon"
38
        app:layout_constraintTop_toTopOf="parent"
39
        tools:text="奥迪" />
40
41
    <LinearLayout
42
        android:layout_width="wrap_content"
43
        android:layout_height="wrap_content"
44
        android:layout_marginLeft="10dp"
45
        android:layout_marginBottom="28dp"
46
        android:orientation="horizontal"
47
        app:layout_constraintBottom_toBottomOf="parent"
48
        app:layout_constraintLeft_toRightOf="@+id/icon">
49
50
        <TextView
51
            android:layout_width="wrap_content"
52
            android:layout_height="wrap_content"
53
            android:textColor="#FFE02020"
54
            android:textSize="14sp"
55
            tools:text="33.8-52.3" />
56
57
        <TextView
58
            android:id="@+id/price"
59
            android:layout_width="wrap_content"
60
            android:layout_height="wrap_content"
61
            android:layout_gravity="center_vertical"
62
            android:layout_marginLeft="5dp"
63
            android:text="万"
64
            android:textColor="#FF222222"
65
            android:textSize="12sp" />
66
67
        <TextView
68
            android:id="@+id/endurance"
69
            android:layout_width="wrap_content"
70
            android:layout_height="wrap_content"
71
            android:layout_marginLeft="20dp"
72
            android:textColor="#FF222222"
73
            android:textSize="12sp"
74
            tools:text="续航:300km" />
75
    </LinearLayout>
76
77
</androidx.constraintlayout.widget.ConstraintLayout>

+ 19 - 0
app/src/main/res/layout/adapter_header_car_brand.xml

@ -0,0 +1,19 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:tools="http://schemas.android.com/tools"
4
    android:layout_width="match_parent"
5
    android:layout_height="25dp"
6
    android:background="#FFF2F6F9"
7
    android:paddingLeft="15dp"
8
    android:paddingRight="15dp">
9
    
10
    <TextView
11
        android:id="@+id/title"
12
        android:layout_width="match_parent"
13
        android:layout_height="match_parent"
14
        android:gravity="center_vertical"
15
        android:lines="1"
16
        android:textColor="#FF6F6F7D"
17
        android:textSize="12sp"
18
        tools:text="A" />
19
</LinearLayout>

+ 19 - 0
app/src/main/res/layout/adapter_header_car_model.xml

@ -0,0 +1,19 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    xmlns:tools="http://schemas.android.com/tools"
4
    android:layout_width="match_parent"
5
    android:layout_height="25dp"
6
    android:background="#FFF2F6F9"
7
    android:paddingLeft="15dp"
8
    android:paddingRight="15dp">
9
    
10
    <TextView
11
        android:id="@+id/title"
12
        android:layout_width="match_parent"
13
        android:layout_height="match_parent"
14
        android:gravity="center_vertical"
15
        android:lines="1"
16
        android:textColor="#FF6F6F7D"
17
        android:textSize="12sp"
18
        tools:text="A" />
19
</LinearLayout>

+ 13 - 0
app/src/main/res/layout/group_adapter_default_empty_view.xml

@ -0,0 +1,13 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="match_parent"
4
    android:layout_height="match_parent"
5
    android:orientation="vertical">
6
7
    <ImageView
8
        android:layout_width="wrap_content"
9
        android:layout_height="wrap_content"
10
        android:layout_gravity="center"
11
        android:src="@drawable/group_adapter_empty_view_image"/>
12
13
</FrameLayout>

+ 5 - 0
app/src/main/res/values/strings.xml

@ -208,4 +208,9 @@
208 208
    <string name="personal_shar_info_content">快来分享吧\n小主大家都很期待你的精彩内容哦</string>
209 209
    <string name="query_all_addresses"><u>查看全部目的地</u></string>
210 210
    <string name="query_all_points"><u>查看全部站点</u></string>
211
212
    <item name="type_header" type="integer" />
213
    <item name="type_footer" type="integer" />
214
    <item name="type_child" type="integer" />
215
    <item name="type_empty" type="integer" />
211 216
</resources>

+ 11 - 0
app/src/main/res/values/styles.xml

@ -355,4 +355,15 @@
355 355
        <!--相册文件夹列表选中图标-->
356 356
        <item name="picture.folder_checked_dot">@drawable/picture_orange_oval</item>
357 357
    </style>
358

359
    <declare-styleable name="TextImageView">
360
        <attr name="drawableLeftWidth" format="dimension" />
361
        <attr name="drawableLeftHeight" format="dimension" />
362
        <attr name="drawableTopWidth" format="dimension" />
363
        <attr name="drawableTopHeight" format="dimension" />
364
        <attr name="drawableRightWidth" format="dimension" />
365
        <attr name="drawableRightHeight" format="dimension" />
366
        <attr name="drawableBottomWidth" format="dimension" />
367
        <attr name="drawableBottomHeight" format="dimension" />
368
    </declare-styleable>
358 369
</resources>

排行榜页面添加季度筛选功能 · 8d1620fba1 - Gogs: Go Git Service
Explorar el Código

排行榜页面添加季度筛选功能

hy %!s(int64=4) %!d(string=hace) años
padre
commit
8d1620fba1

+ 3 - 0
app/build.gradle

@ -245,4 +245,7 @@ dependencies {
245 245
    implementation 'com.github.khoyron:Actionsheet-android:4'
246 246
    implementation 'cn.jiguang.sdk:jpush:4.6.2'
247 247
    implementation 'cn.jiguang.sdk:jcore:3.2.2'
248
249
    //极速版 (预计占用 4M 左右空间),主要移除了一些不常用的编解码器
250
    implementation 'com.github.microshow:RxFFmpeg:4.9.0-lite'
248 251
}

+ 3 - 0
app/src/main/AndroidManifest.xml

@ -100,6 +100,9 @@
100 100
            android:name=".activity.PermissionAgreementActivity"
101 101
            android:screenOrientation="portrait"/>
102 102
        <activity
103
            android:name=".activity.VideoCompressionActivity"
104
            android:screenOrientation="portrait"/>
105
        <activity
103 106
            android:name=".activity.CarModelActivity"
104 107
            android:launchMode="singleTop"
105 108
            android:screenOrientation="portrait" />

+ 11 - 0
app/src/main/java/com/electric/chargingpile/activity/MyWebViewActivity.java

@ -798,6 +798,17 @@ public class MyWebViewActivity extends Activity implements PlatformActionListene
798 798
                    index = "15";
799 799
                }
800 800
                break;
801
802
            case "16":
803
                if (MainApplication.isLogin()) {
804
                    startActivity(new Intent(getApplication(), MemberGetCoinActivity.class));
805
                } else {
806
                    startActivity(new Intent(getApplicationContext(), LoginActivity.class));
807
                    ToastUtil.showToast(getApplicationContext(), "请先登录", Toast.LENGTH_SHORT);
808
809
                }
810
811
                break;
801 812
        }
802 813
803 814
    }

+ 256 - 0
app/src/main/java/com/electric/chargingpile/activity/VideoCompressionActivity.java

@ -0,0 +1,256 @@
1
package com.electric.chargingpile.activity;
2
3
import android.content.Intent;
4
import android.media.MediaMetadataRetriever;
5
import android.net.Uri;
6
import android.os.Build;
7
import android.os.Bundle;
8
import android.util.Log;
9
import android.view.View;
10
import android.widget.TextView;
11
12
import androidx.annotation.Nullable;
13
import androidx.appcompat.app.AppCompatActivity;
14
import androidx.core.content.FileProvider;
15
16
import com.electric.chargingpile.R;
17
import com.electric.chargingpile.engine.GlideEngine;
18
import com.electric.chargingpile.util.PhotoUtils;
19
import com.electric.chargingpile.util.Util;
20
import com.luck.picture.lib.PictureSelector;
21
import com.luck.picture.lib.animators.AnimationType;
22
import com.luck.picture.lib.config.PictureConfig;
23
import com.luck.picture.lib.config.PictureMimeType;
24
import com.luck.picture.lib.entity.LocalMedia;
25
26
import java.io.File;
27
import java.lang.ref.WeakReference;
28
import java.text.DecimalFormat;
29
import java.util.HashMap;
30
31
import io.microshow.rxffmpeg.RxFFmpegInvoke;
32
import io.microshow.rxffmpeg.RxFFmpegSubscriber;
33
34
public class VideoCompressionActivity extends AppCompatActivity implements View.OnClickListener {
35
36
    private TextView viewById;
37
    public static final int REQUEST_CODE_CHOOSE = 339;
38
    @Override
39
    protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
40
        super.onCreate(savedInstanceState);
41
        setContentView(R.layout.activity_video_compression);
42
        findViewById(R.id.openPhoto).setOnClickListener(this);
43
        findViewById(R.id.videoZip).setOnClickListener(this);
44
        findViewById(R.id.startVideoZip).setOnClickListener(this);
45
        viewById = findViewById(R.id.progress);
46
    }
47
48
    @Override
49
    public void onClick(View v) {
50
        switch (v.getId()){
51
            case R.id.openPhoto:
52
                PictureSelector.create(this)
53
                        .openGallery(PictureMimeType.ofVideo())
54
                        .selectionMode(PictureConfig.SINGLE)
55
                        .isCompress(true)//是否压缩
56
                        .isPreviewEggs(true)//预览图片时是否增强左右滑动图片体验
57
                        .isGif(true)//是否显示gif
58
                        .isAndroidQTransform(true)
59
                        .imageEngine(GlideEngine.createGlideEngine())
60
                        .isWeChatStyle(false)// 是否开启微信图片选择风格
61
                        .isUseCustomCamera(false)// 是否使用自定义相机
62
                        .isPageStrategy(true)// 是否开启分页策略 & 每页多少条;默认开启
63
                        .setPictureStyle(Util.getWhiteStyle(this))// 动态自定义相册主题
64
                        .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)// 列表动画效果
65
                        .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果
66
                        .imageSpanCount(4)// 每行显示个数
67
                        .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回
68
                        .isAutomaticTitleRecyclerTop(true)//图片列表超过一屏连续点击顶部标题栏快速回滚至顶部
69
                        .forResult(REQUEST_CODE_CHOOSE);
70
71
                break;
72
73
            case R.id.videoZip:
74
                Log.e("TAG", "开始");
75
                runFFmpegRxJava();
76
                break;
77
78
            case R.id.startVideoZip:
79
                PictureSelector.create(this)
80
                        .setPictureStyle(Util.getWhiteStyle(this))
81
                        .externalPictureVideo(mResultPath);
82
83
                break;
84
        }
85
    }
86
    private String mPath="";
87
    @Override
88
    protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
89
        super.onActivityResult(requestCode, resultCode, data);
90
        LocalMedia media = PictureSelector.obtainMultipleResult(data).get(0);
91
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
92
            mPath= media.getAndroidQToPath();
93
        }else{
94
            mPath=media.getPath();
95
        }
96
    }
97
98
    private  MyRxFFmpegSubscriber myRxFFmpegSubscriber=null;
99
    private  static String mResultPath=null;
100
    private void runFFmpegRxJava() {
101
102
        MediaMetadataRetriever retriever =new MediaMetadataRetriever();
103
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
104
            Uri newUri  = FileProvider.getUriForFile(
105
                    this,
106
                    getPackageName() + ".provider",
107
                    new File(mPath)
108
            );
109
            retriever.setDataSource(this, newUri);
110
        } else {
111
            retriever.setDataSource(mPath, new HashMap<String, String>());
112
        }
113
        retriever.setDataSource(mPath);
114
115
116
        String duration_s = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
117
        long duration = Long.parseLong(duration_s);
118
119
//获取视频帧数
120
        String count_s = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT);
121
122
        long bitrate = Long.parseLong(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
123
        long count = Long.parseLong(count_s);
124
125
//计算帧率
126
        long dt = duration/count; // 平均每帧的时间间隔,35ms
127
128
129
130
        Log.e("TAG", "runFFmpegRxJava帧率为: "+dt);
131
132
        DecimalFormat df = new DecimalFormat("#.00");
133
        String size="";
134
        if (bitrate < 1024) {
135
            size = df.format((double) bitrate) + "BT";
136
        } else if (bitrate < 1048576) {
137
            size = df.format((double) bitrate / 1024) + "KB";
138
        } else if (bitrate < 1073741824) {
139
            size = df.format((double) bitrate / 1048576) + "MB";
140
        } else {
141
            size = df.format((double) bitrate / 1073741824) +"GB";
142
        }
143
144
        Log.e("TAG", "runFFmpegRxJava比特率为: "+size);
145
146
147
148
149
        mResultPath = PhotoUtils.CACHE_DIR + System.currentTimeMillis() + getFileExtension(mPath);
150
        Log.e("TAG", "runFFmpegRxJava: "+GetFileSize(mPath));
151
        if (bitrate < 21299200){//21299200 bit 即 2600k  如果小于2600K则
152
            return;
153
        }
154
//        String text = "ffmpeg -y -i "+mPath+" -vf boxblur=25:5 -preset superfast "+mResultPath;
155
        String text = "ffmpeg -y -i "+mPath+" -b 2600k -r 25 -vcodec libx264 -preset superfast "+mResultPath;
156
157
        String[] commands = text.split(" ");
158
159
        myRxFFmpegSubscriber = new MyRxFFmpegSubscriber(this);
160
161
        //开始执行FFmpeg命令
162
        RxFFmpegInvoke.getInstance()
163
                .runCommandRxJava(commands)
164
                .subscribe(myRxFFmpegSubscriber);
165
166
    }
167
168
    public static class MyRxFFmpegSubscriber extends RxFFmpegSubscriber {
169
170
        private WeakReference<VideoCompressionActivity> mWeakReference;
171
172
        public MyRxFFmpegSubscriber(VideoCompressionActivity homeFragment) {
173
            mWeakReference = new WeakReference<>(homeFragment);
174
        }
175
176
        @Override
177
        public void onFinish() {
178
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
179
            if (mHomeFragment != null) {
180
                Log.e("TAG", "处理成功"+GetFileSize(mResultPath));
181
182
            }
183
        }
184
185
        @Override
186
        public void onProgress(int progress, long progressTime) {
187
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
188
            if (mHomeFragment != null) {
189
                //progressTime 可以在结合视频总时长去计算合适的进度值
190
                Log.e("TAG", "onProgress progress:"+progress+"  progressTime:"+progressTime);
191
            }
192
        }
193
194
        @Override
195
        public void onCancel() {
196
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
197
            if (mHomeFragment != null) {
198
                Log.e("TAG", "已取消");
199
200
            }
201
        }
202
203
        @Override
204
        public void onError(String message) {
205
            final VideoCompressionActivity mHomeFragment = mWeakReference.get();
206
            if (mHomeFragment != null) {
207
                Log.e("TAG", "出错了 onError:" + message);
208
            }
209
        }
210
    }
211
212
    @Override
213
    public void onDestroy() {
214
        super.onDestroy();
215
        if (myRxFFmpegSubscriber != null) {
216
            myRxFFmpegSubscriber.dispose();
217
        }
218
    }
219
220
    public String getFileExtension(String path) {
221
        String extension = "";
222
        File file = new File(path);
223
        try {
224
            if (file != null && file.exists()) {
225
                String name = file.getName();
226
                extension = name.substring(name.lastIndexOf("."));
227
            }
228
        } catch (Exception e) {
229
            extension = "";
230
        }
231
        return extension;
232
    }
233
234
    public static String GetFileSize(String path){
235
        String size = "";
236
        File file = new File(path);
237
        if(file.exists() && file.isFile()){
238
            long fileS = file.length();
239
            DecimalFormat df = new DecimalFormat("#.00");
240
            if (fileS < 1024) {
241
                size = df.format((double) fileS) + "BT";
242
            } else if (fileS < 1048576) {
243
                size = df.format((double) fileS / 1024) + "KB";
244
            } else if (fileS < 1073741824) {
245
                size = df.format((double) fileS / 1048576) + "MB";
246
            } else {
247
                size = df.format((double) fileS / 1073741824) +"GB";
248
            }
249
        }else if(file.exists() && file.isDirectory()){
250
            size = "";
251
        }else{
252
            size = "0BT";
253
        }
254
        return size;
255
    }
256
}

+ 86 - 0
app/src/main/java/com/electric/chargingpile/adapter/QuarterAdapter.java

@ -0,0 +1,86 @@
1
package com.electric.chargingpile.adapter;
2
3
import android.content.Context;
4
import android.graphics.Color;
5
import android.view.LayoutInflater;
6
import android.view.View;
7
import android.view.ViewGroup;
8
import android.widget.TextView;
9
10
import androidx.annotation.NonNull;
11
import androidx.recyclerview.widget.RecyclerView;
12
13
import com.electric.chargingpile.R;
14
15
import org.jetbrains.annotations.NotNull;
16
17
import java.util.ArrayList;
18
19
public class QuarterAdapter extends RecyclerView.Adapter<QuarterAdapter.ViewHolder> {
20
    private Context mContext=null;
21
22
    private int mSelectPostion=0;
23
24
    private ArrayList<String> mDatas= new ArrayList<>();
25
    private ItemOnClick mItemOnClick= null;
26
27
    public QuarterAdapter(Context mContext) {
28
        this.mContext = mContext;
29
        mDatas.add("一季度");
30
        mDatas.add("二季度");
31
        mDatas.add("三季度");
32
        mDatas.add("四季度");
33
    }
34
35
    public ItemOnClick getItemOnClick() {
36
        return mItemOnClick;
37
    }
38
39
    public void setItemOnClick(ItemOnClick mItemOnClick) {
40
        this.mItemOnClick = mItemOnClick;
41
    }
42
43
    @NonNull
44
    @NotNull
45
    @Override
46
    public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
47
        View rootView = LayoutInflater.from(mContext).inflate(R.layout.layout_text_item, parent, false);
48
        return new ViewHolder(rootView);
49
    }
50
51
    @Override
52
    public void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position) {
53
        if (mSelectPostion==position){
54
            holder.mTextView.setTextColor(Color.parseColor("#ff0e0e0e"));
55
        }else{
56
            holder.mTextView.setTextColor(Color.parseColor("#9B9B9B"));
57
        }
58
        holder.mTextView.setText(mDatas.get(position));
59
        holder.mTextView.setOnClickListener(v->{
60
            if (mItemOnClick!=null){
61
                mSelectPostion=position;
62
                mItemOnClick.onClick(position);
63
                notifyDataSetChanged();
64
            }
65
        });
66
    }
67
68
    @Override
69
    public int getItemCount() {
70
        return mDatas.size();
71
    }
72
73
    public static class ViewHolder extends RecyclerView.ViewHolder {
74
75
        private final TextView mTextView;
76
77
        public ViewHolder(@NonNull @NotNull View itemView) {
78
            super(itemView);
79
            mTextView = itemView.findViewById(R.id.textView);
80
        }
81
    }
82
83
    public interface ItemOnClick{
84
        void onClick(int posistion);
85
    }
86
}

+ 54 - 1
app/src/main/java/com/electric/chargingpile/fragment/TotalListFragment.java

@ -1,20 +1,33 @@
1 1
package com.electric.chargingpile.fragment;
2 2
3 3
import android.content.Intent;
4
import android.graphics.Color;
5
import android.graphics.drawable.ColorDrawable;
4 6
import android.os.Bundle;
7
8
import androidx.core.widget.PopupWindowCompat;
5 9
import androidx.fragment.app.Fragment;
10
import androidx.recyclerview.widget.LinearLayoutManager;
11
import androidx.recyclerview.widget.RecyclerView;
12
6 13
import android.util.Log;
14
import android.view.Gravity;
7 15
import android.view.LayoutInflater;
8 16
import android.view.View;
9 17
import android.view.ViewGroup;
10 18
import android.widget.LinearLayout;
11 19
import android.widget.ListView;
20
import android.widget.PopupWindow;
12 21
import android.widget.RelativeLayout;
13 22
import android.widget.TextView;
23
import android.widget.Toast;
14 24
25
import com.blankj.utilcode.util.SizeUtils;
26
import com.blankj.utilcode.util.Utils;
15 27
import com.electric.chargingpile.R;
16 28
import com.electric.chargingpile.activity.LoginActivity;
17 29
import com.electric.chargingpile.activity.MainMapActivity;
30
import com.electric.chargingpile.adapter.QuarterAdapter;
18 31
import com.electric.chargingpile.adapter.TotalListAdapter;
19 32
import com.electric.chargingpile.application.MainApplication;
20 33
import com.electric.chargingpile.data.MyOtto;
@ -28,6 +41,7 @@ import com.squareup.picasso.Picasso;
28 41
import com.zhy.http.okhttp.OkHttpUtils;
29 42
import com.zhy.http.okhttp.callback.StringCallback;
30 43
44
import org.jetbrains.annotations.NotNull;
31 45
import org.json.JSONArray;
32 46
import org.json.JSONException;
33 47
import org.json.JSONObject;
@ -37,13 +51,15 @@ import java.util.ArrayList;
37 51
38 52
import okhttp3.Call;
39 53
40
public class TotalListFragment extends Fragment {
54
public class TotalListFragment extends Fragment implements View.OnClickListener {
41 55
    private TextView tv_total_name, tv_total_ranking, tv_total_charge, tv_notice, tv_ranking_zanwu;
42 56
    private CircleImageView iv_icon;
43 57
    private ListView lv_total;
44 58
    private LinearLayout ll_ranking;
45 59
    private TextView tv_no_login, tv_login;
46 60
    private RelativeLayout rl_totalList;
61
    private LinearLayout layoutQuarter;
62
    private PopupWindow mPopupWindow;
47 63
48 64
    @Override
49 65
    public void onCreate(Bundle savedInstanceState) {
@ -55,6 +71,7 @@ public class TotalListFragment extends Fragment {
55 71
                             Bundle savedInstanceState) {
56 72
        View view = inflater.inflate(R.layout.fragment_total_list, null);
57 73
        initView(view);
74
        initPopupWindow();
58 75
        MyOtto.getInstance().register(this);
59 76
        getData(null);
60 77
        return view;
@ -72,6 +89,8 @@ public class TotalListFragment extends Fragment {
72 89
        tv_no_login = (TextView) v.findViewById(R.id.tv_no_login);
73 90
        tv_login = (TextView) v.findViewById(R.id.tv_login);
74 91
        rl_totalList = (RelativeLayout) v.findViewById(R.id.rl_totalList);
92
        layoutQuarter = (LinearLayout) v.findViewById(R.id.layoutQuarter);
93
        layoutQuarter.setOnClickListener(this);
75 94
    }
76 95
77 96
    @Subscribe
@ -191,4 +210,38 @@ public class TotalListFragment extends Fragment {
191 210
        super.onDestroy();
192 211
        MyOtto.getInstance().unregister(this);
193 212
    }
213
214
    @Override
215
    public void onClick(View v) {
216
        switch (v.getId()){
217
            case R.id.layoutQuarter:
218
                if (mPopupWindow!=null){
219
                    mPopupWindow.showAsDropDown(layoutQuarter,0, 0, Gravity.BOTTOM);
220
                }
221
                break;
222
        }
223
    }
224
225
    @NotNull
226
    private void initPopupWindow() {
227
        View rootView = LayoutInflater.from(requireContext()).inflate(R.layout.layout_quarter, null, false);
228
        mPopupWindow = new PopupWindow(rootView, SizeUtils.dp2px(92),ViewGroup.LayoutParams.WRAP_CONTENT);
229
        // 设置PopupWindow的背景
230
        mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
231
        // 设置PopupWindow是否能响应外部点击事件
232
        mPopupWindow.setOutsideTouchable(true);
233
        // 设置PopupWindow是否能响应点击事件
234
        mPopupWindow.setTouchable(true);
235
236
        RecyclerView recyclerView = rootView.findViewById(R.id.recyclerView);
237
        recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
238
        QuarterAdapter adapter = new QuarterAdapter(requireContext());
239
        adapter.setItemOnClick(posistion -> {
240
            //TODO
241
            Toast.makeText(requireContext(), ""+posistion, Toast.LENGTH_SHORT).show();
242
            mPopupWindow.dismiss();
243
        });
244
245
        recyclerView.setAdapter(adapter);
246
    }
194 247
}

+ 5 - 0
app/src/main/res/drawable/bg_quarter.xml

@ -0,0 +1,5 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<shape xmlns:android="http://schemas.android.com/apk/res/android">
3
    <corners android:radius="4dp" />
4
    <solid android:color="@color/color_white" />
5
</shape>

+ 25 - 0
app/src/main/res/layout/activity_video_compression.xml

@ -0,0 +1,25 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="match_parent"
4
    android:orientation="vertical"
5
    android:layout_height="match_parent">
6
    <Button
7
        android:id="@+id/openPhoto"
8
        android:text="打开相册"
9
        android:layout_width="wrap_content"
10
        android:layout_height="wrap_content"/>
11
    <Button
12
        android:id="@+id/videoZip"
13
        android:text="压缩视频"
14
        android:layout_width="wrap_content"
15
        android:layout_height="wrap_content"/>
16
    <Button
17
        android:id="@+id/startVideoZip"
18
        android:text="播放压缩后的视频"
19
        android:layout_width="wrap_content"
20
        android:layout_height="wrap_content"/>
21
    <TextView
22
        android:id="@+id/progress"
23
        android:layout_width="wrap_content"
24
        android:layout_height="wrap_content"/>
25
</LinearLayout>

+ 28 - 0
app/src/main/res/layout/fragment_total_list.xml

@ -8,6 +8,34 @@
8 8
    tools:context="com.electric.chargingpile.fragment.MonthListFragment">
9 9
10 10
11
    <LinearLayout
12
        android:id="@+id/layoutQuarter"
13
        android:layout_marginBottom="15dp"
14
        android:layout_marginStart="12dp"
15
        android:layout_marginEnd="12dp"
16
        android:layout_marginTop="15dp"
17
        android:layout_width="wrap_content"
18
        android:layout_height="wrap_content">
19
        <TextView
20
            android:layout_width="wrap_content"
21
            android:layout_height="wrap_content"
22
            android:text="当年季度筛选"
23
            android:textColor="@color/color_green_style1"
24
            android:textSize="14sp"
25
            />
26
        <TextView
27
            android:layout_gravity="center_vertical"
28
            android:layout_marginStart="4dp"
29
            android:layout_width="wrap_content"
30
            android:layout_height="wrap_content"
31
            android:text="▼"
32
            android:textColor="@color/color_green_style1"
33
            android:textSize="8dp"
34
            />
35
36
37
    </LinearLayout>
38
11 39
    <RelativeLayout
12 40
        android:id="@+id/rl_totalList"
13 41
        android:layout_width="match_parent"

+ 10 - 0
app/src/main/res/layout/layout_quarter.xml

@ -0,0 +1,10 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="92dp"
4
    android:background="@drawable/bg_quarter"
5
    android:layout_height="wrap_content">
6
    <androidx.recyclerview.widget.RecyclerView
7
        android:id="@+id/recyclerView"
8
        android:layout_width="match_parent"
9
        android:layout_height="wrap_content"/>
10
</LinearLayout>

+ 12 - 0
app/src/main/res/layout/layout_text_item.xml

@ -0,0 +1,12 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="match_parent"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    tools:textColor="#ff0e0e0e"
6
    android:textSize="12sp"
7
    android:id="@+id/textView"
8
    tools:text="第一季度"
9
    android:paddingTop="14dp"
10
    android:paddingBottom="14dp"
11
    android:gravity="center"
12
    android:layout_height="wrap_content" />

+ 4 - 0
app/src/main/res/values/colors.xml

@ -0,0 +1,4 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
    <color name="color_green_style1">#ff3ab948</color>
4
</resources>

+ 1 - 1
app/src/main/res/values/strings.xml

@ -18,7 +18,7 @@
18 18
    <string name="updated_at">上次更新于%1$s前</string>
19 19
    <string name="updated_just_now">刚刚更新</string>
20 20
    <string name="time_error">时间有问题</string>
21
    <string name="string_tab_qa">聊聊</string>
21
    <string name="string_tab_qa">社区</string>
22 22
23 23
24 24
    <string name="main_name">主界面</string>

+ 1 - 0
build.gradle

@ -12,6 +12,7 @@ buildscript {
12 12
        maven {url 'https://maven.aliyun.com/repository/google/'}
13 13
        maven {url 'https://maven.aliyun.com/repository/public/'}
14 14
        maven {url 'https://maven.aliyun.com/repository/gradle-plugin/'}
15
        maven { url "https://www.jitpack.io" }
15 16
        mavenCentral()
16 17
    }
17 18