Browse Source

优化视频与图片选择界面

zengjiebin 7 years ago
parent
commit
1005e7a5ff
31 changed files with 2679 additions and 87 deletions
  1. 0 1
      .idea/gradle.xml
  2. 3 2
      app/build.gradle
  3. 2 2
      app/src/main/AndroidManifest.xml
  4. 14 0
      app/src/main/java/cn/finalteam/rxgalleryfinal/api/CameraCallBack.java
  5. 69 0
      app/src/main/java/cn/finalteam/rxgalleryfinal/bean/BucketBean.java
  6. 283 0
      app/src/main/java/cn/finalteam/rxgalleryfinal/bean/MediaBean.java
  7. 1060 0
      app/src/main/java/cn/finalteam/rxgalleryfinal/utils/FilenameUtils.java
  8. 508 0
      app/src/main/java/cn/finalteam/rxgalleryfinal/utils/MediaUtils.java
  9. 170 0
      app/src/main/java/cn/finalteam/rxgalleryfinal/utils/StorageUtils.java
  10. 70 0
      app/src/main/java/com/sheep/gamegroup/absBase/AbsApiRefresh.java
  11. 4 1
      app/src/main/java/com/sheep/gamegroup/absBase/AbsObserver.java
  12. 19 0
      app/src/main/java/com/sheep/gamegroup/absBase/IApiRefresh.java
  13. 5 8
      app/src/main/java/com/sheep/gamegroup/absBase/ApiRefresh.java
  14. 108 0
      app/src/main/java/com/sheep/gamegroup/find/activity/ActMediaChoose.java
  15. 105 0
      app/src/main/java/com/sheep/gamegroup/find/fragment/FgtMediaPickerImg.java
  16. 102 0
      app/src/main/java/com/sheep/gamegroup/find/fragment/FgtMediaPickerVideo.java
  17. 3 3
      app/src/main/java/com/sheep/gamegroup/model/entity/DiscoveryVideo.java
  18. 23 0
      app/src/main/java/com/sheep/gamegroup/model/entity/Lp.java
  19. 9 0
      app/src/main/java/com/sheep/gamegroup/util/Jump2View.java
  20. 1 1
      app/src/main/java/com/sheep/gamegroup/util/TimeUtil.java
  21. 15 0
      app/src/main/java/com/sheep/gamegroup/util/ViewUtil.java
  22. 2 28
      app/src/main/java/com/sheep/gamegroup/view/activity/ActPublishArticle.java
  23. 29 31
      app/src/main/java/com/sheep/gamegroup/view/fragment/BaseListFragment6.java
  24. 5 5
      app/src/main/java/com/sheep/gamegroup/view/fragment/FgtDiscoveryTopic.java
  25. 5 4
      app/src/main/java/com/sheep/gamegroup/view/fragment/FgtUserFocusLogList.java
  26. 6 0
      app/src/main/res/drawable/shape_oval_solid_10_f5.xml
  27. 6 0
      app/src/main/res/drawable/shape_oval_solid_10_main.xml
  28. 22 0
      app/src/main/res/layout/act_media_choose.xml
  29. 29 0
      app/src/main/res/layout/item_media_picker.xml
  30. 1 0
      app/src/main/res/values/colors.xml
  31. 1 1
      settings.gradle

+ 0 - 1
.idea/gradle.xml

@@ -8,7 +8,6 @@
         <option name="modules">
           <set>
             <option value="$PROJECT_DIR$" />
-            <option value="$PROJECT_DIR$/RxGalleryFinal" />
             <option value="$PROJECT_DIR$/WaterWaveProgress" />
             <option value="$PROJECT_DIR$/app" />
             <option value="$PROJECT_DIR$/ucrop" />

+ 3 - 2
app/build.gradle

@@ -325,7 +325,7 @@ dependencies {
     //    implementation 'com.github.yalantis:ucrop:2.2.1-native'
 
     //    implementation 'com.google.zxing:core:3.3.0'
-//    implementation project(':ucrop')
+    implementation project(':ucrop')
     implementation ('com.sunfusheng:marqueeview:1.3.3') {
         exclude group: 'com.android.support', module: 'appcompat-v7'
     }
@@ -385,7 +385,8 @@ dependencies {
 //        exclude group: 'com.android.support', module: 'recyclerview-v7'
 //    }
 //    implementation "com.android.support:exifinterface:$supportLibVersion"
-    implementation project(':RxGalleryFinal')
+//    implementation project(':RxGalleryFinal')
+    implementation "com.android.support:exifinterface:$supportLibVersion"
     implementation ('com.qiniu:qiniu-android-sdk:7.3.13') {
         exclude group: 'com.squareup.okhttp3', module: 'okhttp'
     }

+ 2 - 2
app/src/main/AndroidManifest.xml

@@ -830,8 +830,8 @@
 
         <!-- 小绵羊3.4.5 选择图片与视频  -->
         <activity
-            android:name="cn.finalteam.rxgalleryfinal.ui.activity.MediaActivity"
-            android:exported="true" />
+            android:name="com.sheep.gamegroup.find.activity.ActMediaChoose"
+            android:screenOrientation="portrait" />
     </application>
 
 </manifest>

+ 14 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/api/CameraCallBack.java

@@ -0,0 +1,14 @@
+package cn.finalteam.rxgalleryfinal.api;
+
+/**
+ * Created by realicing on 2018/11/30.
+ * realicing@sina.com
+ */
+public interface CameraCallBack {
+
+    void onGetImageSuccess(String cropFilePath);
+
+    void onGetVideoSuccess();
+
+    void onCropImageSuccess();
+}

+ 69 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/bean/BucketBean.java

@@ -0,0 +1,69 @@
+package cn.finalteam.rxgalleryfinal.bean;
+
+import android.text.TextUtils;
+
+/**
+ * Desction:文件夹信息
+ * Author:pengjianbo  Dujinyang
+ * Date:16/6/9 下午2:47
+ */
+public class BucketBean {
+    private String bucketId;
+    private String bucketName;
+    private int imageCount;
+    private String cover;
+    //图片方向
+    private int orientation;
+
+    public String getBucketId() {
+        return bucketId;
+    }
+
+    public void setBucketId(String bucketId) {
+        this.bucketId = bucketId;
+    }
+
+    public String getBucketName() {
+        return bucketName;
+    }
+
+    public void setBucketName(String bucketName) {
+        this.bucketName = bucketName;
+    }
+
+    public int getImageCount() {
+        return imageCount;
+    }
+
+    public void setImageCount(int imageCount) {
+        this.imageCount = imageCount;
+    }
+
+    public String getCover() {
+        if (cover == null) {
+            return "";
+        }
+        return cover;
+    }
+
+    public void setCover(String cover) {
+        this.cover = cover;
+    }
+
+    public int getOrientation() {
+        return orientation;
+    }
+
+    public void setOrientation(int orientation) {
+        this.orientation = orientation;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof BucketBean)) {
+            return false;
+        }
+        BucketBean bucketBean = (BucketBean) o;
+        return TextUtils.equals(bucketBean.getBucketId(), getBucketId());
+    }
+}

+ 283 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/bean/MediaBean.java

@@ -0,0 +1,283 @@
+package cn.finalteam.rxgalleryfinal.bean;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.File;
+
+/**
+ * Desction:Media Bean
+ * Author:pengjianbo  Dujinyang
+ * Date:16/5/4 下午4:14
+ */
+public class MediaBean implements Parcelable {
+
+    public static final Creator<MediaBean> CREATOR = new Creator<MediaBean>() {
+        @Override
+        public MediaBean createFromParcel(Parcel in) {
+            return new MediaBean(in);
+        }
+
+        @Override
+        public MediaBean[] newArray(int size) {
+            return new MediaBean[size];
+        }
+    };
+    //图片ID
+    private long id;
+    private String title;
+    //图片、视频源地址
+    private String originalPath;
+    //图片、视频创建时间
+    private long createDate;
+    //图片、视频最后修改时间
+    private long modifiedDate;
+    //媒体类型
+    private String mimeType;
+    //宽
+    private int width;
+    //高
+    private int height;
+    //纬度
+    private double latitude;
+    //经度
+    private double longitude;
+    //图片方向
+    private int orientation;
+    //文件大小
+    private long length;
+    //时长
+    private long duration;
+    //文件夹相关
+    private String bucketId;
+    private String bucketDisplayName;
+    //大缩略图
+    private String thumbnailBigPath;
+    //小缩略图
+    private String thumbnailSmallPath;
+
+    public MediaBean() {
+    }
+
+    MediaBean(Parcel in) {
+        id = in.readLong();
+        title = in.readString();
+        originalPath = in.readString();
+        createDate = in.readLong();
+        modifiedDate = in.readLong();
+        mimeType = in.readString();
+        bucketId = in.readString();
+        bucketDisplayName = in.readString();
+        thumbnailBigPath = in.readString();
+        thumbnailSmallPath = in.readString();
+        width = in.readInt();
+        height = in.readInt();
+        latitude = in.readDouble();
+        longitude = in.readDouble();
+        orientation = in.readInt();
+        length = in.readLong();
+        duration = in.readLong();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeLong(id);
+        dest.writeString(title);
+        dest.writeString(originalPath);
+        dest.writeLong(createDate);
+        dest.writeLong(modifiedDate);
+        dest.writeString(mimeType);
+        dest.writeString(bucketId);
+        dest.writeString(bucketDisplayName);
+        dest.writeString(thumbnailBigPath);
+        dest.writeString(thumbnailSmallPath);
+        dest.writeInt(width);
+        dest.writeInt(height);
+        dest.writeDouble(latitude);
+        dest.writeDouble(longitude);
+        dest.writeInt(orientation);
+        dest.writeLong(length);
+        dest.writeLong(duration);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getOriginalPath() {
+        return originalPath;
+    }
+
+    public void setOriginalPath(String originalPath) {
+        this.originalPath = originalPath;
+    }
+
+    public long getCreateDate() {
+        return createDate;
+    }
+
+    public void setCreateDate(long createDate) {
+        this.createDate = createDate;
+    }
+
+    public long getModifiedDate() {
+        return modifiedDate;
+    }
+
+    public void setModifiedDate(long modifiedDate) {
+        this.modifiedDate = modifiedDate;
+    }
+
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    public void setMimeType(String mimeType) {
+        this.mimeType = mimeType;
+    }
+
+    public String getBucketId() {
+        return bucketId;
+    }
+
+    public void setBucketId(String bucketId) {
+        this.bucketId = bucketId;
+    }
+
+    public String getBucketDisplayName() {
+        return bucketDisplayName;
+    }
+
+    public void setBucketDisplayName(String bucketDisplayName) {
+        this.bucketDisplayName = bucketDisplayName;
+    }
+
+    public String getThumbnailBigPath() {
+        if (new File(thumbnailBigPath).exists()) {
+            return thumbnailBigPath;
+        }
+        return "";
+    }
+
+    public void setThumbnailBigPath(String thumbnailBigPath) {
+        this.thumbnailBigPath = thumbnailBigPath;
+    }
+
+    public String getThumbnailSmallPath() {
+        if (new File(thumbnailSmallPath).exists()) {
+            return thumbnailSmallPath;
+        }
+        return "";
+    }
+
+    public void setThumbnailSmallPath(String thumbnailSmallPath) {
+        this.thumbnailSmallPath = thumbnailSmallPath;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public void setWidth(int width) {
+        this.width = width;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    public void setHeight(int height) {
+        this.height = height;
+    }
+
+    public double getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(double latitude) {
+        this.latitude = latitude;
+    }
+
+    public double getLongitude() {
+        return longitude;
+    }
+
+    public void setLongitude(double longitude) {
+        this.longitude = longitude;
+    }
+
+    public int getOrientation() {
+        return orientation;
+    }
+
+    public void setOrientation(int orientation) {
+        this.orientation = orientation;
+    }
+
+    public long getLength() {
+        return length;
+    }
+
+    public void setLength(long length) {
+        this.length = length;
+    }
+
+    public long getDuration() {
+        return duration;
+    }
+
+    public void setDuration(long duration) {
+        this.duration = duration;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof MediaBean)) {
+            return false;
+        }
+
+        MediaBean bean = (MediaBean) obj;
+        return bean.getId() == getId();
+
+    }
+
+    @Override
+    public String toString() {
+        return "MediaBean{" +
+                "id=" + id +
+                ", title='" + title + '\'' +
+                ", originalPath='" + originalPath + '\'' +
+                ", createDate=" + createDate +
+                ", modifiedDate=" + modifiedDate +
+                ", mimeType='" + mimeType + '\'' +
+                ", width=" + width +
+                ", height=" + height +
+                ", latitude=" + latitude +
+                ", longitude=" + longitude +
+                ", orientation=" + orientation +
+                ", length=" + length +
+                ", duration=" + duration +
+                ", bucketId='" + bucketId + '\'' +
+                ", bucketDisplayName='" + bucketDisplayName + '\'' +
+                ", thumbnailBigPath='" + thumbnailBigPath + '\'' +
+                ", thumbnailSmallPath='" + thumbnailSmallPath + '\'' +
+                '}';
+    }
+}

File diff suppressed because it is too large
+ 1060 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/utils/FilenameUtils.java


+ 508 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/utils/MediaUtils.java

@@ -0,0 +1,508 @@
+package cn.finalteam.rxgalleryfinal.utils;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.MediaStore;
+import android.support.annotation.Nullable;
+import android.support.media.ExifInterface;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.utils.ClassFileHelper;
+import com.yalantis.ucrop.UCrop;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import cn.finalteam.rxgalleryfinal.api.CameraCallBack;
+import cn.finalteam.rxgalleryfinal.bean.BucketBean;
+import cn.finalteam.rxgalleryfinal.bean.MediaBean;
+
+/**
+ * Desction:媒体获取工具
+ * Author:pengjianbo  Dujinyang
+ * Date:16/5/4 下午4:11
+ */
+public class MediaUtils {
+
+    public static List<MediaBean> getMediaWithImageList(Context context, int page, int limit) {
+        return getMediaWithImageList(context, String.valueOf(Integer.MIN_VALUE), page, limit);
+    }
+
+    /**
+     * 从数据库中读取图片
+     */
+    public static List<MediaBean> getMediaWithImageList(Context context, String bucketId, int page, int limit) {
+        int offset = (page - 1) * limit;
+        List<MediaBean> mediaBeanList = new ArrayList<>();
+        ContentResolver contentResolver = context.getContentResolver();
+        List<String> projection = new ArrayList<>();
+        projection.add(MediaStore.Images.Media._ID);
+        projection.add(MediaStore.Images.Media.TITLE);
+        projection.add(MediaStore.Images.Media.DATA);
+        projection.add(MediaStore.Images.Media.BUCKET_ID);
+        projection.add(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
+        projection.add(MediaStore.Images.Media.MIME_TYPE);
+        projection.add(MediaStore.Images.Media.DATE_ADDED);
+        projection.add(MediaStore.Images.Media.DATE_MODIFIED);
+        projection.add(MediaStore.Images.Media.LATITUDE);
+        projection.add(MediaStore.Images.Media.LONGITUDE);
+        projection.add(MediaStore.Images.Media.ORIENTATION);
+        projection.add(MediaStore.Images.Media.SIZE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            projection.add(MediaStore.Images.Media.WIDTH);
+            projection.add(MediaStore.Images.Media.HEIGHT);
+        }
+        String selection = null;
+        String[] selectionArgs = null;
+        if (!TextUtils.equals(bucketId, String.valueOf(Integer.MIN_VALUE))) {
+            selection = MediaStore.Images.Media.BUCKET_ID + "=?";
+            selectionArgs = new String[]{bucketId};
+        }
+        Cursor cursor = contentResolver.query(
+                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection.toArray(new String[projection.size()]), selection,
+                selectionArgs, MediaStore.Images.Media.DATE_ADDED + " DESC LIMIT " + limit + " OFFSET " + offset);
+        if (cursor != null) {
+            int count = cursor.getCount();
+            if (count > 0) {
+                cursor.moveToFirst();
+                do {
+                    MediaBean mediaBean = parseImageCursorAndCreateThumImage(context, cursor);
+                    if (mediaBean != null) {
+                        mediaBeanList.add(mediaBean);
+                    }
+                } while (cursor.moveToNext());
+            }
+        }
+
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+        return mediaBeanList;
+    }
+
+    public static List<MediaBean> getMediaWithVideoList(Context context, int page, int limit) {
+        return getMediaWithVideoList(context, String.valueOf(Integer.MIN_VALUE), page, limit);
+    }
+
+    /**
+     * 从数据库中读取视频
+     */
+    public static List<MediaBean> getMediaWithVideoList(Context context, String bucketId, int page, int limit) {
+        int offset = (page - 1) * limit;
+        List<MediaBean> mediaBeanList = new ArrayList<>();
+        ContentResolver contentResolver = context.getContentResolver();
+        List<String> projection = new ArrayList<>();
+        projection.add(MediaStore.Video.Media._ID);
+        projection.add(MediaStore.Video.Media.TITLE);
+        projection.add(MediaStore.Video.Media.DATA);
+        projection.add(MediaStore.Video.Media.BUCKET_ID);
+        projection.add(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);
+        projection.add(MediaStore.Video.Media.MIME_TYPE);
+        projection.add(MediaStore.Video.Media.DATE_ADDED);
+        projection.add(MediaStore.Video.Media.DATE_MODIFIED);
+        projection.add(MediaStore.Video.Media.LATITUDE);
+        projection.add(MediaStore.Video.Media.LONGITUDE);
+        projection.add(MediaStore.Video.Media.SIZE);
+        projection.add(MediaStore.Video.Media.DURATION);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            projection.add(MediaStore.Video.Media.WIDTH);
+            projection.add(MediaStore.Video.Media.HEIGHT);
+        }
+        String selection = null;
+        String[] selectionArgs = null;
+        if (!TextUtils.equals(bucketId, String.valueOf(Integer.MIN_VALUE))) {
+            selection = MediaStore.Video.Media.BUCKET_ID + "=?";
+            selectionArgs = new String[]{bucketId};
+        }
+
+        Cursor cursor = contentResolver.query(
+                MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection.toArray(new String[projection.size()]), selection,
+                selectionArgs, MediaStore.Video.Media.DATE_ADDED + " DESC LIMIT " + limit + " OFFSET " + offset);
+        if (cursor != null) {
+            int count = cursor.getCount();
+            if (count > 0) {
+                cursor.moveToFirst();
+                do {
+                    MediaBean mediaBean = parseVideoCursorAndCreateThumImage(context, cursor);
+                    mediaBeanList.add(mediaBean);
+                } while (cursor.moveToNext());
+            }
+        }
+
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+        return mediaBeanList;
+    }
+
+    /**
+     * 根据原图获取图片相关信息
+     */
+    public static MediaBean getMediaBeanWithImage(Context context, String originalPath) {
+        ContentResolver contentResolver = context.getContentResolver();
+        List<String> projection = new ArrayList<>();
+        projection.add(MediaStore.Images.Media._ID);
+        projection.add(MediaStore.Images.Media.TITLE);
+        projection.add(MediaStore.Images.Media.DATA);
+        projection.add(MediaStore.Images.Media.BUCKET_ID);
+        projection.add(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
+        projection.add(MediaStore.Images.Media.MIME_TYPE);
+        projection.add(MediaStore.Images.Media.DATE_ADDED);
+        projection.add(MediaStore.Images.Media.DATE_MODIFIED);
+        projection.add(MediaStore.Images.Media.LATITUDE);
+        projection.add(MediaStore.Images.Media.LONGITUDE);
+        projection.add(MediaStore.Images.Media.ORIENTATION);
+        projection.add(MediaStore.Images.Media.SIZE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            projection.add(MediaStore.Images.Media.WIDTH);
+            projection.add(MediaStore.Images.Media.HEIGHT);
+        }
+        Cursor cursor = contentResolver.query(
+                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection.toArray(new String[projection.size()]), MediaStore.Images.Media.DATA + "=?",
+                new String[]{originalPath}, null);
+        MediaBean mediaBean = null;
+        if (cursor != null && cursor.getCount() > 0) {
+            cursor.moveToFirst();
+            mediaBean = parseImageCursorAndCreateThumImage(context, cursor);
+        }
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+        return mediaBean;
+    }
+
+    /**
+     * 根据地址获取视频相关信息
+     */
+    public static MediaBean getMediaBeanWithVideo(Context context, String originalPath) {
+        ContentResolver contentResolver = context.getContentResolver();
+        List<String> projection = new ArrayList<>();
+        projection.add(MediaStore.Video.Media._ID);
+        projection.add(MediaStore.Video.Media.TITLE);
+        projection.add(MediaStore.Video.Media.DATA);
+        projection.add(MediaStore.Video.Media.BUCKET_ID);
+        projection.add(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);
+        projection.add(MediaStore.Video.Media.MIME_TYPE);
+        projection.add(MediaStore.Video.Media.DATE_ADDED);
+        projection.add(MediaStore.Video.Media.DATE_MODIFIED);
+        projection.add(MediaStore.Video.Media.LATITUDE);
+        projection.add(MediaStore.Video.Media.LONGITUDE);
+        projection.add(MediaStore.Video.Media.SIZE);
+        projection.add(MediaStore.Video.Media.DURATION);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            projection.add(MediaStore.Video.Media.WIDTH);
+            projection.add(MediaStore.Video.Media.HEIGHT);
+        }
+        Cursor cursor = contentResolver.query(
+                MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+                projection.toArray(new String[projection.size()]),
+                MediaStore.Images.Media.DATA + "=?",
+                new String[]{originalPath}, null);
+        MediaBean mediaBean = null;
+        if (cursor != null && cursor.getCount() > 0) {
+            cursor.moveToFirst();
+            mediaBean = parseVideoCursorAndCreateThumImage(context, cursor);
+        }
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+        return mediaBean;
+    }
+
+
+    /**
+     * 解析图片cursor并且创建缩略图
+     * <p>
+     * update 17.07.23 log
+     * <p>
+     * 判断图片 Size ,如果小于等于0则返回 Null,避免出现 No such file or directory
+     */
+    @Nullable
+    private static MediaBean parseImageCursorAndCreateThumImage(Context context, Cursor cursor) {
+        long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.SIZE));
+        String originalPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
+        if (TextUtils.isEmpty(originalPath) || size <= 0 || !new File(originalPath).exists()) {
+            return null;
+        }
+
+        long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID));
+        String title = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.TITLE));
+        String bucketId = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID));
+        String bucketDisplayName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
+        String mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.MIME_TYPE));
+        long createDate = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
+        long modifiedDate = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED));
+
+        MediaBean mediaBean = new MediaBean();
+        mediaBean.setId(id);
+        mediaBean.setTitle(title);
+        mediaBean.setOriginalPath(originalPath);
+        mediaBean.setBucketId(bucketId);
+        mediaBean.setBucketDisplayName(bucketDisplayName);
+        mediaBean.setMimeType(mimeType);
+        mediaBean.setCreateDate(createDate);
+        mediaBean.setModifiedDate(modifiedDate);
+        mediaBean.setThumbnailBigPath(createThumbnailBigFileName(context, originalPath).getAbsolutePath());
+        mediaBean.setThumbnailSmallPath(createThumbnailSmallFileName(context, originalPath).getAbsolutePath());
+        int width = 0, height = 0;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            width = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media.WIDTH));
+            height = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media.HEIGHT));
+        } else {
+            try {
+                ExifInterface exifInterface = new ExifInterface(originalPath);
+                width = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
+                height = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
+            } catch (IOException e) {
+//                Logger.e(e);
+            }
+        }
+        mediaBean.setWidth(width);
+        mediaBean.setHeight(height);
+        double latitude = cursor.getDouble(cursor.getColumnIndex(MediaStore.Images.Media.LATITUDE));
+        mediaBean.setLatitude(latitude);
+        double longitude = cursor.getDouble(cursor.getColumnIndex(MediaStore.Images.Media.LONGITUDE));
+        mediaBean.setLongitude(longitude);
+        int orientation = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media.ORIENTATION));
+        mediaBean.setOrientation(orientation);
+        long length = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.SIZE));
+        mediaBean.setLength(length);
+
+        return mediaBean;
+    }
+
+    /**
+     * 解析视频cursor并且创建缩略图
+     */
+    private static MediaBean parseVideoCursorAndCreateThumImage(Context context, Cursor cursor) {
+        MediaBean mediaBean = new MediaBean();
+        long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media._ID));
+        mediaBean.setId(id);
+        String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));
+        mediaBean.setTitle(title);
+        String originalPath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));
+        mediaBean.setOriginalPath(originalPath);
+        String bucketId = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID));
+        mediaBean.setBucketId(bucketId);
+        String bucketDisplayName = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME));
+        mediaBean.setBucketDisplayName(bucketDisplayName);
+        String mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.MIME_TYPE));
+        mediaBean.setMimeType(mimeType);
+        long createDate = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED));
+        mediaBean.setCreateDate(createDate);
+        long modifiedDate = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.DATE_MODIFIED));
+        mediaBean.setModifiedDate(modifiedDate);
+        long length = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.SIZE));
+        mediaBean.setLength(length);
+        long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.DURATION));
+        mediaBean.setDuration(duration);
+
+        //创建缩略图文件
+        mediaBean.setThumbnailBigPath(createThumbnailBigFileName(context, originalPath).getAbsolutePath());
+        mediaBean.setThumbnailSmallPath(createThumbnailSmallFileName(context, originalPath).getAbsolutePath());
+
+        int width = 0, height = 0;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            width = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.WIDTH));
+            height = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT));
+        } else {
+            try {
+                ExifInterface exifInterface = new ExifInterface(originalPath);
+                width = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
+                height = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
+            } catch (IOException e) {
+//                Logger.e(e);
+            }
+        }
+        mediaBean.setWidth(width);
+        mediaBean.setHeight(height);
+
+        double latitude = cursor.getDouble(cursor.getColumnIndex(MediaStore.Video.Media.LATITUDE));
+        mediaBean.setLatitude(latitude);
+        double longitude = cursor.getDouble(cursor.getColumnIndex(MediaStore.Video.Media.LONGITUDE));
+        mediaBean.setLongitude(longitude);
+        return mediaBean;
+    }
+
+    public static File createThumbnailBigFileName(Context context, String originalPath) {
+        File storeFile = StorageUtils.getCacheDirectory(context);
+        return new File(storeFile, "big_" + FilenameUtils.getName(originalPath));
+    }
+
+    public static File createThumbnailSmallFileName(Context context, String originalPath) {
+        File storeFile = StorageUtils.getCacheDirectory(context);
+        return new File(storeFile, "small_" + FilenameUtils.getName(originalPath));
+    }
+
+    /**
+     * 获取所有的图片文件夹
+     */
+    public static List<BucketBean> getAllBucketByImage(Context context) {
+        return getAllBucket(context, true);
+    }
+
+    /**
+     * 获取所以视频文件夹
+     */
+    public static List<BucketBean> getAllBucketByVideo(Context context) {
+        return getAllBucket(context, false);
+    }
+
+    /**
+     * 获取所有的问media文件夹
+     */
+    public static List<BucketBean> getAllBucket(Context context, boolean isImage) {
+        List<BucketBean> bucketBeenList = new ArrayList<>();
+        ContentResolver contentResolver = context.getContentResolver();
+        String[] projection;
+        if (isImage) {
+            projection = new String[]{
+                    MediaStore.Images.Media.BUCKET_ID,
+                    MediaStore.Images.Media.DATA,
+                    MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
+                    MediaStore.Images.Media.ORIENTATION,
+            };
+        } else {
+            projection = new String[]{
+                    MediaStore.Video.Media.BUCKET_ID,
+                    MediaStore.Video.Media.DATA,
+                    MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
+            };
+        }
+        BucketBean allMediaBucket = new BucketBean();
+        allMediaBucket.setBucketId(String.valueOf(Integer.MIN_VALUE));
+        Uri uri;
+        if (isImage) {
+            allMediaBucket.setBucketName("所有图片");
+            uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+        } else {
+            allMediaBucket.setBucketName("所有视频");
+            uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
+        }
+        bucketBeenList.add(allMediaBucket);
+        Cursor cursor = null;
+        try {
+            cursor = contentResolver.query(uri, projection, null, null, MediaStore.Video.Media.DATE_ADDED + " DESC");
+        } catch (Exception e) {
+//            Logger.e(e);
+        }
+
+        if (cursor != null && cursor.getCount() > 0) {
+            cursor.moveToFirst();
+            do {
+                BucketBean bucketBean = new BucketBean();
+                String bucketId;
+                String bucketKey;
+                String cover;
+                if (isImage) {
+                    bucketId = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID));
+                    bucketBean.setBucketId(bucketId);
+                    String bucketDisplayName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
+                    bucketBean.setBucketName(bucketDisplayName);
+                    bucketKey = MediaStore.Images.Media.BUCKET_ID;
+                    cover = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
+                    int orientation = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media.ORIENTATION));
+                    bucketBean.setOrientation(orientation);
+                } else {
+                    bucketId = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID));
+                    bucketBean.setBucketId(bucketId);
+                    String bucketDisplayName = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME));
+                    bucketBean.setBucketName(bucketDisplayName);
+                    bucketKey = MediaStore.Video.Media.BUCKET_ID;
+                    cover = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));
+                }
+                if (TextUtils.isEmpty(allMediaBucket.getCover())) {
+                    allMediaBucket.setCover(cover);
+                }
+                if (bucketBeenList.contains(bucketBean)) {
+                    continue;
+                }
+                //获取数量
+                Cursor c = contentResolver.query(uri, projection, bucketKey + "=?", new String[]{bucketId}, null);
+                if (c != null && c.getCount() > 0) {
+                    bucketBean.setImageCount(c.getCount());
+                }
+                bucketBean.setCover(cover);
+                if (c != null && !c.isClosed()) {
+                    c.close();
+                }
+                bucketBeenList.add(bucketBean);
+            } while (cursor.moveToNext());
+        }
+
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+        return bucketBeenList;
+    }
+
+    public static String openCamera(Activity activity, boolean isImage) {
+        Intent captureIntent = isImage ? new Intent(MediaStore.ACTION_IMAGE_CAPTURE) : new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
+        if (captureIntent.resolveActivity(activity.getPackageManager()) == null) {
+            Toast.makeText(SheepApp.getInstance(), "相机不可用", Toast.LENGTH_SHORT).show();
+            return null;
+        }
+
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
+        String filename = String.format(isImage ? IMAGE_STORE_FILE_NAME : VIDEO_STORE_FILE_NAME, dateFormat.format(new Date()));
+        File fileImagePath = new File(ClassFileHelper.DIR, filename);
+        String mImagePath = fileImagePath.getAbsolutePath();
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileImagePath));
+        } else {
+            ContentValues contentValues = new ContentValues(1);
+            contentValues.put(MediaStore.Images.Media.DATA, mImagePath);
+            Uri uri = SheepApp.getInstance().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
+            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+        }
+        // video : 1: 高质量  0 低质量
+        //        captureIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
+        activity.startActivityForResult(captureIntent, isImage ? TAKE_IMAGE_REQUEST_CODE : TAKE_VIDEO_REQUEST_CODE);
+        return mImagePath;
+    }
+
+    public static void onActivityResult(Activity activity, int requestCode, String path, CameraCallBack cameraCallBack) {
+        Log.i(MediaUtils.class.getSimpleName(), "onActivityResult: requestCode=" + requestCode);
+        switch (requestCode) {
+            case TAKE_IMAGE_REQUEST_CODE:
+                if (path == null) {
+                    Log.i(MediaUtils.class.getSimpleName(), "拍照成功");
+                    cameraCallBack.onGetImageSuccess(null);
+                    break;
+                }
+                String cropFilePath = path.substring(0, path.lastIndexOf(".")) + "temp.png";
+                Log.i(MediaUtils.class.getSimpleName(), "拍照成功: " + cropFilePath);
+                cameraCallBack.onGetImageSuccess(cropFilePath);
+                UCrop.of(Uri.parse(path), Uri.parse(cropFilePath))
+                        .start(activity);
+                break;
+            case TAKE_VIDEO_REQUEST_CODE:
+                Log.i(MediaUtils.class.getSimpleName(), "摄像成功");
+                cameraCallBack.onGetVideoSuccess();
+                break;
+            case UCrop.REQUEST_CROP:
+                Log.i(MediaUtils.class.getSimpleName(), "裁剪成功");
+                cameraCallBack.onCropImageSuccess();
+                break;
+        }
+    }
+
+    public static final String IMAGE_STORE_FILE_NAME = "IMG_%s.jpg";
+    public static final String VIDEO_STORE_FILE_NAME = "IMG_%s.mp4";
+    public static final int TAKE_IMAGE_REQUEST_CODE = 1001;
+    public static final int TAKE_VIDEO_REQUEST_CODE = 1002;
+}

+ 170 - 0
app/src/main/java/cn/finalteam/rxgalleryfinal/utils/StorageUtils.java

@@ -0,0 +1,170 @@
+package cn.finalteam.rxgalleryfinal.utils;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+
+import java.io.File;
+import java.io.IOException;
+
+import static android.os.Environment.MEDIA_MOUNTED;
+
+/**
+ * Provides application storage paths
+ *
+ * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
+ * @since 1.0.0
+ */
+public final class StorageUtils {
+
+    private static final String EXTERNAL_STORAGE_PERMISSION = "android.permission.WRITE_EXTERNAL_STORAGE";
+    private static final String INDIVIDUAL_DIR_NAME = "rxgalleryfinal";
+
+    private StorageUtils() {
+    }
+
+    /**
+     * Returns application cache directory. Cache directory will be created on SD card
+     * <i>("/Android/data/[app_package_name]/cache")</i> if card is mounted and app has appropriate permission. Else -
+     * Android defines cache directory on device's file system.
+     *
+     * @param context Application context
+     * @return Cache {@link File directory}.<br />
+     * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
+     * {@link android.content.Context#getCacheDir() Context.getCacheDir()} returns null).
+     */
+    public static File getCacheDirectory(Context context) {
+        return getCacheDirectory(context, true);
+    }
+
+    /**
+     * Returns application cache directory. Cache directory will be created on SD card
+     * <i>("/Android/data/[app_package_name]/cache")</i> (if card is mounted and app has appropriate permission) or
+     * on device's file system depending incoming parameters.
+     *
+     * @param context        Application context
+     * @param preferExternal Whether prefer external location for cache
+     * @return Cache {@link File directory}.<br />
+     * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
+     * {@link android.content.Context#getCacheDir() Context.getCacheDir()} returns null).
+     */
+    public static File getCacheDirectory(Context context, boolean preferExternal) {
+        File appCacheDir = null;
+
+        if (preferExternal && existSDcard() && hasExternalStoragePermission(context)) {
+            appCacheDir = getExternalCacheDir(context);
+        }
+        if (appCacheDir == null) {
+            appCacheDir = context.getCacheDir();
+        }
+        if (appCacheDir == null) {
+            @SuppressLint("SdCardPath") String cacheDirPath = "/data/data/" + context.getPackageName() + "/cache/";
+//            Logger.w(String.format("Can't define system cache directory! '%s' will be used.", cacheDirPath));
+            appCacheDir = new File(cacheDirPath);
+        }
+        return appCacheDir;
+    }
+
+    public static boolean existSDcard() {
+        String externalStorageState;
+        try {
+            externalStorageState = Environment.getExternalStorageState();
+        } catch (NullPointerException e) { // (sh)it happens (Issue #660)
+            externalStorageState = "";
+        }
+        return MEDIA_MOUNTED.equals(externalStorageState);
+    }
+
+    /**
+     * Returns individual application cache directory (for only image caching from ImageLoader). Cache directory will be
+     * created on SD card <i>("/Android/data/[app_package_name]/cache/uil-images")</i> if card is mounted and app has
+     * appropriate permission. Else - Android defines cache directory on device's file system.
+     *
+     * @param context Application context
+     * @return Cache {@link File directory}
+     */
+    public static File getIndividualCacheDirectory(Context context) {
+        return getIndividualCacheDirectory(context, INDIVIDUAL_DIR_NAME);
+    }
+
+    /**
+     * Returns individual application cache directory (for only image caching from ImageLoader). Cache directory will be
+     * created on SD card <i>("/Android/data/[app_package_name]/cache/uil-images")</i> if card is mounted and app has
+     * appropriate permission. Else - Android defines cache directory on device's file system.
+     *
+     * @param context  Application context
+     * @param cacheDir Cache directory path (e.g.: "AppCacheDir", "AppDir/cache/images")
+     * @return Cache {@link File directory}
+     */
+    public static File getIndividualCacheDirectory(Context context, String cacheDir) {
+        File appCacheDir = getCacheDirectory(context);
+        File individualCacheDir = new File(appCacheDir, cacheDir);
+        if (!individualCacheDir.exists()) {
+            if (!individualCacheDir.mkdir()) {
+                individualCacheDir = appCacheDir;
+            }
+        }
+        return individualCacheDir;
+    }
+
+    /**
+     * Returns specified application cache directory. Cache directory will be created on SD card by defined path if card
+     * is mounted and app has appropriate permission. Else - Android defines cache directory on device's file system.
+     *
+     * @param context  Application context
+     * @param cacheDir Cache directory path (e.g.: "AppCacheDir", "AppDir/cache/images")
+     * @return Cache {@link File directory}
+     */
+    public static File getOwnCacheDirectory(Context context, String cacheDir) {
+        File appCacheDir = null;
+        if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context)) {
+            appCacheDir = new File(Environment.getExternalStorageDirectory(), cacheDir);
+        }
+        if (appCacheDir == null || (!appCacheDir.exists() && !appCacheDir.mkdirs())) {
+            appCacheDir = context.getCacheDir();
+        }
+        return appCacheDir;
+    }
+
+    /**
+     * Returns specified application cache directory. Cache directory will be created on SD card by defined path if card
+     * is mounted and app has appropriate permission. Else - Android defines cache directory on device's file system.
+     *
+     * @param context  Application context
+     * @param cacheDir Cache directory path (e.g.: "AppCacheDir", "AppDir/cache/images")
+     * @return Cache {@link File directory}
+     */
+    public static File getOwnCacheDirectory(Context context, String cacheDir, boolean preferExternal) {
+        File appCacheDir = null;
+        if (preferExternal && MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context)) {
+            appCacheDir = new File(Environment.getExternalStorageDirectory(), cacheDir);
+        }
+        if (appCacheDir == null || (!appCacheDir.exists() && !appCacheDir.mkdirs())) {
+            appCacheDir = context.getCacheDir();
+        }
+        return appCacheDir;
+    }
+
+    private static File getExternalCacheDir(Context context) {
+        File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
+        File appCacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
+        if (!appCacheDir.exists()) {
+            if (!appCacheDir.mkdirs()) {
+//                Logger.w("Unable to create external cache directory");
+                return null;
+            }
+            try {
+                new File(appCacheDir, ".nomedia").createNewFile();
+            } catch (IOException e) {
+//                Logger.i("Can't create \".nomedia\" file in application external cache directory");
+            }
+        }
+        return appCacheDir;
+    }
+
+    private static boolean hasExternalStoragePermission(Context context) {
+        int perm = context.checkCallingOrSelfPermission(EXTERNAL_STORAGE_PERMISSION);
+        return perm == PackageManager.PERMISSION_GRANTED;
+    }
+}

+ 70 - 0
app/src/main/java/com/sheep/gamegroup/absBase/AbsApiRefresh.java

@@ -0,0 +1,70 @@
+package com.sheep.gamegroup.absBase;
+
+import com.sheep.gamegroup.util.ListUtil;
+import com.sheep.gamegroup.view.fragment.BaseListFragment6;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.sheep.gamegroup.util.DataUtil.PER_PAGE;
+
+/**
+ * Created by realicing on 2018/11/30.
+ * realicing@sina.com
+ */
+public abstract class AbsApiRefresh<T> implements IApiRefresh {
+
+    public AbsApiRefresh(BaseListFragment6 baseListFragment6) {
+        this.baseListFragment6 = baseListFragment6;
+    }
+
+    protected List<T> list = new ArrayList<>();
+    private BaseListFragment6 baseListFragment6;
+    protected int page = 1;
+    protected int per_page = PER_PAGE;
+    private boolean loadMore = false;
+
+    @Override
+    public void setLoadMore(boolean loadMore) {
+        this.loadMore = loadMore;
+    }
+
+    //还有数据没有获取
+    private boolean hasMore() {
+        return ListUtil.size(list) >= per_page * page;
+    }
+
+    protected void loadList(List<T> newList) {
+        list.addAll(newList);
+        notifyDataSetChanged();
+    }
+
+    private void notifyDataSetChanged() {
+        if (baseListFragment6 != null)
+            baseListFragment6.notifyDataSetChanged(page, hasMore());
+    }
+    @Override
+    public void clear() {
+        list.clear();
+        page = 1;
+    }
+
+    @Override
+    public void loadMoreData() {
+        if (!loadMore) {
+            loadMore = true;
+            if (hasMore()) {
+                page += 1;
+                initData();
+            } else {
+                if (baseListFragment6 != null)
+                    baseListFragment6.notifyDataSetChanged(page, hasMore());
+            }
+        }
+    }
+
+    @Override
+    public List<T> getList() {
+        return list;
+    }
+}

+ 4 - 1
app/src/main/java/com/sheep/gamegroup/absBase/AbsObserver.java

@@ -1,5 +1,8 @@
 package com.sheep.gamegroup.absBase;
 
+import com.sheep.gamegroup.util.TestUtil;
+import com.sheep.jiuyan.samllsheep.utils.G;
+
 import io.reactivex.Observer;
 import io.reactivex.disposables.Disposable;
 
@@ -20,7 +23,7 @@ public abstract class AbsObserver<T> implements Observer<T> {
 
     @Override
     public void onError(Throwable e) {
-
+        if(TestUtil.isDev()) G.showToast(e.getMessage());
     }
 
     @Override

+ 19 - 0
app/src/main/java/com/sheep/gamegroup/absBase/IApiRefresh.java

@@ -0,0 +1,19 @@
+package com.sheep.gamegroup.absBase;
+
+import java.util.List;
+
+/**
+ * Created by realicing on 2018/11/30.
+ * realicing@sina.com
+ */
+public interface IApiRefresh<T> {
+    void setLoadMore(boolean loadMore);
+
+    void initData();
+
+    void clear();
+
+    void loadMoreData();
+
+    List<T> getList();
+}

+ 5 - 8
app/src/main/java/com/sheep/gamegroup/absBase/ApiRefresh.java

@@ -18,8 +18,8 @@ import io.reactivex.schedulers.Schedulers;
  * Created by realicing on 2018/11/28.
  * realicing@sina.com
  */
-public abstract class ApiRefresh<T> {
-    public ApiRefresh(BaseListFragment6<?> baseListFragment6) {
+public abstract class NetApiRefresh<T> implements IApiRefresh {
+    public NetApiRefresh(BaseListFragment6<?> baseListFragment6) {
         this.baseListFragment6 = baseListFragment6;
     }
 
@@ -49,7 +49,7 @@ public abstract class ApiRefresh<T> {
         return lastMessage;
     }
 
-    public boolean loadMoreData() {
+    public void loadMoreData() {
         if (!loadMore) {
             loadMore = true;
             if (hasMore()) {
@@ -57,11 +57,8 @@ public abstract class ApiRefresh<T> {
                 initData();
             } else {
                 if (baseListFragment6 != null)
-                    baseListFragment6.setNoMore(true);
+                    baseListFragment6.notifyDataSetChanged(page, hasMore());
             }
-            return false;
-        } else {
-            return true;
         }
     }
 
@@ -116,7 +113,7 @@ public abstract class ApiRefresh<T> {
 
     private void notifyDataSetChanged() {
         if (baseListFragment6 != null)
-            baseListFragment6.notifyDataSetChanged();
+            baseListFragment6.notifyDataSetChanged(page, hasMore());
     }
 
     protected List<T> newList;

+ 108 - 0
app/src/main/java/com/sheep/gamegroup/find/activity/ActMediaChoose.java

@@ -0,0 +1,108 @@
+package com.sheep.gamegroup.find.activity;
+
+
+import android.app.Activity;
+import android.content.Intent;
+import android.support.annotation.Nullable;
+import android.support.design.widget.TabLayout;
+import android.support.v4.view.ViewPager;
+import android.view.View;
+
+import com.sheep.gamegroup.absBase.BaseActivity;
+import com.sheep.gamegroup.absBase.IRefresh;
+import com.sheep.gamegroup.find.fragment.FgtMediaPickerImg;
+import com.sheep.gamegroup.find.fragment.FgtMediaPickerVideo;
+import com.sheep.gamegroup.util.CommonUtil;
+import com.sheep.gamegroup.util.DataUtil;
+import com.sheep.gamegroup.view.adapter.TitleFragmentListAdapter;
+import com.sheep.jiuyan.samllsheep.R;
+import com.sheep.jiuyan.samllsheep.utils.TitleBarUtils;
+
+import butterknife.BindView;
+import cn.finalteam.rxgalleryfinal.api.CameraCallBack;
+import cn.finalteam.rxgalleryfinal.utils.MediaUtils;
+
+import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
+import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;
+import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
+
+/**
+ * Created by realicing on 2018/11/26.
+ * realicing@sina.com
+ * 小绵羊3.4.5新增--发布发现内容--选择视频和图片
+ */
+public class ActMediaChoose extends BaseActivity {
+
+    @Override
+    protected int getLayoutId() {
+        return R.layout.act_media_choose;
+    }
+
+    @BindView(R.id.indicator)
+    TabLayout indicator;
+    @BindView(R.id.viewPager)
+    ViewPager viewPager;
+
+    private TitleFragmentListAdapter mAdapter;
+    @Override
+    public void initView() {
+        TitleBarUtils.getInstance().setTitle(this, "选择媒体")
+                .setTitleFinish(this).setRightImgBotton(this, R.drawable.ic_play_but_image, new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+//                Jump2View.getInstance().goActEditVideo(video);
+                MediaUtils.openCamera(ActMediaChoose.this, true);
+            }
+        });
+
+        mAdapter = new TitleFragmentListAdapter(getSupportFragmentManager());
+        mAdapter.add(new FgtMediaPickerVideo(), "视频");
+        mAdapter.add(new FgtMediaPickerImg(), "图片");
+        viewPager.setAdapter(mAdapter);
+        indicator.setupWithViewPager(viewPager);
+        viewPager.setCurrentItem(0);
+        viewPager.setOffscreenPageLimit(mAdapter.getCount());
+        CommonUtil.getInstance().reflex(indicator, this);
+//        Integer type = DataUtil.getObject(getIntent(), Integer.class);
+//        if(type != null){
+//            switch (type){
+//                case MEDIA_TYPE_IMAGE:
+//                    break;
+//                case MEDIA_TYPE_VIDEO:
+//                    break;
+//                case MEDIA_TYPE_NONE:
+//                default:
+//                    break;
+//            }
+//        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if(resultCode == Activity.RESULT_OK){
+            MediaUtils.onActivityResult(this, requestCode, null, new CameraCallBack() {
+                @Override
+                public void onGetImageSuccess(String cropFilePath) {
+                    if(mAdapter.getItem(1) instanceof IRefresh){
+                        ((IRefresh) mAdapter.getItem(1)).refreshData();
+                    }
+                }
+
+                @Override
+                public void onGetVideoSuccess() {
+                    if(mAdapter.getItem(0) instanceof IRefresh){
+                        ((IRefresh) mAdapter.getItem(0)).refreshData();
+                    }
+                }
+
+                @Override
+                public void onCropImageSuccess() {
+                    if(mAdapter.getItem(1) instanceof IRefresh){
+                        ((IRefresh) mAdapter.getItem(1)).refreshData();
+                    }
+                }
+            });
+        }
+    }
+}

+ 105 - 0
app/src/main/java/com/sheep/gamegroup/find/fragment/FgtMediaPickerImg.java

@@ -0,0 +1,105 @@
+package com.sheep.gamegroup.find.fragment;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.util.LongSparseArray;
+import android.widget.ImageView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.BaseViewHolder;
+import com.sheep.gamegroup.absBase.AbsApiRefresh;
+import com.sheep.gamegroup.absBase.AbsObserver;
+import com.sheep.gamegroup.absBase.IApiRefresh;
+import com.sheep.gamegroup.model.entity.Lp;
+import com.sheep.gamegroup.util.TestUtil;
+import com.sheep.gamegroup.util.ViewUtil;
+import com.sheep.gamegroup.util.viewHelper.LayoutParamsUtil;
+import com.sheep.gamegroup.view.fragment.BaseListFragment6;
+import com.sheep.jiuyan.samllsheep.R;
+import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.utils.G;
+
+import java.util.List;
+
+import cn.finalteam.rxgalleryfinal.bean.MediaBean;
+import cn.finalteam.rxgalleryfinal.utils.MediaUtils;
+import io.reactivex.Observable;
+import io.reactivex.ObservableEmitter;
+import io.reactivex.ObservableOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by realicing on 2018/11/27.
+ * realicing@sina.com
+ * 小绵羊3.4.5新增--发布发现内容--选择图片
+ */
+public class FgtMediaPickerImg extends BaseListFragment6<MediaBean> {
+
+    @Override
+    public int getLayoutId() {
+        return R.layout.common_srl_rv;
+    }
+
+    @Override
+    public void initView() {
+        LayoutParamsUtil.resetLayoutParams(recyclerView, new Lp(G.DENSITY).setTbMargin(14).setLrMargin(6));
+    }
+
+    protected LongSparseArray<MediaBean> sparseArray = new LongSparseArray<>();
+    protected LongSparseArray<String> textSparseArray = new LongSparseArray<>();
+
+    private int width = (G.WIDTH - G.getRealPix(48)) / 2;
+
+    @Override
+    protected RecyclerView.LayoutManager getLayoutManager() {
+        return new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
+    }
+
+    @Override
+    protected BaseQuickAdapter<MediaBean, BaseViewHolder> getAdapter() {
+        return new BaseQuickAdapter<MediaBean, BaseViewHolder>(R.layout.item_media_picker, apiRefresh.getList()) {
+
+            @Override
+            protected void convert(BaseViewHolder helper, MediaBean item) {
+                boolean isChoose = sparseArray.get(item.getId()) != null;
+                helper.setText(R.id.item_media_picker_tv, isChoose ? textSparseArray.get(item.getId()) : "√");
+                helper.setBackgroundRes(R.id.item_media_picker_tv, isChoose ? R.drawable.shape_oval_solid_10_main : R.drawable.shape_oval_solid_10_f5);
+                helper.setTextColor(R.id.item_media_picker_tv, SheepApp.getInstance().getResources().getColor(isChoose ? R.color.white : R.color.gray_CBCBCB));
+                ImageView item_media_picker_iv = helper.getView(R.id.item_media_picker_iv);
+                ViewUtil.setViewWH(item_media_picker_iv, width, item.getHeight() * 1.0f / item.getWidth());
+                ViewUtil.setImagePath(item_media_picker_iv, item.getOriginalPath(), G.getRealPix(5));
+            }
+        };
+    }
+
+    private AbsApiRefresh<MediaBean> apiRefresh;
+
+    @Override
+    protected void addApiRefresh(List<IApiRefresh> apiRefreshList) {
+        apiRefresh = new AbsApiRefresh<MediaBean>(this) {
+            @Override
+            public void initData() {
+                Observable.create(new ObservableOnSubscribe<List<MediaBean>>() {
+                    @Override
+                    public void subscribe(ObservableEmitter<List<MediaBean>> emitter) {
+                        emitter.onNext(initNewList(page, per_page));
+                    }
+                })
+                        .subscribeOn(Schedulers.io())
+                        .observeOn(AndroidSchedulers.mainThread()).
+                        subscribe(new AbsObserver<List<MediaBean>>() {
+                            @Override
+                            public void onNext(List<MediaBean> newList) {
+                                loadList(newList);
+                            }
+                        });
+            }
+        };
+        apiRefreshList.add(apiRefresh);
+    }
+
+    protected List<MediaBean> initNewList(int page, int per_page) {
+        return MediaUtils.getMediaWithImageList(SheepApp.getInstance(), page, per_page);
+    }
+}

+ 102 - 0
app/src/main/java/com/sheep/gamegroup/find/fragment/FgtMediaPickerVideo.java

@@ -0,0 +1,102 @@
+package com.sheep.gamegroup.find.fragment;
+
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.util.LongSparseArray;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.BaseViewHolder;
+import com.sheep.gamegroup.absBase.AbsApiRefresh;
+import com.sheep.gamegroup.absBase.AbsObserver;
+import com.sheep.gamegroup.absBase.IApiRefresh;
+import com.sheep.gamegroup.model.entity.Lp;
+import com.sheep.gamegroup.util.TimeUtil;
+import com.sheep.gamegroup.util.ViewUtil;
+import com.sheep.gamegroup.util.viewHelper.LayoutParamsUtil;
+import com.sheep.gamegroup.view.fragment.BaseListFragment6;
+import com.sheep.jiuyan.samllsheep.R;
+import com.sheep.jiuyan.samllsheep.SheepApp;
+import com.sheep.jiuyan.samllsheep.utils.G;
+
+import java.util.List;
+
+import cn.finalteam.rxgalleryfinal.bean.MediaBean;
+import cn.finalteam.rxgalleryfinal.utils.MediaUtils;
+import io.reactivex.Observable;
+import io.reactivex.ObservableEmitter;
+import io.reactivex.ObservableOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by realicing on 2018/11/27.
+ * realicing@sina.com
+ * 小绵羊3.4.5新增--发布发现内容--选择视频
+ */
+public class FgtMediaPickerVideo extends BaseListFragment6<MediaBean> {
+
+    @Override
+    public int getLayoutId() {
+        return R.layout.common_srl_rv;
+    }
+
+    @Override
+    public void initView() {
+        LayoutParamsUtil.resetLayoutParams(recyclerView, new Lp(G.DENSITY).setTbMargin(14).setLrMargin(6));
+    }
+
+    private int width = (G.WIDTH - G.getRealPix(48)) / 2;
+
+    @Override
+    protected RecyclerView.LayoutManager getLayoutManager() {
+        return new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
+    }
+
+    @Override
+    protected BaseQuickAdapter<MediaBean, BaseViewHolder> getAdapter() {
+        return new BaseQuickAdapter<MediaBean, BaseViewHolder>(R.layout.item_video, apiRefresh.getList()) {
+
+            @Override
+            protected void convert(BaseViewHolder helper, MediaBean item) {
+                ImageView item_video_cover = helper.getView(R.id.item_video_cover);
+                TextView item_video_time_tv = helper.itemView.findViewById(R.id.item_video_time_tv);
+                ViewUtil.setViewWH(item_video_cover, width, item.getHeight() * 1.0f / item.getWidth());
+                ViewUtil.setImagePath(item_video_cover, item.getOriginalPath(), G.getRealPix(5));
+                ViewUtil.setText(item_video_time_tv, TimeUtil.getDurationText(item.getDuration() / 1000));
+            }
+        };
+    }
+
+    private AbsApiRefresh<MediaBean> apiRefresh;
+
+    @Override
+    protected void addApiRefresh(List<IApiRefresh> apiRefreshList) {
+        apiRefresh = new AbsApiRefresh<MediaBean>(this) {
+            @Override
+            public void initData() {
+                Observable.create(new ObservableOnSubscribe<List<MediaBean>>() {
+                    @Override
+                    public void subscribe(ObservableEmitter<List<MediaBean>> emitter) {
+                        emitter.onNext(initNewList(page, per_page));
+                    }
+                })
+                        .subscribeOn(Schedulers.io())
+                        .observeOn(AndroidSchedulers.mainThread()).
+                        subscribe(new AbsObserver<List<MediaBean>>() {
+                            @Override
+                            public void onNext(List<MediaBean> newList) {
+                                loadList(newList);
+                            }
+                        });
+            }
+        };
+        apiRefreshList.add(apiRefresh);
+    }
+
+    protected List<MediaBean> initNewList(int page, int per_page) {
+        return MediaUtils.getMediaWithVideoList(SheepApp.getInstance(), page, per_page);
+    }
+}

+ 3 - 3
app/src/main/java/com/sheep/gamegroup/model/entity/DiscoveryVideo.java

@@ -51,7 +51,7 @@ public class DiscoveryVideo implements Serializable {
 
     private int create_time;
 
-    private int duration;
+    private long duration;
 
     private int id;
 
@@ -105,10 +105,10 @@ public class DiscoveryVideo implements Serializable {
     public int getCreate_time(){
         return this.create_time;
     }
-    public void setDuration(int duration){
+    public void setDuration(long duration){
         this.duration = duration;
     }
-    public int getDuration(){
+    public long getDuration(){
         return this.duration;
     }
     public void setId(int id){

+ 23 - 0
app/src/main/java/com/sheep/gamegroup/model/entity/Lp.java

@@ -93,4 +93,27 @@ public class Lp {
         }
         return this;
     }
+
+    public Lp setLrMargin(int margin) {
+        margin = (int) (margin * per);
+        this.leftMargin = margin;
+        this.rightMargin = margin;
+        return this;
+    }
+
+    public Lp setTbMargin(int margin) {
+        margin = (int) (margin * per);
+        this.topMargin = margin;
+        this.bottomMargin = margin;
+        return this;
+    }
+
+    public Lp setMargin(int margin) {
+        margin = (int) (margin * per);
+        this.topMargin = margin;
+        this.bottomMargin = margin;
+        this.leftMargin = margin;
+        this.rightMargin = margin;
+        return this;
+    }
 }

+ 9 - 0
app/src/main/java/com/sheep/gamegroup/util/Jump2View.java

@@ -16,6 +16,7 @@ import com.danikula.videocache.HttpProxyCacheServer;
 import com.sheep.gamegroup.absBase.BaseActivity;
 import com.sheep.gamegroup.absBase.IHomePageSearch;
 import com.sheep.gamegroup.absBase.IJumpWeb;
+import com.sheep.gamegroup.find.activity.ActMediaChoose;
 import com.sheep.gamegroup.greendao.download.DownLoadInfo;
 import com.sheep.gamegroup.model.entity.Advertising;
 import com.sheep.gamegroup.model.entity.Agreement;
@@ -2368,4 +2369,12 @@ public class Jump2View {
         Intent intent = new Intent(activity, ActVideoComment.class);
         activity.startActivity(DataUtil.putObject(intent, video_id));
     }
+    /**
+     * 小绵羊3.4.5新增--跳转到选择视频与图片界面
+     */
+    public void gotoActMediaChoose(@ActPublishArticle.Type int type) {
+        Activity activity = ActivityManager.getInstance().currentActivity();
+        Intent intent = new Intent(activity, ActMediaChoose.class);
+        activity.startActivity(DataUtil.putObject(intent, type));
+    }
 }

+ 1 - 1
app/src/main/java/com/sheep/gamegroup/util/TimeUtil.java

@@ -239,7 +239,7 @@ public class TimeUtil {
         }
     }
 
-    public static String getDurationText(int duration) {
+    public static String getDurationText(long duration) {
         if(duration > 3600)
             return String.format(Locale.CHINA, "%d:%d:%d", duration / 3600, duration / 60 % 60, duration % 60);
         else if(duration > 60)

+ 15 - 0
app/src/main/java/com/sheep/gamegroup/util/ViewUtil.java

@@ -1607,6 +1607,9 @@ public class ViewUtil {
             }
         }
     }
+    public static void setViewWH(View view, int width, float radio) {
+        LayoutParamsUtil.resetLayoutParams(view, new Lp().setWidth(width).setHeight((int) (width * radio)));
+    }
     public static void setImagePath(ImageView imageView, String paths) {
         if (imageView != null){
             if(TextUtils.isEmpty(paths)) {
@@ -1619,6 +1622,18 @@ public class ViewUtil {
             }
         }
     }
+    public static void setImagePath(ImageView imageView, String paths, int radio) {
+        if (imageView != null){
+            if(TextUtils.isEmpty(paths)) {
+                imageView.setImageResource(R.mipmap.icon);
+            } else {
+                if (paths.contains(";")) {
+                    paths = paths.split(";")[0];
+                }
+                Glide.with(SheepApp.getInstance()).load(new File(paths)).apply(new RequestOptions().transform(new RoundedCornersTransformation(radio, 0))).into(imageView);
+            }
+        }
+    }
 
     public static void setImageLoading(ImageView imageView, String pictures) {
         if (imageView != null) {

+ 2 - 28
app/src/main/java/com/sheep/gamegroup/view/activity/ActPublishArticle.java

@@ -43,9 +43,6 @@ import java.io.File;
 import java.util.Locale;
 
 import butterknife.BindView;
-import cn.finalteam.rxgalleryfinal.RxGalleryFinalApi;
-import cn.finalteam.rxgalleryfinal.rxbus.RxBusResultDisposable;
-import cn.finalteam.rxgalleryfinal.rxbus.event.ImageRadioResultEvent;
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.schedulers.Schedulers;
 
@@ -105,8 +102,7 @@ public class ActPublishArticle extends BaseActivity {
                     helper.itemView.setOnClickListener(new View.OnClickListener() {
                         @Override
                         public void onClick(View view) {
-                            if (video != null)
-                                Jump2View.getInstance().goActEditVideo(video);
+                            addVideo();
                         }
                     });
                 }
@@ -126,29 +122,7 @@ public class ActPublishArticle extends BaseActivity {
     }
 
     private void addVideo() {
-        RxGalleryFinalApi
-                .getInstance(ActPublishArticle.this)
-//                .setFilter(new Function<MediaBean, Boolean>() {
-//                    @Override
-//                    public Boolean apply(MediaBean mediaBean) throws Exception {
-//                        boolean result = mediaBean.getDuration() > 15_000L;
-//                        if (result) {
-//                            G.showToast(R.string.need_picker_video_dur_15);
-//                        }
-//                        return result;
-//                    }
-//                })
-                .setType(RxGalleryFinalApi.SelectRXType.TYPE_VIDEO, RxGalleryFinalApi.SelectRXType.TYPE_SELECT_RADIO)
-                .setVDRadioResultEvent(new RxBusResultDisposable<ImageRadioResultEvent>() {
-                    @Override
-                    protected void onEvent(ImageRadioResultEvent imageRadioResultEvent) throws Exception {
-                        Video data = new Video();
-                        data.setFilePath(imageRadioResultEvent.getResult().getOriginalPath());
-                        data.setDuration(imageRadioResultEvent.getResult().getDuration());
-                        Jump2View.getInstance().goActEditVideo(data);
-                    }
-                })
-                .open();
+        Jump2View.getInstance().gotoActMediaChoose(MEDIA_TYPE_NONE);
     }
 
     private int uploadType = UPLOAD_TYPE_NONE;

+ 29 - 31
app/src/main/java/com/sheep/gamegroup/view/fragment/BaseListFragment6.java

@@ -10,7 +10,7 @@ import com.chad.library.adapter.base.BaseQuickAdapter;
 import com.chad.library.adapter.base.BaseViewHolder;
 import com.chad.library.adapter.base.loadmore.LoadMoreView;
 import com.sheep.gamegroup.absBase.AbsObserver;
-import com.sheep.gamegroup.absBase.ApiRefresh;
+import com.sheep.gamegroup.absBase.IApiRefresh;
 import com.sheep.gamegroup.absBase.ILoadMore;
 import com.sheep.gamegroup.absBase.IRefresh;
 import com.sheep.gamegroup.util.ListUtil;
@@ -54,14 +54,14 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
                 break;
             case REFRESH_ON_YOURSELF:
             default:
-                notifyDataSetChanged();
+                notifyDataSetChanged(1, true);
                 break;
         }
     }
 
-    protected abstract void addApiRefresh(List<ApiRefresh<?>> apiRefreshList);
+    protected abstract void addApiRefresh(List<IApiRefresh> apiRefreshList);
 
-    protected List<ApiRefresh<? extends Object>> apiRefreshList = new ArrayList<>();
+    protected List<IApiRefresh> apiRefreshList = new ArrayList<>();
 
     public static final int REFRESH_ON_CREATE = 0;
     public static final int REFRESH_ON_RESUME = 1;
@@ -80,6 +80,7 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
         swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
         recyclerView = findViewById(R.id.recyclerView);
     }
+
     public void initView() {
         ViewUtil.setVisibility(title, false);
     }
@@ -134,25 +135,14 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
     }
 
     public void loadMoreData() {
-        ListUtil.forEach(apiRefreshList, new Action1<ApiRefresh<? extends Object>>() {
+        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
             @Override
-            public void call(ApiRefresh<?> apiRefresh) {
-                if (apiRefresh.loadMoreData()) {
-                    finishRefresh();
-                }
+            public void call(IApiRefresh apiRefresh) {
+                apiRefresh.loadMoreData();
             }
         });
     }
 
-    public void setNoMore(boolean noMore) {
-        if (noMore) {
-            baseQuickAdapter.loadMoreEnd();
-        } else {
-            baseQuickAdapter.loadMoreComplete();
-        }
-        finishRefresh();
-    }
-
     @Override
     public void onResume() {
         super.onResume();
@@ -173,23 +163,23 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
     public void refreshData() {
         checkMetLl();
         clear();
-        ListUtil.forEach(apiRefreshList, new Action1<ApiRefresh<? extends Object>>() {
+        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
             @Override
-            public void call(ApiRefresh<?> apiRefresh) {
+            public void call(IApiRefresh apiRefresh) {
                 apiRefresh.clear();
             }
         });
         ViewUtil.notifyDataSetChanged(recyclerView);
-        ListUtil.forEach(apiRefreshList, new Action1<ApiRefresh<? extends Object>>() {
+        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
             @Override
-            public void call(ApiRefresh<?> apiRefresh) {
+            public void call(IApiRefresh apiRefresh) {
                 apiRefresh.initData();
             }
         });
     }
 
     protected void clear() {
-        setNoMore(false);
+        notifyDataSetChanged(1, true);
         initLoadMoreListener();
     }
 
@@ -204,23 +194,31 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
         }
     }
 
-    public void notifyDataSetChanged() {
+    public void notifyDataSetChanged(int page, boolean hasMore) {
         if (recyclerView == null)
             recyclerView = findViewById(R.id.recyclerView);
-        ListUtil.forEach(apiRefreshList, new Action1<ApiRefresh<? extends Object>>() {
+        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
             @Override
-            public void call(ApiRefresh<?> apiRefresh) {
+            public void call(IApiRefresh apiRefresh) {
                 apiRefresh.setLoadMore(false);
             }
         });
         ViewUtil.notifyDataSetChanged(recyclerView);
-        finishRefresh();
+        if (hasMore) {
+            switch (page) {
+                case 1:
+                    if (swipeRefreshLayout != null)
+                        swipeRefreshLayout.setRefreshing(false);
+                    break;
+                default:
+                    baseQuickAdapter.loadMoreComplete();
+                    break;
+            }
+        } else {
+            baseQuickAdapter.loadMoreEnd(false);
+        }
     }
 
-    protected void finishRefresh() {
-        if (swipeRefreshLayout != null)
-            swipeRefreshLayout.setRefreshing(false);
-    }
 
     @Override
     public void onDestroyView() {

+ 5 - 5
app/src/main/java/com/sheep/gamegroup/view/fragment/FgtDiscoveryTopic.java

@@ -4,7 +4,8 @@ import android.view.View;
 
 import com.chad.library.adapter.base.BaseQuickAdapter;
 import com.chad.library.adapter.base.BaseViewHolder;
-import com.sheep.gamegroup.absBase.ApiRefresh;
+import com.sheep.gamegroup.absBase.IApiRefresh;
+import com.sheep.gamegroup.absBase.NetApiRefresh;
 import com.sheep.gamegroup.model.api.ApiService;
 import com.sheep.gamegroup.model.entity.BaseMessage;
 import com.sheep.gamegroup.model.entity.DiscoveryTopic;
@@ -29,11 +30,10 @@ public class FgtDiscoveryTopic extends BaseListFragment6<DiscoveryTopic> {
         return R.layout.common_srl_rv;
     }
 
-    private ApiRefresh<DiscoveryTopic> mApiRefresh;
-
+    private NetApiRefresh<DiscoveryTopic> mApiRefresh;
     @Override
-    protected void addApiRefresh(List<ApiRefresh<?>> apiRefreshList) {
-        mApiRefresh = new ApiRefresh<DiscoveryTopic>(this) {
+    protected void addApiRefresh(List<IApiRefresh> apiRefreshList) {
+        mApiRefresh = new NetApiRefresh<DiscoveryTopic>(this) {
             @Override
             protected boolean hasMore() {
                 return false;

+ 5 - 4
app/src/main/java/com/sheep/gamegroup/view/fragment/FgtUserFocusLogList.java

@@ -9,7 +9,8 @@ import android.widget.TextView;
 
 import com.chad.library.adapter.base.BaseQuickAdapter;
 import com.chad.library.adapter.base.BaseViewHolder;
-import com.sheep.gamegroup.absBase.ApiRefresh;
+import com.sheep.gamegroup.absBase.IApiRefresh;
+import com.sheep.gamegroup.absBase.NetApiRefresh;
 import com.sheep.gamegroup.model.api.ApiService;
 import com.sheep.gamegroup.model.entity.BaseMessage;
 import com.sheep.gamegroup.model.entity.UserFocusLog;
@@ -51,10 +52,10 @@ public class FgtUserFocusLogList extends BaseListFragment6<String> {
     };
 
     @Override
-    protected void addApiRefresh(List<ApiRefresh<?>> apiRefreshList) {
+    protected void addApiRefresh(List<IApiRefresh> apiRefreshList) {
         tagList.add("1");
         tagList.add("2");
-        ApiRefresh<UserFocusLog> apiRefresh1 = new ApiRefresh<UserFocusLog>(this) {
+        NetApiRefresh<UserFocusLog> apiRefresh1 = new NetApiRefresh<UserFocusLog>(this) {
             @Override
             public String getKey(int page, int per_page) {
                 return ApiKey.pageKeyUrl(ApiKey.getGameUserUserFocusList, page, per_page);
@@ -70,7 +71,7 @@ public class FgtUserFocusLogList extends BaseListFragment6<String> {
                 return UserFocusLog.class;
             }
         };
-        ApiRefresh<UserFocusLog> apiRefresh2 = new ApiRefresh<UserFocusLog>(this) {
+        NetApiRefresh<UserFocusLog> apiRefresh2 = new NetApiRefresh<UserFocusLog>(this) {
             @Override
             public String getKey(int page, int per_page) {
                 return ApiKey.pageKeyUrl(ApiKey.getGameUserUserFocusHotUser, page, per_page);

+ 6 - 0
app/src/main/res/drawable/shape_oval_solid_10_f5.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <corners android:radius="10dp" />
+    <solid android:color="#fff5f5f5" />
+</shape>

+ 6 - 0
app/src/main/res/drawable/shape_oval_solid_10_main.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <corners android:radius="10dp" />
+    <solid android:color="@color/btn_color_main_stroke" />
+</shape>

+ 22 - 0
app/src/main/res/layout/act_media_choose.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/white"
+    android:orientation="vertical">
+
+    <include layout="@layout/title" />
+
+    <android.support.design.widget.TabLayout
+        android:id="@+id/indicator"
+        style="@style/style_tab"
+        android:layout_marginTop="7dp" />
+
+    <include layout="@layout/line_1px_hor" />
+
+    <android.support.v4.view.ViewPager
+        android:id="@+id/viewPager"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" />
+</LinearLayout>

+ 29 - 0
app/src/main/res/layout/item_media_picker.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <ImageView
+        android:id="@+id/item_media_picker_iv"
+        android:layout_width="match_parent"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp"
+        android:layout_marginTop="6dp"
+        android:layout_marginBottom="6dp"
+        android:layout_height="wrap_content"
+        android:adjustViewBounds="true"
+        android:scaleType="fitXY" />
+
+    <TextView
+        android:id="@+id/item_media_picker_tv"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        android:layout_alignTop="@id/item_media_picker_iv"
+        android:layout_alignEnd="@id/item_media_picker_iv"
+        android:layout_margin="10dp"
+        android:background="@drawable/shape_oval_solid_10_f5"
+        android:gravity="center"
+        android:text="√"
+        android:textColor="@color/yellow_D3AF57"
+        android:textSize="12sp" />
+</RelativeLayout>

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

@@ -9,5 +9,6 @@
     <color name="green">#4cd117</color>
 
     <color name="bg_class_grey">#f9f9f9</color>
+    <color name="gray_CBCBCB">#cbcbcb</color>
 
 </resources>

+ 1 - 1
settings.gradle

@@ -1 +1 @@
-include ':app', ':view', ':ucrop', ':WaterWaveProgress', ':RxGalleryFinal'//, ':Aria', ':datashare', ':AriaAnnotations'
+include ':app', ':view', ':ucrop', ':WaterWaveProgress'//, ':RxGalleryFinal', ':Aria', ':datashare', ':AriaAnnotations'