diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index a442416..726b71d 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..9caf446 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 379f37f..058ee6d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "com.ihewro.android_expression_package" minSdkVersion 19 targetSdkVersion 26 - versionCode 201807121 - versionName "3.1" + versionCode 201808101 + versionName "3.2" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } diff --git a/app/release/app-universal-release.apk b/app/release/app-universal-release.apk index d601b6f..f4bb565 100644 Binary files a/app/release/app-universal-release.apk and b/app/release/app-universal-release.apk differ diff --git a/app/release/app-x86-release.apk b/app/release/app-x86-release.apk index 51a4d42..b6e0d3b 100644 Binary files a/app/release/app-x86-release.apk and b/app/release/app-x86-release.apk differ diff --git a/app/release/baby.apk b/app/release/baby.apk index 105e1a2..016b45c 100644 Binary files a/app/release/baby.apk and b/app/release/baby.apk differ diff --git a/app/release/output.json b/app/release/output.json index dd7eb1f..f517529 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -1 +1 @@ -[{"outputType":{"type":"APK"},"apkInfo":{"type":"FULL_SPLIT","splits":[{"filterType":"ABI","value":"x86"}],"versionCode":201807121},"path":"app-x86-release.apk","properties":{"packageId":"com.ihewro.android_expression_package","split":"","minSdkVersion":"19"}},{"outputType":{"type":"APK"},"apkInfo":{"type":"FULL_SPLIT","splits":[{"filterType":"ABI","value":"armeabi-v7a"}],"versionCode":201807121},"path":"app-armeabi-v7a-release.apk","properties":{"packageId":"com.ihewro.android_expression_package","split":"","minSdkVersion":"19"}},{"outputType":{"type":"APK"},"apkInfo":{"type":"FULL_SPLIT","splits":[],"versionCode":201807121},"path":"app-universal-release.apk","properties":{"packageId":"com.ihewro.android_expression_package","split":"","minSdkVersion":"19"}}] \ No newline at end of file +[{"outputType":{"type":"APK"},"apkInfo":{"type":"FULL_SPLIT","splits":[{"filterType":"ABI","value":"x86"}],"versionCode":201808101},"path":"app-x86-release.apk","properties":{"packageId":"com.ihewro.android_expression_package","split":"","minSdkVersion":"19"}},{"outputType":{"type":"APK"},"apkInfo":{"type":"FULL_SPLIT","splits":[],"versionCode":201808101},"path":"app-universal-release.apk","properties":{"packageId":"com.ihewro.android_expression_package","split":"","minSdkVersion":"19"}},{"outputType":{"type":"APK"},"apkInfo":{"type":"FULL_SPLIT","splits":[{"filterType":"ABI","value":"armeabi-v7a"}],"versionCode":201808101},"path":"app-armeabi-v7a-release.apk","properties":{"packageId":"com.ihewro.android_expression_package","split":"","minSdkVersion":"19"}}] \ No newline at end of file diff --git a/app/src/main/java/com/ihewro/android_expression_package/MyDataBase.java b/app/src/main/java/com/ihewro/android_expression_package/MyDataBase.java index dd65b75..f99d4a4 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/MyDataBase.java +++ b/app/src/main/java/com/ihewro/android_expression_package/MyDataBase.java @@ -36,32 +36,41 @@ */ public class MyDataBase { - - /** * 把一个表情信息加入到数据库 * @param expression * @return */ public static boolean addExpressionRecord(Expression expression,File source){ + + byte[] bytes = fileToCompressedBytes(source); + if (bytes == null){ + return false; + }else { + return addExpressionRecord(expression,bytes); + } + } + + private static byte[] fileToCompressedBytes(File source){ //先进行图片压缩,避免数据太大,导致读取问题 - File compressToFile = null; + File compressToFile; compressToFile = FileUtil.returnCompressExp(source); ALog.d("压缩后的路径" + compressToFile.getAbsolutePath() + "大小" + compressToFile.length()); byte[] bytes = FileUtil.fileToBytes(compressToFile); ALog.d("文件大小为" + bytes.length); if (bytes.length>2060826){ - return false; + return null; }else { //因为compressToFile 和 source是同一个文件,所以先判断下,再决定是否删除 if (compressToFile.exists() && !Objects.equals(compressToFile.getAbsolutePath(), source.getAbsolutePath())){ compressToFile.delete(); } - return addExpressionRecord(expression,bytes); + return bytes; } - } + + public static boolean addExpressionRecord(Expression expression,byte[] source) { //1. 检查有没有表情对应的目录 List expressionFolderList = LitePal.where("name = ? and exist = ?",expression.getFolderName(), String.valueOf(1)).find(ExpressionFolder.class); diff --git a/app/src/main/java/com/ihewro/android_expression_package/activity/AboutActivity.java b/app/src/main/java/com/ihewro/android_expression_package/activity/AboutActivity.java index 87e59c8..96924ab 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/activity/AboutActivity.java +++ b/app/src/main/java/com/ihewro/android_expression_package/activity/AboutActivity.java @@ -69,9 +69,6 @@ protected void onCreate(Bundle savedInstanceState) { initListener(); - Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate); - imageView.setAnimation(rotateAnimation); - imageView.startAnimation(rotateAnimation); imageView.setOnClickListener(new View.OnClickListener() { @@ -89,6 +86,9 @@ public void onClick(View v) { if (clickTimes > 3 && !isPlayed){ isPlayed = true; Toasty.info(AboutActivity.this,"准备为您播放彩蛋音乐", Toast.LENGTH_LONG).show(); + Animation rotateAnimation = AnimationUtils.loadAnimation(AboutActivity.this, R.anim.rotate); + imageView.setAnimation(rotateAnimation); + imageView.startAnimation(rotateAnimation); String dataSource = "https://www.ihewro.com/little.mp3"; ALog.d("播放地址为" + dataSource); @@ -102,7 +102,7 @@ public void onClick(View v) { e.printStackTrace(); } }else if (isPlayed){ - Toasty.info(AboutActivity.this,"已经为你播放过啦~",Toast.LENGTH_LONG).show(); + //Toasty.info(AboutActivity.this,"已经为你播放过啦~",Toast.LENGTH_LONG).show(); } }else { lastClickTime = -1; diff --git a/app/src/main/java/com/ihewro/android_expression_package/activity/ExpLocalFolderDetailActivity.java b/app/src/main/java/com/ihewro/android_expression_package/activity/ExpLocalFolderDetailActivity.java index 3ab1dc7..5a74a72 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/activity/ExpLocalFolderDetailActivity.java +++ b/app/src/main/java/com/ihewro/android_expression_package/activity/ExpLocalFolderDetailActivity.java @@ -1,6 +1,7 @@ package com.ihewro.android_expression_package.activity; import android.app.Activity; +import android.content.ContentValues; import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Bundle; @@ -8,6 +9,7 @@ import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.text.InputType; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -16,6 +18,7 @@ import android.widget.TextView; import android.widget.Toast; +import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.blankj.ALog; import com.chad.library.adapter.base.BaseQuickAdapter; @@ -25,10 +28,17 @@ import com.ihewro.android_expression_package.adapter.ExpressionListAdapter; import com.ihewro.android_expression_package.bean.EventMessage; import com.ihewro.android_expression_package.bean.Expression; +import com.ihewro.android_expression_package.bean.ExpressionFolder; import com.ihewro.android_expression_package.callback.GetExpListListener; +import com.ihewro.android_expression_package.callback.SaveImageToGalleryListener; import com.ihewro.android_expression_package.callback.TaskListener; +import com.ihewro.android_expression_package.task.DeleteExpFolderTask; import com.ihewro.android_expression_package.task.DeleteImageTask; +import com.ihewro.android_expression_package.task.EditExpFolderNameTask; import com.ihewro.android_expression_package.task.GetExpListTask; +import com.ihewro.android_expression_package.task.SaveFolderToLocalTask; +import com.ihewro.android_expression_package.task.SaveImageToGalleryTask; +import com.ihewro.android_expression_package.util.DateUtil; import com.ihewro.android_expression_package.util.FileUtil; import com.ihewro.android_expression_package.util.UIUtil; import com.ihewro.android_expression_package.view.ExpImageDialog; @@ -43,6 +53,7 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.litepal.LitePal; +import org.litepal.crud.DataSupport; import java.io.File; import java.io.IOException; @@ -377,7 +388,7 @@ public boolean onCreateOptionsMenu(Menu menu) { @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.re_add) { - // + //添加新的表情 Matisse.from(ExpLocalFolderDetailActivity.this) .choose(MimeType.ofAll(), false) .countable(true) @@ -387,6 +398,63 @@ public boolean onOptionsItemSelected(MenuItem item) { .theme(R.style.Matisse_Dracula) .imageEngine(new MyGlideEngine()) .forResult(1998); + }else if (item.getItemId() == R.id.re_edit){ + //修改表情包名称 + new MaterialDialog.Builder(this) + .title("输入修改后的表情包名称") + .content("具有一点分类意义的名字哦,方便查找") + .inputType(InputType.TYPE_CLASS_TEXT) + .input("任意文字", dirName, new MaterialDialog.InputCallback() { + @Override + public void onInput(final MaterialDialog dialog, CharSequence input) { + List temExpFolderList = LitePal.where("name = ?",dialog.getInputEditText().getText().toString()).find(ExpressionFolder.class); + if (temExpFolderList.size()>0){ + Toasty.error(ExpLocalFolderDetailActivity.this,"表情包名称已存在,请更换",Toast.LENGTH_SHORT).show(); + }else { + //修改数据库的目录名称 + new EditExpFolderNameTask(ExpLocalFolderDetailActivity.this, expressionList.size(), dirName, dialog.getInputEditText().getText().toString(), new SaveImageToGalleryListener() { + @Override + public void onFinish(Boolean result) { + //修改本地表情包目录名称 + File dir = new File(GlobalConfig.appDirPath + dirName); + if (dir.exists()){ + dir.renameTo(new File(GlobalConfig.appDirPath + dialog.getInputEditText().getText().toString())); + } + toolbar.setTitle(dialog.getInputEditText().getText().toString()); + } + }).execute(expressionList); + } + } + }).show(); + }else if (item.getItemId() == R.id.all_download){ + //下载到手机 + new MaterialDialog.Builder(this) + .title("下载提示") + .content("从[表情商店]下载的图片以二进制存储在本地数据库中,不[下载到本地]仍然可以离线使用,无需流量。\n\n [下载到手机]表示将图片以文件形式存在在手机存储卡中") + .negativeText("那就不下载了") + .positiveText("给我下载") + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + new SaveFolderToLocalTask(ExpLocalFolderDetailActivity.this,expressionList.size(),dirName).execute(expressionList); + } + }) + .show(); + + }else if (item.getItemId() == R.id.all_delete){ + //删除本地文件 + new MaterialDialog.Builder(this) + .title("删除提示") + .content("该操作会删除表情包在手机存储卡中的文件。\n\n删除后,表情仍然以二进制保留在数据库,可以离线使用。") + .negativeText("取消") + .positiveText("给我删除") + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + new DeleteExpFolderTask(dirName,ExpLocalFolderDetailActivity.this).execute(); + } + }) + .show(); } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/com/ihewro/android_expression_package/activity/MainActivity.java b/app/src/main/java/com/ihewro/android_expression_package/activity/MainActivity.java index 7a77e60..2aedd51 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/activity/MainActivity.java +++ b/app/src/main/java/com/ihewro/android_expression_package/activity/MainActivity.java @@ -59,12 +59,14 @@ import com.ihewro.android_expression_package.bean.ExpressionFolder; import com.ihewro.android_expression_package.bean.OneDetail; import com.ihewro.android_expression_package.bean.OneDetailList; +import com.ihewro.android_expression_package.callback.GestureListener; import com.ihewro.android_expression_package.callback.RemoveCacheListener; import com.ihewro.android_expression_package.callback.GetMainExpListener; import com.ihewro.android_expression_package.callback.TaskListener; import com.ihewro.android_expression_package.fragment.ExpressionContentFragment; import com.ihewro.android_expression_package.http.HttpUtil; import com.ihewro.android_expression_package.task.CheckUpdateTask; +import com.ihewro.android_expression_package.task.GenerateScreenshotTask; import com.ihewro.android_expression_package.task.RecoverDataTask; import com.ihewro.android_expression_package.task.RemoveCacheTask; import com.ihewro.android_expression_package.task.GetExpFolderTask; @@ -528,6 +530,10 @@ public void onClickedGuideView() { private void initListener() { + //监听图片的左右滑动 + topImage.setLongClickable(true); + topImage.setOnTouchListener(new MyGestureListener(this)); + fabSearch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -686,13 +692,26 @@ public void onLoadFailed(@Nullable Drawable errorDrawable) { topImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - - Expression expression = new Expression(2, oneDetailLists.getDate().substring(0, 10) + (currentItem) + ".jpg", oneDetailList.get(currentItem).getImgUrl(), "头图"); - ExpImageDialog expImageDialog = new ExpImageDialog.Builder(MainActivity.this) + //生成截图 + final Expression expression = new Expression(3, oneDetailLists.getDate().substring(0, 10) + (currentItem) + ".jpg", oneDetailList.get(currentItem).getImgUrl(), "头图"); + final ExpImageDialog expImageDialog = new ExpImageDialog.Builder(MainActivity.this) .setContext(MainActivity.this, null,3) .build(); expImageDialog.setImageData(expression); - expImageDialog.show(); + + //判断是否已经生成过了 + File file = new File(GlobalConfig.appDirPath + expression.getFolderName() + "/" + expression.getName()); + if (file.exists()){ + expImageDialog.show(); + }else { + new GenerateScreenshotTask(MainActivity.this, oneText.getText().toString(), expression, new TaskListener() { + @Override + public void onFinish(Boolean result) { + expImageDialog.show(); + } + }).execute(); + } + } }); } @@ -881,4 +900,28 @@ public void onFileSelection(@NonNull FileChooserDialog dialog, @NonNull File fil public void onFileChooserDismissed(@NonNull FileChooserDialog dialog) { } + + /** + * 继承GestureListener,重写left和right方法 + */ + private class MyGestureListener extends GestureListener { + public MyGestureListener(Context context) { + super(context); + } + + @Override + public boolean left() { + Toasty.info(MainActivity.this,"点击顶部风车按钮切换图片文字哦").show(); + return super.left(); + } + + @Override + public boolean right() { + Toasty.info(MainActivity.this,"点击顶部风车按钮切换图片文字哦").show(); + return super.right(); + } + } + } + + diff --git a/app/src/main/java/com/ihewro/android_expression_package/activity/MyActivity.java b/app/src/main/java/com/ihewro/android_expression_package/activity/MyActivity.java index 835b569..2a0d7c2 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/activity/MyActivity.java +++ b/app/src/main/java/com/ihewro/android_expression_package/activity/MyActivity.java @@ -232,6 +232,7 @@ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) @Override public void onFinished() { updateLoadingDialog.setContent("终于同步完成"); + updateLoadingDialog.dismiss(); Toasty.success(MyActivity.this,"同步完成", Toast.LENGTH_SHORT).show(); //更新RecyclerView 布局 initData(); @@ -244,7 +245,6 @@ public void onProgress(int progress,int max) { if (!updateLoadingDialog.isShowing()){ updateLoadingDialog.setMaxProgress(max); updateLoadingDialog.show(); - ALog.d("有点问题"); } if (progress > 0){ diff --git a/app/src/main/java/com/ihewro/android_expression_package/bean/Expression.java b/app/src/main/java/com/ihewro/android_expression_package/bean/Expression.java index 1411727..8d39f60 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/bean/Expression.java +++ b/app/src/main/java/com/ihewro/android_expression_package/bean/Expression.java @@ -19,7 +19,7 @@ public class Expression extends LitePalSupport{ private int id;//主键 - private int status;//标志位,图片来源:~~-1 apk内置图片~~ 1 sd卡图片 2 网络图片 + private int status;//标志位,图片来源:~~-1 apk内置图片~~ 1 数据库图片 2 网络图片 3 本机图片(数据库中没有存,头图分享卡片就是这种类型) private String name;//图片名称 private String url;//图片路径或者图片地址 private String folderName;//目录的名称 diff --git a/app/src/main/java/com/ihewro/android_expression_package/callback/GestureListener.java b/app/src/main/java/com/ihewro/android_expression_package/callback/GestureListener.java new file mode 100644 index 0000000..c0748b0 --- /dev/null +++ b/app/src/main/java/com/ihewro/android_expression_package/callback/GestureListener.java @@ -0,0 +1,105 @@ +package com.ihewro.android_expression_package.callback; + +/** + *
+ *     author : hewro
+ *     e-mail : ihewro@163.com
+ *     time   : 2018/08/12
+ *     desc   :
+ *     version: 1.0
+ * 
+ */ + +import android.content.Context; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.View; + +/** + * 实现监听左右滑动的事件,哪个view需要的时候直接setOnTouchListener就可以用了 + * @author LinZhiquan + * + */ +public class GestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { + /** 左右滑动的最短距离 */ + private int distance = 100; + /** 左右滑动的最大速度 */ + private int velocity = 200; + + private GestureDetector gestureDetector; + + public GestureListener(Context context) { + super(); + gestureDetector = new GestureDetector(context, this); + } + + /** + * 向左滑的时候调用的方法,子类应该重写 + * @return + */ + public boolean left() { + return false; + } + + /** + * 向右滑的时候调用的方法,子类应该重写 + * @return + */ + public boolean right() { + return false; + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, + float velocityY) { + // TODO Auto-generated method stub + // e1:第1个ACTION_DOWN MotionEvent + // e2:最后一个ACTION_MOVE MotionEvent + // velocityX:X轴上的移动速度(像素/秒) + // velocityY:Y轴上的移动速度(像素/秒) + + // 向左滑 + if (e1.getX() - e2.getX() > distance + && Math.abs(velocityX) > velocity) { + left(); + } + // 向右滑 + if (e2.getX() - e1.getX() > distance + && Math.abs(velocityX) > velocity) { + right(); + } + return false; + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + // TODO Auto-generated method stub + gestureDetector.onTouchEvent(event); + return false; + } + + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public int getVelocity() { + return velocity; + } + + public void setVelocity(int velocity) { + this.velocity = velocity; + } + + public GestureDetector getGestureDetector() { + return gestureDetector; + } + + public void setGestureDetector(GestureDetector gestureDetector) { + this.gestureDetector = gestureDetector; + } +} + diff --git a/app/src/main/java/com/ihewro/android_expression_package/task/DeleteExpFolderTask.java b/app/src/main/java/com/ihewro/android_expression_package/task/DeleteExpFolderTask.java new file mode 100644 index 0000000..2e25b64 --- /dev/null +++ b/app/src/main/java/com/ihewro/android_expression_package/task/DeleteExpFolderTask.java @@ -0,0 +1,52 @@ +package com.ihewro.android_expression_package.task; + +import android.app.Activity; +import android.os.AsyncTask; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.ihewro.android_expression_package.GlobalConfig; +import com.ihewro.android_expression_package.bean.Expression; +import com.ihewro.android_expression_package.util.FileUtil; + +import java.io.File; +import java.util.List; + +import es.dmoral.toasty.Toasty; + +/** + *
+ *     author : hewro
+ *     e-mail : ihewro@163.com
+ *     time   : 2018/08/11
+ *     desc   :
+ *     version: 1.0
+ * 
+ */ +public class DeleteExpFolderTask extends AsyncTask { + + private String folderName; + private Activity activity; + + private MaterialDialog dialog; + + public DeleteExpFolderTask(String folderName,Activity activity) { + this.folderName = folderName; + this.activity = activity; + } + + @Override + protected void onPreExecute() { + + } + + @Override + protected Boolean doInBackground(Void... voids) { + FileUtil.delFolder(GlobalConfig.appDirPath + folderName); + return null; + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + Toasty.success(activity,"删除成功").show(); + } +} diff --git a/app/src/main/java/com/ihewro/android_expression_package/task/EditExpFolderNameTask.java b/app/src/main/java/com/ihewro/android_expression_package/task/EditExpFolderNameTask.java new file mode 100644 index 0000000..563bf08 --- /dev/null +++ b/app/src/main/java/com/ihewro/android_expression_package/task/EditExpFolderNameTask.java @@ -0,0 +1,88 @@ +package com.ihewro.android_expression_package.task; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.os.AsyncTask; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.ihewro.android_expression_package.bean.EventMessage; +import com.ihewro.android_expression_package.bean.Expression; +import com.ihewro.android_expression_package.bean.ExpressionFolder; +import com.ihewro.android_expression_package.callback.SaveImageToGalleryListener; + +import org.greenrobot.eventbus.EventBus; +import org.litepal.LitePal; + +import java.util.List; + +/** + *
+ *     author : hewro
+ *     e-mail : ihewro@163.com
+ *     time   : 2018/08/10
+ *     desc   :
+ *     version: 1.0
+ * 
+ */ +public class EditExpFolderNameTask extends AsyncTask, Integer, Boolean> { + + private MaterialDialog materialDialog; + @SuppressLint("StaticFieldLeak") + private Activity activity; + private int count ; + private String originDirName; + private String targetDirName; + private SaveImageToGalleryListener listener; + public EditExpFolderNameTask(Activity activity, int count,String originDirName,String targetDirName,SaveImageToGalleryListener listener) { + this.activity = activity; + this.count = count; + this.originDirName = originDirName; + this.targetDirName = targetDirName; + this.listener = listener; + } + + @Override + protected void onPreExecute() { + materialDialog = new MaterialDialog.Builder(activity) + .title("正在修改表情包名称,请稍等") + .content("陛下,耐心等下……") + .progress(false, count, true) + .build(); + } + + @Override + protected Boolean doInBackground(List... lists) { + List expressionList = lists[0]; + //从数据库查找该表情包 + ExpressionFolder expressionFolder = LitePal.where("name = ?",originDirName).find(ExpressionFolder.class).get(0); + expressionFolder.setName(targetDirName); + expressionFolder.save(); + + for (int i = 0; i < expressionList.size();i++){ + Expression expression = expressionList.get(i); + expression.setFolderName(targetDirName); + expression.setExpressionFolder(expressionFolder); + expression.save(); + publishProgress(i+1); + } + expressionFolder.setExpressionList(expressionList); + expressionFolder.save(); + return true; + } + + @Override + protected void onProgressUpdate(Integer... values) { + if (values[0] == -1){ + materialDialog.show(); + }else { + materialDialog.setProgress(values[0]); + } + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + materialDialog.setTitle("修改名称成功"); + listener.onFinish(aBoolean); + EventBus.getDefault().post(new EventMessage(EventMessage.DATABASE)); + } +} diff --git a/app/src/main/java/com/ihewro/android_expression_package/task/GenerateScreenshotTask.java b/app/src/main/java/com/ihewro/android_expression_package/task/GenerateScreenshotTask.java new file mode 100644 index 0000000..4981779 --- /dev/null +++ b/app/src/main/java/com/ihewro/android_expression_package/task/GenerateScreenshotTask.java @@ -0,0 +1,113 @@ +package com.ihewro.android_expression_package.task; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.blankj.ALog; +import com.bumptech.glide.Glide; +import com.bumptech.glide.Priority; +import com.bumptech.glide.request.RequestOptions; +import com.ihewro.android_expression_package.R; +import com.ihewro.android_expression_package.bean.Expression; +import com.ihewro.android_expression_package.callback.TaskListener; +import com.ihewro.android_expression_package.util.UIUtil; + +import java.util.concurrent.ExecutionException; + +import es.dmoral.toasty.Toasty; + +/** + *
+ *     author : hewro
+ *     e-mail : ihewro@163.com
+ *     time   : 2018/08/12
+ *     desc   :
+ *     version: 1.0
+ * 
+ */ +public class GenerateScreenshotTask extends AsyncTask { + + private Activity activity; + private String content; + private MaterialDialog dialog; + private TaskListener listener; + private Expression expression; + private Bitmap.Config[] configs + = {Bitmap.Config.ALPHA_8, Bitmap.Config.ARGB_4444, Bitmap.Config.ARGB_8888, Bitmap.Config.RGB_565}; + + public GenerateScreenshotTask(Activity activity, String content ,Expression expression, TaskListener listener) { + this.activity = activity; + this.content = content; + this.listener = listener; + this.expression = expression; + } + + @Override + protected void onPreExecute() { + dialog = new MaterialDialog.Builder(activity) + .content("生成分享图片中……") + .progress(true, 0) + .progressIndeterminateStyle(true) + .show(); + } + + @Override + protected Boolean doInBackground(Void... voids) { + View view = activity.getLayoutInflater().inflate(R.layout.share_one_sreenshot,null); + View v = view.findViewById(R.id.item_view); + ImageView headerImage = view.findViewById(R.id.headerImage); + TextView date = view.findViewById(R.id.dateText); + TextView content = view.findViewById(R.id.content); + ALog.d("名称为" + expression.getName().substring(0,10)); + String text = expression.getName().substring(0,10); + //设置布局内容 + Drawable imageFile = null; + try { + imageFile = Glide.with(activity).asDrawable() + .apply(RequestOptions.priorityOf(Priority.HIGH).onlyRetrieveFromCache(true)) + .load(expression.getUrl()) + .submit().get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + if(imageFile != null){ + headerImage.setImageDrawable(imageFile); + }else { + return false; + } + date.setText(text); + content.setText(this.content); + //生成截图 + v.setDrawingCacheEnabled(true); + //measure()实际测量 自己显示在屏幕上的宽高 2个参数,int widthMeasureSpec 和 int heightMeasureSpec表示具体的测量规则。 + v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); + //确定View的大小和位置的,然后将其绘制出来 + v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); + //调用getDrawingCache方法就可 以获得view的cache图片 + Bitmap bb = Bitmap.createBitmap(v.getDrawingCache()); + //系统把原来的cache销毁 + v.setDrawingCacheEnabled(false); + + + // 保存bitmap到sd卡 + UIUtil.saveBitmapToSdCard(activity,bb,"头图/" + expression.getName()); + return true; + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + Toasty.success(activity, "保存成功", Toast.LENGTH_SHORT).show(); + dialog.dismiss(); + listener.onFinish(true); + } +} diff --git a/app/src/main/java/com/ihewro/android_expression_package/task/GetExpDesTask.java b/app/src/main/java/com/ihewro/android_expression_package/task/GetExpDesTask.java index 4d09d7a..4daa22a 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/task/GetExpDesTask.java +++ b/app/src/main/java/com/ihewro/android_expression_package/task/GetExpDesTask.java @@ -75,7 +75,7 @@ public void onResult(GeneralResult result) { @Override public void onError(OCRError error) { ALog.d(error.getMessage()); - Toasty.info(activity,expression.getName()+"表情的描述自动获取失败,你可以稍后手动识别描述").show(); + //Toasty.info(activity,expression.getName()+"表情的描述自动获取失败,你可以稍后手动识别描述").show(); if (isRepeat){ new GetExpDesTask(activity,isRepeat).execute(expression); } diff --git a/app/src/main/java/com/ihewro/android_expression_package/task/SaveFolderToLocalTask.java b/app/src/main/java/com/ihewro/android_expression_package/task/SaveFolderToLocalTask.java new file mode 100644 index 0000000..30ec222 --- /dev/null +++ b/app/src/main/java/com/ihewro/android_expression_package/task/SaveFolderToLocalTask.java @@ -0,0 +1,79 @@ +package com.ihewro.android_expression_package.task; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.os.AsyncTask; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.ihewro.android_expression_package.GlobalConfig; +import com.ihewro.android_expression_package.bean.Expression; +import com.ihewro.android_expression_package.util.FileUtil; + +import java.util.List; + +/** + *
+ *     author : hewro
+ *     e-mail : ihewro@163.com
+ *     time   : 2018/08/10
+ *     desc   :
+ *     version: 1.0
+ * 
+ */ +public class SaveFolderToLocalTask extends AsyncTask, Integer, Boolean>{ + + private MaterialDialog materialDialog; + @SuppressLint("StaticFieldLeak") + private Activity activity; + private int count ; + private String dirPath; + private String dirName; + public SaveFolderToLocalTask(Activity activity,int count,String dirName) { + this.activity = activity; + this.count = count; + this.dirName = dirName; + + dirPath = GlobalConfig.appDirPath + dirName; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + materialDialog = new MaterialDialog.Builder(activity) + .title("正在下载,请稍等") + .content("陛下,耐心等下……") + .progress(false, count, true) + .build(); + + } + + @SafeVarargs + @Override + protected final Boolean doInBackground(List... lists) { + publishProgress(-1); + List expressionList = lists[0]; + for (int i = 0;i { private UpdateDatabaseListener listener; + @SuppressLint("StaticFieldLeak") private Activity activity; private int lastProgress;//上一个任务执行进度 private int count = 0;//需要扫描的总文件数目 @@ -67,6 +69,7 @@ protected Boolean doInBackground(Void... voids) {//子线程 List expressions = LitePal.select("id","name","foldername","status","url","expressionfolder_id","desstatus","description").where("foldername = ?",expressionFolder.getName()).find(Expression.class); for (Expression expression: expressions) { + ALog.d("对每个表情进行循环"); //1. 重新外键关联 expression.setExpressionFolder(expressionFolder); expression.save(); @@ -93,6 +96,8 @@ protected Boolean doInBackground(Void... voids) {//子线程 publishProgress(alCount); } + //3.1 TODO:上述修复之后,仍然游离的表情(没有外键)进行删除 + //4.修正表情包的数目 expressionFolder.setCount(expressions.size() - num); expressionFolder.save(); @@ -114,7 +119,8 @@ protected void onProgressUpdate(Integer... values) { listener.onProgress(progress,count); lastProgress = progress; } - listener.onProgress(lastProgress,count); + ALog.d("总数目" + count); + //listener.onProgress(lastProgress,count); } } diff --git a/app/src/main/java/com/ihewro/android_expression_package/util/FileUtil.java b/app/src/main/java/com/ihewro/android_expression_package/util/FileUtil.java index 9a0763f..9e95916 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/util/FileUtil.java +++ b/app/src/main/java/com/ihewro/android_expression_package/util/FileUtil.java @@ -213,7 +213,8 @@ public static byte[] fileToBytes(String file) { return fileToBytes(new File(file)); } - public static byte[] fileToBytes(File file){ + + public static byte[] fileToBytes(File file){ InputStream is = null; byte[] bytes = null; try { @@ -249,4 +250,6 @@ public static File returnCompressExp(File file){ return null; } + + } diff --git a/app/src/main/java/com/ihewro/android_expression_package/util/ShareUtil.java b/app/src/main/java/com/ihewro/android_expression_package/util/ShareUtil.java index eb3f419..02cdad6 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/util/ShareUtil.java +++ b/app/src/main/java/com/ihewro/android_expression_package/util/ShareUtil.java @@ -60,6 +60,14 @@ public static void shareQQFriend(String msgTitle, String msgText, int type, msgText, type, uri); } + public static void shareTimFriend(String msgTitle, String msgText, int type, + Uri uri) { + + shareMsg("com.tencent.tim", + "com.tencent.mobileqq.activity.JumpActivity", "Tim", msgTitle, + msgText, type, uri); + } + /** * 分享到微信好友 diff --git a/app/src/main/java/com/ihewro/android_expression_package/util/UIUtil.java b/app/src/main/java/com/ihewro/android_expression_package/util/UIUtil.java index fa5fde2..2613127 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/util/UIUtil.java +++ b/app/src/main/java/com/ihewro/android_expression_package/util/UIUtil.java @@ -2,6 +2,7 @@ import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.graphics.Bitmap; @@ -14,15 +15,20 @@ import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.AsyncTask; +import android.os.Environment; import android.os.Handler; +import android.view.View; import android.widget.ImageView; +import android.widget.Toast; import com.blankj.ALog; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.request.RequestOptions; +import com.ihewro.android_expression_package.GlobalConfig; import com.ihewro.android_expression_package.MyApplication; import com.ihewro.android_expression_package.R; import com.ihewro.android_expression_package.bean.Expression; @@ -35,11 +41,15 @@ import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; +import es.dmoral.toasty.Toasty; + import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade; /** @@ -120,6 +130,10 @@ public static void setImageToImageView(Expression expression, final ImageView im final RequestOptions options = new RequestOptions() .placeholder(R.drawable.loading) .error(R.drawable.fail); + final RequestOptions options2 = new RequestOptions() + .placeholder(R.drawable.loading) + .error(R.drawable.fail) + .dontAnimate(); switch (expression.getStatus()){ case 1: if (expression.getImage() ==null ||expression.getImage().length == 0){ @@ -132,13 +146,16 @@ public void onFinish(Expression expression) { }else { //ALog.d("有图片数据"); Glide.with(UIUtil.getContext()).load(expression.getImage()).apply(options).transition(withCrossFade()).into(imageView); - } - break; case 2: Glide.with(UIUtil.getContext()).load(expression.getUrl()).apply(options).transition(withCrossFade()).into(imageView); break; + + case 3: + Glide.with(UIUtil.getContext()).asBitmap().load(GlobalConfig.appDirPath + expression.getFolderName() + "/" + expression.getName()).apply(options2).into(imageView); + + break; } } @@ -289,5 +306,94 @@ public static void goodEgg(int times, TaskListener listener){ } + /** + * 手动测量摆放View + * 对于手动 inflate 或者其他方式代码生成加载的View进行测量,避免该View无尺寸 + * @param v + * @param width + * @param height + */ + public static void layoutView(View v, int width, int height) { + // validate view.width and view.height + v.layout(0, 0, width, height); + int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); + int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); + + // validate view.measurewidth and view.measureheight + v.measure(measuredWidth, measuredHeight); + v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); + } + + + public static int px2dip(Context context, float pxValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + + /** + * 获取一个 View 的缓存视图 + * (前提是这个View已经渲染完成显示在页面上) + * @param view + * @return + */ + public static Bitmap getCacheBitmapFromView(View view) { + final boolean drawingCacheEnabled = true; + view.setDrawingCacheEnabled(drawingCacheEnabled); + view.buildDrawingCache(drawingCacheEnabled); + final Bitmap drawingCache = view.getDrawingCache(); + Bitmap bitmap; + if (drawingCache != null) { + bitmap = Bitmap.createBitmap(drawingCache); + view.setDrawingCacheEnabled(false); + } else { + bitmap = null; + } + return bitmap; + } + public static boolean saveBitmapToSdCard(Context context, Bitmap mybitmap, String name){ + boolean result = false; + //创建位图保存目录 + String path = GlobalConfig.appDirPath + name; + File sd = new File(path); + File fileParent = sd.getParentFile();//如果表情包目录都不存在,则需要先创建目录 + if(!fileParent.exists()){ + fileParent.mkdirs(); + } + + File file = new File(path); + if (!file.exists()){ + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + FileOutputStream fileOutputStream = null; + try { + // 判断SD卡是否存在,并且是否具有读写权限 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + fileOutputStream = new FileOutputStream(file); + ALog.d(mybitmap); + mybitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream); + fileOutputStream.flush(); + fileOutputStream.close(); + + //update gallery + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + Uri uri = Uri.fromFile(file); + intent.setData(uri); + context.sendBroadcast(intent); + ALog.d("哈哈哈哈哈哈哈"); + result = true; + } + else{ + } + + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + } diff --git a/app/src/main/java/com/ihewro/android_expression_package/view/ExpImageDialog.java b/app/src/main/java/com/ihewro/android_expression_package/view/ExpImageDialog.java index 73039ee..333e51c 100644 --- a/app/src/main/java/com/ihewro/android_expression_package/view/ExpImageDialog.java +++ b/app/src/main/java/com/ihewro/android_expression_package/view/ExpImageDialog.java @@ -64,7 +64,8 @@ public class ExpImageDialog extends MaterialDialog{ private TextView tvExpression; private View save; private View share; - //View timShare; + private View delete; + View timShare; private View weChatShare; private View qqShare;//qq分享 private View love;//输出一句撩人的话 @@ -120,14 +121,25 @@ public void setImageData(Expression expression){ * 更新对话框的界面数据 */ private void updateUI(){ - if (expression.getStatus() == 1){//不是网络图片,将保存按钮取消掉 + if (expression.getStatus() == 1){//本地图片,显示图片识别框 inputView.setVisibility(View.VISIBLE); + if (new File(GlobalConfig.appDirPath + expression.getFolderName() + "/" + expression.getName()).exists()){ + delete.setVisibility(View.VISIBLE); + save.setVisibility(View.GONE); + }else { + save.setVisibility(View.VISIBLE); + delete.setVisibility(View.GONE); + } if (expression.getDesStatus() == 1){ inputText.setText(expression.getDescription()); }else { inputText.setText(""); } - }else { + } else if (expression.getStatus() == 3){ + delete.setVisibility(View.VISIBLE); + save.setVisibility(View.GONE); + } else if (expression.getStatus() == 2){ + delete.setVisibility(View.GONE); inputView.setVisibility(View.GONE); } UIUtil.setImageToImageView(expression,ivExpression); @@ -148,8 +160,9 @@ private void initView(){ ivExpression = view.findViewById(R.id.expression_image); tvExpression = view.findViewById(R.id.expression_name); save = view.findViewById(R.id.save_image); + delete = view.findViewById(R.id.delete_image); share = view.findViewById(R.id.share); - //timShare = view.findViewById(R.id.tim_share); + timShare = view.findViewById(R.id.tim_share); weChatShare = view.findViewById(R.id.weChat_share); qqShare = view.findViewById(R.id.qq_share); love = view.findViewById(R.id.love); @@ -210,6 +223,31 @@ public void onFinish(Boolean result) { } }); + //调用tim分享 + timShare.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SaveImageToGalleryTask(new SaveImageToGalleryListener() { + @Override + public void onFinish(Boolean result) { + if (result){ + FileUtil.updateMediaStore(activity,GlobalConfig.appDirPath + expression.getFolderName() + "/" + expression.getName()); + File filePath = new File(GlobalConfig.appDirPath + expression.getFolderName() + "/" + expression.getName()); + Log.e("filepath", filePath.getAbsolutePath()); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + Uri imageUri = FileProvider.getUriForFile( + activity, + UIUtil.getContext().getPackageName() + ".fileprovider", + filePath); + + ShareUtil.shareTimFriend("title", "content", ShareUtil.DRAWABLE, imageUri); + } + } + },activity).execute(expression); + } + }); + //调用QQ分享 qqShare.setOnClickListener(new View.OnClickListener() { @Override @@ -343,6 +381,19 @@ public void onFinish(Expression expression) { } }); + + delete.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + File file = new File(GlobalConfig.appDirPath + expression.getFolderName() + "/" + expression.getName()); + if (file.exists()){ + //删除 + file.delete(); + Toasty.success(activity,"删除成功").show(); + } + } + }); + } public static class Builder extends MaterialDialog.Builder { diff --git a/app/src/main/java/com/ihewro/android_expression_package/view/LetterSpacingTextView.java b/app/src/main/java/com/ihewro/android_expression_package/view/LetterSpacingTextView.java new file mode 100644 index 0000000..abaad2a --- /dev/null +++ b/app/src/main/java/com/ihewro/android_expression_package/view/LetterSpacingTextView.java @@ -0,0 +1,156 @@ +package com.ihewro.android_expression_package.view; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.style.ScaleXSpan; +import android.util.AttributeSet; +import android.widget.TextView; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *
+ *     author : hewro
+ *     e-mail : ihewro@163.com
+ *     time   : 2018/08/12
+ *     desc   :
+ *     version: 1.0
+ * 
+ */ +public class LetterSpacingTextView extends android.support.v7.widget.AppCompatTextView { + + private String content; + private int width; + private Paint paint; + private int xPadding; + private int yPadding; + private int textHeight; + private int xPaddingMin; + int count; + //记录每个字的二维数组 + int[][] position; + + public LetterSpacingTextView(Context context) { + super(context); + init(); + } + + public LetterSpacingTextView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public LetterSpacingTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + public void setText(String str) { + width = this.getWidth(); + getPositions(str); + //重新画控件 + this.invalidate(); + } + public void init() { + + paint = new Paint(); + paint.setColor(Color.parseColor("#888888")); + paint.setTypeface(Typeface.DEFAULT); + paint.setTextSize(dip2px(this.getContext(), 14f)); + Paint.FontMetrics fm = paint.getFontMetrics();// 得到系统默认字体属性 + textHeight = (int) (Math.ceil(fm.descent - fm.top) + 2);// 获得字体高度 + //字间距 + xPadding = dip2px(this.getContext(), 4f); + //行间距 + yPadding = dip2px(this.getContext(), 10f); + //比较小的字间距(字母和数字应紧凑) + xPaddingMin = dip2px(this.getContext(), 2f); + + } + + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (!TextUtils.isEmpty(content)) { + for (int i = 0; i < count; i++) { + canvas.drawText(String.valueOf(content.charAt(i)), position[i][0],position[i][1], paint); + } + } + } + + + public void getPositions(String content) { + this.content = content; + char ch; + //输入点的 x的坐标 + int x = 0; + //当前行数 + int lineNum = 1; + count = content.length(); + //初始化字体位置数组 + position=new int[count][2]; + for (int i = 0; i < count; i++) { + ch =content.charAt(i); + String str = String.valueOf(ch); + + //根据画笔获得每一个字符的显示的rect 就是包围框(获得字符宽度) + Rect rect = new Rect(); + paint.getTextBounds(str, 0, 1, rect); + int strwidth = rect.width(); + //对有些标点做些处理 + if (str.equals("《") || str.equals("(")) { + strwidth += xPaddingMin * 2; + } + //当前行的宽度 + float textWith = strwidth; + //没画字前预判看是否会出界 + x += textWith; + //出界就换行 + if (x > width) { + lineNum++;// 真实的行数加一 + x = 0; + } else { + //回到预判前的位置 + x -= textWith; + } + //记录每一个字的位置 + position[i][0]=x; + position[i][1]=textHeight * lineNum + yPadding * (lineNum - 1); + //判断是否是数字还是字母 (数字和字母应该紧凑点) + //每次输入完毕 进入下一个输入位置准备就绪 + if (isNumOrLetters(str)) { + x += textWith + xPaddingMin; + } else { + x += textWith + xPadding; + } + } + //根据所画的内容设置控件的高度 + this.setHeight((textHeight +yPadding) * lineNum); + } + + + + //工具类:判断是否是字母或者数字 + public boolean isNumOrLetters(String str) + { + String regEx="^[A-Za-z0-9_]+$"; + Pattern p= Pattern.compile(regEx); + Matcher m=p.matcher(str); + return m.matches(); + } + // 工具类:在代码中使用dp的方法(因为代码中直接用数字表示的是像素) + public static int dip2px(Context context, float dip) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dip * scale + 0.5f); + } + +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/tim.png b/app/src/main/res/drawable-xxhdpi/tim.png new file mode 100644 index 0000000..2465b27 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/tim.png differ diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 13cd4e9..8ba578a 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -98,6 +98,8 @@ android:gravity="center_horizontal" android:text="数据全来自网络(部分来自soul,部分来自酷安ID@pandecheng)如有侵权,请联系作者,提前抱歉" android:textSize="12sp" + android:background="?attr/selectableItemBackground" + android:clickable="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/loading_tip" /> diff --git a/app/src/main/res/layout/item_show_expression.xml b/app/src/main/res/layout/item_show_expression.xml index 6a9f524..4e783dc 100644 --- a/app/src/main/res/layout/item_show_expression.xml +++ b/app/src/main/res/layout/item_show_expression.xml @@ -49,6 +49,17 @@ app:iiv_color="@color/text_secondary_dark" android:layout_alignParentLeft="true" /> + + - + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_local_detail.xml b/app/src/main/res/menu/menu_local_detail.xml index 84c985b..bff3610 100644 --- a/app/src/main/res/menu/menu_local_detail.xml +++ b/app/src/main/res/menu/menu_local_detail.xml @@ -5,4 +5,18 @@ android:id="@+id/re_add" android:title="添加表情" app:showAsAction="always" /> + + + + + \ No newline at end of file diff --git a/sreenshot/end.apk b/sreenshot/end.apk new file mode 100644 index 0000000..b907d01 Binary files /dev/null and b/sreenshot/end.apk differ diff --git a/sreenshot/image10.png b/sreenshot/image10.png new file mode 100755 index 0000000..dc0d461 Binary files /dev/null and b/sreenshot/image10.png differ diff --git a/sreenshot/image3.png b/sreenshot/image3.png new file mode 100755 index 0000000..dacdd17 Binary files /dev/null and b/sreenshot/image3.png differ diff --git a/sreenshot/image4.png b/sreenshot/image4.png new file mode 100755 index 0000000..80f77ed Binary files /dev/null and b/sreenshot/image4.png differ diff --git a/sreenshot/image5.png b/sreenshot/image5.png new file mode 100755 index 0000000..5b85329 Binary files /dev/null and b/sreenshot/image5.png differ diff --git a/sreenshot/image6.png b/sreenshot/image6.png new file mode 100755 index 0000000..f898d58 Binary files /dev/null and b/sreenshot/image6.png differ diff --git a/sreenshot/image7.png b/sreenshot/image7.png new file mode 100755 index 0000000..c0b2ced Binary files /dev/null and b/sreenshot/image7.png differ diff --git a/sreenshot/image8.png b/sreenshot/image8.png new file mode 100755 index 0000000..1dbc456 Binary files /dev/null and b/sreenshot/image8.png differ diff --git a/sreenshot/image9.png b/sreenshot/image9.png new file mode 100755 index 0000000..5cab41c Binary files /dev/null and b/sreenshot/image9.png differ diff --git "a/\347\224\237\344\272\247\345\256\236\344\271\240.docx" "b/\347\224\237\344\272\247\345\256\236\344\271\240.docx" index eb0d353..9f59551 100644 Binary files "a/\347\224\237\344\272\247\345\256\236\344\271\240.docx" and "b/\347\224\237\344\272\247\345\256\236\344\271\240.docx" differ diff --git "a/\347\224\237\344\272\247\345\256\236\344\271\240\344\270\252\344\272\272\346\212\245\345\221\212.docx" "b/\347\224\237\344\272\247\345\256\236\344\271\240\344\270\252\344\272\272\346\212\245\345\221\212.docx" new file mode 100644 index 0000000..a32c1c8 Binary files /dev/null and "b/\347\224\237\344\272\247\345\256\236\344\271\240\344\270\252\344\272\272\346\212\245\345\221\212.docx" differ