Sfoglia il codice sorgente

重写下载管理界面

zengjiebin 7 anni fa
parent
commit
2212190136

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

@@ -939,6 +939,10 @@
             android:name="com.sheep.gamegroup.module.game.activity.ActGameGroupMore"
             android:theme="@style/AppActionTheme"
             android:screenOrientation="portrait" />
+        <activity
+            android:name="com.sheep.gamegroup.module.game.activity.ActDownloadManager"
+            android:theme="@style/AppActionTheme"
+            android:screenOrientation="portrait" />
     </application>
 
 </manifest>

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

@@ -11,6 +11,9 @@ import com.sheep.gamegroup.util.DownloadTextUtl;
 import com.sheep.gamegroup.util.DownloadUtil;
 import com.sheep.jiuyan.samllsheep.utils.PackageUtil;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import rx.functions.Action1;
 
 /**
@@ -144,11 +147,27 @@ public abstract class AbsGetDownloadListener {
     public abstract DownloadHelper getDownloadHelper(String downloadUrl);
 
 
+    private List<AbsDownloadListener> downloadListenerList = new ArrayList<>();
+
+    public void addDownloadListener(AbsDownloadListener item) {
+        downloadListenerList.add(item);
+    }
+
+    public boolean removeDownloadListener(AbsDownloadListener item) {
+        return downloadListenerList.remove(item);
+    }
+
     public void onEventMainThread(Intent intent) {
         absDownloadListener.onEventMainThread(intent);
+        for (AbsDownloadListener item : downloadListenerList) {
+            item.onEventMainThread(intent);
+        }
     }
 
     public void onEventMainThread(BigEvent bigEvent) {
         absDownloadListener.onEventMainThread(bigEvent);
+        for (AbsDownloadListener item : downloadListenerList) {
+            item.onEventMainThread(bigEvent);
+        }
     }
 }

+ 15 - 0
app/src/main/java/com/sheep/gamegroup/greendao/DDProviderHelper.java

@@ -134,6 +134,21 @@ public class DDProviderHelper {
             return false;
         }
     }
+    /**
+     * 删除指定任务;
+     *
+     * @param downLoadInfo
+     */
+    public boolean deleteDownloadTask(DownLoadInfo downLoadInfo) {
+        try {
+            DownLoadInfoDao loadInfoDao = getDaossion().getDownLoadInfoDao();
+            loadInfoDao.delete(downLoadInfo);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
 
     /**
      * 获取下载中的任务;

+ 39 - 0
app/src/main/java/com/sheep/gamegroup/module/game/activity/ActDownloadManager.java

@@ -0,0 +1,39 @@
+package com.sheep.gamegroup.module.game.activity;
+
+import android.support.v4.app.Fragment;
+
+import com.sheep.gamegroup.absBase.BaseContainerActivity;
+import com.sheep.gamegroup.module.game.fragment.FgtDownloadManager;
+import com.sheep.jiuyan.samllsheep.R;
+import com.sheep.jiuyan.samllsheep.utils.TitleBarUtils;
+
+/**
+ * Created by realicing on 2019/1/21.
+ * realicing@sina.com
+ *
+ * 下载管理界面
+ */
+public class ActDownloadManager extends BaseContainerActivity {
+    @Override
+    public void initView() {
+        super.initView();
+        TitleBarUtils
+                .getInstance()
+                .setShowOrHide(this, true)
+                .setTitle(this, getString(R.string.my_games))
+                .setRightBtn(this, "清空记录", 0, view -> {
+                    if(fgtDownloadManager != null){
+                        fgtDownloadManager.removeAll();
+                    }
+                })
+                .setTitleFinish(this);
+    }
+
+
+    private FgtDownloadManager fgtDownloadManager;
+    @Override
+    protected Fragment initFragment() {
+        fgtDownloadManager = new FgtDownloadManager();
+        return fgtDownloadManager;
+    }
+}

+ 275 - 0
app/src/main/java/com/sheep/gamegroup/module/game/fragment/FgtDownloadManager.java

@@ -0,0 +1,275 @@
+package com.sheep.gamegroup.module.game.fragment;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+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.AbsDownloadListener;
+import com.sheep.gamegroup.absBase.AbsGetDownloadListener;
+import com.sheep.gamegroup.absBase.AbsObserver;
+import com.sheep.gamegroup.absBase.IApiRefresh;
+import com.sheep.gamegroup.event.BigEvent;
+import com.sheep.gamegroup.greendao.download.DownLoadInfo;
+import com.sheep.gamegroup.helper.DownloadHelper;
+import com.sheep.gamegroup.module.game.model.DownloadInfoHelper;
+import com.sheep.gamegroup.util.DownloadUtil;
+import com.sheep.gamegroup.util.ViewUtil;
+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.ClassFileHelper;
+
+import org.greenrobot.eventbus.Subscribe;
+
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import io.reactivex.Observable;
+import io.reactivex.ObservableOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+import static com.sheep.gamegroup.view.adapter.TryMakeMoneyAdp.PUBLIC_TAG_PREFIX_TEXTVIEW_LIST;
+
+/**
+ * Created by realicing on 2019/1/21.
+ * realicing@sina.com
+ */
+public class FgtDownloadManager extends BaseListFragment6<DownLoadInfo> {
+
+    private DownloadUtil downloadUtil;
+    @Override
+    public void initListener() {
+        super.initListener();
+        downloadUtil = new DownloadUtil();
+    }
+
+    private AbsApiRefresh<DownLoadInfo> apiRefresh;
+    @Override
+    protected void addApiRefresh(List<IApiRefresh> apiRefreshList) {
+        apiRefresh = new AbsApiRefresh<DownLoadInfo>(this) {
+
+            @Override
+            public void initData() {
+                Observable.create((ObservableOnSubscribe<List<DownLoadInfo>>) emitter -> emitter.onNext(downloadUtil.getAllDownloadTasks()))
+                        .subscribeOn(Schedulers.io())
+                        .observeOn(AndroidSchedulers.mainThread()).
+                        subscribe(new AbsObserver<List<DownLoadInfo>>() {
+                            @Override
+                            public void onNext(List<DownLoadInfo> newList) {
+                                loadList(newList);
+                            }
+                        });
+            }
+
+            @Override
+            protected boolean hasMore() {
+                return false;
+            }
+        };
+        apiRefreshList.add(apiRefresh);
+    }
+
+    @Override
+    protected BaseQuickAdapter<DownLoadInfo, BaseViewHolder> getAdapter() {
+        return new BaseQuickAdapter<DownLoadInfo, BaseViewHolder>(R.layout.item_download_manager, apiRefresh.getList()){
+            @Override
+            protected void convert(BaseViewHolder helper, DownLoadInfo item) {
+                ImageView item_dm_icon_iv = helper.getView(R.id.item_dm_icon_iv);
+                TextView item_dm_name_tv = helper.getView(R.id.item_dm_name_tv);
+                TextView item_dm_info_tv = helper.getView(R.id.item_dm_info_tv);
+                ProgressBar item_dm_pb = helper.getView(R.id.item_dm_pb);
+                ImageView item_dm_delete_iv = helper.getView(R.id.item_dm_delete_iv);
+                TextView item_dm_btn_tv = helper.getView(R.id.item_dm_btn_tv);
+
+                ViewUtil.setImage(item_dm_icon_iv, item.getMIconUrl());
+                ViewUtil.setText(item_dm_name_tv, item.getMGameName());
+                if(item.getMPercent() == 100){
+                    if(item.getMTotalSize() == null){
+                        ViewUtil.setText(item_dm_info_tv, "全部下载完成");
+                    } else {
+                        ViewUtil.setText(item_dm_info_tv, String.format(Locale.CHINA, "%dMB 下载完成", (item.getMTotalSize().intValue() / (1024 * 1024))));
+                    }
+                } else {
+                    ViewUtil.setText(item_dm_info_tv, strFormat(item.getMDownloadedSize(), item.getMTotalSize()));
+                }
+                item_dm_pb.setProgress(item.getMPercent() != null ? item.getMPercent() : 0);
+                item_dm_delete_iv.setOnClickListener(view -> {
+                    if(apiRefresh != null && apiRefresh.getList() != null)
+                        apiRefresh.getList().remove(item);
+                    if(baseQuickAdapter != null)
+                        baseQuickAdapter.notifyDataSetChanged();
+                    Observable.create((ObservableOnSubscribe<Boolean>) emitter -> emitter.onNext(downloadUtil.deleteDownloadTask(item)))
+                            .subscribeOn(Schedulers.io())
+                            .observeOn(AndroidSchedulers.mainThread()).
+                                    subscribe(new AbsObserver<Boolean>() {
+                                        @Override
+                                        public void onNext(Boolean result) {
+                                            //删除成功
+                                        }
+                                    });
+                });
+
+                updateView(getActivity(), item, item_dm_btn_tv);
+            }
+        };
+    }
+
+    //删除所有下载任务与文件
+    public void removeAll() {
+        Observable.just(1).map(integer -> {
+            try {
+                downloadUtil.deleteAllDownloadTask();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            try {
+                ClassFileHelper.getInstance().clearDir();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return integer;
+        }).subscribeOn(Schedulers.io())
+        .observeOn(AndroidSchedulers.mainThread())
+        .subscribe(new AbsObserver<Integer>() {
+            @Override
+            public void onNext(Integer integer) {
+                clear();
+            }
+        });
+    }
+
+
+
+    //格式化下载大小
+    private DecimalFormat decimalFormat;
+    public String strFormat(Double fileDownloadSize, Double fileTotalSize) {
+        if (fileTotalSize == null) {
+            return SheepApp.getInstance().getString(R.string.calculating);
+        }
+        if (fileDownloadSize == null) {
+            return "0MB / " + (fileTotalSize.intValue() / (1024 * 1024)) + "MB";
+        }
+        if(decimalFormat == null){
+            decimalFormat = new DecimalFormat("######0.0");
+        }
+        return decimalFormat.format(fileDownloadSize / (1024 * 1024)) + "MB / " + (fileTotalSize.intValue() / (1024 * 1024)) + "MB";
+    }
+
+    @Override
+    public void onDestroyView() {
+        decimalFormat = null;
+        super.onDestroyView();
+    }
+
+
+    //更新下载进度
+    private Map<String, DownloadInfoHelper> downloadInfoHelperMap = new HashMap<>();
+
+
+
+    //更新按钮状态与添加点击事件
+    private void updateView(Activity activity, DownLoadInfo item, TextView textView) {
+        DownloadInfoHelper downloadInfoHelper = downloadInfoHelperMap.get(item.getMDownloadUrl());
+        if(downloadInfoHelper == null) {
+            downloadInfoHelper = new DownloadInfoHelper(item);
+            downloadInfoHelperMap.put(item.getMDownloadUrl(), downloadInfoHelper);
+            downloadInfoHelperMap.put(item.getMPackageName(), downloadInfoHelper);
+            downloadInfoHelper.updateDownloadTaskView(activity, textView);
+        } else {
+            downloadInfoHelper.updateDownloadTaskView(activity, textView);
+        }
+    }
+
+    private AbsGetDownloadListener absGetDownloadListener = new AbsGetDownloadListener(true) {
+        @Override
+        public String getDownloadUrl(String packageName) {
+            DownloadInfoHelper item = downloadInfoHelperMap.get(packageName);
+            return item != null ? item.getDownload_link() : null;
+        }
+
+        @Override
+        public TextView getTextView2(String packageName) {
+            return recyclerView.findViewWithTag(PUBLIC_TAG_PREFIX_TEXTVIEW_LIST + getDownloadUrl(packageName));
+        }
+
+        @Override
+        public TextView getTextView(String downloadUrl) {
+            return recyclerView.findViewWithTag(PUBLIC_TAG_PREFIX_TEXTVIEW_LIST + downloadUrl);
+        }
+
+        @Override
+        public DownloadHelper getDownloadHelper(String downloadUrl) {
+            DownloadInfoHelper item = downloadInfoHelperMap.get(downloadUrl);
+            return item != null ? item.getDownloadHelper() : null;
+        }
+    };
+
+    @Subscribe
+    public void onEventMainThread(Intent intent) {
+        absGetDownloadListener.onEventMainThread(intent);
+    }
+
+    @Subscribe
+    public void onEventMainThread(BigEvent event) {
+        absGetDownloadListener.onEventMainThread(event);
+    }
+
+    @Override
+    public void initView() {
+        super.initView();
+        absGetDownloadListener.addDownloadListener(new AbsDownloadListener() {
+            @Override
+            public void removedApk(String packageName) {
+
+            }
+
+            @Override
+            public void addedApk(String packageName) {
+
+            }
+
+            @Override
+            public void running(DownLoadInfo task) {
+                int position = apiRefresh.getList().indexOf(task);
+                if(position >= 0)
+                    baseQuickAdapter.notifyItemChanged(position, task);
+            }
+
+            @Override
+            public void taskStop(DownLoadInfo task) {
+
+            }
+
+            @Override
+            public void taskComplete(DownLoadInfo task) {
+
+            }
+
+            @Override
+            public void taskCancel(DownLoadInfo task) {
+
+            }
+
+            @Override
+            public void taskFail(DownLoadInfo task) {
+
+            }
+        });
+        ViewUtil.register(this);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        ViewUtil.unregister(this);
+    }
+}

+ 2 - 2
app/src/main/java/com/sheep/gamegroup/module/game/fragment/FgtGameCenter.java

@@ -7,9 +7,9 @@ import android.view.View;
 import android.widget.Button;
 import android.widget.ImageButton;
 
+import com.sheep.gamegroup.module.game.activity.ActDownloadManager;
 import com.sheep.gamegroup.util.Jump2View;
 import com.sheep.gamegroup.util.UMConfigUtils;
-import com.sheep.gamegroup.view.activity.ActDownloadMgr;
 import com.sheep.gamegroup.view.activity.ActMain;
 import com.sheep.gamegroup.view.adapter.TitleFragmentListAdapter;
 import com.sheep.gamegroup.view.fragment.FgtWelfareCenter;
@@ -98,7 +98,7 @@ public class FgtGameCenter extends BaseFragment {
 
     @OnClick(R.id.download_btn)
     public void doDownload(View v) {
-        startActivity(new Intent(getContext(), ActDownloadMgr.class));
+        startActivity(new Intent(getContext(), ActDownloadManager.class));
         UMConfigUtils.onEvent(UMConfigUtils.Event.GAME_DOWNLOAD_MANAGER);
     }
 

+ 80 - 0
app/src/main/java/com/sheep/gamegroup/module/game/model/DownloadInfoHelper.java

@@ -0,0 +1,80 @@
+package com.sheep.gamegroup.module.game.model;
+
+import android.app.Activity;
+import android.widget.TextView;
+
+import com.sheep.gamegroup.greendao.download.DownLoadInfo;
+import com.sheep.gamegroup.helper.DownloadHelper;
+import com.sheep.gamegroup.model.api.IDownload;
+
+import static com.sheep.gamegroup.view.adapter.TryMakeMoneyAdp.PUBLIC_TAG_PREFIX_TEXTVIEW_LIST;
+
+/**
+ * Created by realicing on 2019/1/21.
+ * realicing@sina.com
+ */
+public class DownloadInfoHelper implements IDownload {
+
+    private DownloadHelper downloadHelper = new DownloadHelper();
+    private DownLoadInfo downLoadInfo;
+
+    public DownloadInfoHelper(DownLoadInfo downLoadInfo) {
+        this.downLoadInfo = downLoadInfo;
+    }
+
+    public DownloadHelper getDownloadHelper() {
+        return downloadHelper;
+    }
+
+    public void setDownloadHelper(DownloadHelper downloadHelper) {
+        this.downloadHelper = downloadHelper;
+    }
+
+    public DownLoadInfo getDownLoadInfo() {
+        return downLoadInfo;
+    }
+
+    public void setDownLoadInfo(DownLoadInfo downLoadInfo) {
+        this.downLoadInfo = downLoadInfo;
+    }
+
+    public void updateDownloadTaskView(Activity activity, TextView textView) {
+        textView.setTag(PUBLIC_TAG_PREFIX_TEXTVIEW_LIST + getDownload_link());
+        downloadHelper.updateDownloadTaskView(activity, this, textView);
+    }
+
+    @Override
+    public String getPackage_names() {
+        return downLoadInfo.getMPackageName();
+    }
+
+    @Override
+    public int getTask_type() {
+        return 0;
+    }
+
+    @Override
+    public String getDownload_link() {
+        return downLoadInfo.getMDownloadUrl();
+    }
+
+    @Override
+    public String getTask_name() {
+        return downLoadInfo.getMGameName();
+    }
+
+    @Override
+    public String getIcon() {
+        return downLoadInfo.getMIconUrl();
+    }
+
+    @Override
+    public String getPackage_size() {
+        return downLoadInfo.getMTotalSize() == null ? "0" : Long.toString(downLoadInfo.getMTotalSize().longValue() / (1024 * 1024));
+    }
+
+    @Override
+    public int getAppId() {
+        return  downLoadInfo.getMGameID() == null ? 0 : downLoadInfo.getMGameID();
+    }
+}

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

@@ -444,7 +444,7 @@ public class DownloadUtil {
      * 删除文件并删除记录
      * @param downLoadInfo
      */
-    public void delete(DownLoadInfo downLoadInfo) {
+    public boolean delete(DownLoadInfo downLoadInfo) {
         if(downLoadInfo != null) {
             if(downLoadInfo.getMDownloadTaskId() != null) {
                 OkDownload.with().downloadDispatcher().cancel(downLoadInfo.getMDownloadTaskId());
@@ -452,8 +452,32 @@ public class DownloadUtil {
             }
             if (!TextUtils.isEmpty(downLoadInfo.getMApkPath()) && new File(downLoadInfo.getMApkPath()).delete()) {
                 LogUtil.println("DownloadUtil", "delete", "删除成功");
+                return true;
             }
         }
+        return false;
+    }
+    /**
+     * 删除文件并删除记录
+     * @param downLoadInfo
+     */
+    public boolean deleteDownloadTask(DownLoadInfo downLoadInfo) {
+        if(downLoadInfo != null) {
+            if(downLoadInfo.getMDownloadTaskId() != null) {
+                try {
+                    OkDownload.with().downloadDispatcher().cancel(downLoadInfo.getMDownloadTaskId());
+                    OkDownload.with().breakpointStore().remove(downLoadInfo.getMDownloadTaskId());
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            boolean isSuccess = DDProviderHelper.getInstance().deleteDownloadTask(downLoadInfo);
+            if (!TextUtils.isEmpty(downLoadInfo.getMApkPath()) && new File(downLoadInfo.getMApkPath()).delete() && isSuccess) {
+                LogUtil.println("DownloadUtil", "delete", "删除成功");
+                return true;
+            }
+        }
+        return false;
     }
 
     /**

+ 3 - 2
app/src/main/java/com/sheep/gamegroup/view/activity/GamemakeMoneyAct.java

@@ -7,9 +7,10 @@ import android.support.v4.view.ViewPager;
 import android.view.View;
 import android.widget.LinearLayout;
 
-import com.sheep.gamegroup.event.BigEvent;
 import com.sheep.gamegroup.absBase.BaseActivity;
+import com.sheep.gamegroup.event.BigEvent;
 import com.sheep.gamegroup.model.entity.DialogConfig;
+import com.sheep.gamegroup.module.game.activity.ActDownloadManager;
 import com.sheep.gamegroup.util.CommonUtil;
 import com.sheep.gamegroup.util.UMConfigUtils;
 import com.sheep.gamegroup.util.ViewUtil;
@@ -77,7 +78,7 @@ public class GamemakeMoneyAct extends BaseActivity {
                     public void onClick(View view) {
                         TitleBarUtils.getInstance()
                                 .setRightRedPoint(activity, View.GONE);
-                        startActivity(new Intent(activity, ActDownloadMgr.class));
+                        startActivity(new Intent(activity, ActDownloadManager.class));
                         UMConfigUtils.onEvent(UMConfigUtils.Event.GAME_DOWNLOAD_MANAGER);
                     }
                 });

+ 2 - 1
app/src/main/java/com/sheep/gamegroup/view/activity/TryMakeMoneyact.java

@@ -9,6 +9,7 @@ import android.view.View;
 import com.sheep.gamegroup.absBase.BaseActivity;
 import com.sheep.gamegroup.event.BigEvent;
 import com.sheep.gamegroup.model.entity.DialogConfig;
+import com.sheep.gamegroup.module.game.activity.ActDownloadManager;
 import com.sheep.gamegroup.util.UMConfigUtils;
 import com.sheep.gamegroup.util.ViewUtil;
 import com.sheep.gamegroup.view.adapter.AdpTryMakemoney;
@@ -72,7 +73,7 @@ public class TryMakeMoneyact extends BaseActivity {
                     public void onClick(View view) {
                         TitleBarUtils.getInstance()
                                 .setRightRedPoint(activity, View.GONE);
-                        startActivity(new Intent(TryMakeMoneyact.this, ActDownloadMgr.class));
+                        startActivity(new Intent(TryMakeMoneyact.this, ActDownloadManager.class));
                         UMConfigUtils.onEvent(UMConfigUtils.Event.GAME_DOWNLOAD_MANAGER);
                     }
                 });

+ 11 - 37
app/src/main/java/com/sheep/gamegroup/view/fragment/BaseListFragment6.java

@@ -87,12 +87,7 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
 
     public void initListener() {
         if (swipeRefreshLayout != null) {
-            swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
-                @Override
-                public void onRefresh() {
-                    refreshData();
-                }
-            });
+            swipeRefreshLayout.setOnRefreshListener(this::refreshData);
         }
         recyclerView.setLayoutManager(getLayoutManager());
         baseQuickAdapter = getAdapter();
@@ -123,12 +118,7 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
     }
 
     protected void initLoadMoreListener() {
-        baseQuickAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
-            @Override
-            public void onLoadMoreRequested() {
-                loadMoreData();
-            }
-        }, recyclerView);
+        baseQuickAdapter.setOnLoadMoreListener(this::loadMoreData, recyclerView);
     }
 
     protected RecyclerView.LayoutManager getLayoutManager() {
@@ -136,12 +126,7 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
     }
 
     public void loadMoreData() {
-        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
-            @Override
-            public void call(IApiRefresh apiRefresh) {
-                apiRefresh.loadMoreData();
-            }
-        });
+        ListUtil.forEach(apiRefreshList, IApiRefresh::loadMoreData);
     }
 
     @Override
@@ -164,22 +149,16 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
     public void refreshData() {
         checkMetLl();
         clear();
-        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
-            @Override
-            public void call(IApiRefresh apiRefresh) {
-                apiRefresh.clear();
-            }
-        });
+        ListUtil.forEach(apiRefreshList, IApiRefresh::initData);
+    }
+
+    public void clear() {
+        mClear();
+        ListUtil.forEach(apiRefreshList, IApiRefresh::clear);
         ViewUtil.notifyDataSetChanged(recyclerView);
-        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
-            @Override
-            public void call(IApiRefresh apiRefresh) {
-                apiRefresh.initData();
-            }
-        });
     }
 
-    protected void clear() {
+    protected void mClear() {
         notifyDataSetChanged(1, true);
         initLoadMoreListener();
     }
@@ -198,12 +177,7 @@ public abstract class BaseListFragment6<T> extends BaseFragment implements IRefr
     public void notifyDataSetChanged(int page, boolean hasMore) {
         if (recyclerView == null)
             recyclerView = findViewById(R.id.recyclerView);
-        ListUtil.forEach(apiRefreshList, new Action1<IApiRefresh>() {
-            @Override
-            public void call(IApiRefresh apiRefresh) {
-                apiRefresh.setLoadMore(false);
-            }
-        });
+        ListUtil.forEach(apiRefreshList, apiRefresh -> apiRefresh.setLoadMore(false));
         ViewUtil.notifyDataSetChanged(recyclerView);
         if (hasMore) {
             switch (page) {

+ 41 - 0
app/src/main/res/drawable/lay_list_progress_green.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="5dip" />
+            <stroke
+                android:width="1dp"
+                android:color="#F6F6F6"/>
+        </shape>
+    </item>
+
+    <item android:id="@android:id/secondaryProgress">
+        <clip>
+            <shape>
+                <corners android:radius="5dip" />
+                <gradient
+                    android:angle="270"
+                    android:centerColor="#8000ae7c"
+                    android:centerY="0.75"
+                    android:endColor="#a000be7c"
+                    android:startColor="#8000ce7c" />
+            </shape>
+        </clip>
+    </item>
+
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="5dip" />
+                <gradient
+                    android:angle="270"
+                    android:centerColor="#02A640"
+                    android:centerY="0.75"
+                    android:endColor="#03A640"
+                    android:startColor="#01A640" />
+            </shape>
+        </clip>
+    </item>
+
+</layer-list>

+ 88 - 0
app/src/main/res/layout/item_download_manager.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="94dp"
+    android:paddingStart="16dp"
+    android:paddingTop="16dp"
+    android:paddingEnd="16dp">
+
+    <ImageView
+        android:id="@+id/item_dm_icon_iv"
+        android:layout_width="62dp"
+        android:layout_height="62dp"
+        android:src="@drawable/loading_01"
+        android:layout_marginBottom="16dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/item_dm_name_tv"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="11dp"
+        android:text="永恒仙域"
+        android:textColor="#ff333333"
+        android:textSize="14sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/item_dm_icon_iv"
+        app:layout_constraintTop_toTopOf="@id/item_dm_icon_iv" />
+
+    <TextView
+        android:id="@+id/item_dm_info_tv"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:gravity="center_vertical"
+        android:text="1.28G"
+        android:textColor="#ff8e8e8e"
+        android:textSize="10sp"
+        android:layout_marginBottom="16dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="@id/item_dm_name_tv"
+        app:layout_constraintTop_toBottomOf="@id/item_dm_name_tv" />
+
+    <ProgressBar
+        android:id="@+id/item_dm_pb"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="0dp"
+        android:layout_height="7dp"
+        android:layout_marginEnd="10dp"
+        android:layout_marginBottom="3dp"
+        android:max="100"
+        android:progress="50"
+        android:progressDrawable="@drawable/lay_list_progress_green"
+        app:layout_constraintBottom_toBottomOf="@id/item_dm_icon_iv"
+        app:layout_constraintEnd_toStartOf="@id/item_dm_delete_iv"
+        app:layout_constraintStart_toStartOf="@id/item_dm_name_tv" />
+
+    <ImageView
+        android:id="@+id/item_dm_delete_iv"
+        android:layout_width="13dp"
+        android:layout_height="13dp"
+        android:layout_marginEnd="28dp"
+        android:src="@mipmap/delete_x_red_img"
+        app:layout_constraintBottom_toBottomOf="@id/item_dm_icon_iv"
+        app:layout_constraintEnd_toStartOf="@id/item_dm_btn_tv"
+        app:layout_constraintStart_toEndOf="@id/item_dm_pb" />
+
+    <TextView
+        android:id="@+id/item_dm_btn_tv"
+        style="@style/style_button_find"
+        android:text="开始下载"
+        android:layout_marginBottom="16dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="8dp"
+        android:background="#F2F2F2"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+</android.support.constraint.ConstraintLayout>