version:1.0.6
update: bugfixes:增加相册模块
BIN
JZVideo/src/main/res/drawable-xhdpi/icon_play.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
@@ -196,7 +196,7 @@
|
|||||||
android:id="@+id/start"
|
android:id="@+id/start"
|
||||||
android:layout_width="@dimen/jz_start_button_w_h_normal"
|
android:layout_width="@dimen/jz_start_button_w_h_normal"
|
||||||
android:layout_height="@dimen/jz_start_button_w_h_normal"
|
android:layout_height="@dimen/jz_start_button_w_h_normal"
|
||||||
android:src="@drawable/jz_click_play_selector" />
|
android:src="@drawable/icon_play" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,15 +16,16 @@ android {
|
|||||||
applicationId "com.uiui.videoplayer"
|
applicationId "com.uiui.videoplayer"
|
||||||
minSdkVersion 24
|
minSdkVersion 24
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 106
|
versionCode 107
|
||||||
versionName "1.0.5"
|
versionName "1.0.6"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
ndk {
|
ndk {
|
||||||
// add support lib
|
// add support lib
|
||||||
abiFilters /*"armeabi",*/ "armeabi-v7a", "arm64-v8a", "x86"/*, "x86_64", "mips", "mips64"*/
|
abiFilters /*"armeabi",*/ "armeabi-v7a", "arm64-v8a", "x86"
|
||||||
|
/*, "x86_64", "mips", "mips64"*/
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
@@ -158,6 +159,8 @@ dependencies {
|
|||||||
|
|
||||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
|
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
|
||||||
// implementation 'com.github.SheHuan:NiceImageView:1.0.5'
|
// implementation 'com.github.SheHuan:NiceImageView:1.0.5'
|
||||||
|
//指示器
|
||||||
|
implementation 'com.github.hackware1993:MagicIndicator:1.7.0' // for androidx
|
||||||
|
implementation 'com.github.Othershe:CombineBitmap:1.0.5'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,21 +12,30 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".activity.main.MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:screenOrientation="userPortrait" />
|
||||||
|
<activity
|
||||||
|
android:name=".activity.video.VideoActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:screenOrientation="userPortrait" />
|
||||||
|
<activity
|
||||||
|
android:name=".activity.pic.GalleryActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:screenOrientation="userPortrait" />
|
||||||
|
<activity
|
||||||
|
android:name=".activity.preview.PreviewActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:screenOrientation="userPortrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.PlayActivity"
|
android:name=".activity.PlayActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
android:screenOrientation="sensor" />
|
android:screenOrientation="sensor" />
|
||||||
<activity
|
|
||||||
android:name=".activity.main.MainActivity"
|
|
||||||
android:exported="true"
|
|
||||||
android:launchMode="singleTask">
|
|
||||||
<intent-filter>
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<!-- <action android:name="android.intent.action.MAIN" />-->
|
|
||||||
|
|
||||||
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.ActivityTikTok"
|
android:name=".activity.ActivityTikTok"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
|
|||||||
@@ -1,126 +1,85 @@
|
|||||||
package com.uiui.videoplayer.activity.main;
|
package com.uiui.videoplayer.activity.main;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.style.ForegroundColorSpan;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
|
||||||
|
|
||||||
import com.arialyy.annotations.Download;
|
import android.Manifest;
|
||||||
import com.arialyy.aria.core.Aria;
|
import android.content.Context;
|
||||||
import com.arialyy.aria.core.task.DownloadTask;
|
import android.content.Intent;
|
||||||
import com.google.gson.JsonObject;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.target.SimpleTarget;
|
||||||
|
import com.bumptech.glide.request.transition.Transition;
|
||||||
|
import com.othershe.combinebitmap.CombineBitmap;
|
||||||
|
import com.othershe.combinebitmap.layout.DingLayoutManager;
|
||||||
|
import com.othershe.combinebitmap.layout.WechatLayoutManager;
|
||||||
|
import com.shehuan.niv.NiceImageView;
|
||||||
import com.uiui.videoplayer.R;
|
import com.uiui.videoplayer.R;
|
||||||
|
import com.uiui.videoplayer.activity.pic.GalleryActivity;
|
||||||
|
import com.uiui.videoplayer.activity.video.VideoActivity;
|
||||||
import com.uiui.videoplayer.adapter.VideoAdapter;
|
import com.uiui.videoplayer.adapter.VideoAdapter;
|
||||||
import com.uiui.videoplayer.base.BaseLightActivity;
|
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||||
import com.uiui.videoplayer.base.CustomDialog;
|
import com.uiui.videoplayer.utils.JGYUtils;
|
||||||
import com.uiui.videoplayer.base.RecycleGridLayoutManager;
|
|
||||||
import com.uiui.videoplayer.base.SpacesItemDecoration;
|
|
||||||
import com.uiui.videoplayer.bean.LocalVideoInfo;
|
|
||||||
import com.uiui.videoplayer.gson.GsonUtils;
|
|
||||||
import com.uiui.videoplayer.utils.SPUtils;
|
|
||||||
import com.uiui.videoplayer.utils.ToastUtil;
|
import com.uiui.videoplayer.utils.ToastUtil;
|
||||||
|
import com.uiui.videoplayer.utils.Utils;
|
||||||
import com.uiui.videoplayer.utils.VideoUtils;
|
import com.uiui.videoplayer.utils.VideoUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||||
|
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||||
|
import io.reactivex.rxjava3.core.Observer;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import wseemann.media.FFmpegMediaMetadataRetriever;
|
||||||
|
|
||||||
public class MainActivity extends BaseLightActivity implements MainAContact.MainView {
|
public class MainActivity extends BaseLightActivity {
|
||||||
|
|
||||||
private static final int REQUEST_PERMISSION_CODE = 200;
|
private static final int REQUEST_PERMISSION_CODE = 200;
|
||||||
private static final String TAG = MainActivity.class.getSimpleName();
|
|
||||||
|
|
||||||
private MainAPresenter mPresenter;
|
|
||||||
|
|
||||||
|
@BindView(R.id.iv_back)
|
||||||
|
ImageView iv_back;
|
||||||
|
@BindView(R.id.cl_pic)
|
||||||
|
ConstraintLayout cl_pic;
|
||||||
|
@BindView(R.id.vl_video)
|
||||||
|
ConstraintLayout vl_video;
|
||||||
|
@BindView(R.id.nv_pic)
|
||||||
|
NiceImageView nv_pic;
|
||||||
|
@BindView(R.id.nv_video)
|
||||||
|
NiceImageView nv_video;
|
||||||
|
|
||||||
String[] permissions = new String[]{
|
String[] permissions = new String[]{
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
};
|
};
|
||||||
private RecyclerView recyclerView;
|
|
||||||
private TextView tips, tv_scan;
|
|
||||||
private SwipeRefreshLayout refreshLayout;
|
|
||||||
private VideoAdapter adapter;
|
|
||||||
|
|
||||||
private List<String> paths = new ArrayList<>();
|
|
||||||
private RecycleGridLayoutManager mManager;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initView() {
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
mPresenter = new MainAPresenter(this);
|
|
||||||
mPresenter.setLifecycle(lifecycleSubject);
|
|
||||||
mPresenter.attachView(this);
|
|
||||||
|
|
||||||
Aria.download(this).register();
|
|
||||||
|
|
||||||
checkSelfPermission();
|
|
||||||
|
|
||||||
initActionBar();
|
|
||||||
tips = findViewById(R.id.tips);
|
|
||||||
tv_scan = findViewById(R.id.tv_scan);
|
|
||||||
refreshLayout = findViewById(R.id.swipeRefreshLayout);
|
|
||||||
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
|
||||||
@Override
|
|
||||||
public void onRefresh() {
|
|
||||||
mPresenter.getHomeVideo();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
refreshLayout.setRefreshing(true);
|
|
||||||
recyclerView = findViewById(R.id.recyclerView);
|
|
||||||
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
|
||||||
int orientation = getResources().getConfiguration().orientation;
|
|
||||||
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
|
||||||
mManager = new RecycleGridLayoutManager(MainActivity.this, 3);
|
|
||||||
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
|
||||||
mManager = new RecycleGridLayoutManager(MainActivity.this, 2);
|
|
||||||
}
|
|
||||||
recyclerView.setLayoutManager(mManager);
|
|
||||||
recyclerView.setNestedScrollingEnabled(false);
|
|
||||||
recyclerView.addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x),
|
|
||||||
getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x)));
|
|
||||||
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
|
||||||
adapter = new VideoAdapter(MainActivity.this);
|
|
||||||
adapter.setOnLongClickListener(new VideoAdapter.onItemLongClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemLongClick(String path, int position) {
|
|
||||||
showDialog(path, position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
recyclerView.setAdapter(adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initData() {
|
|
||||||
mPresenter.getHomeVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLayoutId() {
|
public int getLayoutId() {
|
||||||
@@ -128,204 +87,41 @@ public class MainActivity extends BaseLightActivity implements MainAContact.Main
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
public void initView() {
|
||||||
super.onResume();
|
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||||
|
// //注意要清除 FLAG_TRANSLUCENT_STATUS flag
|
||||||
|
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||||
|
// getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
cl_pic.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
startActivity(new Intent(MainActivity.this, GalleryActivity.class));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
vl_video.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
startActivity(new Intent(MainActivity.this, VideoActivity.class));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
iv_back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
public void initData() {
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
Configuration config = getResources().getConfiguration();
|
|
||||||
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
|
||||||
mManager = new RecycleGridLayoutManager(MainActivity.this, 2);
|
|
||||||
recyclerView.setLayoutManager(mManager);
|
|
||||||
}
|
|
||||||
if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
|
||||||
mManager = new RecycleGridLayoutManager(MainActivity.this, 3);
|
|
||||||
recyclerView.setLayoutManager(mManager);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showDialog(String path, int position) {
|
@Override
|
||||||
CustomDialog dialog = new CustomDialog(MainActivity.this);
|
protected void onResume() {
|
||||||
dialog.setTitle("删除文件")
|
super.onResume();
|
||||||
.setMessage("确定要删除文件 " + VideoUtils.getFileNameWithoutExtension(path) + "吗")
|
checkSelfPermission();
|
||||||
.setPositive("确定")
|
|
||||||
.setNegtive("取消")
|
|
||||||
.setOnClickBottomListener(new CustomDialog.OnClickBottomListener() {
|
|
||||||
@Override
|
|
||||||
public void onPositiveClick() {
|
|
||||||
dialog.dismiss();
|
|
||||||
File file = new File(path);
|
|
||||||
if (file.delete()) {
|
|
||||||
adapter.removeItem(position);
|
|
||||||
ToastUtil.show("删除成功");
|
|
||||||
} else {
|
|
||||||
ToastUtil.show("删除失败,检查权限是否开启");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNegtiveClick() {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void initActionBar() {
|
|
||||||
setToolbarCustomTheme();
|
|
||||||
//显示返回按钮
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.setHomeButtonEnabled(true);
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
SpannableString spannableString = new SpannableString(getString(R.string.app_name));
|
|
||||||
ForegroundColorSpan colorSpan = new ForegroundColorSpan(getResources().getColor(R.color.defaultColor));
|
|
||||||
spannableString.setSpan(colorSpan, 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
|
||||||
actionBar.setTitle(spannableString);
|
|
||||||
}
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
//自定义颜色返回按钮
|
|
||||||
protected void setToolbarCustomTheme() {
|
|
||||||
Drawable upArrow = ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_material);
|
|
||||||
if (upArrow != null) {
|
|
||||||
upArrow.setColorFilter(ContextCompat.getColor(this, R.color.defaultColor), PorterDuff.Mode.SRC_ATOP);
|
|
||||||
if (getSupportActionBar() != null) {
|
|
||||||
getSupportActionBar().setHomeAsUpIndicator(upArrow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void traverseFolder(String path) {
|
|
||||||
int fileNum = 0, folderNum = 0;
|
|
||||||
File file = new File(path);
|
|
||||||
if (file.exists()) {
|
|
||||||
LinkedList<File> list = new LinkedList<File>();
|
|
||||||
File[] files = file.listFiles();
|
|
||||||
for (File file2 : files) {
|
|
||||||
if (file2.isDirectory()) {
|
|
||||||
Log.e("traverseFolder1", "文件夹:" + file2.getAbsolutePath());
|
|
||||||
list.add(file2);
|
|
||||||
folderNum++;
|
|
||||||
} else {
|
|
||||||
Log.e("traverseFolder1", "文件:" + file2.getAbsolutePath());
|
|
||||||
fileNum++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File temp_file;
|
|
||||||
while (!list.isEmpty()) {
|
|
||||||
temp_file = list.removeFirst();
|
|
||||||
files = temp_file.listFiles();
|
|
||||||
for (File file2 : files) {
|
|
||||||
if (file2.isDirectory()) {
|
|
||||||
Log.e("traverseFolder2", "文件夹:" + file2.getAbsolutePath());
|
|
||||||
list.add(file2);
|
|
||||||
folderNum++;
|
|
||||||
} else {
|
|
||||||
Log.e("traverseFolder2", "文件:" + file2.getAbsolutePath());
|
|
||||||
fileNum++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e("traverseFolder1", "文件不存在!");
|
|
||||||
}
|
|
||||||
Log.e("traverseFolder1", "文件夹共有:" + folderNum + ",文件共有:" + fileNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class ScanTask extends AsyncTask<Void, String, List<String>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<String> doInBackground(Void... voids) {
|
|
||||||
long s1 = System.currentTimeMillis();
|
|
||||||
paths.clear();
|
|
||||||
List<String> fileList = new ArrayList<>();
|
|
||||||
String rootPath = Environment.getExternalStorageDirectory().getPath() + File.separator;
|
|
||||||
File file = new File(rootPath);
|
|
||||||
if (file.exists()) {
|
|
||||||
LinkedList<File> list = new LinkedList<File>();
|
|
||||||
File[] files = file.listFiles();
|
|
||||||
if (files == null) return null;
|
|
||||||
for (File file2 : files) {
|
|
||||||
publishProgress(file2.getAbsolutePath());
|
|
||||||
if (file2.isDirectory()) {
|
|
||||||
list.add(file2);
|
|
||||||
} else {
|
|
||||||
if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
|
||||||
fileList.add(file2.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File temp_file;
|
|
||||||
while (!list.isEmpty()) {
|
|
||||||
temp_file = list.removeFirst();
|
|
||||||
files = temp_file.listFiles();
|
|
||||||
if (files == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (File file2 : files) {
|
|
||||||
publishProgress(file2.getAbsolutePath());
|
|
||||||
if (file2.isDirectory()) {
|
|
||||||
list.add(file2);
|
|
||||||
} else {
|
|
||||||
if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
|
||||||
fileList.add(file2.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e("traverseFolder1", "文件不存在!");
|
|
||||||
}
|
|
||||||
Log.e("ScanTask", "doInBackground: " + "Scan time = " + (System.currentTimeMillis() - s1) + "ms");
|
|
||||||
return fileList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(String... values) {
|
|
||||||
super.onProgressUpdate(values);
|
|
||||||
paths.add(values[0]);
|
|
||||||
tv_scan.setVisibility(View.VISIBLE);
|
|
||||||
tv_scan.setText("正在扫描:" + values[0]);
|
|
||||||
// adapter.setData(paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(List<String> strings) {
|
|
||||||
super.onPostExecute(strings);
|
|
||||||
Log.e("ScanTask", "onPostExecute: " + strings.size());
|
|
||||||
if (strings.size() == 0) {
|
|
||||||
tips.setVisibility(View.VISIBLE);
|
|
||||||
recyclerView.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
tips.setVisibility(View.GONE);
|
|
||||||
recyclerView.setVisibility(View.VISIBLE);
|
|
||||||
// adapter.setData(strings);
|
|
||||||
}
|
|
||||||
tv_scan.setVisibility(View.GONE);
|
|
||||||
refreshLayout.setRefreshing(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkSelfPermission() {
|
|
||||||
List<String> mPermissionList = new ArrayList<>();
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
for (String s : permissions) {
|
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
|
|
||||||
mPermissionList.add(s);
|
|
||||||
} else {
|
|
||||||
// mPresenter.getHomeVideo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
|
|
||||||
ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSION_CODE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -333,7 +129,8 @@ public class MainActivity extends BaseLightActivity implements MainAContact.Main
|
|||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (requestCode == REQUEST_PERMISSION_CODE) {
|
if (requestCode == REQUEST_PERMISSION_CODE) {
|
||||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
mPresenter.getHomeVideo();
|
Log.e("TAG", "onRequestPermissionsResult: ");
|
||||||
|
getThumbnail();
|
||||||
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
|
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
|
||||||
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||||
ToastUtil.show("需要存储空间权限才能正常使用软件");
|
ToastUtil.show("需要存储空间权限才能正常使用软件");
|
||||||
@@ -345,151 +142,187 @@ public class MainActivity extends BaseLightActivity implements MainAContact.Main
|
|||||||
intent.setData(Uri.parse("package:" + this.getPackageName()));
|
intent.setData(Uri.parse("package:" + this.getPackageName()));
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
refreshLayout.setRefreshing(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MenuItem refresh, single_loop, loop;
|
private void checkSelfPermission() {
|
||||||
|
List<String> mPermissionList = new ArrayList<>();
|
||||||
@Override
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
for (String s : permissions) {
|
||||||
getMenuInflater().inflate(R.menu.main, menu);
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
|
||||||
refresh = menu.findItem(R.id.refresh);
|
mPermissionList.add(s);
|
||||||
single_loop = menu.findItem(R.id.single_loop);
|
|
||||||
loop = menu.findItem(R.id.loop);
|
|
||||||
updateMenuIcon();
|
|
||||||
return super.onCreateOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
//返回按钮点击事件
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.setting:
|
|
||||||
|
|
||||||
break;
|
|
||||||
case android.R.id.home:
|
|
||||||
if (System.currentTimeMillis() - mPreClickTime > 1000) {
|
|
||||||
ToastUtil.show("再按一次,退出");
|
|
||||||
mPreClickTime = System.currentTimeMillis();
|
|
||||||
} else {
|
} else {
|
||||||
finish();
|
Log.e("TAG", "checkSelfPermission: ");
|
||||||
|
// mPresenter.getHomeVideo();
|
||||||
|
getThumbnail();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case R.id.refresh:
|
|
||||||
refreshLayout.setRefreshing(true);
|
|
||||||
mPresenter.getHomeVideo();
|
|
||||||
break;
|
|
||||||
case R.id.single_loop:
|
|
||||||
if (null != single_loop) {
|
|
||||||
int singleLoop = (int) SPUtils.get(MainActivity.this, "single_loop", 0);
|
|
||||||
if (singleLoop == 0) {
|
|
||||||
SPUtils.put(MainActivity.this, "single_loop", 1);
|
|
||||||
SPUtils.put(MainActivity.this, "loop", 0);
|
|
||||||
single_loop.setIcon(R.drawable.menu_selected);
|
|
||||||
} else {
|
|
||||||
SPUtils.put(MainActivity.this, "single_loop", 0);
|
|
||||||
single_loop.setIcon(R.drawable.menu_transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case R.id.loop:
|
|
||||||
if (null != loop) {
|
|
||||||
int singleLoop = (int) SPUtils.get(MainActivity.this, "loop", 0);
|
|
||||||
if (singleLoop == 0) {
|
|
||||||
SPUtils.put(MainActivity.this, "single_loop", 0);
|
|
||||||
SPUtils.put(MainActivity.this, "loop", 1);
|
|
||||||
loop.setIcon(R.drawable.menu_selected);
|
|
||||||
} else {
|
|
||||||
SPUtils.put(MainActivity.this, "loop", 0);
|
|
||||||
loop.setIcon(R.drawable.menu_transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
updateMenuIcon();
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private long mPreClickTime;
|
|
||||||
|
|
||||||
private void updateMenuIcon() {
|
|
||||||
if (null != refresh) {
|
|
||||||
|
|
||||||
}
|
|
||||||
if (null != single_loop) {
|
|
||||||
int singleLoop = (int) SPUtils.get(MainActivity.this, "single_loop", 0);
|
|
||||||
if (singleLoop == 0) {
|
|
||||||
single_loop.setIcon(R.drawable.menu_transparent);
|
|
||||||
} else {
|
|
||||||
single_loop.setIcon(R.drawable.menu_selected);
|
|
||||||
}
|
}
|
||||||
}
|
if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
|
||||||
if (null != loop) {
|
ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSION_CODE);
|
||||||
int singleLoop = (int) SPUtils.get(MainActivity.this, "loop", 0);
|
|
||||||
if (singleLoop == 0) {
|
|
||||||
loop.setIcon(R.drawable.menu_transparent);
|
|
||||||
} else {
|
|
||||||
loop.setIcon(R.drawable.menu_selected);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void getThumbnail() {
|
||||||
public void setHomeVideo(ArrayList<LocalVideoInfo> video) {
|
long s1 = System.currentTimeMillis();
|
||||||
if (video == null || video.size() == 0) {
|
List<String> picFileList = new ArrayList<>();
|
||||||
tips.setVisibility(View.VISIBLE);
|
List<String> videoFileList = new ArrayList<>();
|
||||||
recyclerView.setVisibility(View.GONE);
|
String rootPath = JGYUtils.getInstance().getDownLoadPath() + File.separator;
|
||||||
|
File file = new File(rootPath);
|
||||||
|
if (file.exists()) {
|
||||||
|
LinkedList<File> list = new LinkedList<File>();
|
||||||
|
File[] files = file.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (File file2 : files) {
|
||||||
|
if (file2.isDirectory()) {
|
||||||
|
list.add(file2);
|
||||||
|
} else {
|
||||||
|
if (VideoUtils.isPicFormat(file2.getAbsolutePath())) {
|
||||||
|
picFileList.add(file2.getAbsolutePath());
|
||||||
|
} else if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
||||||
|
videoFileList.add(file2.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File temp_file;
|
||||||
|
while (!list.isEmpty()) {
|
||||||
|
temp_file = list.removeFirst();
|
||||||
|
files = temp_file.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (File file2 : files) {
|
||||||
|
if (file2.isDirectory()) {
|
||||||
|
list.add(file2);
|
||||||
|
} else {
|
||||||
|
if (VideoUtils.isPicFormat(file2.getAbsolutePath())) {
|
||||||
|
picFileList.add(file2.getAbsolutePath());
|
||||||
|
} else if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
||||||
|
videoFileList.add(file2.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tips.setVisibility(View.GONE);
|
Log.e("traverseFolder1", "文件不存在!");
|
||||||
recyclerView.setVisibility(View.VISIBLE);
|
|
||||||
adapter.setData(video);
|
|
||||||
}
|
}
|
||||||
tv_scan.setVisibility(View.GONE);
|
Log.e("ScanTask", "doInBackground: " + "Scan time = " + (System.currentTimeMillis() - s1) + "ms");
|
||||||
refreshLayout.setRefreshing(false);
|
Log.e("getThumbnail", "picFileList: " + picFileList);
|
||||||
}
|
Log.e("getThumbnail", "videoFileList: " + videoFileList);
|
||||||
|
Log.e("getThumbnail", "picFileList size = " + picFileList.size());
|
||||||
|
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||||
|
if (picFileList.size() == 0) {
|
||||||
|
nv_pic.setImageDrawable(getDrawable(R.drawable.icon_pic));
|
||||||
|
} else {
|
||||||
|
nv_pic.setImageDrawable(path2Drawable(picFileList.get(0)));
|
||||||
|
}
|
||||||
|
if (videoFileList.size() == 0) {
|
||||||
|
nv_video.setImageDrawable(getDrawable(R.drawable.icon_video));
|
||||||
|
} else {
|
||||||
|
Observable.create(new ObservableOnSubscribe<Bitmap>() {
|
||||||
|
@Override
|
||||||
|
public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
|
||||||
|
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
|
||||||
|
mmr.setDataSource(videoFileList.get(0));
|
||||||
|
Bitmap bitmap = mmr.getFrameAtTime();//获得视频第一帧的Bitmap对象.
|
||||||
|
mmr.release();
|
||||||
|
emitter.onNext(bitmap);
|
||||||
|
}
|
||||||
|
}).subscribeOn(Schedulers.newThread())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Observer<Bitmap>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(Disposable d) {
|
||||||
|
Log.e("VideoResult", "onSubscribe: ");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getHomeVideoFinish() {
|
public void onNext(Bitmap result) {
|
||||||
refreshLayout.setRefreshing(false);
|
Log.e("VideoResult", "onNext: " + result);
|
||||||
|
nv_video.setImageBitmap(result);
|
||||||
|
// Glide.with(nv_video).load(result).error(R.drawable.icon_video).into(nv_video);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
Log.e("VideoResult", "onError: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
Log.e("VideoResult", "onComplete: ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||||
|
// CombineBitmap.init(this)
|
||||||
|
// .setLayoutManager(new DingLayoutManager()) // 必选, 设置图片的组合形式,支持WechatLayoutManager、DingLayoutManager
|
||||||
|
// .setSize(100) // 必选,组合后Bitmap的尺寸,单位dp
|
||||||
|
// .setGap(1) // 单个图片之间的距离,单位dp,默认0dp
|
||||||
|
//// .setGapColor() // 单个图片间距的颜色,默认白色
|
||||||
|
//// .setPlaceholder() // 单个图片加载失败的默认显示图片
|
||||||
|
// .setUrls(picFileList.toArray(new String[picFileList.size()])) // 要加载的图片url数组
|
||||||
|
// .setBitmaps() // 要加载的图片bitmap数组
|
||||||
|
// .setResourceIds() // 要加载的图片资源id数组
|
||||||
|
// .setImageView(nv_pic) // 直接设置要显示图片的ImageView
|
||||||
|
// // 设置“子图片”的点击事件,需使用setImageView(),index和图片资源数组的索引对应
|
||||||
|
//// .setOnSubItemClickListener(new OnSubItemClickListener() {
|
||||||
|
//// @Override
|
||||||
|
//// public void onSubItemClick(int index) {
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
//// })
|
||||||
|
//// // 加载进度的回调函数,如果不使用setImageView()方法,可在onComplete()完成最终图片的显示
|
||||||
|
//// .setProgressListener(new ProgressListener() {
|
||||||
|
//// @Override
|
||||||
|
//// public void onStart() {
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// @Override
|
||||||
|
//// public void onComplete(Bitmap bitmap) {
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
//// })
|
||||||
|
// .build();
|
||||||
|
|
||||||
|
// CombineBitmap.init(this)
|
||||||
|
// .setLayoutManager(new DingLayoutManager()) // 必选, 设置图片的组合形式,支持WechatLayoutManager、DingLayoutManager
|
||||||
|
// .setSize(100) // 必选,组合后Bitmap的尺寸,单位dp
|
||||||
|
// .setGap(1) // 单个图片之间的距离,单位dp,默认0dp
|
||||||
|
//// .setGapColor() // 单个图片间距的颜色,默认白色
|
||||||
|
//// .setPlaceholder() // 单个图片加载失败的默认显示图片
|
||||||
|
// .setUrls(videoFileList.toArray(new String[videoFileList.size()])) // 要加载的图片url数组
|
||||||
|
// .setBitmaps() // 要加载的图片bitmap数组
|
||||||
|
// .setResourceIds() // 要加载的图片资源id数组
|
||||||
|
// .setImageView(nv_video) // 直接设置要显示图片的ImageView
|
||||||
|
// .build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//在这里处理任务执行中的状态,如进度进度条的刷新
|
/**
|
||||||
@Download.onTaskRunning
|
* 将本地图片转换为 Drawable
|
||||||
void running(DownloadTask task) {
|
*
|
||||||
Log.e("aria running", "正在下载:" + task.getState() + "-" + task.getPercent() + "--" + task.getExtendField());
|
* @param file 文件路径
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Drawable path2Drawable(String file) {
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Drawable drawable = null;
|
||||||
try {
|
try {
|
||||||
String jsonString = task.getExtendField();
|
FileInputStream fis = new FileInputStream(file);
|
||||||
JsonObject jsonObject = GsonUtils.getJsonObject(jsonString);
|
Bitmap bitmap = BitmapFactory.decodeStream(fis);
|
||||||
} catch (Exception e) {
|
drawable = new BitmapDrawable(getResources(), bitmap);
|
||||||
Log.e("running", "running: " + e.getMessage());
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Download.onTaskComplete
|
return drawable;
|
||||||
void taskComplete(DownloadTask task) {
|
|
||||||
//在这里处理任务完成的状态
|
|
||||||
Log.e("taskComplete", task.getExtendField());
|
|
||||||
// Aria.download(this).load(task.getDownloadEntity().getId()).cancel();
|
|
||||||
mPresenter.getHomeVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Download.onTaskFail
|
|
||||||
void taskFail(DownloadTask task, Exception e) {
|
|
||||||
Aria.download(this).resumeAllTask();
|
|
||||||
final String filepath = task.getFilePath();
|
|
||||||
final String packageName = task.getExtendField();
|
|
||||||
try {
|
|
||||||
Aria.download(this).load(task.getDownloadEntity().getId()).cancel(true);
|
|
||||||
Log.e(TAG, "taskFail: " + "Exception: " + e.getLocalizedMessage());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
|
|
||||||
}
|
|
||||||
Log.e(TAG, "taskFail: " + packageName + "filepath: " + filepath);
|
|
||||||
mPresenter.getHomeVideo();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.uiui.videoplayer.activity.pic;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.uiui.videoplayer.R;
|
||||||
|
import com.uiui.videoplayer.adapter.PicAdapter;
|
||||||
|
import com.uiui.videoplayer.base.BGAGridDivider;
|
||||||
|
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||||
|
import com.uiui.videoplayer.base.GridSpaceItemDecoration;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
|
public class GalleryActivity extends BaseLightActivity implements GalleryContact.GalleryView {
|
||||||
|
|
||||||
|
@BindView(R.id.swipeRefreshLayout)
|
||||||
|
SwipeRefreshLayout swipeRefreshLayout;
|
||||||
|
@BindView(R.id.recyclerView)
|
||||||
|
RecyclerView recyclerView;
|
||||||
|
@BindView(R.id.iv_back)
|
||||||
|
ImageView iv_back;
|
||||||
|
|
||||||
|
private GalleryPresenter mPresenter;
|
||||||
|
private PicAdapter mPicAdapter;
|
||||||
|
private static final int SPAN_COUNT = 3;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLayoutId() {
|
||||||
|
return R.layout.activity_gallery;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initView() {
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
mPresenter = new GalleryPresenter(this);
|
||||||
|
mPresenter.setLifecycle(lifecycleSubject);
|
||||||
|
mPresenter.attachView(this);
|
||||||
|
|
||||||
|
GridLayoutManager layoutManager = new GridLayoutManager(this, SPAN_COUNT, LinearLayoutManager.VERTICAL, false);
|
||||||
|
mPicAdapter = new PicAdapter(layoutManager);
|
||||||
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
recyclerView.addItemDecoration(BGAGridDivider.newInstanceWithSpaceRes(R.dimen.dp_2));
|
||||||
|
recyclerView.setAdapter(mPicAdapter);
|
||||||
|
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
swipeRefreshLayout.setRefreshing(true);
|
||||||
|
mPresenter.getHomePhoto();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
iv_back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initData() {
|
||||||
|
mPresenter.getHomePhoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHomePhoto(ArrayList<PhotoInfo> photoInfos) {
|
||||||
|
mPicAdapter.setPhotoInfos(photoInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getHomePhotoFinish() {
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.uiui.videoplayer.activity.pic;
|
||||||
|
|
||||||
|
import com.uiui.videoplayer.base.BasePresenter;
|
||||||
|
import com.uiui.videoplayer.base.BaseView;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GalleryContact {
|
||||||
|
interface Presenter extends BasePresenter<GalleryView> {
|
||||||
|
/*获取视频*/
|
||||||
|
void getHomePhoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface GalleryView extends BaseView {
|
||||||
|
void setHomePhoto(ArrayList<PhotoInfo> photoInfos);
|
||||||
|
void getHomePhotoFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.uiui.videoplayer.activity.pic;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.trello.rxlifecycle4.RxLifecycle;
|
||||||
|
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||||
|
import com.uiui.videoplayer.bean.BaseResponse;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
|
import com.uiui.videoplayer.network.NetInterfaceManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.annotations.NonNull;
|
||||||
|
import io.reactivex.rxjava3.core.Observer;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||||
|
|
||||||
|
public class GalleryPresenter implements GalleryContact.Presenter {
|
||||||
|
|
||||||
|
private GalleryContact.GalleryView mView;
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
public GalleryPresenter(Context context) {
|
||||||
|
this.mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BehaviorSubject<ActivityEvent> lifecycle;
|
||||||
|
|
||||||
|
public void setLifecycle(BehaviorSubject<ActivityEvent> lifecycle) {
|
||||||
|
this.lifecycle = lifecycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BehaviorSubject<ActivityEvent> getLifecycle() {
|
||||||
|
return lifecycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attachView(GalleryContact.GalleryView view) {
|
||||||
|
this.mView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void detachView() {
|
||||||
|
this.mView = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getHomePhoto() {
|
||||||
|
NetInterfaceManager.getInstance().getHomePhoto(true, getLifecycle(), new NetInterfaceManager.onPhotoCallback() {
|
||||||
|
@Override
|
||||||
|
public void setPhotoList(ArrayList<PhotoInfo> photoList) {
|
||||||
|
mView.setHomePhoto(photoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
mView.getHomePhotoFinish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.uiui.videoplayer.activity.preview;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.uiui.videoplayer.R;
|
||||||
|
import com.uiui.videoplayer.adapter.PreviewAdapter;
|
||||||
|
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||||
|
import com.uiui.videoplayer.base.ScaleCircleNavigator;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
|
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.MagicIndicator;
|
||||||
|
import net.lucode.hackware.magicindicator.ViewPagerHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
|
public class PreviewActivity extends BaseLightActivity {
|
||||||
|
|
||||||
|
@BindView(R.id.viewPager)
|
||||||
|
ViewPager viewPager;
|
||||||
|
@BindView(R.id.magicIndicator)
|
||||||
|
MagicIndicator mMagicIndicator;
|
||||||
|
|
||||||
|
private PreviewAdapter mPreviewAdapter;
|
||||||
|
private ScaleCircleNavigator scaleCircleNavigator;
|
||||||
|
private ArrayList<PhotoInfo> mPhotoInfos;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLayoutId() {
|
||||||
|
return R.layout.activity_preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initView() {
|
||||||
|
UltimateBarX.statusBar(this)
|
||||||
|
.transparent()
|
||||||
|
.fitWindow(false)
|
||||||
|
.light(true)
|
||||||
|
.apply();
|
||||||
|
UltimateBarX.navigationBar(this)
|
||||||
|
.transparent()
|
||||||
|
.light(true)
|
||||||
|
.apply();
|
||||||
|
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
mPreviewAdapter = new PreviewAdapter();
|
||||||
|
viewPager.setAdapter(mPreviewAdapter);
|
||||||
|
scaleCircleNavigator = new ScaleCircleNavigator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initData() {
|
||||||
|
Intent intent = getIntent();
|
||||||
|
Bundle bundle = intent.getExtras();
|
||||||
|
if (bundle == null) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ArrayList<PhotoInfo> photoInfos = bundle.getParcelableArrayList("mPhotoInfos");
|
||||||
|
if (photoInfos == null) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int position = bundle.getInt("position");
|
||||||
|
setImageViews(photoInfos);
|
||||||
|
viewPager.setCurrentItem(position);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setImageViews(List<PhotoInfo> photoInfos) {
|
||||||
|
mMagicIndicator.setNavigator(scaleCircleNavigator);
|
||||||
|
scaleCircleNavigator.setCircleCount(photoInfos.size());
|
||||||
|
scaleCircleNavigator.setNormalCircleColor(Color.DKGRAY);
|
||||||
|
scaleCircleNavigator.setSelectedCircleColor(Color.LTGRAY);
|
||||||
|
scaleCircleNavigator.setCircleClickListener(new ScaleCircleNavigator.OnCircleClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(int index) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ViewPagerHelper.bind(mMagicIndicator, viewPager);
|
||||||
|
List<ImageView> imageViews = new ArrayList<>();
|
||||||
|
for (PhotoInfo photoInfo : photoInfos) {
|
||||||
|
ImageView image = new ImageView(this);
|
||||||
|
image.setAdjustViewBounds(true);
|
||||||
|
image.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||||
|
Glide.with(this).load(photoInfo.getFile()).into(image);
|
||||||
|
imageViews.add(image);
|
||||||
|
}
|
||||||
|
mPreviewAdapter.setImageViews(imageViews);
|
||||||
|
mPreviewAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,459 @@
|
|||||||
|
package com.uiui.videoplayer.activity.video;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.Spanned;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
|
import com.arialyy.annotations.Download;
|
||||||
|
import com.arialyy.aria.core.Aria;
|
||||||
|
import com.arialyy.aria.core.task.DownloadTask;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.uiui.videoplayer.R;
|
||||||
|
import com.uiui.videoplayer.adapter.VideoAdapter;
|
||||||
|
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||||
|
import com.uiui.videoplayer.base.CustomDialog;
|
||||||
|
import com.uiui.videoplayer.base.RecycleGridLayoutManager;
|
||||||
|
import com.uiui.videoplayer.base.SpacesItemDecoration;
|
||||||
|
import com.uiui.videoplayer.bean.LocalVideoInfo;
|
||||||
|
import com.uiui.videoplayer.gson.GsonUtils;
|
||||||
|
import com.uiui.videoplayer.utils.SPUtils;
|
||||||
|
import com.uiui.videoplayer.utils.ToastUtil;
|
||||||
|
import com.uiui.videoplayer.utils.VideoUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
|
public class VideoActivity extends BaseLightActivity implements VideoContact.VideoView {
|
||||||
|
|
||||||
|
private static final String TAG = VideoActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
@BindView(R.id.recyclerView)
|
||||||
|
RecyclerView recyclerView;
|
||||||
|
@BindView(R.id.cl_nodata)
|
||||||
|
ConstraintLayout cl_nodata;
|
||||||
|
@BindView(R.id.tv_scan)
|
||||||
|
TextView tv_scan;
|
||||||
|
@BindView(R.id.swipeRefreshLayout)
|
||||||
|
SwipeRefreshLayout refreshLayout;
|
||||||
|
@BindView(R.id.iv_back)
|
||||||
|
ImageView iv_back;
|
||||||
|
|
||||||
|
private VideoPresenter mPresenter;
|
||||||
|
private List<String> paths = new ArrayList<>();
|
||||||
|
private RecycleGridLayoutManager mManager;
|
||||||
|
private VideoAdapter adapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initView() {
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
mPresenter = new VideoPresenter(this);
|
||||||
|
mPresenter.setLifecycle(lifecycleSubject);
|
||||||
|
mPresenter.attachView(this);
|
||||||
|
|
||||||
|
Aria.download(this).register();
|
||||||
|
|
||||||
|
// initActionBar();
|
||||||
|
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
mPresenter.getHomeVideo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
refreshLayout.setRefreshing(true);
|
||||||
|
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||||
|
int orientation = getResources().getConfiguration().orientation;
|
||||||
|
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
mManager = new RecycleGridLayoutManager(VideoActivity.this, 3);
|
||||||
|
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
|
mManager = new RecycleGridLayoutManager(VideoActivity.this, 2);
|
||||||
|
}
|
||||||
|
recyclerView.setLayoutManager(mManager);
|
||||||
|
recyclerView.setNestedScrollingEnabled(false);
|
||||||
|
recyclerView.addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x),
|
||||||
|
getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x)));
|
||||||
|
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||||
|
adapter = new VideoAdapter(VideoActivity.this);
|
||||||
|
adapter.setOnLongClickListener(new VideoAdapter.onItemLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemLongClick(String path, int position) {
|
||||||
|
showDialog(path, position);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
iv_back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initData() {
|
||||||
|
mPresenter.getHomeVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLayoutId() {
|
||||||
|
return R.layout.activity_video;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
Configuration config = getResources().getConfiguration();
|
||||||
|
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
mManager = new RecycleGridLayoutManager(VideoActivity.this, 2);
|
||||||
|
recyclerView.setLayoutManager(mManager);
|
||||||
|
}
|
||||||
|
if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
|
mManager = new RecycleGridLayoutManager(VideoActivity.this, 3);
|
||||||
|
recyclerView.setLayoutManager(mManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialog(String path, int position) {
|
||||||
|
CustomDialog dialog = new CustomDialog(VideoActivity.this);
|
||||||
|
dialog.setTitle("删除文件")
|
||||||
|
.setMessage("确定要删除文件 " + VideoUtils.getFileNameWithoutExtension(path) + "吗")
|
||||||
|
.setPositive("确定")
|
||||||
|
.setNegtive("取消")
|
||||||
|
.setOnClickBottomListener(new CustomDialog.OnClickBottomListener() {
|
||||||
|
@Override
|
||||||
|
public void onPositiveClick() {
|
||||||
|
dialog.dismiss();
|
||||||
|
File file = new File(path);
|
||||||
|
if (file.delete()) {
|
||||||
|
adapter.removeItem(position);
|
||||||
|
ToastUtil.show("删除成功");
|
||||||
|
} else {
|
||||||
|
ToastUtil.show("删除失败,检查权限是否开启");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNegtiveClick() {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initActionBar() {
|
||||||
|
setToolbarCustomTheme();
|
||||||
|
//显示返回按钮
|
||||||
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setHomeButtonEnabled(true);
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
SpannableString spannableString = new SpannableString(getString(R.string.app_name));
|
||||||
|
ForegroundColorSpan colorSpan = new ForegroundColorSpan(getResources().getColor(R.color.defaultColor));
|
||||||
|
spannableString.setSpan(colorSpan, 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
|
actionBar.setTitle(spannableString);
|
||||||
|
}
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
//自定义颜色返回按钮
|
||||||
|
protected void setToolbarCustomTheme() {
|
||||||
|
Drawable upArrow = ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_material);
|
||||||
|
if (upArrow != null) {
|
||||||
|
upArrow.setColorFilter(ContextCompat.getColor(this, R.color.defaultColor), PorterDuff.Mode.SRC_ATOP);
|
||||||
|
if (getSupportActionBar() != null) {
|
||||||
|
getSupportActionBar().setHomeAsUpIndicator(upArrow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void traverseFolder(String path) {
|
||||||
|
int fileNum = 0, folderNum = 0;
|
||||||
|
File file = new File(path);
|
||||||
|
if (file.exists()) {
|
||||||
|
LinkedList<File> list = new LinkedList<File>();
|
||||||
|
File[] files = file.listFiles();
|
||||||
|
for (File file2 : files) {
|
||||||
|
if (file2.isDirectory()) {
|
||||||
|
Log.e("traverseFolder1", "文件夹:" + file2.getAbsolutePath());
|
||||||
|
list.add(file2);
|
||||||
|
folderNum++;
|
||||||
|
} else {
|
||||||
|
Log.e("traverseFolder1", "文件:" + file2.getAbsolutePath());
|
||||||
|
fileNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File temp_file;
|
||||||
|
while (!list.isEmpty()) {
|
||||||
|
temp_file = list.removeFirst();
|
||||||
|
files = temp_file.listFiles();
|
||||||
|
for (File file2 : files) {
|
||||||
|
if (file2.isDirectory()) {
|
||||||
|
Log.e("traverseFolder2", "文件夹:" + file2.getAbsolutePath());
|
||||||
|
list.add(file2);
|
||||||
|
folderNum++;
|
||||||
|
} else {
|
||||||
|
Log.e("traverseFolder2", "文件:" + file2.getAbsolutePath());
|
||||||
|
fileNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("traverseFolder1", "文件不存在!");
|
||||||
|
}
|
||||||
|
Log.e("traverseFolder1", "文件夹共有:" + folderNum + ",文件共有:" + fileNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ScanTask extends AsyncTask<Void, String, List<String>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> doInBackground(Void... voids) {
|
||||||
|
long s1 = System.currentTimeMillis();
|
||||||
|
paths.clear();
|
||||||
|
List<String> fileList = new ArrayList<>();
|
||||||
|
String rootPath = Environment.getExternalStorageDirectory().getPath() + File.separator;
|
||||||
|
File file = new File(rootPath);
|
||||||
|
if (file.exists()) {
|
||||||
|
LinkedList<File> list = new LinkedList<File>();
|
||||||
|
File[] files = file.listFiles();
|
||||||
|
if (files == null) return null;
|
||||||
|
for (File file2 : files) {
|
||||||
|
publishProgress(file2.getAbsolutePath());
|
||||||
|
if (file2.isDirectory()) {
|
||||||
|
list.add(file2);
|
||||||
|
} else {
|
||||||
|
if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
||||||
|
fileList.add(file2.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File temp_file;
|
||||||
|
while (!list.isEmpty()) {
|
||||||
|
temp_file = list.removeFirst();
|
||||||
|
files = temp_file.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (File file2 : files) {
|
||||||
|
publishProgress(file2.getAbsolutePath());
|
||||||
|
if (file2.isDirectory()) {
|
||||||
|
list.add(file2);
|
||||||
|
} else {
|
||||||
|
if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
||||||
|
fileList.add(file2.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("traverseFolder1", "文件不存在!");
|
||||||
|
}
|
||||||
|
Log.e("ScanTask", "doInBackground: " + "Scan time = " + (System.currentTimeMillis() - s1) + "ms");
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProgressUpdate(String... values) {
|
||||||
|
super.onProgressUpdate(values);
|
||||||
|
paths.add(values[0]);
|
||||||
|
tv_scan.setVisibility(View.VISIBLE);
|
||||||
|
tv_scan.setText("正在扫描:" + values[0]);
|
||||||
|
// adapter.setData(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(List<String> strings) {
|
||||||
|
super.onPostExecute(strings);
|
||||||
|
Log.e("ScanTask", "onPostExecute: " + strings.size());
|
||||||
|
if (strings.size() == 0) {
|
||||||
|
cl_nodata.setVisibility(View.VISIBLE);
|
||||||
|
recyclerView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
cl_nodata.setVisibility(View.GONE);
|
||||||
|
recyclerView.setVisibility(View.VISIBLE);
|
||||||
|
// adapter.setData(strings);
|
||||||
|
}
|
||||||
|
tv_scan.setVisibility(View.GONE);
|
||||||
|
refreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MenuItem refresh, single_loop, loop;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.main, menu);
|
||||||
|
refresh = menu.findItem(R.id.refresh);
|
||||||
|
single_loop = menu.findItem(R.id.single_loop);
|
||||||
|
loop = menu.findItem(R.id.loop);
|
||||||
|
updateMenuIcon();
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
//返回按钮点击事件
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.setting:
|
||||||
|
|
||||||
|
break;
|
||||||
|
case android.R.id.home:
|
||||||
|
if (System.currentTimeMillis() - mPreClickTime > 1000) {
|
||||||
|
ToastUtil.show("再按一次,退出");
|
||||||
|
mPreClickTime = System.currentTimeMillis();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R.id.refresh:
|
||||||
|
refreshLayout.setRefreshing(true);
|
||||||
|
mPresenter.getHomeVideo();
|
||||||
|
break;
|
||||||
|
case R.id.single_loop:
|
||||||
|
if (null != single_loop) {
|
||||||
|
int singleLoop = (int) SPUtils.get(VideoActivity.this, "single_loop", 0);
|
||||||
|
if (singleLoop == 0) {
|
||||||
|
SPUtils.put(VideoActivity.this, "single_loop", 1);
|
||||||
|
SPUtils.put(VideoActivity.this, "loop", 0);
|
||||||
|
single_loop.setIcon(R.drawable.menu_selected);
|
||||||
|
} else {
|
||||||
|
SPUtils.put(VideoActivity.this, "single_loop", 0);
|
||||||
|
single_loop.setIcon(R.drawable.menu_transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R.id.loop:
|
||||||
|
if (null != loop) {
|
||||||
|
int singleLoop = (int) SPUtils.get(VideoActivity.this, "loop", 0);
|
||||||
|
if (singleLoop == 0) {
|
||||||
|
SPUtils.put(VideoActivity.this, "single_loop", 0);
|
||||||
|
SPUtils.put(VideoActivity.this, "loop", 1);
|
||||||
|
loop.setIcon(R.drawable.menu_selected);
|
||||||
|
} else {
|
||||||
|
SPUtils.put(VideoActivity.this, "loop", 0);
|
||||||
|
loop.setIcon(R.drawable.menu_transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
updateMenuIcon();
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long mPreClickTime;
|
||||||
|
|
||||||
|
private void updateMenuIcon() {
|
||||||
|
if (null != refresh) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (null != single_loop) {
|
||||||
|
int singleLoop = (int) SPUtils.get(VideoActivity.this, "single_loop", 0);
|
||||||
|
if (singleLoop == 0) {
|
||||||
|
single_loop.setIcon(R.drawable.menu_transparent);
|
||||||
|
} else {
|
||||||
|
single_loop.setIcon(R.drawable.menu_selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null != loop) {
|
||||||
|
int singleLoop = (int) SPUtils.get(VideoActivity.this, "loop", 0);
|
||||||
|
if (singleLoop == 0) {
|
||||||
|
loop.setIcon(R.drawable.menu_transparent);
|
||||||
|
} else {
|
||||||
|
loop.setIcon(R.drawable.menu_selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHomeVideo(ArrayList<LocalVideoInfo> video) {
|
||||||
|
if (video == null || video.size() == 0) {
|
||||||
|
cl_nodata.setVisibility(View.VISIBLE);
|
||||||
|
recyclerView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
cl_nodata.setVisibility(View.GONE);
|
||||||
|
recyclerView.setVisibility(View.VISIBLE);
|
||||||
|
adapter.setData(video);
|
||||||
|
}
|
||||||
|
tv_scan.setVisibility(View.GONE);
|
||||||
|
refreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getHomeVideoFinish() {
|
||||||
|
refreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//在这里处理任务执行中的状态,如进度进度条的刷新
|
||||||
|
@Download.onTaskRunning
|
||||||
|
void running(DownloadTask task) {
|
||||||
|
Log.e("aria running", "正在下载:" + task.getState() + "-" + task.getPercent() + "--" + task.getExtendField());
|
||||||
|
try {
|
||||||
|
String jsonString = task.getExtendField();
|
||||||
|
JsonObject jsonObject = GsonUtils.getJsonObject(jsonString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("running", "running: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Download.onTaskComplete
|
||||||
|
void taskComplete(DownloadTask task) {
|
||||||
|
//在这里处理任务完成的状态
|
||||||
|
Log.e("taskComplete", task.getExtendField());
|
||||||
|
// Aria.download(this).load(task.getDownloadEntity().getId()).cancel();
|
||||||
|
mPresenter.getHomeVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Download.onTaskFail
|
||||||
|
void taskFail(DownloadTask task, Exception e) {
|
||||||
|
Aria.download(this).resumeAllTask();
|
||||||
|
final String filepath = task.getFilePath();
|
||||||
|
final String packageName = task.getExtendField();
|
||||||
|
try {
|
||||||
|
Aria.download(this).load(task.getDownloadEntity().getId()).cancel(true);
|
||||||
|
Log.e(TAG, "taskFail: " + "Exception: " + e.getLocalizedMessage());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
Log.e(TAG, "taskFail: " + packageName + "filepath: " + filepath);
|
||||||
|
mPresenter.getHomeVideo();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.uiui.videoplayer.activity.main;
|
package com.uiui.videoplayer.activity.video;
|
||||||
|
|
||||||
import com.uiui.videoplayer.base.BasePresenter;
|
import com.uiui.videoplayer.base.BasePresenter;
|
||||||
import com.uiui.videoplayer.base.BaseView;
|
import com.uiui.videoplayer.base.BaseView;
|
||||||
@@ -6,13 +6,13 @@ import com.uiui.videoplayer.bean.LocalVideoInfo;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class MainAContact {
|
public class VideoContact {
|
||||||
interface Presenter extends BasePresenter<MainView> {
|
interface Presenter extends BasePresenter<VideoView> {
|
||||||
/*获取视频*/
|
/*获取视频*/
|
||||||
void getHomeVideo();
|
void getHomeVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface MainView extends BaseView {
|
public interface VideoView extends BaseView {
|
||||||
void setHomeVideo(ArrayList<LocalVideoInfo> video);
|
void setHomeVideo(ArrayList<LocalVideoInfo> video);
|
||||||
void getHomeVideoFinish();
|
void getHomeVideoFinish();
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.uiui.videoplayer.activity.main;
|
package com.uiui.videoplayer.activity.video;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
@@ -14,14 +14,14 @@ import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
|||||||
/**
|
/**
|
||||||
* @author jgy02
|
* @author jgy02
|
||||||
*/
|
*/
|
||||||
public class MainAPresenter implements MainAContact.Presenter {
|
public class VideoPresenter implements VideoContact.Presenter {
|
||||||
private static final String TAG = MainAPresenter.class.getSimpleName();
|
private static final String TAG = VideoPresenter.class.getSimpleName();
|
||||||
|
|
||||||
private MainAContact.MainView mView;
|
private VideoContact.VideoView mView;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private CacheHelper mCacheHelper;
|
private CacheHelper mCacheHelper;
|
||||||
|
|
||||||
public MainAPresenter(Context context) {
|
public VideoPresenter(Context context) {
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
this.mCacheHelper = new CacheHelper(context);
|
this.mCacheHelper = new CacheHelper(context);
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ public class MainAPresenter implements MainAContact.Presenter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attachView(MainAContact.MainView view) {
|
public void attachView(VideoContact.VideoView view) {
|
||||||
this.mView = view;
|
this.mView = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
104
app/src/main/java/com/uiui/videoplayer/adapter/PicAdapter.java
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package com.uiui.videoplayer.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.uiui.videoplayer.R;
|
||||||
|
import com.uiui.videoplayer.activity.preview.PreviewActivity;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
|
import com.uiui.videoplayer.gson.GsonUtils;
|
||||||
|
import com.uiui.videoplayer.utils.JGYUtils;
|
||||||
|
import com.uiui.videoplayer.utils.VideoUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PicAdapter extends RecyclerView.Adapter<PicAdapter.Holder> {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private GridLayoutManager mGridLayoutManager;
|
||||||
|
private ArrayList<PhotoInfo> mPhotoInfos;
|
||||||
|
|
||||||
|
public PicAdapter(GridLayoutManager gridLayoutManager) {
|
||||||
|
this.mGridLayoutManager = gridLayoutManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
mContext = parent.getContext();
|
||||||
|
Holder holder = new Holder(LayoutInflater.from(mContext).inflate(R.layout.item_pic, parent, false));
|
||||||
|
ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
|
||||||
|
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) holder.iv_pic.getLayoutParams();
|
||||||
|
//动态计算,设置item的宽高一致,总宽度-左右margin-左右padding /总列数-item左右margin-item左右padding
|
||||||
|
params.height =
|
||||||
|
(mGridLayoutManager.getWidth() - layoutParams.leftMargin
|
||||||
|
- layoutParams.rightMargin - holder.iv_pic.getPaddingStart() - holder.iv_pic.getPaddingEnd()) / mGridLayoutManager.getSpanCount()
|
||||||
|
- 2 * holder.itemView.getPaddingLeft() - 2 * ((ViewGroup.MarginLayoutParams) params).leftMargin;
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull Holder holder, int position) {
|
||||||
|
PhotoInfo photoInfo = mPhotoInfos.get(position);
|
||||||
|
String fileName = photoInfo.getFile_name();
|
||||||
|
String fileUrl = photoInfo.getFile();
|
||||||
|
if (TextUtils.isEmpty(fileName)) {
|
||||||
|
holder.tv_name.setText(VideoUtils.getFileNameWithoutExtension(fileUrl));
|
||||||
|
} else {
|
||||||
|
holder.tv_name.setText(fileName);
|
||||||
|
}
|
||||||
|
if (!JGYUtils.getInstance().fileExists(photoInfo.getFile())) {
|
||||||
|
Glide.with(mContext).load(fileUrl).into(holder.iv_pic);
|
||||||
|
} else {
|
||||||
|
Glide.with(mContext).load(JGYUtils.getInstance().getUrlLocalPath(photoInfo.getFile())).into(holder.iv_pic);
|
||||||
|
}
|
||||||
|
holder.root.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(mContext, PreviewActivity.class);
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putParcelableArrayList("mPhotoInfos", mPhotoInfos);
|
||||||
|
bundle.putInt("position", position);
|
||||||
|
intent.putExtras(bundle);
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mPhotoInfos == null ? 0 : mPhotoInfos.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhotoInfos(ArrayList<PhotoInfo> photoInfos) {
|
||||||
|
this.mPhotoInfos = photoInfos;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Holder extends RecyclerView.ViewHolder {
|
||||||
|
ConstraintLayout root;
|
||||||
|
ImageView iv_pic;
|
||||||
|
TextView tv_name;
|
||||||
|
|
||||||
|
public Holder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
root = itemView.findViewById(R.id.root);
|
||||||
|
iv_pic = itemView.findViewById(R.id.iv_pic);
|
||||||
|
tv_name = itemView.findViewById(R.id.tv_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.uiui.videoplayer.adapter;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.viewpager.widget.PagerAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PreviewAdapter extends PagerAdapter {
|
||||||
|
private List<ImageView> mImageViews;
|
||||||
|
|
||||||
|
public void setImageViews(List<ImageView> imageViews) {
|
||||||
|
this.mImageViews = imageViews;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mImageViews == null ? 0 : mImageViews.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
|
||||||
|
return view == object;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Object instantiateItem(@NonNull ViewGroup container, int position) {
|
||||||
|
// 给 container 添加一个view
|
||||||
|
container.addView(mImageViews.get(position));
|
||||||
|
// 返回一个和该view相对的object
|
||||||
|
return mImageViews.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||||
|
container.removeView(mImageViews.get(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package com.uiui.videoplayer.base;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import androidx.annotation.ColorRes;
|
||||||
|
import androidx.annotation.DimenRes;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作者:王浩 邮件:bingoogolapple@gmail.com
|
||||||
|
* 创建时间:17/1/6 上午4:04
|
||||||
|
* 描述:
|
||||||
|
*/
|
||||||
|
public class BGABaseAdapterUtil {
|
||||||
|
private static final Application sApp;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Application app = null;
|
||||||
|
try {
|
||||||
|
app = (Application) Class.forName("android.app.AppGlobals").getMethod("getInitialApplication").invoke(null);
|
||||||
|
if (app == null)
|
||||||
|
throw new IllegalStateException("Static initialization of Applications must be on main thread.");
|
||||||
|
} catch (final Exception e) {
|
||||||
|
Log.e(BGABaseAdapterUtil.class.getSimpleName(), "Failed to get current application from AppGlobals." + e.getMessage());
|
||||||
|
try {
|
||||||
|
app = (Application) Class.forName("android.app.ActivityThread").getMethod("currentApplication").invoke(null);
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
Log.e(BGABaseAdapterUtil.class.getSimpleName(), "Failed to get current application from ActivityThread." + e.getMessage());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
sApp = app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BGABaseAdapterUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Application getApp() {
|
||||||
|
return sApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int dp2px(float dpValue) {
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, getApp().getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int sp2px(float dpValue) {
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, dpValue, getApp().getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDimensionPixelOffset(@DimenRes int resId) {
|
||||||
|
return getApp().getResources().getDimensionPixelOffset(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getColor(@ColorRes int resId) {
|
||||||
|
return getApp().getResources().getColor(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Drawable rotateBitmap(Bitmap inputBitmap) {
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.setRotate(90, (float) inputBitmap.getWidth() / 2, (float) inputBitmap.getHeight() / 2);
|
||||||
|
|
||||||
|
float outputX = inputBitmap.getHeight();
|
||||||
|
float outputY = 0;
|
||||||
|
|
||||||
|
final float[] values = new float[9];
|
||||||
|
matrix.getValues(values);
|
||||||
|
float x1 = values[Matrix.MTRANS_X];
|
||||||
|
float y1 = values[Matrix.MTRANS_Y];
|
||||||
|
matrix.postTranslate(outputX - x1, outputY - y1);
|
||||||
|
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap.getHeight(), inputBitmap.getWidth(), Bitmap.Config.ARGB_8888);
|
||||||
|
Paint paint = new Paint();
|
||||||
|
Canvas canvas = new Canvas(outputBitmap);
|
||||||
|
canvas.drawBitmap(inputBitmap, matrix, paint);
|
||||||
|
return new BitmapDrawable(null, outputBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isListNotEmpty(List list) {
|
||||||
|
return list != null && !list.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.uiui.videoplayer.base;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.DimenRes;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作者:王浩 邮件:bingoogolapple@gmail.com
|
||||||
|
* 创建时间:17/1/9 下午11:12
|
||||||
|
* 描述:
|
||||||
|
*/
|
||||||
|
public class BGAGridDivider extends RecyclerView.ItemDecoration {
|
||||||
|
private int mSpace;
|
||||||
|
|
||||||
|
private BGAGridDivider(int space) {
|
||||||
|
mSpace = space;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置间距资源 id
|
||||||
|
*
|
||||||
|
* @param resId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static BGAGridDivider newInstanceWithSpaceRes(@DimenRes int resId) {
|
||||||
|
return new BGAGridDivider(BGABaseAdapterUtil.getDimensionPixelOffset(resId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置间距
|
||||||
|
*
|
||||||
|
* @param spaceDp 单位为 dp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static BGAGridDivider newInstanceWithSpaceDp(int spaceDp) {
|
||||||
|
return new BGAGridDivider(BGABaseAdapterUtil.dp2px(spaceDp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置间距
|
||||||
|
*
|
||||||
|
* @param spacePx 单位为 px
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static BGAGridDivider newInstanceWithSpacePx(int spacePx) {
|
||||||
|
return new BGAGridDivider(spacePx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
outRect.left = mSpace;
|
||||||
|
outRect.right = mSpace;
|
||||||
|
outRect.top = mSpace;
|
||||||
|
outRect.bottom = mSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.uiui.videoplayer.base;
|
package com.uiui.videoplayer.base;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -61,17 +62,19 @@ public abstract class BaseLightActivity extends AppCompatActivity implements Lif
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
lifecycleSubject.onNext(ActivityEvent.CREATE);
|
lifecycleSubject.onNext(ActivityEvent.CREATE);
|
||||||
// StatusBarUtil.init(this);
|
// StatusBarUtil.init(this);
|
||||||
|
setContentView(this.getLayoutId());
|
||||||
UltimateBarX.statusBar(this)
|
UltimateBarX.statusBar(this)
|
||||||
.transparent()
|
// .transparent()
|
||||||
.colorRes(R.color.colorPrimaryDark)
|
.colorRes(R.color.colorAccent)
|
||||||
.light(true)
|
.fitWindow(true)
|
||||||
|
.light(false)
|
||||||
.apply();
|
.apply();
|
||||||
UltimateBarX.navigationBar(this)
|
UltimateBarX.navigationBar(this)
|
||||||
.transparent()
|
.transparent()
|
||||||
.colorRes(R.color.colorPrimaryDark)
|
// .color(Color.TRANSPARENT)
|
||||||
.light(true)
|
.fitWindow(false)
|
||||||
|
.light(false)
|
||||||
.apply();
|
.apply();
|
||||||
setContentView(this.getLayoutId());
|
|
||||||
initView();
|
initView();
|
||||||
initData();
|
initData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.uiui.videoplayer.base;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述 : RecyclerView GridLayoutManager 等间距。
|
||||||
|
* <p>
|
||||||
|
* 等间距需满足两个条件:
|
||||||
|
* 1.各个模块的大小相等,即 各列的left+right 值相等;
|
||||||
|
* 2.各列的间距相等,即 前列的right + 后列的left = 列间距;
|
||||||
|
* <p>
|
||||||
|
* 在{@link #getItemOffsets(Rect, View, RecyclerView, RecyclerView.State)} 中针对 outRect 的left 和right 满足这两个条件即可
|
||||||
|
* <p>
|
||||||
|
* 作者 : shiguotao
|
||||||
|
* 版本 : V1
|
||||||
|
* 创建时间 : 2020/3/19 4:54 PM
|
||||||
|
*/
|
||||||
|
public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
|
||||||
|
private final String TAG = "GridSpaceItemDecoration";
|
||||||
|
|
||||||
|
private int mSpanCount;//横条目数量
|
||||||
|
private int mRowSpacing;//行间距
|
||||||
|
private int mColumnSpacing;// 列间距
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param spanCount 列数
|
||||||
|
* @param rowSpacing 行间距
|
||||||
|
* @param columnSpacing 列间距
|
||||||
|
*/
|
||||||
|
public GridSpaceItemDecoration(int spanCount, int rowSpacing, int columnSpacing) {
|
||||||
|
this.mSpanCount = spanCount;
|
||||||
|
this.mRowSpacing = rowSpacing;
|
||||||
|
this.mColumnSpacing = columnSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||||
|
int position = parent.getChildAdapterPosition(view); // 获取view 在adapter中的位置。
|
||||||
|
int column = position % mSpanCount; // view 所在的列
|
||||||
|
|
||||||
|
outRect.left = column * mColumnSpacing / mSpanCount; // column * (列间距 * (1f / 列数))
|
||||||
|
outRect.right = mColumnSpacing - (column + 1) * mColumnSpacing / mSpanCount; // 列间距 - (column + 1) * (列间距 * (1f /列数))
|
||||||
|
|
||||||
|
Log.e(TAG, "position:" + position
|
||||||
|
+ " columnIndex: " + column
|
||||||
|
+ " left,right ->" + outRect.left + "," + outRect.right);
|
||||||
|
|
||||||
|
// 如果position > 行数,说明不是在第一行,则不指定行高,其他行的上间距为 top=mRowSpacing
|
||||||
|
if (position >= mSpanCount) {
|
||||||
|
outRect.top = mRowSpacing; // item top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
package com.uiui.videoplayer.base;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import net.lucode.hackware.magicindicator.NavigatorHelper;
|
||||||
|
import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.ArgbEvaluatorHolder;
|
||||||
|
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// _oo0oo_
|
||||||
|
// o8888888o
|
||||||
|
// 88" . "88
|
||||||
|
// (| -_- |)
|
||||||
|
// 0\ = /0
|
||||||
|
// ___/`---'\___
|
||||||
|
// .' \\| |// '.
|
||||||
|
// / \\||| : |||// \
|
||||||
|
// / _||||| -:- |||||- \
|
||||||
|
// | | \\\ - /// | |
|
||||||
|
// | \_| ''\---/'' |_/ |
|
||||||
|
// \ .-\__ '-' ___/-. /
|
||||||
|
// ___'. .' /--.--\ `. .'___
|
||||||
|
// ."" '< `.___\_<|>_/___.' >' "".
|
||||||
|
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
|
||||||
|
// \ \ `_. \_ __\ /__ _/ .-` / /
|
||||||
|
// =====`-.____`.___ \_____/___.-`___.-'=====
|
||||||
|
// `=---='
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// 佛祖保佑 永无BUG
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类似CircleIndicator的效果
|
||||||
|
* Created by hackware on 2016/9/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ScaleCircleNavigator extends View implements IPagerNavigator, NavigatorHelper.OnNavigatorScrollListener {
|
||||||
|
private int mMinRadius;
|
||||||
|
private int mMaxRadius;
|
||||||
|
private int mNormalCircleColor = Color.LTGRAY;
|
||||||
|
private int mSelectedCircleColor = Color.GRAY;
|
||||||
|
private int mCircleSpacing;
|
||||||
|
private int mCircleCount;
|
||||||
|
|
||||||
|
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
private List<PointF> mCirclePoints = new ArrayList<PointF>();
|
||||||
|
private SparseArray<Float> mCircleRadiusArray = new SparseArray<Float>();
|
||||||
|
|
||||||
|
// 事件回调
|
||||||
|
private boolean mTouchable;
|
||||||
|
private ScaleCircleNavigator.OnCircleClickListener mCircleClickListener;
|
||||||
|
private float mDownX;
|
||||||
|
private float mDownY;
|
||||||
|
private int mTouchSlop;
|
||||||
|
|
||||||
|
private boolean mFollowTouch = true; // 是否跟随手指滑动
|
||||||
|
private NavigatorHelper mNavigatorHelper = new NavigatorHelper();
|
||||||
|
private Interpolator mStartInterpolator = new LinearInterpolator();
|
||||||
|
|
||||||
|
public ScaleCircleNavigator(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||||
|
mMinRadius = UIUtil.dip2px(context, 3);
|
||||||
|
mMaxRadius = UIUtil.dip2px(context, 4);
|
||||||
|
mCircleSpacing = UIUtil.dip2px(context, 8);
|
||||||
|
mNavigatorHelper.setNavigatorScrollListener(this);
|
||||||
|
mNavigatorHelper.setSkimOver(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureWidth(int widthMeasureSpec) {
|
||||||
|
int mode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int result = 0;
|
||||||
|
switch (mode) {
|
||||||
|
case MeasureSpec.EXACTLY:
|
||||||
|
result = width;
|
||||||
|
break;
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
if (mCircleCount <= 0) {
|
||||||
|
result = getPaddingLeft() + getPaddingRight();
|
||||||
|
} else {
|
||||||
|
result = (mCircleCount - 1) * mMinRadius * 2 + mMaxRadius * 2 + (mCircleCount - 1) * mCircleSpacing + getPaddingLeft() + getPaddingRight();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureHeight(int heightMeasureSpec) {
|
||||||
|
int mode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
int result = 0;
|
||||||
|
switch (mode) {
|
||||||
|
case MeasureSpec.EXACTLY:
|
||||||
|
result = height;
|
||||||
|
break;
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
result = mMaxRadius * 2 + getPaddingTop() + getPaddingBottom();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
for (int i = 0, j = mCirclePoints.size(); i < j; i++) {
|
||||||
|
PointF point = mCirclePoints.get(i);
|
||||||
|
float radius = mCircleRadiusArray.get(i, (float) mMinRadius);
|
||||||
|
mPaint.setColor(ArgbEvaluatorHolder.eval((radius - mMinRadius) / (mMaxRadius - mMinRadius), mNormalCircleColor, mSelectedCircleColor));
|
||||||
|
canvas.drawCircle(point.x, getHeight() / 2.0f, radius, mPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareCirclePoints() {
|
||||||
|
mCirclePoints.clear();
|
||||||
|
if (mCircleCount > 0) {
|
||||||
|
int y = Math.round(getHeight() / 2.0f);
|
||||||
|
int centerSpacing = mMinRadius * 2 + mCircleSpacing;
|
||||||
|
int startX = mMaxRadius + getPaddingLeft();
|
||||||
|
for (int i = 0; i < mCircleCount; i++) {
|
||||||
|
PointF pointF = new PointF(startX, y);
|
||||||
|
mCirclePoints.add(pointF);
|
||||||
|
startX += centerSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
float x = event.getX();
|
||||||
|
float y = event.getY();
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if (mTouchable) {
|
||||||
|
mDownX = x;
|
||||||
|
mDownY = y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if (mCircleClickListener != null) {
|
||||||
|
if (Math.abs(x - mDownX) <= mTouchSlop && Math.abs(y - mDownY) <= mTouchSlop) {
|
||||||
|
float max = Float.MAX_VALUE;
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < mCirclePoints.size(); i++) {
|
||||||
|
PointF pointF = mCirclePoints.get(i);
|
||||||
|
float offset = Math.abs(pointF.x - x);
|
||||||
|
if (offset < max) {
|
||||||
|
max = offset;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCircleClickListener.onClick(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
mNavigatorHelper.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
mNavigatorHelper.onPageSelected(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
mNavigatorHelper.onPageScrollStateChanged(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
prepareCirclePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDataSetChanged() {
|
||||||
|
prepareCirclePoints();
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachToMagicIndicator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachFromMagicIndicator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinRadius(int minRadius) {
|
||||||
|
mMinRadius = minRadius;
|
||||||
|
prepareCirclePoints();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxRadius(int maxRadius) {
|
||||||
|
mMaxRadius = maxRadius;
|
||||||
|
prepareCirclePoints();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNormalCircleColor(int normalCircleColor) {
|
||||||
|
mNormalCircleColor = normalCircleColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedCircleColor(int selectedCircleColor) {
|
||||||
|
mSelectedCircleColor = selectedCircleColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleSpacing(int circleSpacing) {
|
||||||
|
mCircleSpacing = circleSpacing;
|
||||||
|
prepareCirclePoints();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||||
|
mStartInterpolator = startInterpolator;
|
||||||
|
if (mStartInterpolator == null) {
|
||||||
|
mStartInterpolator = new LinearInterpolator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleCount(int count) {
|
||||||
|
mCircleCount = count; // 此处不调用invalidate,让外部调用notifyDataSetChanged
|
||||||
|
mNavigatorHelper.setTotalCount(mCircleCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTouchable(boolean touchable) {
|
||||||
|
mTouchable = touchable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFollowTouch(boolean followTouch) {
|
||||||
|
mFollowTouch = followTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkimOver(boolean skimOver) {
|
||||||
|
mNavigatorHelper.setSkimOver(skimOver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCircleClickListener(OnCircleClickListener circleClickListener) {
|
||||||
|
if (!mTouchable) {
|
||||||
|
mTouchable = true;
|
||||||
|
}
|
||||||
|
mCircleClickListener = circleClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||||
|
if (mFollowTouch) {
|
||||||
|
float radius = mMinRadius + (mMaxRadius - mMinRadius) * mStartInterpolator.getInterpolation(enterPercent);
|
||||||
|
mCircleRadiusArray.put(index, radius);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||||
|
if (mFollowTouch) {
|
||||||
|
float radius = mMaxRadius + (mMinRadius - mMaxRadius) * mStartInterpolator.getInterpolation(leavePercent);
|
||||||
|
mCircleRadiusArray.put(index, radius);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelected(int index, int totalCount) {
|
||||||
|
if (!mFollowTouch) {
|
||||||
|
mCircleRadiusArray.put(index, (float) mMaxRadius);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeselected(int index, int totalCount) {
|
||||||
|
if (!mFollowTouch) {
|
||||||
|
mCircleRadiusArray.put(index, (float) mMinRadius);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnCircleClickListener {
|
||||||
|
void onClick(int index);
|
||||||
|
}
|
||||||
|
}
|
||||||
79
app/src/main/java/com/uiui/videoplayer/bean/PhotoInfo.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package com.uiui.videoplayer.bean;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class PhotoInfo implements Serializable, Parcelable {
|
||||||
|
private static final long serialVersionUID = 4205742067664126524L;
|
||||||
|
|
||||||
|
String file_name;
|
||||||
|
String file;
|
||||||
|
long file_size;
|
||||||
|
|
||||||
|
protected PhotoInfo(Parcel in) {
|
||||||
|
file_name = in.readString();
|
||||||
|
file = in.readString();
|
||||||
|
file_size = in.readLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<PhotoInfo> CREATOR = new Creator<PhotoInfo>() {
|
||||||
|
@Override
|
||||||
|
public PhotoInfo createFromParcel(Parcel in) {
|
||||||
|
return new PhotoInfo(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PhotoInfo[] newArray(int size) {
|
||||||
|
return new PhotoInfo[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getFile_name() {
|
||||||
|
return file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile_name(String file_name) {
|
||||||
|
this.file_name = file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile(String file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFile_size() {
|
||||||
|
return file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile_size(long file_size) {
|
||||||
|
this.file_size = file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(file_name);
|
||||||
|
dest.writeString(file);
|
||||||
|
dest.writeLong(file_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import android.util.Log;
|
|||||||
import com.tencent.mmkv.MMKV;
|
import com.tencent.mmkv.MMKV;
|
||||||
import com.uiui.sn.IGetInfoInterface;
|
import com.uiui.sn.IGetInfoInterface;
|
||||||
import com.uiui.videoplayer.BuildConfig;
|
import com.uiui.videoplayer.BuildConfig;
|
||||||
|
import com.uiui.videoplayer.config.CommonConfig;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -27,7 +28,7 @@ public class RemoteManager {
|
|||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private static RemoteManager sInstance;
|
private static RemoteManager sInstance;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private MMKV mMMKV = MMKV.defaultMMKV();
|
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||||
private IGetInfoInterface mIGetInfoInterface;
|
private IGetInfoInterface mIGetInfoInterface;
|
||||||
private ServiceConnection mServiceConnection;
|
private ServiceConnection mServiceConnection;
|
||||||
|
|
||||||
@@ -117,7 +118,7 @@ public class RemoteManager {
|
|||||||
|
|
||||||
public String getSerial() {
|
public String getSerial() {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
return "T1030B128GB22435020359";
|
// return "T1030B128GB22435020359";
|
||||||
}
|
}
|
||||||
String sn = mMMKV.decodeString(serialKey, "");
|
String sn = mMMKV.decodeString(serialKey, "");
|
||||||
Log.e(TAG, "sn: " + sn);
|
Log.e(TAG, "sn: " + sn);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.tencent.mmkv.MMKV;
|
|||||||
import com.trello.rxlifecycle4.RxLifecycle;
|
import com.trello.rxlifecycle4.RxLifecycle;
|
||||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||||
import com.uiui.videoplayer.bean.BaseResponse;
|
import com.uiui.videoplayer.bean.BaseResponse;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
import com.uiui.videoplayer.bean.VideoInfo;
|
import com.uiui.videoplayer.bean.VideoInfo;
|
||||||
import com.uiui.videoplayer.bean.LocalVideoInfo;
|
import com.uiui.videoplayer.bean.LocalVideoInfo;
|
||||||
import com.uiui.videoplayer.config.CommonConfig;
|
import com.uiui.videoplayer.config.CommonConfig;
|
||||||
@@ -21,6 +22,7 @@ import com.uiui.videoplayer.gson.GsonUtils;
|
|||||||
import com.uiui.videoplayer.manager.ConnectManager;
|
import com.uiui.videoplayer.manager.ConnectManager;
|
||||||
import com.uiui.videoplayer.manager.ConnectMode;
|
import com.uiui.videoplayer.manager.ConnectMode;
|
||||||
import com.uiui.videoplayer.manager.RemoteManager;
|
import com.uiui.videoplayer.manager.RemoteManager;
|
||||||
|
import com.uiui.videoplayer.network.api.HomePhotoApi;
|
||||||
import com.uiui.videoplayer.network.api.HomeVideoApi;
|
import com.uiui.videoplayer.network.api.HomeVideoApi;
|
||||||
import com.uiui.videoplayer.network.interceptor.RepeatRequestInterceptor;
|
import com.uiui.videoplayer.network.interceptor.RepeatRequestInterceptor;
|
||||||
import com.uiui.videoplayer.utils.JGYUtils;
|
import com.uiui.videoplayer.utils.JGYUtils;
|
||||||
@@ -156,6 +158,13 @@ public class NetInterfaceManager {
|
|||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Observable<BaseResponse<ArrayList<PhotoInfo>>> getHomePhotoControl() {
|
||||||
|
return mRetrofit.create(HomePhotoApi.class)
|
||||||
|
.getHomePhoto(RemoteManager.getInstance().getSerial())
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
|
}
|
||||||
|
|
||||||
public interface onVideoPathCallback {
|
public interface onVideoPathCallback {
|
||||||
void setVideoList(ArrayList<LocalVideoInfo> videoList);
|
void setVideoList(ArrayList<LocalVideoInfo> videoList);
|
||||||
|
|
||||||
@@ -385,4 +394,115 @@ public class NetInterfaceManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface onPhotoCallback {
|
||||||
|
void setPhotoList(ArrayList<PhotoInfo> photoList);
|
||||||
|
|
||||||
|
void onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getHomePhoto(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, onPhotoCallback callback) {
|
||||||
|
ConnectMode connectMode = ConnectMode.ONE_MINUTE;
|
||||||
|
if (refresh) {
|
||||||
|
connectMode = ConnectMode.DEFAULT;
|
||||||
|
}
|
||||||
|
if (ConnectManager.getInstance().isNeedConnect(UrlAddress.HOME_PHOTO, connectMode)) {
|
||||||
|
getHomePhoto(lifecycle, callback);
|
||||||
|
} else {
|
||||||
|
String jsonString = mCacheHelper.getAsString(UrlAddress.HOME_PHOTO);
|
||||||
|
//为 "" 是已经请求成功的
|
||||||
|
if (jsonString == null) {
|
||||||
|
getHomePhoto(lifecycle, callback);
|
||||||
|
} else {
|
||||||
|
getHomePhotoCache(jsonString, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void getHomePhotoCache(String jsonString, onPhotoCallback callback) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Type type = new TypeToken<List<PhotoInfo>>() {
|
||||||
|
}.getType();
|
||||||
|
try {
|
||||||
|
ArrayList<PhotoInfo> photoInfoList = gson.fromJson(jsonString, type);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.setPhotoList(photoInfoList);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "getHomePhotoCache: " + e.getMessage());
|
||||||
|
if (callback != null) {
|
||||||
|
callback.setPhotoList(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getHomePhoto(BehaviorSubject<ActivityEvent> lifecycle, onPhotoCallback callback) {
|
||||||
|
getHomePhotoControl()
|
||||||
|
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
|
||||||
|
.subscribe(getHomePhotoObserver(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getHomePhoto(onPhotoCallback callback) {
|
||||||
|
getHomePhotoControl()
|
||||||
|
.subscribe(getHomePhotoObserver(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getHomePhoto() {
|
||||||
|
getHomePhotoControl()
|
||||||
|
.subscribe(getHomePhotoObserver(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Observer<BaseResponse<ArrayList<PhotoInfo>>> getHomePhotoObserver(onPhotoCallback callback) {
|
||||||
|
return new Observer<BaseResponse<ArrayList<PhotoInfo>>>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@NonNull Disposable d) {
|
||||||
|
Log.e("getHomePhotoObserver", "onSubscribe: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@NonNull BaseResponse<ArrayList<PhotoInfo>> listBaseResponse) {
|
||||||
|
Log.e("getHomePhotoObserver", "onNext: " + listBaseResponse);
|
||||||
|
int code = listBaseResponse.code;
|
||||||
|
if (code == 200) {
|
||||||
|
ArrayList<PhotoInfo> photoInfoList = listBaseResponse.data;
|
||||||
|
for (PhotoInfo photoInfo : photoInfoList) {
|
||||||
|
if (!JGYUtils.getInstance().fileExists(photoInfo.getFile())) {
|
||||||
|
JGYUtils.getInstance().ariaDownload(photoInfo.getFile(), GsonUtils.getJsonObject(GsonUtils.toJSONString(photoInfo)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCacheHelper.put(UrlAddress.HOME_PHOTO, GsonUtils.toJSONString(photoInfoList));
|
||||||
|
if (callback != null) {
|
||||||
|
callback.setPhotoList(photoInfoList);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mCacheHelper.put(UrlAddress.HOME_PHOTO, "");
|
||||||
|
if (callback != null) {
|
||||||
|
callback.setPhotoList(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull Throwable e) {
|
||||||
|
Log.e("getHomePhotoObserver", "onError: " + e.getMessage());
|
||||||
|
ToastUtil.show("网络连接失败");
|
||||||
|
String jsonString = mCacheHelper.getAsString(UrlAddress.HOME_PHOTO);
|
||||||
|
getHomePhotoCache(jsonString, callback);
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
Log.e("getHomePhotoObserver", "onComplete: ");
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ public class UrlAddress {
|
|||||||
/*主页接口*/
|
/*主页接口*/
|
||||||
public static final String ROOT_URL = "https://led.zuoyepad.com/android/";
|
public static final String ROOT_URL = "https://led.zuoyepad.com/android/";
|
||||||
|
|
||||||
/*获取视频*/
|
/*获取家庭视频*/
|
||||||
public static final String HOME_VIDEO ="File/getHomeVideo";
|
public static final String HOME_VIDEO ="File/getHomeVideo";
|
||||||
|
/*获取家庭照片*/
|
||||||
|
public static final String HOME_PHOTO ="File/getHomePhoto";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.uiui.videoplayer.network.api;
|
||||||
|
|
||||||
|
import com.uiui.videoplayer.bean.BaseResponse;
|
||||||
|
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||||
|
import com.uiui.videoplayer.network.UrlAddress;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
|
||||||
|
public interface HomePhotoApi {
|
||||||
|
@GET(UrlAddress.HOME_PHOTO)
|
||||||
|
Observable<BaseResponse<ArrayList<PhotoInfo>>> getHomePhoto(
|
||||||
|
@Query("sn") String sn
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,14 +1,7 @@
|
|||||||
package com.uiui.videoplayer.utils;
|
package com.uiui.videoplayer.utils;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import com.arialyy.aria.core.Aria;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@@ -36,12 +29,25 @@ public class VideoUtils {
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] extension = new String[]{
|
private static final String[] video_extension = new String[]{
|
||||||
".3gp", ".avi", ".flv", ".mkv", ".mov", ".mp4", ".webm"
|
".3gp", ".avi", ".flv", ".mkv", ".mov", ".mp4", ".webm"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final String[] picture_extension = new String[]{
|
||||||
|
".jgp", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".jpe"
|
||||||
|
};
|
||||||
|
|
||||||
public static boolean isVideoFormat(String filePath) {
|
public static boolean isVideoFormat(String filePath) {
|
||||||
for (String s : extension) {
|
for (String s : video_extension) {
|
||||||
|
if (filePath.endsWith(s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPicFormat(String filePath) {
|
||||||
|
for (String s : picture_extension) {
|
||||||
if (filePath.endsWith(s)) {
|
if (filePath.endsWith(s)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
app/src/main/res/drawable-hdpi/back.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-hdpi/icon_pic.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
app/src/main/res/drawable-hdpi/icon_video.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
app/src/main/res/drawable-hdpi/no_video_data.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
app/src/main/res/drawable-hdpi/play.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,30 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000" />
|
|
||||||
</vector>
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".activity.main.MainActivity">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tv_scan">
|
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/swipeRefreshLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/white">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recyclerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tips"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="没有找到视频文件"
|
|
||||||
android:textColor="@color/defaultColor"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_scan"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text=""
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textColor="@color/defaultColor"
|
|
||||||
android:textSize="@dimen/sp_12"
|
|
||||||
android:background="@color/white"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
110
app/src/main/res/layout-land/activity_video.xml
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".activity.video.VideoActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_32"
|
||||||
|
android:background="@color/colorAccent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_back"
|
||||||
|
android:layout_width="@dimen/dp_20"
|
||||||
|
android:layout_height="@dimen/dp_16"
|
||||||
|
android:layout_marginStart="@dimen/dp_4"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="家庭视频"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_15"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/white">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/cl_nodata"
|
||||||
|
android:layout_width="@dimen/dp_128"
|
||||||
|
android:layout_height="@dimen/dp_128"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView3"
|
||||||
|
android:layout_width="@dimen/dp_64"
|
||||||
|
android:layout_height="@dimen/dp_64"
|
||||||
|
android:src="@drawable/no_video_data"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tips"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="没有找到视频文件"
|
||||||
|
android:textColor="@color/defaultColor"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/imageView3" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_scan"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text=""
|
||||||
|
android:textColor="@color/defaultColor"
|
||||||
|
android:textSize="@dimen/sp_12"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".activity.main.MainActivity">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tv_scan">
|
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/swipeRefreshLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/white">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recyclerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tips"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="没有找到视频文件"
|
|
||||||
android:textColor="@color/defaultColor"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_scan"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text=""
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textColor="@color/defaultColor"
|
|
||||||
android:textSize="@dimen/sp_12"
|
|
||||||
android:background="@color/white"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
110
app/src/main/res/layout-port/activity_video.xml
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".activity.video.VideoActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_32"
|
||||||
|
android:background="@color/colorAccent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_back"
|
||||||
|
android:layout_width="@dimen/dp_20"
|
||||||
|
android:layout_height="@dimen/dp_16"
|
||||||
|
android:layout_marginStart="@dimen/dp_4"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="家庭视频"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_15"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/white">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/cl_nodata"
|
||||||
|
android:layout_width="@dimen/dp_128"
|
||||||
|
android:layout_height="@dimen/dp_128"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView3"
|
||||||
|
android:layout_width="@dimen/dp_64"
|
||||||
|
android:layout_height="@dimen/dp_64"
|
||||||
|
android:src="@drawable/no_video_data"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tips"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="没有找到视频文件"
|
||||||
|
android:textColor="@color/defaultColor"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/imageView3" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_scan"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text=""
|
||||||
|
android:textColor="@color/defaultColor"
|
||||||
|
android:textSize="@dimen/sp_12"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
60
app/src/main/res/layout/activity_gallery.xml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".activity.pic.GalleryActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_32"
|
||||||
|
android:background="@color/colorAccent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_back"
|
||||||
|
android:layout_width="@dimen/dp_20"
|
||||||
|
android:layout_height="@dimen/dp_16"
|
||||||
|
android:layout_marginStart="@dimen/dp_4"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="家庭相册"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_15"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
136
app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".activity.main.MainActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_32"
|
||||||
|
android:background="@color/colorAccent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_back"
|
||||||
|
android:layout_width="@dimen/dp_20"
|
||||||
|
android:layout_height="@dimen/dp_16"
|
||||||
|
android:layout_marginStart="@dimen/dp_4"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="家庭空间"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_15"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/cl_pic"
|
||||||
|
android:layout_width="@dimen/dp_128"
|
||||||
|
android:layout_height="@dimen/dp_128"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:layout_marginTop="@dimen/dp_8"
|
||||||
|
android:background="@drawable/bg_dialog"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:text="相册"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="@dimen/sp_10"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/nv_pic"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.shehuan.niv.NiceImageView
|
||||||
|
android:id="@+id/nv_pic"
|
||||||
|
android:layout_width="@dimen/dp_80"
|
||||||
|
android:layout_height="@dimen/dp_80"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/icon_pic"
|
||||||
|
app:corner_radius="@dimen/dp_4"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/vl_video"
|
||||||
|
android:layout_width="@dimen/dp_128"
|
||||||
|
android:layout_height="@dimen/dp_128"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:background="@drawable/bg_dialog"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/cl_pic"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/cl_pic">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:text="视频"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="@dimen/sp_10"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/nv_video"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.shehuan.niv.NiceImageView
|
||||||
|
android:id="@+id/nv_video"
|
||||||
|
android:layout_width="@dimen/dp_80"
|
||||||
|
android:layout_height="@dimen/dp_80"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/icon_video"
|
||||||
|
app:corner_radius="@dimen/dp_4"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="@dimen/dp_32"
|
||||||
|
android:layout_height="@dimen/dp_32"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/play"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/nv_video"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/nv_video"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/nv_video"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/nv_video" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
28
app/src/main/res/layout/activity_preview.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".activity.preview.PreviewActivity">
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/viewPager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/magicIndicator"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<net.lucode.hackware.magicindicator.MagicIndicator
|
||||||
|
android:id="@+id/magicIndicator"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
34
app/src/main/res/layout/item_pic.xml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/root"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_pic"
|
||||||
|
android:layout_width="@dimen/dp_128"
|
||||||
|
android:layout_height="@dimen/dp_128"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/dp_2"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/lightGray"
|
||||||
|
android:textSize="@dimen/sp_9"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="pic_name" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.0 KiB |
@@ -2,7 +2,9 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#6200EE</color>
|
<color name="colorPrimary">#6200EE</color>
|
||||||
<color name="colorPrimaryDark">#3700B3</color>
|
<color name="colorPrimaryDark">#3700B3</color>
|
||||||
<color name="colorAccent">#03DAC5</color>
|
<color name="colorAccent">#4880ff</color>
|
||||||
|
<color name="colorBackground">#f3f3f3</color>
|
||||||
|
|
||||||
<color name="white">#FFFFFF</color>
|
<color name="white">#FFFFFF</color>
|
||||||
<color name="black">#000000</color>
|
<color name="black">#000000</color>
|
||||||
<color name="defaultColor">#333333</color>
|
<color name="defaultColor">#333333</color>
|
||||||
@@ -11,4 +13,144 @@
|
|||||||
<color name="btn_cancel">#d0d0d0</color>
|
<color name="btn_cancel">#d0d0d0</color>
|
||||||
<color name="btn_cancel_pressed">#9F9F9F</color>
|
<color name="btn_cancel_pressed">#9F9F9F</color>
|
||||||
|
|
||||||
|
<!--https://www.jianshu.com/p/8dc258dfd189-->
|
||||||
|
<color name="transparent">#00000000</color><!--透明色-->
|
||||||
|
<color name="colorYang">#FFE2C59B</color><!--羊皮纸色-->
|
||||||
|
<color name="ivory">#FFFFFFF0</color><!--象牙色-->
|
||||||
|
<color name="lightYellow">#FFFFFFE0</color><!--亮黄色-->
|
||||||
|
<color name="yellow">#FFFFFF00</color><!--黄色-->
|
||||||
|
<color name="snow">#FFFFFAFA</color><!--雪白色-->
|
||||||
|
<color name="floralWhite">#FFFFFAF0</color><!--花白色-->
|
||||||
|
<color name="lemonChiffon">#FFFFFACD</color><!--柠檬绸色-->
|
||||||
|
<color name="cornSilk">#FFFFF8DC</color><!--米绸色-->
|
||||||
|
<color name="seashell">#FFFFF5EE</color><!--海贝色-->
|
||||||
|
<color name="lavenderBlush">#FFFFF0F5</color><!--淡紫红色-->
|
||||||
|
<color name="papayaWhip">#FFFFEFD5</color><!--番木色-->
|
||||||
|
<color name="blanchedAlmond">#FFFFEBCD</color><!--白杏色-->
|
||||||
|
<color name="mistyRose">#FFFFE4E1</color><!--浅玫瑰色-->
|
||||||
|
<color name="bisque">#FFFFE4C4</color><!--桔黄色-->
|
||||||
|
<color name="moccasin">#FFFFE4B5</color><!--鹿皮色-->
|
||||||
|
<color name="navajoWhite">#FFFFDEAD</color><!--纳瓦白-->
|
||||||
|
<color name="peachPuff">#FFFFDAB9</color><!--桃色-->
|
||||||
|
<color name="gold">#FFFFD700</color><!--金色-->
|
||||||
|
<color name="pink">#FFFFC0CB</color><!--粉红色-->
|
||||||
|
<color name="lightPink">#FFFFB6C1</color><!--亮粉红色-->
|
||||||
|
<color name="orange">#FFFFA500</color><!--橙色-->
|
||||||
|
<color name="lightSalmon">#FFFFA07A</color><!--亮肉色-->
|
||||||
|
<color name="darkOrange">#FFFF8C00</color><!--暗桔黄色-->
|
||||||
|
<color name="coral">#FFFF7F50</color><!--珊瑚色-->
|
||||||
|
<color name="hotPink">#FFFF69B4</color><!--热粉红色-->
|
||||||
|
<color name="tomato">#FFFF6347</color><!--西红柿色-->
|
||||||
|
<color name="orangeRed">#FFFF4500</color><!--红橙色-->
|
||||||
|
<color name="deepPink">#FFFF1493</color><!--深粉红色-->
|
||||||
|
<color name="fuchsia">#FFFF00FF</color><!--紫红色-->
|
||||||
|
<color name="red">#FFFF0000</color><!--红色-->
|
||||||
|
<color name="oldLace">#FFFDF5E6</color><!--老花色-->
|
||||||
|
<color name="lightGoldenrodYellow">#FFFAFAD2</color><!--亮金黄色-->
|
||||||
|
<color name="linen">#FFFAF0E6</color><!--亚麻色-->
|
||||||
|
<color name="antiqueWhite">#FFFAEBD7</color><!--古董白色-->
|
||||||
|
<color name="salmon">#FFFA8072</color><!--鲜肉色-->
|
||||||
|
<color name="ghostWhite">#FFF8F8FF</color><!--幽灵白-->
|
||||||
|
<color name="mintCream">#FFF5FFFA</color><!--薄荷色-->
|
||||||
|
<color name="whiteSmoke">#FFF5F5F5</color><!--烟白色-->
|
||||||
|
<color name="beige">#FFF5F5DC</color><!--米色-->
|
||||||
|
<color name="wheat">#FFF5DEB3</color><!--浅黄色-->
|
||||||
|
<color name="sandyBrown">#FFF4A460</color><!--沙褐色-->
|
||||||
|
<color name="azure">#FFF0FFFF</color><!--天蓝色-->
|
||||||
|
<color name="aliceBlue">#FFF0F8FF</color><!--艾利斯兰色-->
|
||||||
|
<color name="khaki">#FFF0E68C</color><!--黄褐色-->
|
||||||
|
<color name="lightCoral">#FFF08080</color><!--亮珊瑚色-->
|
||||||
|
<color name="paleGoldenrod">#FFEEE8AA</color><!--苍麒麟色-->
|
||||||
|
<color name="violet">#FFEE82EE</color><!--紫罗兰色-->
|
||||||
|
<color name="darkSalmon">#FFE9967A</color><!--暗肉色-->
|
||||||
|
<color name="lavender">#FFE6E6FA</color><!--淡紫色-->
|
||||||
|
<color name="lightCyan">#FFE0FFFF</color><!--亮青色-->
|
||||||
|
<color name="burlyWood">#FFDEB887</color><!--实木色-->
|
||||||
|
<color name="plum">#FFDDA0DD</color><!--洋李色-->
|
||||||
|
<color name="lightGrey">#FFDCDCDC</color><!--淡灰色-->
|
||||||
|
<color name="crimson">#FFDC143C</color><!--暗深红色-->
|
||||||
|
<color name="paleVioletRed">#FFDB7093</color><!--苍紫罗兰色-->
|
||||||
|
<color name="goldenrod">#FFDAA520</color><!--金麒麟色-->
|
||||||
|
<color name="orchid">#FFDA70D6</color><!--淡紫色-->
|
||||||
|
<color name="thistle">#FFD8BFD8</color><!--蓟色-->
|
||||||
|
<color name="lightGray">#FFD3D3D3</color><!--亮灰色-->
|
||||||
|
<color name="tan">#FFD2B48C</color><!--茶色-->
|
||||||
|
<color name="chocolate">#FFD2691E</color><!--巧可力色-->
|
||||||
|
<color name="peru">#FFCD853F</color><!--秘鲁色-->
|
||||||
|
<color name="indianRed">#FFCD5C5C</color><!--印第安红色-->
|
||||||
|
<color name="mediumVioletRed">#FFC71585</color><!--中紫罗兰色-->
|
||||||
|
<color name="silver">#FFC0C0C0</color><!--银色-->
|
||||||
|
<color name="darkKhaki">#FFBDB76B</color><!--暗黄褐色-->
|
||||||
|
<color name="rosyBrown">#FFBC8F8F</color><!--褐玫瑰红色-->
|
||||||
|
<color name="mediumOrchid">#FFBA55D3</color><!--中粉紫色-->
|
||||||
|
<color name="darkGoldenrod">#FFB8860B</color><!--暗金黄色-->
|
||||||
|
<color name="firebrick">#FFB22222</color><!--火砖色-->
|
||||||
|
<color name="powderBlue">#FFB0E0E6</color><!--粉蓝色-->
|
||||||
|
<color name="lightSteelBlue">#FFB0C4DE</color><!--亮钢兰色-->
|
||||||
|
<color name="paleTurquoise">#FFAFEEEE</color><!--苍宝石绿色-->
|
||||||
|
<color name="greenYellow">#FFADFF2F</color><!--黄绿色-->
|
||||||
|
<color name="lightBlue">#FFADD8E6</color><!--亮蓝色-->
|
||||||
|
<color name="darkGray">#FFA9A9A9</color><!--暗灰色-->
|
||||||
|
<color name="brown">#FFA52A2A</color><!--褐色-->
|
||||||
|
<color name="sienna">#FFA0522D</color><!--赭色-->
|
||||||
|
<color name="darkOrchid">#FF9932CC</color><!--暗紫色-->
|
||||||
|
<color name="paleGreen">#FF98FB98</color><!--苍绿色-->
|
||||||
|
<color name="darkViolet">#FF9400D3</color><!--暗紫罗兰色-->
|
||||||
|
<color name="mediumPurple">#FF9370DB</color><!--中紫色-->
|
||||||
|
<color name="lightGreen">#FF90EE90</color><!--亮绿色-->
|
||||||
|
<color name="darkSeaGreen">#FF8FBC8F</color><!--暗海兰色-->
|
||||||
|
<color name="saddleBrown">#FF8B4513</color><!--重褐色-->
|
||||||
|
<color name="darkMagenta">#FF8B008B</color><!--暗洋红色-->
|
||||||
|
<color name="darkRed">#FF8B0000</color><!--暗红色-->
|
||||||
|
<color name="blueViolet">#FF8A2BE2</color><!--紫罗兰蓝色-->
|
||||||
|
<color name="lightSkyBlue">#FF87CEFA</color><!--亮天蓝色-->
|
||||||
|
<color name="skyBlue">#FF87CEEB</color><!--天蓝色-->
|
||||||
|
<color name="gray">#FF808080</color><!--灰色-->
|
||||||
|
<color name="olive">#FF808000</color><!--橄榄色-->
|
||||||
|
<color name="purple">#FF800080</color><!--紫色-->
|
||||||
|
<color name="maroon">#FF800000</color><!--粟色-->
|
||||||
|
<color name="aquamarine">#FF7FFFD4</color><!--碧绿色-->
|
||||||
|
<color name="chartreuse">#FF7FFF00</color><!--黄绿色-->
|
||||||
|
<color name="lawnGreen">#FF7CFC00</color><!--草绿色-->
|
||||||
|
<color name="mediumSlateBlue">#FF7B68EE</color><!--中暗蓝色-->
|
||||||
|
<color name="lightSlateGray">#FF778899</color><!--亮蓝灰色-->
|
||||||
|
<color name="slateGray">#FF708090</color><!--灰石色-->
|
||||||
|
<color name="oliveDrab">#FF6B8E23</color><!--深绿褐色-->
|
||||||
|
<color name="slateBlue">#FF6A5ACD</color><!--石蓝色-->
|
||||||
|
<color name="dimGray">#FF696969</color><!--暗灰色-->
|
||||||
|
<color name="mediumAquamarine">#FF66CDAA</color><!--中绿色-->
|
||||||
|
<color name="cornFlowerBlue">#FF6495ED</color><!--菊兰色-->
|
||||||
|
<color name="cadetBlue">#FF5F9EA0</color><!--军兰色-->
|
||||||
|
<color name="darkOliveGreen">#FF556B2F</color><!--暗橄榄绿色-->
|
||||||
|
<color name="indigo">#FF4B0082</color><!--靛青色-->
|
||||||
|
<color name="mediumTurquoise">#FF48D1CC</color><!--中绿宝石色-->
|
||||||
|
<color name="darkSlateBlue">#FF483D8B</color><!--暗灰蓝色-->
|
||||||
|
<color name="steelBlue">#FF4682B4</color><!--钢兰色-->
|
||||||
|
<color name="royalBlue">#FF4169E1</color><!--皇家蓝色-->
|
||||||
|
<color name="turquoise">#FF40E0D0</color><!--青绿色-->
|
||||||
|
<color name="mediumSeaGreen">#FF3CB371</color><!--中海蓝色-->
|
||||||
|
<color name="limeGreen">#FF32CD32</color><!--橙绿色-->
|
||||||
|
<color name="darkSlateGray">#FF2F4F4F</color><!--暗瓦灰色-->
|
||||||
|
<color name="seaGreen">#FF2E8B57</color><!--海绿色-->
|
||||||
|
<color name="forestGreen">#FF228B22</color><!--森林绿色-->
|
||||||
|
<color name="lightSeaGreen">#FF20B2AA</color><!--亮海蓝色-->
|
||||||
|
<color name="dodgerBlue">#FF1E90FF</color><!--闪兰色-->
|
||||||
|
<color name="midnightBlue">#FF191970</color><!--中灰兰色-->
|
||||||
|
<color name="aqua">#FF00FFFF</color><!--浅绿色-->
|
||||||
|
<color name="springGreen">#FF00FF7F</color><!--春绿色-->
|
||||||
|
<color name="lime">#FF00FF00</color><!--酸橙色-->
|
||||||
|
<color name="mediumSpringGreen">#FF00FA9A</color><!--中春绿色-->
|
||||||
|
<color name="darkTurquoise">#FF00CED1</color><!--暗宝石绿色-->
|
||||||
|
<color name="deepSkyBlue">#FF00BFFF</color><!--深天蓝色-->
|
||||||
|
<color name="darkCyan">#FF008B8B</color><!--暗青色-->
|
||||||
|
<color name="teal">#FF008080</color><!--水鸭色-->
|
||||||
|
<color name="green">#FF008000</color><!--绿色-->
|
||||||
|
<color name="darkGreen">#FF006400</color><!--暗绿色-->
|
||||||
|
<color name="blue">#FF0000FF</color><!--蓝色-->
|
||||||
|
<color name="mediumBlue">#FF0000CD</color><!--中兰色-->
|
||||||
|
<color name="darkBlue">#FF00008B</color><!--暗蓝色-->
|
||||||
|
<color name="navy">#FF000080</color><!--海军色-->
|
||||||
|
<color name="unBlack">#FF2B2B2B</color><!--不知名黑色-->
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<!-- Customize your theme here. -->
|
<!-- Customize your theme here. -->
|
||||||
<item name="colorPrimary">@color/white</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/white</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/defaultColor</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
<item name="android:windowBackground">@color/colorBackground</item>
|
||||||
|
<item name="android:navigationBarColor">?attr/colorPrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- <!– Base application theme. –>-->
|
||||||
|
<!-- <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">-->
|
||||||
|
<!-- <!– Customize your theme here. –>-->
|
||||||
|
<!-- <item name="colorPrimary">@color/white</item>-->
|
||||||
|
<!-- <item name="colorPrimaryDark">@color/white</item>-->
|
||||||
|
<!-- <item name="colorAccent">@color/defaultColor</item>-->
|
||||||
|
<!-- </style>-->
|
||||||
|
|
||||||
<style name="CustomDialog" parent="android:style/Theme.Dialog">
|
<style name="CustomDialog" parent="android:style/Theme.Dialog">
|
||||||
<!--背景颜色及和透明程度-->
|
<!--背景颜色及和透明程度-->
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
|
|||||||