package ml.puredark.hviewer.ui.activities; import android.content.Context; import android.content.Intent; import android.graphics.drawable.NinePatchDrawable; import android.os.Bundle; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.v4.content.ContextCompat; import android.support.v4.util.Pair; import android.support.v7.app.AlertDialog; import android.support.v7.widget.AppCompatCheckBox; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator; import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator; import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager; import com.h6ah4i.android.widget.advrecyclerview.expandable.RecyclerViewExpandableItemManager; import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager; import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager; import com.rengwuxian.materialedittext.MaterialEditText; import java.util.ArrayList; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import ml.puredark.hviewer.HViewerApplication; import ml.puredark.hviewer.R; import ml.puredark.hviewer.beans.CollectionGroup; import ml.puredark.hviewer.beans.DownloadTask; import ml.puredark.hviewer.beans.LocalCollection; import ml.puredark.hviewer.dataholders.DownloadTaskHolder; import ml.puredark.hviewer.download.DownloadManager; import ml.puredark.hviewer.download.DownloadService; import ml.puredark.hviewer.helpers.FileHelper; import ml.puredark.hviewer.helpers.Logger; import ml.puredark.hviewer.helpers.MDStatusBarCompat; import ml.puredark.hviewer.libraries.advrecyclerview.common.data.AbstractExpandableDataProvider; import ml.puredark.hviewer.ui.adapters.DownloadedTaskAdapter; import ml.puredark.hviewer.ui.adapters.DownloadingTaskAdapter; import ml.puredark.hviewer.ui.adapters.LocalCollectionAdapter; import ml.puredark.hviewer.ui.adapters.ViewPagerAdapter; import ml.puredark.hviewer.ui.customs.ExTabLayout; import ml.puredark.hviewer.ui.customs.ExViewPager; import ml.puredark.hviewer.ui.dataproviders.ExpandableDataProvider; import ml.puredark.hviewer.ui.dataproviders.ListDataProvider; public class DownloadActivity extends BaseActivity { @BindView(R.id.btn_return) ImageView btnReturn; @BindView(R.id.tv_title) TextView tvTitle; @BindView(R.id.app_bar) AppBarLayout appbar; @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.tab_layout) ExTabLayout tabLayout; @BindView(R.id.view_pager) ExViewPager viewPager; @BindView(R.id.shadowDown) View shadowDown; @BindView(R.id.coordinator_layout) CoordinatorLayout coordinatorLayout; private RecyclerView rvDownloading, rvDownloaded; private DownloadingTaskAdapter downloadingTaskAdapter; private DownloadedTaskAdapter downloadedTaskAdapter; private RecyclerView.Adapter mWrappedAdapter; private RecyclerViewExpandableItemManager mRecyclerViewExpandableItemManager; private RecyclerViewDragDropManager mRecyclerViewDragDropManager; private RecyclerViewSwipeManager mRecyclerViewSwipeManager; private RecyclerViewTouchActionGuardManager mRecyclerViewTouchActionGuardManager; private DownloadManager manager; private DownloadReceiver receiver; private DownloadTaskHolder holder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_download_list); ButterKnife.bind(this); tvTitle.setText("下载管理"); setSupportActionBar(toolbar); setContainer(coordinatorLayout); setReturnButton(btnReturn); getSupportActionBar().setDisplayShowTitleEnabled(false); MDStatusBarCompat.setSwipeBackToolBar(this, coordinatorLayout, appbar, toolbar); receiver = new MyDownloadReceiver(); setDownloadReceiver(receiver); reportShortcutUsed(this, "scdownload"); Intent intent = getIntent(); if (intent != null) { Logger.d("ShortcutTest", "DownloadActivity"); Logger.d("ShortcutTest", intent.toString()); String action = intent.getAction(); if (HViewerApplication.INTENT_SHORTCUT.equals(action) && LockActivity.isSetLockMethod(this)) { Intent lockIntent = new Intent(DownloadActivity.this, LockActivity.class); lockIntent.setAction(HViewerApplication.INTENT_FROM_DOWNLOAD); startActivity(lockIntent); finish(); return; } } manager = new DownloadManager(this); holder = new DownloadTaskHolder(this); initTabAndViewPager(); initDownloadedTask(); new Thread(() -> distinguishDownloadTasks()).start(); } @OnClick(R.id.btn_return) void back() { onBackPressed(); } @Override public void onResume() { super.onResume(); new Thread(() -> distinguishDownloadTasks()).start(); } @Override public void onDestroy() { super.onDestroy(); try { if (manager != null) { manager.unbindService(this); } } catch (Exception e) { } } private void initTabAndViewPager() { //初始化Tab和ViewPager List<View> views = new ArrayList<>(); View viewDownloading = getLayoutInflater().inflate(R.layout.view_collection_list, null); View viewDownloaded = getLayoutInflater().inflate(R.layout.view_collection_list, null); views.add(viewDownloading); views.add(viewDownloaded); List<String> titles = new ArrayList<>(); titles.add("当前任务"); titles.add("已完成 "); ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(views, titles); viewPager.setAdapter(viewPagerAdapter); tabLayout.setupWithViewPager(viewPager); rvDownloading = (RecyclerView) viewDownloading.findViewById(R.id.rv_collection); rvDownloaded = (RecyclerView) viewDownloaded.findViewById(R.id.rv_collection); downloadingTaskAdapter = new DownloadingTaskAdapter(this, new ListDataProvider(new ArrayList<DownloadTask>())); rvDownloading.setAdapter(downloadingTaskAdapter); downloadingTaskAdapter.setOnItemClickListener(new DownloadingTaskAdapter.OnItemClickListener() { @Override public void onItemClick(View v, int position) { DownloadTask task = (DownloadTask) downloadingTaskAdapter.getDataProvider().getItem(position); if (task.status == DownloadTask.STATUS_GETTING) { manager.pauseDownload(); } else if (task.status == DownloadTask.STATUS_IN_QUEUE) { task.status = DownloadTask.STATUS_PAUSED; } else if (task.status == DownloadTask.STATUS_PAUSED) { task.status = DownloadTask.STATUS_IN_QUEUE; if (!manager.isDownloading()) startNextTaskInQueue(); } downloadingTaskAdapter.notifyDataSetChanged(); } @Override public boolean onItemLongClick(View v, int position) { final DownloadTask task = (DownloadTask) downloadingTaskAdapter.getDataProvider().getItem(position); String[] options = (task.collection.videos != null && task.collection.videos.size() > 0) ? new String[]{"重新下载", "删除"} : new String[]{"浏览", "删除"}; new AlertDialog.Builder(DownloadActivity.this) .setTitle("操作") .setItems(options, (dialogInterface, i) -> { if (i == 0) { if (task.collection.videos != null && task.collection.videos.size() > 0) { manager.restartDownload(task); } else { HViewerApplication.temp = task; Intent intent = new Intent(DownloadActivity.this, DownloadTaskActivity.class); startActivity(intent); } } else if (i == 1) { View view = LayoutInflater.from(DownloadActivity.this).inflate(R.layout.dialog_delete_confirm, null); AppCompatCheckBox checkBoxDeleteFile = (AppCompatCheckBox) view.findViewById(R.id.checkbox_delete_file); new AlertDialog.Builder(DownloadActivity.this) .setView(view) .setPositiveButton(getString(R.string.ok), (dialog, which) -> { manager.deleteDownloadTask(task); new Thread(() -> distinguishDownloadTasks()).start(); if (checkBoxDeleteFile.isChecked()) { String rootPath = task.path.substring(0, task.path.lastIndexOf("/")); String dirName = task.path.substring(task.path.lastIndexOf("/") + 1, task.path.length()); FileHelper.deleteFile(dirName, rootPath); } }).setNegativeButton(getString(R.string.cancel), null).show(); } }) .setNegativeButton(getString(R.string.cancel), null) .show(); return true; } }); } private void initDownloadedTask() { ExpandableDataProvider dataProvider = new ExpandableDataProvider(new ArrayList<>()); mRecyclerViewExpandableItemManager = new RecyclerViewExpandableItemManager(null); // touch guard manager (this class is required to suppress scrolling while swipe-dismiss animation is running) mRecyclerViewTouchActionGuardManager = new RecyclerViewTouchActionGuardManager(); mRecyclerViewTouchActionGuardManager.setInterceptVerticalScrollingWhileAnimationRunning(true); mRecyclerViewTouchActionGuardManager.setEnabled(true); // drag & drop manager mRecyclerViewDragDropManager = new RecyclerViewDragDropManager(); mRecyclerViewDragDropManager.setInitiateOnMove(false); mRecyclerViewDragDropManager.setInitiateOnTouch(false); mRecyclerViewDragDropManager.setInitiateOnLongPress(true); // 拖拽时的阴影 mRecyclerViewDragDropManager.setDraggingItemShadowDrawable( (NinePatchDrawable) ContextCompat.getDrawable(this, R.drawable.material_shadow_z3)); // swipe manager mRecyclerViewSwipeManager = new RecyclerViewSwipeManager(); downloadedTaskAdapter = new DownloadedTaskAdapter(this, dataProvider); // wrap for expanding mWrappedAdapter = mRecyclerViewExpandableItemManager.createWrappedAdapter(downloadedTaskAdapter); // wrap for dragging mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mWrappedAdapter); // wrap for swiping mWrappedAdapter = mRecyclerViewSwipeManager.createWrappedAdapter(mWrappedAdapter); rvDownloaded.setAdapter(mWrappedAdapter); rvDownloaded.setHasFixedSize(false); final GeneralItemAnimator animator = new SwipeDismissItemAnimator(); // Change animations are enabled by default since support-v7-recyclerview v22. // Disable the change animation in order to make turning back animation of swiped item works properly. animator.setSupportsChangeAnimations(false); rvDownloaded.setItemAnimator(animator); downloadedTaskAdapter.setExpandableItemManager(mRecyclerViewExpandableItemManager); // NOTE: // The initialization order is very important! This order determines the priority of touch event handling. // // priority: TouchActionGuard > Swipe > DragAndDrop mRecyclerViewTouchActionGuardManager.attachRecyclerView(rvDownloaded); mRecyclerViewSwipeManager.attachRecyclerView(rvDownloaded); mRecyclerViewDragDropManager.attachRecyclerView(rvDownloaded); mRecyclerViewExpandableItemManager.attachRecyclerView(rvDownloaded); downloadedTaskAdapter.setOnItemClickListener(new DownloadedTaskAdapter.OnItemClickListener() { @Override public void onGroupClick(View v, int groupPosition) { // 点击分类(如果是新建按钮则创建,否则展开) if (groupPosition == downloadedTaskAdapter.getGroupCount() - 1) { View view = getLayoutInflater().inflate(R.layout.view_input_text, null); MaterialEditText inputGroupTitle = (MaterialEditText) view.findViewById(R.id.input_text); new AlertDialog.Builder(DownloadActivity.this) .setTitle("新建组名") .setView(view) .setNegativeButton("取消", null) .setPositiveButton("确定", (dialog, which) -> { String title = inputGroupTitle.getText().toString(); CollectionGroup group = new CollectionGroup(0, title); int gid = holder.addDlGroup(group); group.gid = gid; group.index = gid; holder.updateDlGroupIndex(group); downloadedTaskAdapter.getDataProvider().setDataSet(holder.getDownloadedTasksFromDB()); downloadedTaskAdapter.notifyDataSetChanged(); }).show(); } else { mRecyclerViewExpandableItemManager.notifyGroupItemChanged(groupPosition); } } @Override public boolean onGroupLongClick(View v, final int groupPosition) { if (mRecyclerViewDragDropManager.isDragging()) return true; // 分类上长按,选择操作 ExpandableDataProvider<CollectionGroup, DownloadTask> provider = downloadedTaskAdapter.getDataProvider(); final CollectionGroup group = provider.getGroupItem(groupPosition); new AlertDialog.Builder(DownloadActivity.this) .setTitle("操作") .setItems(new String[]{"重命名", "删除"}, (dialogInterface, i) -> { if (i == 0) { View view = getLayoutInflater().inflate(R.layout.view_input_text, null); MaterialEditText inputGroupTitle = (MaterialEditText) view.findViewById(R.id.input_text); new AlertDialog.Builder(DownloadActivity.this).setTitle("重命名组") .setView(view) .setNegativeButton("取消", null) .setPositiveButton("确定", (dialog, which) -> { String title = inputGroupTitle.getText().toString(); group.title = title; holder.updateDlGroup(group); downloadedTaskAdapter.notifyDataSetChanged(); }).show(); } else if (i == 1) { new AlertDialog.Builder(DownloadActivity.this).setTitle("是否删除?") .setMessage("删除后将无法恢复") .setNegativeButton("取消", null) .setPositiveButton("确定", (dialog, which) -> { holder.deleteDlGroup(group); downloadedTaskAdapter.getDataProvider().removeGroupItem(groupPosition); downloadedTaskAdapter.notifyDataSetChanged(); }).show(); } }) .setNegativeButton("取消", null) .show(); return true; } @Override public void onItemClick(View v, int groupPosition, int childPosition) { try { ExpandableDataProvider<CollectionGroup, DownloadTask> provider = downloadedTaskAdapter.getDataProvider(); DownloadTask task = provider.getChildItem(groupPosition, childPosition); HViewerApplication.temp = task; Intent intent = new Intent(DownloadActivity.this, DownloadTaskActivity.class); startActivity(intent); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } @Override public boolean onItemLongClick(View v, final int groupPosition, final int childPosition) { return false; } }); downloadedTaskAdapter.setOnItemEventListener(new DownloadedTaskAdapter.OnItemEventListener() { @Override public void onGroupMove(int fromGroupPosition, int toGroupPosition) { ExpandableDataProvider<CollectionGroup, DownloadTask> provider = downloadedTaskAdapter.getDataProvider(); int groupCount = downloadedTaskAdapter.getGroupCount() - 1; for (int m = 0; m < groupCount; m++) { CollectionGroup group = provider.getGroupItem(m); group.index = m + 1; holder.updateDlGroupIndex(group); } } @Override public void onItemMove(int fromGroupPosition, int fromChildPosition, int toGroupPosition, int toChildPosition) { ExpandableDataProvider<CollectionGroup, DownloadTask> provider = downloadedTaskAdapter.getDataProvider(); CollectionGroup group = provider.getGroupItem(toGroupPosition); DownloadTask task = provider.getChildItem(toGroupPosition, toChildPosition); task.collection.gid = group.gid; holder.updateDownloadItemIndex(task); updateGroupItemIndex(fromGroupPosition); if (fromGroupPosition != toGroupPosition) updateGroupItemIndex(toGroupPosition); } @Override public void onItemRemoved(int groupPosition, int childPosition) { final ExpandableDataProvider<CollectionGroup, DownloadTask> provider = downloadedTaskAdapter.getDataProvider(); final DownloadTask task = provider.getChildItem(groupPosition, childPosition); holder.deleteDownloadTask(task); downloadedTaskAdapter.getDataProvider().removeChildItem(groupPosition, childPosition); mRecyclerViewExpandableItemManager.notifyChildItemRemoved(groupPosition, childPosition); View view = LayoutInflater.from(DownloadActivity.this).inflate(R.layout.dialog_delete_confirm, null); AppCompatCheckBox checkBoxDeleteFile = (AppCompatCheckBox) view.findViewById(R.id.checkbox_delete_file); new AlertDialog.Builder(DownloadActivity.this) .setView(view) .setPositiveButton("确定", (dialog, which) -> { manager.deleteDownloadTask(task); new Thread(() -> distinguishDownloadTasks()).start(); if (checkBoxDeleteFile.isChecked()) { String rootPath = task.path.substring(0, task.path.lastIndexOf("/")); String dirName = task.path.substring(task.path.lastIndexOf("/") + 1, task.path.length()); FileHelper.deleteFile(dirName, rootPath); } }).setNegativeButton("撤销", (dialog, which) -> { DownloadTask recoveredItem = provider.undoLastRemoval(); mRecyclerViewExpandableItemManager.notifyChildItemInserted(groupPosition, childPosition); holder.addDownloadTask(recoveredItem); }).show(); } private void updateGroupItemIndex(int groupPosition) { ExpandableDataProvider<CollectionGroup, DownloadTask> provider = downloadedTaskAdapter.getDataProvider(); int childCount = downloadedTaskAdapter.getChildCount(groupPosition); for (int i = 0; i < childCount; i++) { DownloadTask task = provider.getChildItem(groupPosition, i); task.collection.index = i + 1; holder.updateDownloadItemIndex(task); } } }); } private synchronized void distinguishDownloadTasks() { manager.checkDownloadedTask(); List<DownloadTask> downloadingTasks = manager.getDownloadingTasks(); List<Pair<CollectionGroup, List<DownloadTask>>> downloadedTasks = manager.getDownloadedTasks(); downloadingTaskAdapter.getDataProvider().setDataSet(downloadingTasks); downloadedTaskAdapter.getDataProvider().setDataSet(downloadedTasks); runOnUiThread(() -> { downloadingTaskAdapter.notifyDataSetChanged(); downloadedTaskAdapter.notifyDataSetChanged(); }); } private void startNextTaskInQueue() { List<DownloadTask> downloadingTasks = manager.getDownloadingTasks(); for (DownloadTask task : downloadingTasks) { if (task.status == DownloadTask.STATUS_IN_QUEUE) { manager.startDownload(task); break; } } } public class MyDownloadReceiver extends DownloadReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(DownloadService.ON_START) || intent.getAction().equals(DownloadService.ON_PROGRESS)) { downloadingTaskAdapter.notifyDataSetChanged(); } else if (intent.getAction().equals(DownloadService.ON_PAUSE)) { startNextTaskInQueue(); } else if (intent.getAction().equals(DownloadService.ON_FAILURE)) { String message = intent.getStringExtra("message"); message = ("".equals(message)) ? "下载失败,请重试" : message; showSnackBar(message); downloadingTaskAdapter.notifyDataSetChanged(); } else if (intent.getAction().equals(DownloadService.ON_COMPLETE)) { showSnackBar("任务下载成功"); new Thread(() -> distinguishDownloadTasks()).start(); startNextTaskInQueue(); } Log.d("MyDownloadReceiver", intent.getAction()); } } }