Commit c125f4f5c5a989b25534e2939c497e5d632ddc14
1 parent
cb7ee015
图库模块:图片预览,网格模式全屏预览
Showing
45 changed files
with
4247 additions
and
66 deletions
app/strike/src/main/AndroidManifest.xml
| @@ -17,7 +17,8 @@ | @@ -17,7 +17,8 @@ | ||
| 17 | android:roundIcon="@mipmap/ic_launcher_round" | 17 | android:roundIcon="@mipmap/ic_launcher_round" |
| 18 | android:supportsRtl="true" | 18 | android:supportsRtl="true" |
| 19 | android:theme="@style/AppTheme"> | 19 | android:theme="@style/AppTheme"> |
| 20 | - <activity android:name="com.cnlive.strike.demo.activity.HappyChinaActivity"></activity> | 20 | + <activity android:name="com.cnlive.strike.imgutil.SimplePrevActivity"></activity> |
| 21 | + <activity android:name="com.cnlive.strike.demo.activity.HappyChinaActivity" /> | ||
| 21 | 22 | ||
| 22 | <provider | 23 | <provider |
| 23 | android:name="androidx.core.content.FileProvider" | 24 | android:name="androidx.core.content.FileProvider" |
app/strike/src/main/java/com/cnlive/strike/imgutil/ImgActivity.java
| @@ -3,6 +3,7 @@ package com.cnlive.strike.imgutil; | @@ -3,6 +3,7 @@ package com.cnlive.strike.imgutil; | ||
| 3 | import androidx.appcompat.app.AppCompatActivity; | 3 | import androidx.appcompat.app.AppCompatActivity; |
| 4 | 4 | ||
| 5 | import android.animation.ObjectAnimator; | 5 | import android.animation.ObjectAnimator; |
| 6 | +import android.content.Intent; | ||
| 6 | import android.graphics.Bitmap; | 7 | import android.graphics.Bitmap; |
| 7 | import android.os.Bundle; | 8 | import android.os.Bundle; |
| 8 | import android.os.Handler; | 9 | import android.os.Handler; |
| @@ -85,6 +86,8 @@ public class ImgActivity extends AppCompatActivity { | @@ -85,6 +86,8 @@ public class ImgActivity extends AppCompatActivity { | ||
| 85 | iv_test9 = findViewById(R.id.iv_test9); | 86 | iv_test9 = findViewById(R.id.iv_test9); |
| 86 | iv_test10 = findViewById(R.id.iv_test10); | 87 | iv_test10 = findViewById(R.id.iv_test10); |
| 87 | iv_test11 = findViewById(R.id.iv_test11); | 88 | iv_test11 = findViewById(R.id.iv_test11); |
| 89 | + | ||
| 90 | + findViewById(R.id.simpla_see).setOnClickListener(view -> startActivity(new Intent(this,SimplePrevActivity.class))); | ||
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | 93 | ||
| @@ -100,6 +103,7 @@ public class ImgActivity extends AppCompatActivity { | @@ -100,6 +103,7 @@ public class ImgActivity extends AppCompatActivity { | ||
| 100 | } | 103 | } |
| 101 | }; | 104 | }; |
| 102 | 105 | ||
| 106 | + | ||
| 103 | ImageLoader.with(this) | 107 | ImageLoader.with(this) |
| 104 | .url(URL1) | 108 | .url(URL1) |
| 105 | .animate(animation) | 109 | .animate(animation) |
| @@ -125,7 +129,7 @@ public class ImgActivity extends AppCompatActivity { | @@ -125,7 +129,7 @@ public class ImgActivity extends AppCompatActivity { | ||
| 125 | data.setShowImg(URL1); | 129 | data.setShowImg(URL1); |
| 126 | iv_test1.setOnClickListener(view -> PreviewImageViewActivity.startPreviewPictrue(this, view, data)); | 130 | iv_test1.setOnClickListener(view -> PreviewImageViewActivity.startPreviewPictrue(this, view, data)); |
| 127 | 131 | ||
| 128 | -// ImageLoader.with(this) | 132 | +// LoadImage.with(this) |
| 129 | // .url(URL1) | 133 | // .url(URL1) |
| 130 | // .scale(ScaleMode.FIT_CENTER) | 134 | // .scale(ScaleMode.FIT_CENTER) |
| 131 | // .into(iv_test2); | 135 | // .into(iv_test2); |
| @@ -168,7 +172,7 @@ public class ImgActivity extends AppCompatActivity { | @@ -168,7 +172,7 @@ public class ImgActivity extends AppCompatActivity { | ||
| 168 | .into(iv_test7); | 172 | .into(iv_test7); |
| 169 | 173 | ||
| 170 | //加载本地图片 | 174 | //加载本地图片 |
| 171 | -// ImageLoader.with(this) | 175 | +// LoadImage.with(this) |
| 172 | // .file(new File(getFilesDir(), IMG_NAME_C)) | 176 | // .file(new File(getFilesDir(), IMG_NAME_C)) |
| 173 | // .placeHolder(R.mipmap.ic_launcher) | 177 | // .placeHolder(R.mipmap.ic_launcher) |
| 174 | // .scale(ScaleMode.FIT_CENTER) | 178 | // .scale(ScaleMode.FIT_CENTER) |
app/strike/src/main/java/com/cnlive/strike/imgutil/SimplePrevActivity.java
0 → 100644
| 1 | +package com.cnlive.strike.imgutil; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +import android.graphics.drawable.Drawable; | ||
| 5 | +import android.view.KeyEvent; | ||
| 6 | +import android.view.View; | ||
| 7 | +import android.widget.ImageView; | ||
| 8 | + | ||
| 9 | +import com.bumptech.glide.request.target.SimpleTarget; | ||
| 10 | +import com.bumptech.glide.request.transition.Transition; | ||
| 11 | +import com.cnlive.cloud.R; | ||
| 12 | +import com.cnlive.core.gridview.AutoGridView; | ||
| 13 | +import com.cnlive.core.gridview.GridImgUtil; | ||
| 14 | +import com.cnlive.core.gridview.adapter.BaseAutoGridHolder; | ||
| 15 | +import com.cnlive.core.gridview.adapter.SimpleAutoGridAdapter; | ||
| 16 | +import com.cnlive.core.imagepreview.ImagePreView; | ||
| 17 | +import com.cnlive.core.imagepreview.PhotoLoader; | ||
| 18 | +import com.cnlive.core.imagepreview.ViewerStatus; | ||
| 19 | +import com.cnlive.core.imagepreview.listener.OnBrowseStatusListener; | ||
| 20 | +import com.cnlive.core.libs.base.frame.activity.BaseActivity; | ||
| 21 | +import com.cnlive.core.libs.base.util.GlideUtil; | ||
| 22 | + | ||
| 23 | +import java.util.ArrayList; | ||
| 24 | +import java.util.List; | ||
| 25 | + | ||
| 26 | +import androidx.annotation.NonNull; | ||
| 27 | +import androidx.annotation.Nullable; | ||
| 28 | + | ||
| 29 | +public class SimplePrevActivity extends BaseActivity { | ||
| 30 | + | ||
| 31 | + private ImagePreView preView; | ||
| 32 | + private AutoGridView autoGridView; | ||
| 33 | + List<String> list = new ArrayList<>(); | ||
| 34 | + private SimpleAutoGridAdapter adapter; | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + @Override | ||
| 38 | + protected int getViewLayoutId() { | ||
| 39 | + return R.layout.activity_simple_prev; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + protected void initView() { | ||
| 45 | + preView = findViewById(R.id.image_pre); | ||
| 46 | + autoGridView = findViewById(R.id.grid_view); | ||
| 47 | + list.add("https://b-ssl.duitang.com/uploads/item/201505/09/20150509221719_kyNrM.jpeg"); | ||
| 48 | + list.add("https://b-ssl.duitang.com/uploads/item/201709/26/20170926131419_8YhLA.jpeg"); | ||
| 49 | + list.add("https://b-ssl.duitang.com/uploads/item/201505/11/20150511122951_MAwVZ.jpeg"); | ||
| 50 | + list.add("https://b-ssl.duitang.com/uploads/item/201704/23/20170423205828_BhNSv.jpeg"); | ||
| 51 | + list.add("https://b-ssl.duitang.com/uploads/item/201706/30/20170630181644_j4mh5.jpeg"); | ||
| 52 | + | ||
| 53 | + preView.overlayStatusBar(false) | ||
| 54 | + .imageData(list) | ||
| 55 | + .imageLoader(new PhotoLoader()); | ||
| 56 | + | ||
| 57 | + adapter = new SimpleAutoGridAdapter<String, BaseAutoGridHolder>(list); | ||
| 58 | + adapter.setImageLoader(new SimpleAutoGridAdapter.ImageLoader() { | ||
| 59 | + @Override | ||
| 60 | + public void onLoadImage(int position, Object item, ImageView imageView) { | ||
| 61 | + | ||
| 62 | + GridImgUtil.loadImage(SimplePrevActivity.this, item, new SimpleTarget<Drawable>() { | ||
| 63 | + @Override | ||
| 64 | + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||
| 65 | + preView.getViewData().get(position).setImageWidth(resource.getIntrinsicWidth()); | ||
| 66 | + preView.getViewData().get(position).setImageHeight(resource.getIntrinsicHeight()); | ||
| 67 | + imageView.setImageDrawable(resource); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + @Override | ||
| 71 | + public void onLoadFailed(@Nullable Drawable errorDrawable) { | ||
| 72 | + super.onLoadFailed(errorDrawable); | ||
| 73 | + imageView.setImageDrawable(errorDrawable); | ||
| 74 | + } | ||
| 75 | + }); | ||
| 76 | + } | ||
| 77 | + }); | ||
| 78 | + autoGridView.setOnItemClickListener(new AutoGridView.OnItemClickListener() { | ||
| 79 | + @Override | ||
| 80 | + public void onItemClick(int position, View view) { | ||
| 81 | + preView.bindViewGroup(autoGridView); | ||
| 82 | + preView.watch(position); | ||
| 83 | + } | ||
| 84 | + }); | ||
| 85 | + | ||
| 86 | + autoGridView.setAdapter(adapter); | ||
| 87 | + preView.setOnBrowseStatusListener(new OnBrowseStatusListener() { | ||
| 88 | + @Override | ||
| 89 | + public void onBrowseStatus(int status) { | ||
| 90 | + //可以根据状态去设置状态栏颜色 | ||
| 91 | + if(status == ViewerStatus.STATUS_BEGIN_OPEN){ | ||
| 92 | + | ||
| 93 | + }else if(status == ViewerStatus.STATUS_SILENCE){ | ||
| 94 | + | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + }); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + @Override | ||
| 101 | + public boolean onKeyDown(int keyCode, KeyEvent event) { | ||
| 102 | + boolean b = preView.onKeyDown(keyCode, event); | ||
| 103 | + if (b) { | ||
| 104 | + return b; | ||
| 105 | + } | ||
| 106 | + return super.onKeyDown(keyCode, event); | ||
| 107 | + } | ||
| 108 | +} |
app/strike/src/main/res/layout/activity_img.xml
| @@ -3,11 +3,19 @@ | @@ -3,11 +3,19 @@ | ||
| 3 | android:layout_width="match_parent" | 3 | android:layout_width="match_parent" |
| 4 | android:layout_height="match_parent"> | 4 | android:layout_height="match_parent"> |
| 5 | 5 | ||
| 6 | + | ||
| 7 | + | ||
| 6 | <LinearLayout | 8 | <LinearLayout |
| 7 | android:layout_width="match_parent" | 9 | android:layout_width="match_parent" |
| 8 | android:layout_height="match_parent" | 10 | android:layout_height="match_parent" |
| 9 | android:orientation="vertical"> | 11 | android:orientation="vertical"> |
| 10 | 12 | ||
| 13 | + <Button | ||
| 14 | + android:id="@+id/simpla_see" | ||
| 15 | + android:layout_width="wrap_content" | ||
| 16 | + android:layout_height="wrap_content" | ||
| 17 | + android:text="简单预览" /> | ||
| 18 | + | ||
| 11 | <TextView | 19 | <TextView |
| 12 | android:layout_width="wrap_content" | 20 | android:layout_width="wrap_content" |
| 13 | android:layout_height="wrap_content" | 21 | android:layout_height="wrap_content" |
app/strike/src/main/res/layout/activity_simple_prev.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + tools:context="com.cnlive.strike.imgutil.SimplePrevActivity"> | ||
| 8 | + | ||
| 9 | + <com.cnlive.core.gridview.AutoGridView | ||
| 10 | + android:id="@+id/grid_view" | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="wrap_content"/> | ||
| 13 | + | ||
| 14 | + <com.cnlive.core.imagepreview.ImagePreView | ||
| 15 | + android:id="@+id/image_pre" | ||
| 16 | + android:layout_width="match_parent" | ||
| 17 | + android:layout_height="match_parent"/> | ||
| 18 | +</RelativeLayout> |
core/database/src/main/java/com/cnlive/database/dao/DaoMaster.java
| @@ -29,9 +29,11 @@ public class DaoMaster extends AbstractDaoMaster { | @@ -29,9 +29,11 @@ public class DaoMaster extends AbstractDaoMaster { | ||
| 29 | ContactListDao.createTable(db, ifNotExists); | 29 | ContactListDao.createTable(db, ifNotExists); |
| 30 | ContanctDaRenEntityDao.createTable(db, ifNotExists); | 30 | ContanctDaRenEntityDao.createTable(db, ifNotExists); |
| 31 | ContanctGroupChatEntityDao.createTable(db, ifNotExists); | 31 | ContanctGroupChatEntityDao.createTable(db, ifNotExists); |
| 32 | - DBFriendCircleMessageDao.createTable(db, ifNotExists); | ||
| 33 | DarenDetailMsgDao.createTable(db, ifNotExists); | 32 | DarenDetailMsgDao.createTable(db, ifNotExists); |
| 34 | DarenListMsgDao.createTable(db, ifNotExists); | 33 | DarenListMsgDao.createTable(db, ifNotExists); |
| 34 | + DBFriendCircleMessageDao.createTable(db, ifNotExists); | ||
| 35 | + DBMomentDetailDao.createTable(db, ifNotExists); | ||
| 36 | + DBMomentItemDao.createTable(db, ifNotExists); | ||
| 35 | DownloadInfoDao.createTable(db, ifNotExists); | 37 | DownloadInfoDao.createTable(db, ifNotExists); |
| 36 | ExceptionInfoDao.createTable(db, ifNotExists); | 38 | ExceptionInfoDao.createTable(db, ifNotExists); |
| 37 | HolidayThemeInfoDao.createTable(db, ifNotExists); | 39 | HolidayThemeInfoDao.createTable(db, ifNotExists); |
| @@ -49,9 +51,6 @@ public class DaoMaster extends AbstractDaoMaster { | @@ -49,9 +51,6 @@ public class DaoMaster extends AbstractDaoMaster { | ||
| 49 | SearchHistoryDao.createTable(db, ifNotExists); | 51 | SearchHistoryDao.createTable(db, ifNotExists); |
| 50 | SysNumReadableDao.createTable(db, ifNotExists); | 52 | SysNumReadableDao.createTable(db, ifNotExists); |
| 51 | WitnessDao.createTable(db, ifNotExists); | 53 | WitnessDao.createTable(db, ifNotExists); |
| 52 | - DBMomentDetailDao.createTable(db, ifNotExists); | ||
| 53 | - DBMomentItemDao.createTable(db, ifNotExists); | ||
| 54 | - TestInfoDao.createTable(db, ifNotExists); | ||
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | /** Drops underlying database table using DAOs. */ | 56 | /** Drops underlying database table using DAOs. */ |
| @@ -64,9 +63,11 @@ public class DaoMaster extends AbstractDaoMaster { | @@ -64,9 +63,11 @@ public class DaoMaster extends AbstractDaoMaster { | ||
| 64 | ContactListDao.dropTable(db, ifExists); | 63 | ContactListDao.dropTable(db, ifExists); |
| 65 | ContanctDaRenEntityDao.dropTable(db, ifExists); | 64 | ContanctDaRenEntityDao.dropTable(db, ifExists); |
| 66 | ContanctGroupChatEntityDao.dropTable(db, ifExists); | 65 | ContanctGroupChatEntityDao.dropTable(db, ifExists); |
| 67 | - DBFriendCircleMessageDao.dropTable(db, ifExists); | ||
| 68 | DarenDetailMsgDao.dropTable(db, ifExists); | 66 | DarenDetailMsgDao.dropTable(db, ifExists); |
| 69 | DarenListMsgDao.dropTable(db, ifExists); | 67 | DarenListMsgDao.dropTable(db, ifExists); |
| 68 | + DBFriendCircleMessageDao.dropTable(db, ifExists); | ||
| 69 | + DBMomentDetailDao.dropTable(db, ifExists); | ||
| 70 | + DBMomentItemDao.dropTable(db, ifExists); | ||
| 70 | DownloadInfoDao.dropTable(db, ifExists); | 71 | DownloadInfoDao.dropTable(db, ifExists); |
| 71 | ExceptionInfoDao.dropTable(db, ifExists); | 72 | ExceptionInfoDao.dropTable(db, ifExists); |
| 72 | HolidayThemeInfoDao.dropTable(db, ifExists); | 73 | HolidayThemeInfoDao.dropTable(db, ifExists); |
| @@ -84,9 +85,6 @@ public class DaoMaster extends AbstractDaoMaster { | @@ -84,9 +85,6 @@ public class DaoMaster extends AbstractDaoMaster { | ||
| 84 | SearchHistoryDao.dropTable(db, ifExists); | 85 | SearchHistoryDao.dropTable(db, ifExists); |
| 85 | SysNumReadableDao.dropTable(db, ifExists); | 86 | SysNumReadableDao.dropTable(db, ifExists); |
| 86 | WitnessDao.dropTable(db, ifExists); | 87 | WitnessDao.dropTable(db, ifExists); |
| 87 | - DBMomentDetailDao.dropTable(db, ifExists); | ||
| 88 | - DBMomentItemDao.dropTable(db, ifExists); | ||
| 89 | - TestInfoDao.dropTable(db, ifExists); | ||
| 90 | } | 88 | } |
| 91 | 89 | ||
| 92 | /** | 90 | /** |
| @@ -113,9 +111,11 @@ public class DaoMaster extends AbstractDaoMaster { | @@ -113,9 +111,11 @@ public class DaoMaster extends AbstractDaoMaster { | ||
| 113 | registerDaoClass(ContactListDao.class); | 111 | registerDaoClass(ContactListDao.class); |
| 114 | registerDaoClass(ContanctDaRenEntityDao.class); | 112 | registerDaoClass(ContanctDaRenEntityDao.class); |
| 115 | registerDaoClass(ContanctGroupChatEntityDao.class); | 113 | registerDaoClass(ContanctGroupChatEntityDao.class); |
| 116 | - registerDaoClass(DBFriendCircleMessageDao.class); | ||
| 117 | registerDaoClass(DarenDetailMsgDao.class); | 114 | registerDaoClass(DarenDetailMsgDao.class); |
| 118 | registerDaoClass(DarenListMsgDao.class); | 115 | registerDaoClass(DarenListMsgDao.class); |
| 116 | + registerDaoClass(DBFriendCircleMessageDao.class); | ||
| 117 | + registerDaoClass(DBMomentDetailDao.class); | ||
| 118 | + registerDaoClass(DBMomentItemDao.class); | ||
| 119 | registerDaoClass(DownloadInfoDao.class); | 119 | registerDaoClass(DownloadInfoDao.class); |
| 120 | registerDaoClass(ExceptionInfoDao.class); | 120 | registerDaoClass(ExceptionInfoDao.class); |
| 121 | registerDaoClass(HolidayThemeInfoDao.class); | 121 | registerDaoClass(HolidayThemeInfoDao.class); |
| @@ -133,9 +133,6 @@ public class DaoMaster extends AbstractDaoMaster { | @@ -133,9 +133,6 @@ public class DaoMaster extends AbstractDaoMaster { | ||
| 133 | registerDaoClass(SearchHistoryDao.class); | 133 | registerDaoClass(SearchHistoryDao.class); |
| 134 | registerDaoClass(SysNumReadableDao.class); | 134 | registerDaoClass(SysNumReadableDao.class); |
| 135 | registerDaoClass(WitnessDao.class); | 135 | registerDaoClass(WitnessDao.class); |
| 136 | - registerDaoClass(DBMomentDetailDao.class); | ||
| 137 | - registerDaoClass(DBMomentItemDao.class); | ||
| 138 | - registerDaoClass(TestInfoDao.class); | ||
| 139 | } | 136 | } |
| 140 | 137 | ||
| 141 | public DaoSession newSession() { | 138 | public DaoSession newSession() { |
core/database/src/main/java/com/cnlive/database/dao/DaoSession.java
| @@ -16,9 +16,11 @@ import com.cnlive.database.bean.ChatMedia; | @@ -16,9 +16,11 @@ import com.cnlive.database.bean.ChatMedia; | ||
| 16 | import com.cnlive.database.bean.ContactList; | 16 | import com.cnlive.database.bean.ContactList; |
| 17 | import com.cnlive.database.bean.ContanctDaRenEntity; | 17 | import com.cnlive.database.bean.ContanctDaRenEntity; |
| 18 | import com.cnlive.database.bean.ContanctGroupChatEntity; | 18 | import com.cnlive.database.bean.ContanctGroupChatEntity; |
| 19 | -import com.cnlive.database.bean.DBFriendCircleMessage; | ||
| 20 | import com.cnlive.database.bean.DarenDetailMsg; | 19 | import com.cnlive.database.bean.DarenDetailMsg; |
| 21 | import com.cnlive.database.bean.DarenListMsg; | 20 | import com.cnlive.database.bean.DarenListMsg; |
| 21 | +import com.cnlive.database.bean.DBFriendCircleMessage; | ||
| 22 | +import com.cnlive.database.bean.DBMomentDetail; | ||
| 23 | +import com.cnlive.database.bean.DBMomentItem; | ||
| 22 | import com.cnlive.database.bean.DownloadInfo; | 24 | import com.cnlive.database.bean.DownloadInfo; |
| 23 | import com.cnlive.database.bean.ExceptionInfo; | 25 | import com.cnlive.database.bean.ExceptionInfo; |
| 24 | import com.cnlive.database.bean.HolidayThemeInfo; | 26 | import com.cnlive.database.bean.HolidayThemeInfo; |
| @@ -36,8 +38,37 @@ import com.cnlive.database.bean.SearchContent; | @@ -36,8 +38,37 @@ import com.cnlive.database.bean.SearchContent; | ||
| 36 | import com.cnlive.database.bean.SearchHistory; | 38 | import com.cnlive.database.bean.SearchHistory; |
| 37 | import com.cnlive.database.bean.SysNumReadable; | 39 | import com.cnlive.database.bean.SysNumReadable; |
| 38 | import com.cnlive.database.bean.Witness; | 40 | import com.cnlive.database.bean.Witness; |
| 39 | -import com.cnlive.database.bean.DBMomentDetail; | ||
| 40 | -import com.cnlive.database.bean.DBMomentItem; | 41 | + |
| 42 | +import com.cnlive.database.dao.AudioPlayHistoricalRecordDao; | ||
| 43 | +import com.cnlive.database.dao.AudioPlayLastInfoDao; | ||
| 44 | +import com.cnlive.database.dao.ChatFileMsgDao; | ||
| 45 | +import com.cnlive.database.dao.ChatImageAndVideoMsgDao; | ||
| 46 | +import com.cnlive.database.dao.ChatMediaDao; | ||
| 47 | +import com.cnlive.database.dao.ContactListDao; | ||
| 48 | +import com.cnlive.database.dao.ContanctDaRenEntityDao; | ||
| 49 | +import com.cnlive.database.dao.ContanctGroupChatEntityDao; | ||
| 50 | +import com.cnlive.database.dao.DarenDetailMsgDao; | ||
| 51 | +import com.cnlive.database.dao.DarenListMsgDao; | ||
| 52 | +import com.cnlive.database.dao.DBFriendCircleMessageDao; | ||
| 53 | +import com.cnlive.database.dao.DBMomentDetailDao; | ||
| 54 | +import com.cnlive.database.dao.DBMomentItemDao; | ||
| 55 | +import com.cnlive.database.dao.DownloadInfoDao; | ||
| 56 | +import com.cnlive.database.dao.ExceptionInfoDao; | ||
| 57 | +import com.cnlive.database.dao.HolidayThemeInfoDao; | ||
| 58 | +import com.cnlive.database.dao.IMConversationInfoDao; | ||
| 59 | +import com.cnlive.database.dao.IMGroupFaceMemberIdsDao; | ||
| 60 | +import com.cnlive.database.dao.IMGroupMembersDao; | ||
| 61 | +import com.cnlive.database.dao.IMGroupMembersListDao; | ||
| 62 | +import com.cnlive.database.dao.IMGroupMembersManagerListDao; | ||
| 63 | +import com.cnlive.database.dao.IMUserInfoDao; | ||
| 64 | +import com.cnlive.database.dao.LaunchAdInfoDao; | ||
| 65 | +import com.cnlive.database.dao.NewContactFriendEntityDao; | ||
| 66 | +import com.cnlive.database.dao.NewPhoneContactEntityDao; | ||
| 67 | +import com.cnlive.database.dao.NewsNumberDao; | ||
| 68 | +import com.cnlive.database.dao.SearchContentDao; | ||
| 69 | +import com.cnlive.database.dao.SearchHistoryDao; | ||
| 70 | +import com.cnlive.database.dao.SysNumReadableDao; | ||
| 71 | +import com.cnlive.database.dao.WitnessDao; | ||
| 41 | 72 | ||
| 42 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. | 73 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. |
| 43 | 74 | ||
| @@ -56,9 +87,11 @@ public class DaoSession extends AbstractDaoSession { | @@ -56,9 +87,11 @@ public class DaoSession extends AbstractDaoSession { | ||
| 56 | private final DaoConfig contactListDaoConfig; | 87 | private final DaoConfig contactListDaoConfig; |
| 57 | private final DaoConfig contanctDaRenEntityDaoConfig; | 88 | private final DaoConfig contanctDaRenEntityDaoConfig; |
| 58 | private final DaoConfig contanctGroupChatEntityDaoConfig; | 89 | private final DaoConfig contanctGroupChatEntityDaoConfig; |
| 59 | - private final DaoConfig dBFriendCircleMessageDaoConfig; | ||
| 60 | private final DaoConfig darenDetailMsgDaoConfig; | 90 | private final DaoConfig darenDetailMsgDaoConfig; |
| 61 | private final DaoConfig darenListMsgDaoConfig; | 91 | private final DaoConfig darenListMsgDaoConfig; |
| 92 | + private final DaoConfig dBFriendCircleMessageDaoConfig; | ||
| 93 | + private final DaoConfig dBMomentDetailDaoConfig; | ||
| 94 | + private final DaoConfig dBMomentItemDaoConfig; | ||
| 62 | private final DaoConfig downloadInfoDaoConfig; | 95 | private final DaoConfig downloadInfoDaoConfig; |
| 63 | private final DaoConfig exceptionInfoDaoConfig; | 96 | private final DaoConfig exceptionInfoDaoConfig; |
| 64 | private final DaoConfig holidayThemeInfoDaoConfig; | 97 | private final DaoConfig holidayThemeInfoDaoConfig; |
| @@ -76,9 +109,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -76,9 +109,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 76 | private final DaoConfig searchHistoryDaoConfig; | 109 | private final DaoConfig searchHistoryDaoConfig; |
| 77 | private final DaoConfig sysNumReadableDaoConfig; | 110 | private final DaoConfig sysNumReadableDaoConfig; |
| 78 | private final DaoConfig witnessDaoConfig; | 111 | private final DaoConfig witnessDaoConfig; |
| 79 | - private final DaoConfig dBMomentDetailDaoConfig; | ||
| 80 | - private final DaoConfig dBMomentItemDaoConfig; | ||
| 81 | - private final DaoConfig testInfoDaoConfig; | ||
| 82 | 112 | ||
| 83 | private final AudioPlayHistoricalRecordDao audioPlayHistoricalRecordDao; | 113 | private final AudioPlayHistoricalRecordDao audioPlayHistoricalRecordDao; |
| 84 | private final AudioPlayLastInfoDao audioPlayLastInfoDao; | 114 | private final AudioPlayLastInfoDao audioPlayLastInfoDao; |
| @@ -88,9 +118,11 @@ public class DaoSession extends AbstractDaoSession { | @@ -88,9 +118,11 @@ public class DaoSession extends AbstractDaoSession { | ||
| 88 | private final ContactListDao contactListDao; | 118 | private final ContactListDao contactListDao; |
| 89 | private final ContanctDaRenEntityDao contanctDaRenEntityDao; | 119 | private final ContanctDaRenEntityDao contanctDaRenEntityDao; |
| 90 | private final ContanctGroupChatEntityDao contanctGroupChatEntityDao; | 120 | private final ContanctGroupChatEntityDao contanctGroupChatEntityDao; |
| 91 | - private final DBFriendCircleMessageDao dBFriendCircleMessageDao; | ||
| 92 | private final DarenDetailMsgDao darenDetailMsgDao; | 121 | private final DarenDetailMsgDao darenDetailMsgDao; |
| 93 | private final DarenListMsgDao darenListMsgDao; | 122 | private final DarenListMsgDao darenListMsgDao; |
| 123 | + private final DBFriendCircleMessageDao dBFriendCircleMessageDao; | ||
| 124 | + private final DBMomentDetailDao dBMomentDetailDao; | ||
| 125 | + private final DBMomentItemDao dBMomentItemDao; | ||
| 94 | private final DownloadInfoDao downloadInfoDao; | 126 | private final DownloadInfoDao downloadInfoDao; |
| 95 | private final ExceptionInfoDao exceptionInfoDao; | 127 | private final ExceptionInfoDao exceptionInfoDao; |
| 96 | private final HolidayThemeInfoDao holidayThemeInfoDao; | 128 | private final HolidayThemeInfoDao holidayThemeInfoDao; |
| @@ -108,9 +140,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -108,9 +140,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 108 | private final SearchHistoryDao searchHistoryDao; | 140 | private final SearchHistoryDao searchHistoryDao; |
| 109 | private final SysNumReadableDao sysNumReadableDao; | 141 | private final SysNumReadableDao sysNumReadableDao; |
| 110 | private final WitnessDao witnessDao; | 142 | private final WitnessDao witnessDao; |
| 111 | - private final DBMomentDetailDao dBMomentDetailDao; | ||
| 112 | - private final DBMomentItemDao dBMomentItemDao; | ||
| 113 | - private final TestInfoDao testInfoDao; | ||
| 114 | 143 | ||
| 115 | public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> | 144 | public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> |
| 116 | daoConfigMap) { | 145 | daoConfigMap) { |
| @@ -140,15 +169,21 @@ public class DaoSession extends AbstractDaoSession { | @@ -140,15 +169,21 @@ public class DaoSession extends AbstractDaoSession { | ||
| 140 | contanctGroupChatEntityDaoConfig = daoConfigMap.get(ContanctGroupChatEntityDao.class).clone(); | 169 | contanctGroupChatEntityDaoConfig = daoConfigMap.get(ContanctGroupChatEntityDao.class).clone(); |
| 141 | contanctGroupChatEntityDaoConfig.initIdentityScope(type); | 170 | contanctGroupChatEntityDaoConfig.initIdentityScope(type); |
| 142 | 171 | ||
| 143 | - dBFriendCircleMessageDaoConfig = daoConfigMap.get(DBFriendCircleMessageDao.class).clone(); | ||
| 144 | - dBFriendCircleMessageDaoConfig.initIdentityScope(type); | ||
| 145 | - | ||
| 146 | darenDetailMsgDaoConfig = daoConfigMap.get(DarenDetailMsgDao.class).clone(); | 172 | darenDetailMsgDaoConfig = daoConfigMap.get(DarenDetailMsgDao.class).clone(); |
| 147 | darenDetailMsgDaoConfig.initIdentityScope(type); | 173 | darenDetailMsgDaoConfig.initIdentityScope(type); |
| 148 | 174 | ||
| 149 | darenListMsgDaoConfig = daoConfigMap.get(DarenListMsgDao.class).clone(); | 175 | darenListMsgDaoConfig = daoConfigMap.get(DarenListMsgDao.class).clone(); |
| 150 | darenListMsgDaoConfig.initIdentityScope(type); | 176 | darenListMsgDaoConfig.initIdentityScope(type); |
| 151 | 177 | ||
| 178 | + dBFriendCircleMessageDaoConfig = daoConfigMap.get(DBFriendCircleMessageDao.class).clone(); | ||
| 179 | + dBFriendCircleMessageDaoConfig.initIdentityScope(type); | ||
| 180 | + | ||
| 181 | + dBMomentDetailDaoConfig = daoConfigMap.get(DBMomentDetailDao.class).clone(); | ||
| 182 | + dBMomentDetailDaoConfig.initIdentityScope(type); | ||
| 183 | + | ||
| 184 | + dBMomentItemDaoConfig = daoConfigMap.get(DBMomentItemDao.class).clone(); | ||
| 185 | + dBMomentItemDaoConfig.initIdentityScope(type); | ||
| 186 | + | ||
| 152 | downloadInfoDaoConfig = daoConfigMap.get(DownloadInfoDao.class).clone(); | 187 | downloadInfoDaoConfig = daoConfigMap.get(DownloadInfoDao.class).clone(); |
| 153 | downloadInfoDaoConfig.initIdentityScope(type); | 188 | downloadInfoDaoConfig.initIdentityScope(type); |
| 154 | 189 | ||
| @@ -200,15 +235,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -200,15 +235,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 200 | witnessDaoConfig = daoConfigMap.get(WitnessDao.class).clone(); | 235 | witnessDaoConfig = daoConfigMap.get(WitnessDao.class).clone(); |
| 201 | witnessDaoConfig.initIdentityScope(type); | 236 | witnessDaoConfig.initIdentityScope(type); |
| 202 | 237 | ||
| 203 | - dBMomentDetailDaoConfig = daoConfigMap.get(DBMomentDetailDao.class).clone(); | ||
| 204 | - dBMomentDetailDaoConfig.initIdentityScope(type); | ||
| 205 | - | ||
| 206 | - dBMomentItemDaoConfig = daoConfigMap.get(DBMomentItemDao.class).clone(); | ||
| 207 | - dBMomentItemDaoConfig.initIdentityScope(type); | ||
| 208 | - | ||
| 209 | - testInfoDaoConfig = daoConfigMap.get(TestInfoDao.class).clone(); | ||
| 210 | - testInfoDaoConfig.initIdentityScope(type); | ||
| 211 | - | ||
| 212 | audioPlayHistoricalRecordDao = new AudioPlayHistoricalRecordDao(audioPlayHistoricalRecordDaoConfig, this); | 238 | audioPlayHistoricalRecordDao = new AudioPlayHistoricalRecordDao(audioPlayHistoricalRecordDaoConfig, this); |
| 213 | audioPlayLastInfoDao = new AudioPlayLastInfoDao(audioPlayLastInfoDaoConfig, this); | 239 | audioPlayLastInfoDao = new AudioPlayLastInfoDao(audioPlayLastInfoDaoConfig, this); |
| 214 | chatFileMsgDao = new ChatFileMsgDao(chatFileMsgDaoConfig, this); | 240 | chatFileMsgDao = new ChatFileMsgDao(chatFileMsgDaoConfig, this); |
| @@ -217,9 +243,11 @@ public class DaoSession extends AbstractDaoSession { | @@ -217,9 +243,11 @@ public class DaoSession extends AbstractDaoSession { | ||
| 217 | contactListDao = new ContactListDao(contactListDaoConfig, this); | 243 | contactListDao = new ContactListDao(contactListDaoConfig, this); |
| 218 | contanctDaRenEntityDao = new ContanctDaRenEntityDao(contanctDaRenEntityDaoConfig, this); | 244 | contanctDaRenEntityDao = new ContanctDaRenEntityDao(contanctDaRenEntityDaoConfig, this); |
| 219 | contanctGroupChatEntityDao = new ContanctGroupChatEntityDao(contanctGroupChatEntityDaoConfig, this); | 245 | contanctGroupChatEntityDao = new ContanctGroupChatEntityDao(contanctGroupChatEntityDaoConfig, this); |
| 220 | - dBFriendCircleMessageDao = new DBFriendCircleMessageDao(dBFriendCircleMessageDaoConfig, this); | ||
| 221 | darenDetailMsgDao = new DarenDetailMsgDao(darenDetailMsgDaoConfig, this); | 246 | darenDetailMsgDao = new DarenDetailMsgDao(darenDetailMsgDaoConfig, this); |
| 222 | darenListMsgDao = new DarenListMsgDao(darenListMsgDaoConfig, this); | 247 | darenListMsgDao = new DarenListMsgDao(darenListMsgDaoConfig, this); |
| 248 | + dBFriendCircleMessageDao = new DBFriendCircleMessageDao(dBFriendCircleMessageDaoConfig, this); | ||
| 249 | + dBMomentDetailDao = new DBMomentDetailDao(dBMomentDetailDaoConfig, this); | ||
| 250 | + dBMomentItemDao = new DBMomentItemDao(dBMomentItemDaoConfig, this); | ||
| 223 | downloadInfoDao = new DownloadInfoDao(downloadInfoDaoConfig, this); | 251 | downloadInfoDao = new DownloadInfoDao(downloadInfoDaoConfig, this); |
| 224 | exceptionInfoDao = new ExceptionInfoDao(exceptionInfoDaoConfig, this); | 252 | exceptionInfoDao = new ExceptionInfoDao(exceptionInfoDaoConfig, this); |
| 225 | holidayThemeInfoDao = new HolidayThemeInfoDao(holidayThemeInfoDaoConfig, this); | 253 | holidayThemeInfoDao = new HolidayThemeInfoDao(holidayThemeInfoDaoConfig, this); |
| @@ -237,9 +265,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -237,9 +265,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 237 | searchHistoryDao = new SearchHistoryDao(searchHistoryDaoConfig, this); | 265 | searchHistoryDao = new SearchHistoryDao(searchHistoryDaoConfig, this); |
| 238 | sysNumReadableDao = new SysNumReadableDao(sysNumReadableDaoConfig, this); | 266 | sysNumReadableDao = new SysNumReadableDao(sysNumReadableDaoConfig, this); |
| 239 | witnessDao = new WitnessDao(witnessDaoConfig, this); | 267 | witnessDao = new WitnessDao(witnessDaoConfig, this); |
| 240 | - dBMomentDetailDao = new DBMomentDetailDao(dBMomentDetailDaoConfig, this); | ||
| 241 | - dBMomentItemDao = new DBMomentItemDao(dBMomentItemDaoConfig, this); | ||
| 242 | - testInfoDao = new TestInfoDao(testInfoDaoConfig, this); | ||
| 243 | 268 | ||
| 244 | registerDao(AudioPlayHistoricalRecord.class, audioPlayHistoricalRecordDao); | 269 | registerDao(AudioPlayHistoricalRecord.class, audioPlayHistoricalRecordDao); |
| 245 | registerDao(AudioPlayLastInfo.class, audioPlayLastInfoDao); | 270 | registerDao(AudioPlayLastInfo.class, audioPlayLastInfoDao); |
| @@ -249,9 +274,11 @@ public class DaoSession extends AbstractDaoSession { | @@ -249,9 +274,11 @@ public class DaoSession extends AbstractDaoSession { | ||
| 249 | registerDao(ContactList.class, contactListDao); | 274 | registerDao(ContactList.class, contactListDao); |
| 250 | registerDao(ContanctDaRenEntity.class, contanctDaRenEntityDao); | 275 | registerDao(ContanctDaRenEntity.class, contanctDaRenEntityDao); |
| 251 | registerDao(ContanctGroupChatEntity.class, contanctGroupChatEntityDao); | 276 | registerDao(ContanctGroupChatEntity.class, contanctGroupChatEntityDao); |
| 252 | - registerDao(DBFriendCircleMessage.class, dBFriendCircleMessageDao); | ||
| 253 | registerDao(DarenDetailMsg.class, darenDetailMsgDao); | 277 | registerDao(DarenDetailMsg.class, darenDetailMsgDao); |
| 254 | registerDao(DarenListMsg.class, darenListMsgDao); | 278 | registerDao(DarenListMsg.class, darenListMsgDao); |
| 279 | + registerDao(DBFriendCircleMessage.class, dBFriendCircleMessageDao); | ||
| 280 | + registerDao(DBMomentDetail.class, dBMomentDetailDao); | ||
| 281 | + registerDao(DBMomentItem.class, dBMomentItemDao); | ||
| 255 | registerDao(DownloadInfo.class, downloadInfoDao); | 282 | registerDao(DownloadInfo.class, downloadInfoDao); |
| 256 | registerDao(ExceptionInfo.class, exceptionInfoDao); | 283 | registerDao(ExceptionInfo.class, exceptionInfoDao); |
| 257 | registerDao(HolidayThemeInfo.class, holidayThemeInfoDao); | 284 | registerDao(HolidayThemeInfo.class, holidayThemeInfoDao); |
| @@ -269,9 +296,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -269,9 +296,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 269 | registerDao(SearchHistory.class, searchHistoryDao); | 296 | registerDao(SearchHistory.class, searchHistoryDao); |
| 270 | registerDao(SysNumReadable.class, sysNumReadableDao); | 297 | registerDao(SysNumReadable.class, sysNumReadableDao); |
| 271 | registerDao(Witness.class, witnessDao); | 298 | registerDao(Witness.class, witnessDao); |
| 272 | - registerDao(DBMomentDetail.class, dBMomentDetailDao); | ||
| 273 | - registerDao(DBMomentItem.class, dBMomentItemDao); | ||
| 274 | - registerDao(TestInfo.class, testInfoDao); | ||
| 275 | } | 299 | } |
| 276 | 300 | ||
| 277 | public void clear() { | 301 | public void clear() { |
| @@ -283,9 +307,11 @@ public class DaoSession extends AbstractDaoSession { | @@ -283,9 +307,11 @@ public class DaoSession extends AbstractDaoSession { | ||
| 283 | contactListDaoConfig.clearIdentityScope(); | 307 | contactListDaoConfig.clearIdentityScope(); |
| 284 | contanctDaRenEntityDaoConfig.clearIdentityScope(); | 308 | contanctDaRenEntityDaoConfig.clearIdentityScope(); |
| 285 | contanctGroupChatEntityDaoConfig.clearIdentityScope(); | 309 | contanctGroupChatEntityDaoConfig.clearIdentityScope(); |
| 286 | - dBFriendCircleMessageDaoConfig.clearIdentityScope(); | ||
| 287 | darenDetailMsgDaoConfig.clearIdentityScope(); | 310 | darenDetailMsgDaoConfig.clearIdentityScope(); |
| 288 | darenListMsgDaoConfig.clearIdentityScope(); | 311 | darenListMsgDaoConfig.clearIdentityScope(); |
| 312 | + dBFriendCircleMessageDaoConfig.clearIdentityScope(); | ||
| 313 | + dBMomentDetailDaoConfig.clearIdentityScope(); | ||
| 314 | + dBMomentItemDaoConfig.clearIdentityScope(); | ||
| 289 | downloadInfoDaoConfig.clearIdentityScope(); | 315 | downloadInfoDaoConfig.clearIdentityScope(); |
| 290 | exceptionInfoDaoConfig.clearIdentityScope(); | 316 | exceptionInfoDaoConfig.clearIdentityScope(); |
| 291 | holidayThemeInfoDaoConfig.clearIdentityScope(); | 317 | holidayThemeInfoDaoConfig.clearIdentityScope(); |
| @@ -303,9 +329,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -303,9 +329,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 303 | searchHistoryDaoConfig.clearIdentityScope(); | 329 | searchHistoryDaoConfig.clearIdentityScope(); |
| 304 | sysNumReadableDaoConfig.clearIdentityScope(); | 330 | sysNumReadableDaoConfig.clearIdentityScope(); |
| 305 | witnessDaoConfig.clearIdentityScope(); | 331 | witnessDaoConfig.clearIdentityScope(); |
| 306 | - dBMomentDetailDaoConfig.clearIdentityScope(); | ||
| 307 | - dBMomentItemDaoConfig.clearIdentityScope(); | ||
| 308 | - testInfoDaoConfig.clearIdentityScope(); | ||
| 309 | } | 332 | } |
| 310 | 333 | ||
| 311 | public AudioPlayHistoricalRecordDao getAudioPlayHistoricalRecordDao() { | 334 | public AudioPlayHistoricalRecordDao getAudioPlayHistoricalRecordDao() { |
| @@ -340,10 +363,6 @@ public class DaoSession extends AbstractDaoSession { | @@ -340,10 +363,6 @@ public class DaoSession extends AbstractDaoSession { | ||
| 340 | return contanctGroupChatEntityDao; | 363 | return contanctGroupChatEntityDao; |
| 341 | } | 364 | } |
| 342 | 365 | ||
| 343 | - public DBFriendCircleMessageDao getDBFriendCircleMessageDao() { | ||
| 344 | - return dBFriendCircleMessageDao; | ||
| 345 | - } | ||
| 346 | - | ||
| 347 | public DarenDetailMsgDao getDarenDetailMsgDao() { | 366 | public DarenDetailMsgDao getDarenDetailMsgDao() { |
| 348 | return darenDetailMsgDao; | 367 | return darenDetailMsgDao; |
| 349 | } | 368 | } |
| @@ -352,6 +371,18 @@ public class DaoSession extends AbstractDaoSession { | @@ -352,6 +371,18 @@ public class DaoSession extends AbstractDaoSession { | ||
| 352 | return darenListMsgDao; | 371 | return darenListMsgDao; |
| 353 | } | 372 | } |
| 354 | 373 | ||
| 374 | + public DBFriendCircleMessageDao getDBFriendCircleMessageDao() { | ||
| 375 | + return dBFriendCircleMessageDao; | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + public DBMomentDetailDao getDBMomentDetailDao() { | ||
| 379 | + return dBMomentDetailDao; | ||
| 380 | + } | ||
| 381 | + | ||
| 382 | + public DBMomentItemDao getDBMomentItemDao() { | ||
| 383 | + return dBMomentItemDao; | ||
| 384 | + } | ||
| 385 | + | ||
| 355 | public DownloadInfoDao getDownloadInfoDao() { | 386 | public DownloadInfoDao getDownloadInfoDao() { |
| 356 | return downloadInfoDao; | 387 | return downloadInfoDao; |
| 357 | } | 388 | } |
| @@ -420,16 +451,4 @@ public class DaoSession extends AbstractDaoSession { | @@ -420,16 +451,4 @@ public class DaoSession extends AbstractDaoSession { | ||
| 420 | return witnessDao; | 451 | return witnessDao; |
| 421 | } | 452 | } |
| 422 | 453 | ||
| 423 | - public DBMomentDetailDao getDBMomentDetailDao() { | ||
| 424 | - return dBMomentDetailDao; | ||
| 425 | - } | ||
| 426 | - | ||
| 427 | - public DBMomentItemDao getDBMomentItemDao() { | ||
| 428 | - return dBMomentItemDao; | ||
| 429 | - } | ||
| 430 | - | ||
| 431 | - public TestInfoDao getTestInfoDao() { | ||
| 432 | - return testInfoDao; | ||
| 433 | - } | ||
| 434 | - | ||
| 435 | } | 454 | } |
core/imageload/src/main/java/com/cnlive/core/gridview/AutoGridMode.java
0 → 100644
| 1 | +package com.cnlive.core.gridview; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.Retention; | ||
| 4 | +import java.lang.annotation.RetentionPolicy; | ||
| 5 | + | ||
| 6 | +import androidx.annotation.IntDef; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * created by hanyayun | ||
| 10 | + * on 2020/2/13 | ||
| 11 | + */ | ||
| 12 | +@IntDef({AutoGridMode.GRID_NINE, | ||
| 13 | + AutoGridMode.GRID_NORMAL}) | ||
| 14 | +@Retention(RetentionPolicy.SOURCE) | ||
| 15 | +public @interface AutoGridMode { | ||
| 16 | + // 网格图的两种模式中的九宫格模式 | ||
| 17 | + int GRID_NINE = 0; | ||
| 18 | + // 网格图的两种模式中的普通模式 | ||
| 19 | + int GRID_NORMAL = 1; | ||
| 20 | +} |
core/imageload/src/main/java/com/cnlive/core/gridview/AutoGridView.java
0 → 100644
| 1 | +package com.cnlive.core.gridview; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.content.res.TypedArray; | ||
| 5 | +import android.database.DataSetObserver; | ||
| 6 | +import android.util.AttributeSet; | ||
| 7 | +import android.view.View; | ||
| 8 | +import android.view.ViewGroup; | ||
| 9 | + | ||
| 10 | +import com.cnlive.core.gridview.adapter.BaseAutoGridAdapter; | ||
| 11 | +import com.cnlive.core.gridview.model.SizeHelper; | ||
| 12 | +import com.cnlive.core.gridview.model.SizeInfo; | ||
| 13 | +import com.cnlive.core.gridview.model.SizeParam; | ||
| 14 | +import com.cnlive.core.imageload.R; | ||
| 15 | + | ||
| 16 | +import java.lang.ref.SoftReference; | ||
| 17 | +import java.util.ArrayList; | ||
| 18 | +import java.util.HashMap; | ||
| 19 | +import java.util.List; | ||
| 20 | + | ||
| 21 | +import androidx.annotation.FloatRange; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * created by hanyayun | ||
| 25 | + * on 2020/2/13 | ||
| 26 | + */ | ||
| 27 | +public class AutoGridView extends ViewGroup { | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * 默认值 | ||
| 31 | + */ | ||
| 32 | + // 无效的值 | ||
| 33 | + private static final int INVALID_VAL = -1; | ||
| 34 | + // 默认网格图模式 | ||
| 35 | + private static final int DEF_MODE = AutoGridMode.GRID_NINE; | ||
| 36 | + // 默认的 item 最大行数 | ||
| 37 | + private static final int DEF_ROW = 3; | ||
| 38 | + // 默认的 item 最大列数 | ||
| 39 | + private static final int DEF_COLUMN = 3; | ||
| 40 | + // 默认的 item 高度 | ||
| 41 | + public static final int DEF_ITEM_HEIGHT = INVALID_VAL; | ||
| 42 | + // 默认的 item 横向间距 | ||
| 43 | + private static final int DEF_HORIZONTAL_SPACE = 10; | ||
| 44 | + // 默认的 item 纵向间距 | ||
| 45 | + private static final int DEF_VERTICAL_SPACE = 10; | ||
| 46 | + // 九宫格模式时,当只有一个 item 时,item 的宽与父容器可用总宽度(即去除左右 padding 后的 width )的比 | ||
| 47 | + // 此处默认 DEF_SINGLE_WIDTH_PERCENT 为无效值,即 item 的宽度自适应 | ||
| 48 | + private static final float DEF_SINGLE_WIDTH_PERCENT = INVALID_VAL; | ||
| 49 | + // 九宫格模式时,当只有一个 item 时,item 的高与父容器可用总宽度(即去除左右 padding 后的 width )的比 | ||
| 50 | + private static final float DEF_SINGLE_HEIGHT_PERCENT = INVALID_VAL; | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 变量 | ||
| 54 | + */ | ||
| 55 | + // 网格图的模式 | ||
| 56 | + private int mMode; | ||
| 57 | + // item 的行数 | ||
| 58 | + private int mRow; | ||
| 59 | + // item 的列数 | ||
| 60 | + private int mColumn; | ||
| 61 | + // item 的高度 | ||
| 62 | + private float mItemHeight; | ||
| 63 | + // item 之间的横向间距 | ||
| 64 | + private float mHorizontalSpace; | ||
| 65 | + // item 之间的纵向间距 | ||
| 66 | + private float mVerticalSpace; | ||
| 67 | + // 九宫格模式时,当只有一个 item 时,item 的宽与父容器可用总宽度(即去除左右 padding 后的 width )的比 | ||
| 68 | + private float mNineSingleWidthPer; | ||
| 69 | + // 九宫格模式时,当只有一个 item 时,item 的高与父容器可用总宽度(即去除左右 padding 后的 width )的比 | ||
| 70 | + private float mNineSingleHeightPer; | ||
| 71 | + | ||
| 72 | + // 网格数据计算辅助类 | ||
| 73 | + private SizeHelper mSizeHelper; | ||
| 74 | + private SizeParam mSizeParam; | ||
| 75 | + // SizeHelper 中计算结果后,返回的结果类 | ||
| 76 | + private SizeInfo mSizeInfo; | ||
| 77 | + // 缓存 item 的 viewType | ||
| 78 | + private ArrayList<String> mCacheTypeBin; | ||
| 79 | + // 缓存器,存储 item,用于复用 | ||
| 80 | + private HashMap<String, List<SoftReference<View>>> mCacheBin; | ||
| 81 | + private AdapterObserver mDataSetObserver; | ||
| 82 | + private BaseAutoGridAdapter mAdapter; | ||
| 83 | + private OnItemClickListener mItemClickListener; | ||
| 84 | + private OnItemLongClickListener mItemLongClickListener; | ||
| 85 | + | ||
| 86 | + public AutoGridView(Context context) { | ||
| 87 | + super(context); | ||
| 88 | + init(context, null); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + public AutoGridView(Context context, AttributeSet attrs) { | ||
| 92 | + super(context, attrs); | ||
| 93 | + init(context, attrs); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + public AutoGridView(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 97 | + super(context, attrs, defStyleAttr); | ||
| 98 | + init(context, attrs); | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + private void init(Context context, AttributeSet attrs) { | ||
| 102 | + initData(); | ||
| 103 | + if (attrs != null) { | ||
| 104 | + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoGridView); | ||
| 105 | + if (a != null) { | ||
| 106 | + mMode = a.getInt(R.styleable.AutoGridView_agv_mode, DEF_MODE); | ||
| 107 | + mRow = a.getInt(R.styleable.AutoGridView_agv_row, DEF_ROW); | ||
| 108 | + mColumn = a.getInt(R.styleable.AutoGridView_agv_column, DEF_COLUMN); | ||
| 109 | + mItemHeight = a.getDimension(R.styleable.AutoGridView_agv_item_height, DEF_ITEM_HEIGHT); | ||
| 110 | + mHorizontalSpace = a.getDimension(R.styleable.AutoGridView_agv_horizontal_space, DEF_HORIZONTAL_SPACE); | ||
| 111 | + mVerticalSpace = a.getDimension(R.styleable.AutoGridView_agv_vertical_space, DEF_VERTICAL_SPACE); | ||
| 112 | + mNineSingleWidthPer = a.getFloat(R.styleable.AutoGridView_agv_nines_widthper, DEF_SINGLE_WIDTH_PERCENT); | ||
| 113 | + mNineSingleHeightPer = a.getFloat(R.styleable.AutoGridView_agv_nines_heightper, DEF_SINGLE_HEIGHT_PERCENT); | ||
| 114 | + a.recycle(); | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + private void initData() { | ||
| 120 | + mMode = DEF_MODE; | ||
| 121 | + mRow = DEF_ROW; | ||
| 122 | + mColumn = DEF_COLUMN; | ||
| 123 | + mItemHeight = DEF_ITEM_HEIGHT; | ||
| 124 | + mHorizontalSpace = DEF_HORIZONTAL_SPACE; | ||
| 125 | + mVerticalSpace = DEF_VERTICAL_SPACE; | ||
| 126 | + mNineSingleWidthPer = DEF_SINGLE_WIDTH_PERCENT; | ||
| 127 | + mNineSingleHeightPer = DEF_SINGLE_HEIGHT_PERCENT; | ||
| 128 | + | ||
| 129 | + mSizeHelper = new SizeHelper(); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + public void setAdapter(BaseAutoGridAdapter adapter) { | ||
| 133 | + if (mAdapter != null && mDataSetObserver != null) { | ||
| 134 | + // 删除已经存在的观察者 | ||
| 135 | + mAdapter.unregisterDataSetObserver(mDataSetObserver); | ||
| 136 | + } | ||
| 137 | + removeAllViews(); | ||
| 138 | + // 清空缓存器 | ||
| 139 | + if (mCacheTypeBin != null) { | ||
| 140 | + mCacheTypeBin.clear(); | ||
| 141 | + } | ||
| 142 | + if (mCacheBin != null) { | ||
| 143 | + mCacheBin.clear(); | ||
| 144 | + } | ||
| 145 | + // 重置 adapter | ||
| 146 | + mAdapter = adapter; | ||
| 147 | + if (mAdapter != null) { | ||
| 148 | + mDataSetObserver = new AdapterObserver(); | ||
| 149 | + // 注册观察者 | ||
| 150 | + mAdapter.registerDataSetObserver(mDataSetObserver); | ||
| 151 | + if (mAdapter.getItemCount() > 0) { | ||
| 152 | + addItemViews(); | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + /** | ||
| 158 | + * 通知刷新 | ||
| 159 | + */ | ||
| 160 | + private void notifyChanged() { | ||
| 161 | + if (mAdapter != null) { | ||
| 162 | + int newSize = mAdapter.getItemCount(); | ||
| 163 | + if (newSize == 0) { | ||
| 164 | + if (mCacheTypeBin != null) { | ||
| 165 | + mCacheTypeBin.clear(); | ||
| 166 | + } | ||
| 167 | + if (mCacheBin != null) { | ||
| 168 | + mCacheBin.clear(); | ||
| 169 | + } | ||
| 170 | + } else { | ||
| 171 | + if (mCacheBin == null) mCacheBin = new HashMap<>(); | ||
| 172 | + for (int i = 0, len = mCacheTypeBin.size(); i < len; i++) { | ||
| 173 | + String key = mCacheTypeBin.get(i); | ||
| 174 | + List<SoftReference<View>> views = mCacheBin.get(key); | ||
| 175 | + views = (views != null ? views : new ArrayList<SoftReference<View>>()); | ||
| 176 | + views.add(new SoftReference<View>(getChildAt(i))); | ||
| 177 | + mCacheBin.put(key, views); | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + removeAllViews(); | ||
| 181 | + if (mCacheTypeBin != null) { | ||
| 182 | + mCacheTypeBin.clear(); | ||
| 183 | + } | ||
| 184 | + for (int i = 0; i < newSize; i++) { | ||
| 185 | + String key = mMode + "_" + mAdapter.getItemViewType(i); | ||
| 186 | + mCacheTypeBin.add(key); | ||
| 187 | + // 从缓存器中取出 key 类型的 view 列表 | ||
| 188 | + List<SoftReference<View>> views = mCacheBin.get(key); | ||
| 189 | + /** 此处做简单的缓存复用处理 */ | ||
| 190 | + if (views != null && views.size() > 0) { | ||
| 191 | + boolean isAddItem = false; | ||
| 192 | + for (SoftReference<View> softReference : views) { | ||
| 193 | + if (softReference != null && softReference.get() != null) { | ||
| 194 | + View itemView = softReference.get(); | ||
| 195 | + // 如果列表中的 item 还没有父容器,则复用该 item | ||
| 196 | + if (itemView.getParent() == null) { | ||
| 197 | + addItemClickListener(itemView, i); | ||
| 198 | + addItemLongClickListener(itemView, i); | ||
| 199 | + addView(mAdapter.getView(i, itemView, this), new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 200 | + isAddItem = true; | ||
| 201 | + views.remove(itemView); | ||
| 202 | + mCacheBin.put(key, views); | ||
| 203 | + break; | ||
| 204 | + } | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | + // 如果从 views 中未找到匹配的 item ,则新建 item | ||
| 208 | + if (!isAddItem) { | ||
| 209 | + View itemView = mAdapter.getView(i, null, this); | ||
| 210 | + // 将新建的 item 存入列表中 | ||
| 211 | + views.add(new SoftReference<View>(itemView)); | ||
| 212 | + addItemClickListener(itemView, i); | ||
| 213 | + addItemLongClickListener(itemView, i); | ||
| 214 | + addView(itemView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + // 如果没有 key 类型的 view 存在,则新建 item | ||
| 218 | + else { | ||
| 219 | + View itemView = mAdapter.getView(i, null, this); | ||
| 220 | + views = (views != null ? views : new ArrayList<SoftReference<View>>()); | ||
| 221 | + views.add(new SoftReference<View>(itemView)); | ||
| 222 | + addItemClickListener(itemView, i); | ||
| 223 | + addItemLongClickListener(itemView, i); | ||
| 224 | + addView(itemView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 225 | + } | ||
| 226 | + } | ||
| 227 | + if (mCacheBin != null && mCacheBin.size() > 0) { | ||
| 228 | + mCacheBin.clear(); | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + requestLayout(); | ||
| 232 | + invalidate(); | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + /** | ||
| 236 | + * 添加 item | ||
| 237 | + */ | ||
| 238 | + private void addItemViews() { | ||
| 239 | + int totalCount = mAdapter.getItemCount(); | ||
| 240 | + int maxCount = mRow * mColumn; | ||
| 241 | + int childCount = totalCount > maxCount ? maxCount : totalCount; | ||
| 242 | + if (mCacheTypeBin == null) mCacheTypeBin = new ArrayList<>(); | ||
| 243 | + for (int i = 0; i < childCount; i++) { | ||
| 244 | + View itemView = mAdapter.getView(i, null, this); | ||
| 245 | + String key = mMode + "_" + mAdapter.getItemViewType(i); | ||
| 246 | + mCacheTypeBin.add(key); | ||
| 247 | + addItemClickListener(itemView, i); | ||
| 248 | + addItemLongClickListener(itemView, i); | ||
| 249 | + /** 一定要有 LayoutParams ,addView 的时候,item 在 xml 中的 width 和 height 设置的值,都是没效果的(变成 wrap_content ), | ||
| 250 | + * 可能会出现控件的宽高显示偏差,所以必须设置此句)*/ | ||
| 251 | + addView(itemView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||
| 252 | + } | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + /** | ||
| 256 | + * 设置 item 的点击监听事件 | ||
| 257 | + * | ||
| 258 | + * @param view | ||
| 259 | + * @param position | ||
| 260 | + */ | ||
| 261 | + private void addItemClickListener(View view, final int position) { | ||
| 262 | + view.setOnClickListener(new OnClickListener() { | ||
| 263 | + @Override | ||
| 264 | + public void onClick(View v) { | ||
| 265 | + if (mItemClickListener != null) { | ||
| 266 | + mItemClickListener.onItemClick(position, v); | ||
| 267 | + } | ||
| 268 | + } | ||
| 269 | + }); | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + /** | ||
| 273 | + * 设置 item 的长按监听事件 | ||
| 274 | + * | ||
| 275 | + * @param view | ||
| 276 | + * @param position | ||
| 277 | + */ | ||
| 278 | + private void addItemLongClickListener(View view, final int position) { | ||
| 279 | + view.setOnLongClickListener(new OnLongClickListener() { | ||
| 280 | + @Override | ||
| 281 | + public boolean onLongClick(View v) { | ||
| 282 | + if (mItemLongClickListener != null) { | ||
| 283 | + return mItemLongClickListener.onItemLongClick(position, v); | ||
| 284 | + } | ||
| 285 | + return false; | ||
| 286 | + } | ||
| 287 | + }); | ||
| 288 | + } | ||
| 289 | + | ||
| 290 | + @Override | ||
| 291 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 292 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 293 | + int measureWidth = MeasureSpec.getSize(widthMeasureSpec); | ||
| 294 | + int measureHeight = MeasureSpec.getSize(heightMeasureSpec); | ||
| 295 | + int widthMode = MeasureSpec.getMode(widthMeasureSpec); | ||
| 296 | + int heightMode = MeasureSpec.getMode(heightMeasureSpec); | ||
| 297 | + if (mAdapter == null || getChildCount() == 0) { | ||
| 298 | + setMeasuredDimension(measureWidth, heightMode == MeasureSpec.EXACTLY ? measureHeight : getPaddingTop() + getPaddingBottom()); | ||
| 299 | + return; | ||
| 300 | + } | ||
| 301 | + int maxWidth = measureWidth - getPaddingLeft() - getPaddingRight(); | ||
| 302 | + int childCount = getChildCount(); | ||
| 303 | + mSizeParam = new SizeParam(); | ||
| 304 | + mSizeParam.setMode(mMode) | ||
| 305 | + .setRow(mRow) | ||
| 306 | + .setColumn(mColumn) | ||
| 307 | + .setMaxWidth(maxWidth) | ||
| 308 | + .setItemCount(childCount) | ||
| 309 | + .setItemHeight(mItemHeight) | ||
| 310 | + .setHorizontalSpace(mHorizontalSpace) | ||
| 311 | + .setVerticalSpace(mVerticalSpace) | ||
| 312 | + .setSingleWidthPer(mNineSingleWidthPer) | ||
| 313 | + .setSingleHeightPer(mNineSingleHeightPer); | ||
| 314 | + if (mSizeHelper == null) { | ||
| 315 | + mSizeHelper = new SizeHelper(); | ||
| 316 | + } | ||
| 317 | + mSizeInfo = mSizeHelper.calculateSize(mSizeParam); | ||
| 318 | + // 如果只有一个 child ,且当前模式为九宫格模式 | ||
| 319 | + if (childCount == 1 && mMode == AutoGridMode.GRID_NINE) { | ||
| 320 | + View child = getChildAt(0); | ||
| 321 | + int childWms, childHms; | ||
| 322 | + // 宽度自适应 | ||
| 323 | + if (mNineSingleWidthPer == INVALID_VAL) { | ||
| 324 | + // child 的宽度介于 0 到 父容器的最大宽度之间 | ||
| 325 | + childWms = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST); | ||
| 326 | + } else { | ||
| 327 | + childWms = MeasureSpec.makeMeasureSpec((int) mSizeInfo.getChildWidth(), MeasureSpec.EXACTLY); | ||
| 328 | + } | ||
| 329 | + // 高度自适应 | ||
| 330 | + if (mNineSingleHeightPer == INVALID_VAL) { | ||
| 331 | + // child 可以获取它想要的高度 | ||
| 332 | + childHms = MeasureSpec.makeMeasureSpec((int) mSizeInfo.getChildHeight(), MeasureSpec.UNSPECIFIED); | ||
| 333 | + } else { | ||
| 334 | + childHms = MeasureSpec.makeMeasureSpec((int) mSizeInfo.getChildHeight(), MeasureSpec.EXACTLY); | ||
| 335 | + } | ||
| 336 | + child.measure(childWms, childHms); | ||
| 337 | + int cw = child.getMeasuredWidth() == 0 ? maxWidth : child.getMeasuredWidth(); | ||
| 338 | + int ch = child.getMeasuredHeight() == 0 ? (int) (0.6 * maxWidth) : child.getMeasuredHeight(); | ||
| 339 | + mSizeInfo.setChildWidth(cw); | ||
| 340 | + mSizeInfo.setChildHeight(ch); | ||
| 341 | + mSizeInfo.setParentWidth(cw); | ||
| 342 | + mSizeInfo.setParentHeight(ch); | ||
| 343 | + } else { | ||
| 344 | + for (int i = 0; i < getChildCount(); i++) { | ||
| 345 | + View child = getChildAt(i); | ||
| 346 | + if (child != null) { | ||
| 347 | + child.measure(MeasureSpec.makeMeasureSpec((int) mSizeInfo.getChildWidth(), MeasureSpec.EXACTLY), | ||
| 348 | + MeasureSpec.makeMeasureSpec((int) mSizeInfo.getChildHeight(), MeasureSpec.EXACTLY)); | ||
| 349 | + } | ||
| 350 | + } | ||
| 351 | + } | ||
| 352 | + | ||
| 353 | + // 测量 AutoGridView 的大小 | ||
| 354 | + if (mSizeInfo != null) { | ||
| 355 | + int widthMeasure = (int) (mSizeInfo.getParentWidth() + getPaddingLeft() + getPaddingRight()); | ||
| 356 | + int heightMeasure = (int) (mSizeInfo.getParentHeight() + getPaddingTop() + getPaddingBottom()); | ||
| 357 | + setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? measureWidth : widthMeasure, heightMode == MeasureSpec.EXACTLY ? measureHeight : heightMeasure); | ||
| 358 | + } else { | ||
| 359 | + setMeasuredDimension(measureWidth, heightMode == MeasureSpec.EXACTLY ? measureHeight : getPaddingTop() + getPaddingBottom()); | ||
| 360 | + } | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + @Override | ||
| 364 | + protected void onLayout(boolean changed, int l, int t, int r, int b) { | ||
| 365 | + if (mAdapter == null || getChildCount() == 0 || mSizeInfo == null) { | ||
| 366 | + return; | ||
| 367 | + } | ||
| 368 | + // 遍历 child,设置每个 child 所在的位置 | ||
| 369 | + int childCount = getChildCount(); | ||
| 370 | + for (int i = 0; i < childCount; i++) { | ||
| 371 | + int[] position = mSizeHelper.findPosition(mSizeInfo, i); | ||
| 372 | + int left = (int) (getPaddingLeft() + position[1] * (mSizeInfo.getChildWidth() + mHorizontalSpace)); | ||
| 373 | + int top = (int) (getPaddingTop() + position[0] * (mSizeInfo.getChildHeight() + mVerticalSpace)); | ||
| 374 | + int right = (int) (left + mSizeInfo.getChildWidth()); | ||
| 375 | + int bottom = (int) (top + mSizeInfo.getChildHeight()); | ||
| 376 | + View child = getChildAt(i); | ||
| 377 | + child.layout(left, top, right, bottom); | ||
| 378 | + } | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + public interface OnItemClickListener { | ||
| 382 | + void onItemClick(int position, View view); | ||
| 383 | + } | ||
| 384 | + | ||
| 385 | + public interface OnItemLongClickListener { | ||
| 386 | + boolean onItemLongClick(int position, View view); | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + public void setOnItemClickListener(OnItemClickListener listener) { | ||
| 390 | + this.mItemClickListener = listener; | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + public void setOnItemLongClickListener(OnItemLongClickListener listener) { | ||
| 394 | + this.mItemLongClickListener = listener; | ||
| 395 | + } | ||
| 396 | + | ||
| 397 | + public void setMode(@AutoGridMode int mode) { | ||
| 398 | + this.mMode = mode; | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | + @AutoGridMode | ||
| 402 | + public int getMode() { | ||
| 403 | + return mMode; | ||
| 404 | + } | ||
| 405 | + | ||
| 406 | + public void setRow(int row) { | ||
| 407 | + this.mRow = row; | ||
| 408 | + } | ||
| 409 | + | ||
| 410 | + public int getRow() { | ||
| 411 | + return mRow; | ||
| 412 | + } | ||
| 413 | + | ||
| 414 | + public void setColumn(int column) { | ||
| 415 | + this.mColumn = column; | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + public int getColumn() { | ||
| 419 | + return mColumn; | ||
| 420 | + } | ||
| 421 | + | ||
| 422 | + public void setItemHeight(float itemHeight) { | ||
| 423 | + this.mItemHeight = itemHeight; | ||
| 424 | + } | ||
| 425 | + | ||
| 426 | + public float getItemHeight() { | ||
| 427 | + return mItemHeight; | ||
| 428 | + } | ||
| 429 | + | ||
| 430 | + public void setHorizontalSpace(float horizontalSpace) { | ||
| 431 | + this.mHorizontalSpace = horizontalSpace; | ||
| 432 | + } | ||
| 433 | + | ||
| 434 | + public float getHorizontalSpace() { | ||
| 435 | + return mHorizontalSpace; | ||
| 436 | + } | ||
| 437 | + | ||
| 438 | + public void setVerticalSpace(float verticalSpace) { | ||
| 439 | + this.mVerticalSpace = verticalSpace; | ||
| 440 | + } | ||
| 441 | + | ||
| 442 | + public float getVerticalSpace() { | ||
| 443 | + return mVerticalSpace; | ||
| 444 | + } | ||
| 445 | + | ||
| 446 | + public void setNineSingleWidthPercent(@FloatRange(from = 0f, to = 1f) float nineSingleWidthPercent) { | ||
| 447 | + this.mNineSingleWidthPer = nineSingleWidthPercent; | ||
| 448 | + } | ||
| 449 | + | ||
| 450 | + public float getNineSingleWidthPercent() { | ||
| 451 | + return mNineSingleWidthPer; | ||
| 452 | + } | ||
| 453 | + | ||
| 454 | + public void setNineSingleHeightPercent(@FloatRange(from = 0f, to = 1f) float nineSingleHeightPercent) { | ||
| 455 | + this.mNineSingleHeightPer = nineSingleHeightPercent; | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + public float getNineSingleHeightPercent() { | ||
| 459 | + return mNineSingleHeightPer; | ||
| 460 | + } | ||
| 461 | + | ||
| 462 | + private class AdapterObserver extends DataSetObserver { | ||
| 463 | + | ||
| 464 | + @Override | ||
| 465 | + public void onChanged() { | ||
| 466 | + super.onChanged(); | ||
| 467 | + notifyChanged(); | ||
| 468 | + } | ||
| 469 | + | ||
| 470 | + @Override | ||
| 471 | + public void onInvalidated() { | ||
| 472 | + super.onInvalidated(); | ||
| 473 | + } | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + @Override | ||
| 477 | + protected void onDetachedFromWindow() { | ||
| 478 | + if (mAdapter != null) { | ||
| 479 | + if (mDataSetObserver != null) { | ||
| 480 | + mAdapter.unregisterDataSetObserver(mDataSetObserver); | ||
| 481 | + } | ||
| 482 | + mAdapter = null; | ||
| 483 | + } | ||
| 484 | + if (mCacheTypeBin != null) { | ||
| 485 | + mCacheTypeBin.clear(); | ||
| 486 | + mCacheTypeBin = null; | ||
| 487 | + } | ||
| 488 | + if (mCacheBin != null) { | ||
| 489 | + mCacheBin.clear(); | ||
| 490 | + mCacheBin = null; | ||
| 491 | + } | ||
| 492 | + mItemClickListener = null; | ||
| 493 | + mItemLongClickListener = null; | ||
| 494 | + super.onDetachedFromWindow(); | ||
| 495 | + } | ||
| 496 | +} | ||
| 497 | + |
core/imageload/src/main/java/com/cnlive/core/gridview/GridImgUtil.java
0 → 100644
| 1 | +package com.cnlive.core.gridview; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.graphics.drawable.Drawable; | ||
| 5 | +import android.widget.ImageView; | ||
| 6 | + | ||
| 7 | +import com.bumptech.glide.request.RequestListener; | ||
| 8 | +import com.bumptech.glide.request.target.SimpleTarget; | ||
| 9 | +import com.cnlive.core.imageload.R; | ||
| 10 | +import com.cnlive.core.libs.base.application.GlideApp; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * created by hanyayun | ||
| 14 | + * on 2020/2/13 | ||
| 15 | + */ | ||
| 16 | +public class GridImgUtil { | ||
| 17 | + public static void loadImage(Context context, final Object src, final ImageView view) { | ||
| 18 | + GlideApp.with(context) | ||
| 19 | + .load(src) | ||
| 20 | +// .placeholder(R.drawable.img_placeholder) | ||
| 21 | +// .error(R.drawable.img_placeholder) | ||
| 22 | + .into(view); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public static void loadImage(Context context, final Object src, final ImageView view, RequestListener<Drawable> listener) { | ||
| 26 | + GlideApp.with(context) | ||
| 27 | + .load(src) | ||
| 28 | +// .placeholder(R.drawable.img_placeholder) | ||
| 29 | +// .error(R.drawable.img_placeholder) | ||
| 30 | + .listener(listener) | ||
| 31 | + .into(view); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public static void loadImage(Context context, final Object src, final SimpleTarget<Drawable> target) { | ||
| 35 | + GlideApp.with(context) | ||
| 36 | + .load(src) | ||
| 37 | + .thumbnail(0.1f) | ||
| 38 | +// .placeholder(R.drawable.img_placeholder) | ||
| 39 | +// .error(R.drawable.img_placeholder) | ||
| 40 | + .into(target); | ||
| 41 | + } | ||
| 42 | +} | ||
| 43 | + |
core/imageload/src/main/java/com/cnlive/core/gridview/adapter/BaseAutoGridAdapter.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.adapter; | ||
| 2 | + | ||
| 3 | +import android.database.DataSetObservable; | ||
| 4 | +import android.database.DataSetObserver; | ||
| 5 | +import android.view.View; | ||
| 6 | +import android.view.ViewGroup; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * created by hanyayun | ||
| 10 | + * on 2020/2/13 | ||
| 11 | + */ | ||
| 12 | +public abstract class BaseAutoGridAdapter<VH extends BaseAutoGridHolder> { | ||
| 13 | +// 被观察者,用来注册观察者 | ||
| 14 | +private final DataSetObservable mDataSetObservable = new DataSetObservable(); | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * 创建 ViewHolder | ||
| 18 | + */ | ||
| 19 | +public abstract VH onCreateViewHolder(ViewGroup parent, int viewType); | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * 绑定 item 的 ViewHolder | ||
| 23 | + */ | ||
| 24 | +public abstract void onBindViewHolder(VH holder, int position); | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * 获取 item 的数量 | ||
| 28 | + */ | ||
| 29 | +public abstract int getItemCount(); | ||
| 30 | + | ||
| 31 | +public int getItemViewType(int position) { | ||
| 32 | + return 0; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | +public View getView(int position, View convertView, ViewGroup parent) { | ||
| 36 | + int viewType = getItemViewType(position); | ||
| 37 | + VH holder = null; | ||
| 38 | + if (convertView == null) { | ||
| 39 | + holder = onCreateViewHolder(parent, viewType); | ||
| 40 | + convertView = holder.getConvertView(); | ||
| 41 | + convertView.setTag(holder); | ||
| 42 | + } else { | ||
| 43 | + holder = (VH) convertView.getTag(); | ||
| 44 | + } | ||
| 45 | + holder.setViewType(viewType); | ||
| 46 | + onBindViewHolder(holder, position); | ||
| 47 | + return convertView; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + | ||
| 51 | +/** | ||
| 52 | + * 注册观察者 | ||
| 53 | + * | ||
| 54 | + * @param observer | ||
| 55 | + */ | ||
| 56 | +public void registerDataSetObserver(DataSetObserver observer) { | ||
| 57 | + mDataSetObservable.registerObserver(observer); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | +/** | ||
| 61 | + * 删除已经注册过的观察者 | ||
| 62 | + * | ||
| 63 | + * @param observer | ||
| 64 | + */ | ||
| 65 | +public void unregisterDataSetObserver(DataSetObserver observer) { | ||
| 66 | + mDataSetObservable.unregisterObserver(observer); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | +/** | ||
| 70 | + * 通知刷新 | ||
| 71 | + */ | ||
| 72 | +public void notifyDataSetChanged() { | ||
| 73 | + mDataSetObservable.notifyChanged(); | ||
| 74 | + } | ||
| 75 | + } |
core/imageload/src/main/java/com/cnlive/core/gridview/adapter/BaseAutoGridHolder.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.adapter; | ||
| 2 | + | ||
| 3 | +import android.view.View; | ||
| 4 | +import android.widget.ImageView; | ||
| 5 | +import android.widget.TextView; | ||
| 6 | + | ||
| 7 | +import androidx.annotation.IdRes; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * created by hanyayun | ||
| 11 | + * on 2020/2/13 | ||
| 12 | + */ | ||
| 13 | +public class BaseAutoGridHolder { | ||
| 14 | + private View convertView; | ||
| 15 | + private int mViewType; | ||
| 16 | + | ||
| 17 | + public BaseAutoGridHolder(final View convertView) { | ||
| 18 | + this.convertView = convertView; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + public View getConvertView() { | ||
| 22 | + return convertView; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public <T extends View> T findViewById(@IdRes int viewId) { | ||
| 26 | + T view = (T) convertView.findViewById(viewId); | ||
| 27 | + return view; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public ImageView getImageView(@IdRes int viewId) { | ||
| 31 | + return findViewById(viewId); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public TextView getTextView(@IdRes int viewId) { | ||
| 35 | + return findViewById(viewId); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public int getViewType() { | ||
| 39 | + return mViewType; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public void setViewType(int viewType) { | ||
| 43 | + this.mViewType = viewType; | ||
| 44 | + } | ||
| 45 | +} |
core/imageload/src/main/java/com/cnlive/core/gridview/adapter/QuickAutoGridAdapter.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.adapter; | ||
| 2 | + | ||
| 3 | +import android.util.SparseIntArray; | ||
| 4 | +import android.view.LayoutInflater; | ||
| 5 | +import android.view.View; | ||
| 6 | +import android.view.ViewGroup; | ||
| 7 | + | ||
| 8 | +import java.lang.reflect.Constructor; | ||
| 9 | +import java.lang.reflect.InvocationTargetException; | ||
| 10 | +import java.lang.reflect.Modifier; | ||
| 11 | +import java.lang.reflect.ParameterizedType; | ||
| 12 | +import java.lang.reflect.Type; | ||
| 13 | +import java.util.List; | ||
| 14 | + | ||
| 15 | +import androidx.annotation.LayoutRes; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * created by hanyayun | ||
| 19 | + * on 2020/2/13 | ||
| 20 | + */ | ||
| 21 | +public abstract class QuickAutoGridAdapter<T, VH extends BaseAutoGridHolder> extends BaseAutoGridAdapter<VH> { | ||
| 22 | + private static final int LAYOUT_NOT_FOUND = -404; | ||
| 23 | + | ||
| 24 | + private LayoutInflater mLayoutInflater; | ||
| 25 | + private SparseIntArray mLayoutTypes; | ||
| 26 | + protected List<T> mData; | ||
| 27 | + | ||
| 28 | + public QuickAutoGridAdapter() { | ||
| 29 | + | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public void setData(List<T> list) { | ||
| 33 | + this.mData = list; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public List<T> getData() { | ||
| 37 | + return mData; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public void updateData(List<T> list) { | ||
| 41 | + mData = list; | ||
| 42 | + notifyDataSetChanged(); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + protected void addItemType(int type, @LayoutRes int layoutId) { | ||
| 46 | + if (mLayoutTypes == null) { | ||
| 47 | + mLayoutTypes = new SparseIntArray(); | ||
| 48 | + } | ||
| 49 | + mLayoutTypes.put(type, layoutId); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + @Override | ||
| 53 | + public int getItemViewType(int position) { | ||
| 54 | + return onHandleViewType(position); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Override | ||
| 58 | + public VH onCreateViewHolder(ViewGroup parent, int viewType) { | ||
| 59 | + if (mLayoutInflater == null) mLayoutInflater = LayoutInflater.from(parent.getContext()); | ||
| 60 | + View convertView = getItemView(getLayoutId(viewType), parent); | ||
| 61 | + VH holder = createBaseViewHolder(convertView); | ||
| 62 | + return holder; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public void onBindViewHolder(VH holder, int position) { | ||
| 67 | + onHandleViewHolder(holder, position, mData.get(position)); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + @Override | ||
| 71 | + public int getItemCount() { | ||
| 72 | + return mData != null ? mData.size() : 0; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public abstract int onHandleViewType(int position); | ||
| 76 | + | ||
| 77 | + public abstract void onHandleViewHolder(VH holder, int position, T item); | ||
| 78 | + | ||
| 79 | + protected View getItemView(int layoutResId, ViewGroup parent) { | ||
| 80 | + if (layoutResId != LAYOUT_NOT_FOUND) { | ||
| 81 | + return mLayoutInflater.inflate(layoutResId, parent, false); | ||
| 82 | + } | ||
| 83 | + return null; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + private int getLayoutId(int vieType) { | ||
| 87 | + return mLayoutTypes.get(vieType, LAYOUT_NOT_FOUND); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + protected VH createBaseViewHolder(View view) { | ||
| 91 | + Class temp = getClass(); | ||
| 92 | + Class z = null; | ||
| 93 | + while (z == null && null != temp) { | ||
| 94 | + z = getInstancedGenericKClass(temp); | ||
| 95 | + temp = temp.getSuperclass(); | ||
| 96 | + } | ||
| 97 | + VH k; | ||
| 98 | + // 泛型擦除会导致 z 为 null | ||
| 99 | + if (z == null) { | ||
| 100 | + k = (VH) new BaseAutoGridHolder(view); | ||
| 101 | + } else { | ||
| 102 | + k = createGenericKInstance(z, view); | ||
| 103 | + } | ||
| 104 | + return k != null ? k : (VH) new BaseAutoGridHolder(view); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + @SuppressWarnings("unchecked") | ||
| 108 | + private VH createGenericKInstance(Class z, View view) { | ||
| 109 | + try { | ||
| 110 | + Constructor constructor; | ||
| 111 | + // inner and unstatic class | ||
| 112 | + if (z.isMemberClass() && !Modifier.isStatic(z.getModifiers())) { | ||
| 113 | + constructor = z.getDeclaredConstructor(getClass(), View.class); | ||
| 114 | + constructor.setAccessible(true); | ||
| 115 | + return (VH) constructor.newInstance(this, view); | ||
| 116 | + } else { | ||
| 117 | + constructor = z.getDeclaredConstructor(View.class); | ||
| 118 | + constructor.setAccessible(true); | ||
| 119 | + return (VH) constructor.newInstance(view); | ||
| 120 | + } | ||
| 121 | + } catch (NoSuchMethodException e) { | ||
| 122 | + e.printStackTrace(); | ||
| 123 | + } catch (IllegalAccessException e) { | ||
| 124 | + e.printStackTrace(); | ||
| 125 | + } catch (InstantiationException e) { | ||
| 126 | + e.printStackTrace(); | ||
| 127 | + } catch (InvocationTargetException e) { | ||
| 128 | + e.printStackTrace(); | ||
| 129 | + } | ||
| 130 | + return null; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + private Class getInstancedGenericKClass(Class z) { | ||
| 134 | + Type type = z.getGenericSuperclass(); | ||
| 135 | + if (type instanceof ParameterizedType) { | ||
| 136 | + Type[] types = ((ParameterizedType) type).getActualTypeArguments(); | ||
| 137 | + for (Type temp : types) { | ||
| 138 | + if (temp instanceof Class) { | ||
| 139 | + Class tempClass = (Class) temp; | ||
| 140 | + if (BaseAutoGridHolder.class.isAssignableFrom(tempClass)) { | ||
| 141 | + return tempClass; | ||
| 142 | + } | ||
| 143 | + } else if (temp instanceof ParameterizedType) { | ||
| 144 | + Type rawType = ((ParameterizedType) temp).getRawType(); | ||
| 145 | + if (rawType instanceof Class && BaseAutoGridHolder.class.isAssignableFrom((Class<?>) rawType)) { | ||
| 146 | + return (Class<?>) rawType; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + return null; | ||
| 152 | + } | ||
| 153 | +} |
core/imageload/src/main/java/com/cnlive/core/gridview/adapter/SimpleAutoGridAdapter.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.adapter; | ||
| 2 | + | ||
| 3 | +import android.widget.ImageView; | ||
| 4 | + | ||
| 5 | +import com.cnlive.core.gridview.AutoGridMode; | ||
| 6 | +import com.cnlive.core.imageload.R; | ||
| 7 | + | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * created by hanyayun | ||
| 12 | + * on 2020/2/13 | ||
| 13 | + */ | ||
| 14 | +public class SimpleAutoGridAdapter<T, VH extends BaseAutoGridHolder> extends QuickAutoGridAdapter<T, VH> { | ||
| 15 | + // item 类型 | ||
| 16 | + private final int ITEM_TYPE_SINGLE = 0; | ||
| 17 | + private final int ITEM_TYPE_NORMAL = 1; | ||
| 18 | + | ||
| 19 | + private int mGridMode; | ||
| 20 | + private ImageLoader mImageLoader; | ||
| 21 | + | ||
| 22 | + public SimpleAutoGridAdapter() { | ||
| 23 | + init(); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public SimpleAutoGridAdapter(List<T> list) { | ||
| 27 | + setData(list); | ||
| 28 | + init(); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + private void init() { | ||
| 32 | + addItemType(ITEM_TYPE_SINGLE, R.layout.auto_grid_item_simple_pic_single); | ||
| 33 | + addItemType(ITEM_TYPE_NORMAL, R.layout.auto_grid_item_simple_pic); | ||
| 34 | + mGridMode = AutoGridMode.GRID_NINE; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public void setMode(@AutoGridMode int mode) { | ||
| 38 | + this.mGridMode = mode; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public void setImageLoader(ImageLoader loader) { | ||
| 42 | + this.mImageLoader = loader; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @Override | ||
| 46 | + public int onHandleViewType(int position) { | ||
| 47 | + int viewType; | ||
| 48 | + if (mGridMode == AutoGridMode.GRID_NINE) { | ||
| 49 | + if (getItemCount() == 1) { | ||
| 50 | + viewType = ITEM_TYPE_SINGLE; | ||
| 51 | + } else { | ||
| 52 | + viewType = ITEM_TYPE_NORMAL; | ||
| 53 | + } | ||
| 54 | + } else { | ||
| 55 | + viewType = ITEM_TYPE_NORMAL; | ||
| 56 | + } | ||
| 57 | + return viewType; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public void onHandleViewHolder(VH holder, int position, T item) { | ||
| 62 | + if (mImageLoader != null) { | ||
| 63 | + mImageLoader.onLoadImage(position, item, holder.getImageView(R.id.iv_auto_grid_item_simple_pic)); | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public interface ImageLoader<T> { | ||
| 68 | + /** | ||
| 69 | + * 加载图片 | ||
| 70 | + */ | ||
| 71 | + void onLoadImage(int position, T item, ImageView imageView); | ||
| 72 | + } | ||
| 73 | +} |
core/imageload/src/main/java/com/cnlive/core/gridview/model/SizeHelper.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.model; | ||
| 2 | + | ||
| 3 | +import com.cnlive.core.gridview.AutoGridMode; | ||
| 4 | +import com.cnlive.core.gridview.AutoGridView; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 网格数据计算辅助类 | ||
| 8 | + * created by hanyayun | ||
| 9 | + * on 2020/2/13 | ||
| 10 | + */ | ||
| 11 | +public class SizeHelper { | ||
| 12 | + /** | ||
| 13 | + * 计算 item 和 parent 的宽高 | ||
| 14 | + * | ||
| 15 | + * @param param | ||
| 16 | + * @return | ||
| 17 | + */ | ||
| 18 | + public SizeInfo calculateSize(SizeParam param) { | ||
| 19 | + if (param != null) { | ||
| 20 | + float childWidth, childHeight; | ||
| 21 | + float parentWidth, parentHeight; | ||
| 22 | + int childRow, childColumn; | ||
| 23 | + | ||
| 24 | + int parentRow = param.getRow(); | ||
| 25 | + int parentColumn = param.getColumn(); | ||
| 26 | + float parentMaxWidth = param.getMaxWidth(); | ||
| 27 | + int totalCount = param.getItemCount(); | ||
| 28 | + float totalHorizontalSpace = (parentColumn - 1) * param.getHorizontalSpace(); | ||
| 29 | + childWidth = (parentMaxWidth - totalHorizontalSpace) / parentColumn; | ||
| 30 | + childHeight = param.getItemHeight() != AutoGridView.DEF_ITEM_HEIGHT ? param.getItemHeight() : childWidth; | ||
| 31 | + // 判断当前网格是九宫格模式还是普通模式 | ||
| 32 | + // 当前模式为九宫格模式时 | ||
| 33 | + if (param.getMode() == AutoGridMode.GRID_NINE) { | ||
| 34 | + // 只有一个 item 时 | ||
| 35 | + if (totalCount == 1) { | ||
| 36 | + float widthPer = param.getSingleWidthPer(); | ||
| 37 | + float heightPer = param.getSingleHeightPer(); | ||
| 38 | + childRow = 1; | ||
| 39 | + childColumn = 1; | ||
| 40 | + if (widthPer <= 0) { | ||
| 41 | + childWidth = 0; | ||
| 42 | + } else { | ||
| 43 | + if (widthPer > 1) { | ||
| 44 | + widthPer = 1; | ||
| 45 | + } | ||
| 46 | + childWidth = widthPer * parentMaxWidth; | ||
| 47 | + } | ||
| 48 | + if (heightPer <= 0) { | ||
| 49 | + childHeight = 0; | ||
| 50 | + } else { | ||
| 51 | + childHeight = heightPer * parentMaxWidth; | ||
| 52 | + } | ||
| 53 | + parentWidth = childWidth; | ||
| 54 | + parentHeight = childHeight; | ||
| 55 | + return new SizeInfo(childRow, childColumn, childWidth, childHeight, parentWidth, parentHeight); | ||
| 56 | + } else { | ||
| 57 | + // 如果 item 的个数大于可以显示的最大个数 | ||
| 58 | + if (parentRow * parentColumn < totalCount) { | ||
| 59 | + childRow = parentRow; | ||
| 60 | + childColumn = parentColumn; | ||
| 61 | + } else { | ||
| 62 | + // 判断 item 的个数是否可以开平方(即判断是否可以将 itemView 拼成正方形放置) | ||
| 63 | + int temp = (int) Math.sqrt(totalCount); | ||
| 64 | + if (temp * temp == totalCount) { | ||
| 65 | + // 如果 item 的个数不满一行,则不做正方形放置,否则做正方形放置 | ||
| 66 | + if (totalCount <= parentColumn) { | ||
| 67 | + childRow = 1; | ||
| 68 | + childColumn = totalCount; | ||
| 69 | + } else { | ||
| 70 | + childRow = temp; | ||
| 71 | + childColumn = temp; | ||
| 72 | + } | ||
| 73 | + } else { | ||
| 74 | + childRow = totalCount / parentColumn + (totalCount % parentColumn == 0 ? 0 : 1); | ||
| 75 | + childColumn = param.getColumn(); | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + // 当前模式为普通网格模式时 | ||
| 81 | + else { | ||
| 82 | + if (parentRow * parentColumn < totalCount) { | ||
| 83 | + childRow = parentRow; | ||
| 84 | + childColumn = parentColumn; | ||
| 85 | + } else { | ||
| 86 | + childRow = totalCount / parentColumn + (totalCount % parentColumn == 0 ? 0 : 1); | ||
| 87 | + childColumn = parentColumn; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + parentWidth = childColumn * childWidth + (childColumn - 1) * param.getHorizontalSpace(); | ||
| 91 | + parentHeight = childRow * childHeight + (childRow - 1) * param.getVerticalSpace(); | ||
| 92 | + // 当只有一个 child 的时候,parent 的总宽度与 item 的宽度一致 | ||
| 93 | + if (totalCount == 1) { | ||
| 94 | + parentWidth = childWidth; | ||
| 95 | + } | ||
| 96 | + return new SizeInfo(childRow, childColumn, childWidth, childHeight, parentWidth, parentHeight); | ||
| 97 | + } | ||
| 98 | + return null; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * 找到 item 在网格中的位置 | ||
| 103 | + * | ||
| 104 | + * @param bean | ||
| 105 | + * @param index | ||
| 106 | + * @return | ||
| 107 | + */ | ||
| 108 | + public int[] findPosition(SizeInfo bean, int index) { | ||
| 109 | + if (bean == null) { | ||
| 110 | + return null; | ||
| 111 | + } | ||
| 112 | + int[] position = new int[2]; | ||
| 113 | + position[0] = index / bean.getChildColumn(); | ||
| 114 | + position[1] = index - position[0] * bean.getChildColumn(); | ||
| 115 | + return position; | ||
| 116 | + } | ||
| 117 | +} |
core/imageload/src/main/java/com/cnlive/core/gridview/model/SizeInfo.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.model; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * created by hanyayun | ||
| 5 | + * on 2020/2/13 | ||
| 6 | + */ | ||
| 7 | +public class SizeInfo { | ||
| 8 | + private int childRow; | ||
| 9 | + private int childColumn; | ||
| 10 | + private float childWidth; | ||
| 11 | + private float childHeight; | ||
| 12 | + private float parentWidth; | ||
| 13 | + private float parentHeight; | ||
| 14 | + | ||
| 15 | + public SizeInfo() { | ||
| 16 | + super(); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public SizeInfo(int childRow, int childColumn, float childWidth, float childHeight, float parentWidth, float parentHeight) { | ||
| 20 | + this.childRow = childRow; | ||
| 21 | + this.childColumn = childColumn; | ||
| 22 | + this.childWidth = childWidth; | ||
| 23 | + this.childHeight = childHeight; | ||
| 24 | + this.parentWidth = parentWidth; | ||
| 25 | + this.parentHeight = parentHeight; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + public int getChildRow() { | ||
| 29 | + return childRow; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public void setChildRow(int childRow) { | ||
| 33 | + this.childRow = childRow; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public int getChildColumn() { | ||
| 37 | + return childColumn; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public void setChildColumn(int childColumn) { | ||
| 41 | + this.childColumn = childColumn; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public float getChildWidth() { | ||
| 45 | + return childWidth; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public void setChildWidth(float childWidth) { | ||
| 49 | + this.childWidth = childWidth; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public float getChildHeight() { | ||
| 53 | + return childHeight; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public void setChildHeight(float childHeight) { | ||
| 57 | + this.childHeight = childHeight; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + public float getParentWidth() { | ||
| 61 | + return parentWidth; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + public void setParentWidth(float parentWidth) { | ||
| 65 | + this.parentWidth = parentWidth; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public float getParentHeight() { | ||
| 69 | + return parentHeight; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + public void setParentHeight(float parentHeight) { | ||
| 73 | + this.parentHeight = parentHeight; | ||
| 74 | + } | ||
| 75 | +} | ||
| 0 | \ No newline at end of file | 76 | \ No newline at end of file |
core/imageload/src/main/java/com/cnlive/core/gridview/model/SizeParam.java
0 → 100644
| 1 | +package com.cnlive.core.gridview.model; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * created by hanyayun | ||
| 5 | + * on 2020/2/13 | ||
| 6 | + */ | ||
| 7 | +public class SizeParam { | ||
| 8 | + private int mode; | ||
| 9 | + private int row; | ||
| 10 | + private int column; | ||
| 11 | + private int maxWidth; | ||
| 12 | + private int itemCount; | ||
| 13 | + private float itemWidth; | ||
| 14 | + private float itemHeight; | ||
| 15 | + private float horizontalSpace; | ||
| 16 | + private float verticalSpace; | ||
| 17 | + private float singleWidthPer; | ||
| 18 | + private float singleHeightPer; | ||
| 19 | + | ||
| 20 | + public SizeParam() { | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public SizeParam(int mode, int row, int column, int maxWidth, int itemCount, | ||
| 24 | + float itemWidth, float itemHeight, float horizontalSpace, float verticalSpace, | ||
| 25 | + float singleWidthPer, float singleHeightPer) { | ||
| 26 | + this.mode = mode; | ||
| 27 | + this.row = row; | ||
| 28 | + this.column = column; | ||
| 29 | + this.maxWidth = maxWidth; | ||
| 30 | + this.itemCount = itemCount; | ||
| 31 | + this.itemWidth = itemWidth; | ||
| 32 | + this.itemHeight = itemHeight; | ||
| 33 | + this.horizontalSpace = horizontalSpace; | ||
| 34 | + this.verticalSpace = verticalSpace; | ||
| 35 | + this.singleWidthPer = singleWidthPer; | ||
| 36 | + this.singleHeightPer = singleHeightPer; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + public int getMode() { | ||
| 40 | + return mode; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public SizeParam setMode(int mode) { | ||
| 44 | + this.mode = mode; | ||
| 45 | + return this; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public int getRow() { | ||
| 49 | + return row; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public SizeParam setRow(int row) { | ||
| 53 | + this.row = row; | ||
| 54 | + return this; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + public int getColumn() { | ||
| 58 | + return column; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public SizeParam setColumn(int column) { | ||
| 62 | + this.column = column; | ||
| 63 | + return this; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + public int getMaxWidth() { | ||
| 67 | + return maxWidth; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + public SizeParam setMaxWidth(int maxWidth) { | ||
| 71 | + this.maxWidth = maxWidth; | ||
| 72 | + return this; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public int getItemCount() { | ||
| 76 | + return itemCount; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + public SizeParam setItemCount(int itemCount) { | ||
| 80 | + this.itemCount = itemCount; | ||
| 81 | + return this; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + public float getItemWidth() { | ||
| 85 | + return itemWidth; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + public SizeParam setItemWidth(float itemWidth) { | ||
| 89 | + this.itemWidth = itemWidth; | ||
| 90 | + return this; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + public float getItemHeight() { | ||
| 94 | + return itemHeight; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public SizeParam setItemHeight(float itemHeight) { | ||
| 98 | + this.itemHeight = itemHeight; | ||
| 99 | + return this; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + public float getHorizontalSpace() { | ||
| 103 | + return horizontalSpace; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + public SizeParam setHorizontalSpace(float horizontalSpace) { | ||
| 107 | + this.horizontalSpace = horizontalSpace; | ||
| 108 | + return this; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + public float getVerticalSpace() { | ||
| 112 | + return verticalSpace; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + public SizeParam setVerticalSpace(float verticalSpace) { | ||
| 116 | + this.verticalSpace = verticalSpace; | ||
| 117 | + return this; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + public float getSingleWidthPer() { | ||
| 121 | + return singleWidthPer; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + public SizeParam setSingleWidthPer(float singleWidthPer) { | ||
| 125 | + this.singleWidthPer = singleWidthPer; | ||
| 126 | + return this; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + public float getSingleHeightPer() { | ||
| 130 | + return singleHeightPer; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + public SizeParam setSingleHeightPer(float singleHeightPer) { | ||
| 134 | + this.singleHeightPer = singleHeightPer; | ||
| 135 | + return this; | ||
| 136 | + } | ||
| 137 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/ImageDrawee.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.graphics.Bitmap; | ||
| 5 | +import android.graphics.drawable.Drawable; | ||
| 6 | +import android.util.Log; | ||
| 7 | +import android.widget.FrameLayout; | ||
| 8 | +import android.widget.ImageView; | ||
| 9 | + | ||
| 10 | +import com.cnlive.core.imagepreview.indexui.ProgressUI; | ||
| 11 | + | ||
| 12 | +import androidx.annotation.NonNull; | ||
| 13 | +import uk.co.senab.photoview.PhotoView; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * created by hanyayun | ||
| 17 | + * on 2020/1/20 | ||
| 18 | + */ | ||
| 19 | +public class ImageDrawee extends FrameLayout { | ||
| 20 | + private PhotoView imageView; | ||
| 21 | + private ProgressUI progressUI; | ||
| 22 | + | ||
| 23 | + public ImageDrawee(@NonNull Context context) { | ||
| 24 | + super(context); | ||
| 25 | + init(); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + private void init() { | ||
| 29 | + // 添加 imageView | ||
| 30 | + imageView = new PhotoView(getContext()); | ||
| 31 | + addView(imageView); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public void setProgressUI(ProgressUI progressUI) { | ||
| 35 | + this.progressUI = progressUI; | ||
| 36 | + if (progressUI != null) { | ||
| 37 | + progressUI.init(this); | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * 更新加载进度 | ||
| 43 | + */ | ||
| 44 | + public void handleProgress(float progress) { | ||
| 45 | + if (progressUI != null && progressUI.getProgressView() != null) { | ||
| 46 | + if (progress == 0) { | ||
| 47 | + progressUI.start(); | ||
| 48 | + } else if (progress == 1f) { | ||
| 49 | + progressUI.stop(); | ||
| 50 | + } | ||
| 51 | + progressUI.handleProgress(progress); | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public void hideProgressUI() { | ||
| 56 | + if (progressUI != null && progressUI.getProgressView() != null | ||
| 57 | + && progressUI.getProgressView().getVisibility() == VISIBLE) { | ||
| 58 | + progressUI.stop(); | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * 释放 imageView 占据的内存 | ||
| 64 | + * <p> | ||
| 65 | + * Bitmap 的存储分为两部分,一部分是 Bitmap 的数据,一部分是 Bitmap 的引用。 | ||
| 66 | + * 在 Android2.3 时代,Bitmap 的引用是放在堆中的,而 Bitmap 的数据部分是放在栈中的,需要用户调用 recycle 方法手动进行内存回收; | ||
| 67 | + * 在 Android2.3 之后,整个 Bitmap(包括数据和引用)都放在了堆中,整个 Bitmap 的回收就全部交给GC了,不用在手动调用 recycle 方法回收内存。 | ||
| 68 | + */ | ||
| 69 | + public void recycle() { | ||
| 70 | +// Drawable drawable = imageView.getDrawable(); | ||
| 71 | +// if (drawable != null && drawable instanceof BitmapDrawable) { | ||
| 72 | +// Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); | ||
| 73 | +// if (bitmap != null && !bitmap.isRecycled()) { | ||
| 74 | +// /** | ||
| 75 | +// * 当如果图片加载框架设置了缓存且 bitmap 已经被回收, | ||
| 76 | +// * 但是 canvas 在 draw 时,继续使用被回收的 bitmap,会抛出异常: | ||
| 77 | +// * a BitmapDrawable: Canvas: trying to use a recycled bitmap. | ||
| 78 | +// * 故此处不使用 bitmap.recycle() 方法(或者图片加载框架去除缓存设置)。 | ||
| 79 | +// */ | ||
| 80 | +// bitmap.recycle(); | ||
| 81 | +// bitmap = null; | ||
| 82 | +// } | ||
| 83 | +// } | ||
| 84 | + // 调用 setImageDrawable(null) 方法,然后 GC 会完成图片的回收 | ||
| 85 | + imageView.setImageDrawable(null); | ||
| 86 | + // 手动调用 GC(但是 GC 并不一定是马上执行的,只能说是加速 GC 回收) | ||
| 87 | +// System.gc(); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + public ImageView getImageView() { | ||
| 91 | + return imageView; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + public void setImage(Object obj) { | ||
| 95 | + if (obj == null) { | ||
| 96 | + return; | ||
| 97 | + } | ||
| 98 | + if (obj instanceof Drawable) { | ||
| 99 | + imageView.setImageDrawable((Drawable) obj); | ||
| 100 | + } else if (obj instanceof Bitmap) { | ||
| 101 | + imageView.setImageBitmap((Bitmap) obj); | ||
| 102 | + } else if (obj instanceof Integer) { | ||
| 103 | + imageView.setImageResource((Integer) obj); | ||
| 104 | + } else { | ||
| 105 | + Log.e("ImageDrawee", "Unable to identify picture resources."); | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + public float getScale() { | ||
| 110 | + return imageView.getScale(); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + public void setScale(float scale) { | ||
| 114 | + imageView.setScale(scale); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + public float getMaxScale() { | ||
| 118 | + return imageView.getMaximumScale(); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + public void setMaxScale(float scale) { | ||
| 122 | + this.imageView.setMaximumScale(scale); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + public float getMinScale() { | ||
| 126 | + return imageView.getMinimumScale(); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + public void setMinScale(float scale) { | ||
| 130 | + imageView.setMinimumScale(scale); | ||
| 131 | + } | ||
| 132 | +} | ||
| 0 | \ No newline at end of file | 133 | \ No newline at end of file |
core/imageload/src/main/java/com/cnlive/core/imagepreview/ImagePreView.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.content.res.TypedArray; | ||
| 5 | +import android.graphics.Color; | ||
| 6 | +import android.graphics.drawable.Drawable; | ||
| 7 | +import android.util.AttributeSet; | ||
| 8 | +import android.util.Log; | ||
| 9 | +import android.view.KeyEvent; | ||
| 10 | +import android.view.MotionEvent; | ||
| 11 | +import android.view.View; | ||
| 12 | +import android.view.ViewGroup; | ||
| 13 | +import android.widget.FrameLayout; | ||
| 14 | + | ||
| 15 | +import com.cnlive.core.imageload.R; | ||
| 16 | +import com.cnlive.core.imagepreview.dragger.DragHandler; | ||
| 17 | +import com.cnlive.core.imagepreview.dragger.DragMode; | ||
| 18 | +import com.cnlive.core.imagepreview.dragger.DragStatus; | ||
| 19 | +import com.cnlive.core.imagepreview.indexui.DefaultIndexUI; | ||
| 20 | +import com.cnlive.core.imagepreview.indexui.DefaultProgressUI; | ||
| 21 | +import com.cnlive.core.imagepreview.indexui.IndexUI; | ||
| 22 | +import com.cnlive.core.imagepreview.indexui.ProgressUI; | ||
| 23 | +import com.cnlive.core.imagepreview.listener.OnBrowseStatusListener; | ||
| 24 | +import com.cnlive.core.imagepreview.listener.OnDragStatusListener; | ||
| 25 | +import com.cnlive.core.imagepreview.listener.OnItemChangedListener; | ||
| 26 | +import com.cnlive.core.imagepreview.listener.OnItemClickListener; | ||
| 27 | +import com.cnlive.core.imagepreview.listener.OnItemLongPressListener; | ||
| 28 | +import com.cnlive.core.imagepreview.viewpager.ImagePagerAdapter; | ||
| 29 | +import com.cnlive.core.imagepreview.viewpager.ImageViewPager; | ||
| 30 | + | ||
| 31 | +import java.util.ArrayList; | ||
| 32 | +import java.util.List; | ||
| 33 | + | ||
| 34 | +import androidx.annotation.IntRange; | ||
| 35 | +import androidx.annotation.NonNull; | ||
| 36 | +import androidx.viewpager.widget.ViewPager; | ||
| 37 | + | ||
| 38 | +/** | ||
| 39 | + * created by hanyayun | ||
| 40 | + * on 2020/1/21 | ||
| 41 | + */ | ||
| 42 | +public class ImagePreView extends FrameLayout implements ViewPager.OnPageChangeListener { | ||
| 43 | + private final String TAG = getClass().getSimpleName(); | ||
| 44 | + | ||
| 45 | + // 索引视图 | ||
| 46 | + private IndexUI indexUI; | ||
| 47 | + // 加载进度视图 | ||
| 48 | + private ProgressUI progressUI; | ||
| 49 | + private ImageViewPager viewPager; | ||
| 50 | + private ImagePagerAdapter mAdapter; | ||
| 51 | + private LoadImage mLoader; | ||
| 52 | + private DragHandler mDragHandler; | ||
| 53 | + | ||
| 54 | + // 是否执行进场动画 | ||
| 55 | + private boolean playEnterAnim = true; | ||
| 56 | + // 是否执行退场动画 | ||
| 57 | + private boolean playExitAnim = true; | ||
| 58 | + // 动画执行时间 | ||
| 59 | + private long mDuration = 300; | ||
| 60 | + // 是否显示图片索引 | ||
| 61 | + private boolean showIndex = true; | ||
| 62 | + // 是否可拖拽图片 | ||
| 63 | + private boolean draggable = true; | ||
| 64 | + // 拖拽模式 | ||
| 65 | + private int mDragMode = DragMode.MODE_AGILE; | ||
| 66 | + | ||
| 67 | + private List<ViewData> mSourceList; | ||
| 68 | + // ImageViewer 是否会占据 StatusBar 的空间 | ||
| 69 | + private boolean overlayStatusBar = false; | ||
| 70 | + private float mMaxScale; | ||
| 71 | + private float mMinScale; | ||
| 72 | + | ||
| 73 | + // 上一次的触摸点坐标 | ||
| 74 | + private float mLastX, mLastY; | ||
| 75 | + // 是否正在进行拖拽 | ||
| 76 | + private boolean isDragging; | ||
| 77 | + // 是否有动画正在执行 | ||
| 78 | + private boolean hasAnimRunning; | ||
| 79 | + // 是否已经执行了进场动画 | ||
| 80 | + private boolean hasPlayEnterAnim = false; | ||
| 81 | + // ImageViewer 的当前状态 | ||
| 82 | + private int mViewStatus = ViewerStatus.STATUS_SILENCE; | ||
| 83 | + // 缓存 item,用于复用 | ||
| 84 | + private ArrayList<ImageDrawee> mViewBox = new ArrayList<ImageDrawee>(); | ||
| 85 | + | ||
| 86 | + private OnItemClickListener mItemClickListener; | ||
| 87 | + private OnItemLongPressListener mItemLongPressListener; | ||
| 88 | + private OnItemChangedListener mItemChangedListener; | ||
| 89 | + private OnDragStatusListener mDragStatusListener; | ||
| 90 | + private OnBrowseStatusListener mBrowseStatusListener; | ||
| 91 | + | ||
| 92 | + public ImagePreView(@NonNull Context context) { | ||
| 93 | + super(context); | ||
| 94 | + init(context, null); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public ImagePreView(Context context, AttributeSet attrs) { | ||
| 98 | + super(context, attrs); | ||
| 99 | + init(context, attrs); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + public ImagePreView(Context context, AttributeSet attrs, int defStyleAttr) { | ||
| 103 | + super(context, attrs, defStyleAttr); | ||
| 104 | + init(context, attrs); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + private void init(Context context, AttributeSet attrs) { | ||
| 108 | + if (attrs != null) { | ||
| 109 | + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImagePreView); | ||
| 110 | + if (a != null) { | ||
| 111 | + playEnterAnim = a.getBoolean(R.styleable.ImagePreView_ivr_playEnterAnim, true); | ||
| 112 | + playExitAnim = a.getBoolean(R.styleable.ImagePreView_ivr_playExitAnim, true); | ||
| 113 | + mDuration = a.getInteger(R.styleable.ImagePreView_ivr_duration, 300); | ||
| 114 | + showIndex = a.getBoolean(R.styleable.ImagePreView_ivr_showIndex, true); | ||
| 115 | + draggable = a.getBoolean(R.styleable.ImagePreView_ivr_draggable, true); | ||
| 116 | + mDragMode = a.getInteger(R.styleable.ImagePreView_ivr_dragMode, DragMode.MODE_AGILE); | ||
| 117 | + a.recycle(); | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + initView(); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + private void initView() { | ||
| 124 | + if (getBackground() == null) { | ||
| 125 | + setBackgroundColor(Color.BLACK); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + // 添加 ViewPager | ||
| 129 | + viewPager = new ImageViewPager(getContext()); | ||
| 130 | + viewPager.setOffscreenPageLimit(1); | ||
| 131 | + viewPager.addOnPageChangeListener(this); | ||
| 132 | + addView(viewPager, new FrameLayout.LayoutParams( | ||
| 133 | + FrameLayout.LayoutParams.MATCH_PARENT, | ||
| 134 | + FrameLayout.LayoutParams.MATCH_PARENT)); | ||
| 135 | + | ||
| 136 | + setVisibility(View.INVISIBLE); | ||
| 137 | + | ||
| 138 | + progressUI = new DefaultProgressUI(); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + | ||
| 142 | + @Override | ||
| 143 | + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { | ||
| 144 | + | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + @Override | ||
| 148 | + public void onPageSelected(int position) { | ||
| 149 | + if (showIndex && indexUI != null && mSourceList != null) { | ||
| 150 | + indexUI.handleItemChanged(position, mSourceList.size()); | ||
| 151 | + } | ||
| 152 | + if (mItemChangedListener != null) { | ||
| 153 | + mItemChangedListener.onItemChanged(position, getCurrentItem()); | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + @Override | ||
| 158 | + public void onPageScrollStateChanged(int state) { | ||
| 159 | + | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + public ImagePreView imageData(@NonNull List list) { | ||
| 163 | + if (mSourceList == null) { | ||
| 164 | + mSourceList = new ArrayList<ViewData>(); | ||
| 165 | + } else { | ||
| 166 | + mSourceList.clear(); | ||
| 167 | + } | ||
| 168 | + for (int i = 0, len = list.size(); i < len; i++) { | ||
| 169 | + ViewData vd = new ViewData(list.get(i)); | ||
| 170 | + mSourceList.add(vd); | ||
| 171 | + } | ||
| 172 | + return this; | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + public ImagePreView overlayStatusBar(boolean overlayStatusBar) { | ||
| 176 | + this.overlayStatusBar = overlayStatusBar; | ||
| 177 | + return this; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + public ImagePreView bindViewGroup(@NonNull ViewGroup viewGroup) { | ||
| 181 | + for (int i = 0, len = viewGroup.getChildCount(); i < len; i++) { | ||
| 182 | + View child = viewGroup.getChildAt(i); | ||
| 183 | + int[] location = new int[2]; | ||
| 184 | + // 获取 child 在屏幕中的坐标,其中 getLocationOnScreen() 方法获取的 y 轴坐标包含状态栏的高度 | ||
| 185 | + child.getLocationOnScreen(location); | ||
| 186 | + mSourceList.get(i).setTargetX(location[0]); | ||
| 187 | + mSourceList.get(i).setTargetY(overlayStatusBar ? location[1] : location[1] - Utils.getStatusBarHeight(getContext())); | ||
| 188 | + mSourceList.get(i).setTargetWidth(child.getMeasuredWidth()); | ||
| 189 | + mSourceList.get(i).setTargetHeight(child.getMeasuredHeight()); | ||
| 190 | + } | ||
| 191 | + return this; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + public ImagePreView viewData(@NonNull List<ViewData> list) { | ||
| 195 | + this.mSourceList = list; | ||
| 196 | + return this; | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + public ImagePreView imageLoader(@NonNull LoadImage loader) { | ||
| 200 | + this.mLoader = loader; | ||
| 201 | + return this; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + public ImagePreView playEnterAnim(boolean play) { | ||
| 205 | + this.playEnterAnim = play; | ||
| 206 | + return this; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + public ImagePreView playExitAnim(boolean play) { | ||
| 210 | + this.playExitAnim = play; | ||
| 211 | + return this; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + public ImagePreView duration(long duration) { | ||
| 215 | + this.mDuration = duration; | ||
| 216 | + return this; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + public ImagePreView showIndex(boolean showIndex) { | ||
| 220 | + this.showIndex = showIndex; | ||
| 221 | + return this; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + public ImagePreView loadIndexUI(@NonNull IndexUI indexUI) { | ||
| 225 | + this.indexUI = indexUI; | ||
| 226 | + return this; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + public ImagePreView loadProgressUI(@NonNull ProgressUI progressUI) { | ||
| 230 | + this.progressUI = progressUI; | ||
| 231 | + return this; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + public ImagePreView draggable(boolean draggable) { | ||
| 235 | + this.draggable = draggable; | ||
| 236 | + return this; | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + public ImagePreView dragMode(int mode) { | ||
| 240 | + this.mDragMode = mode; | ||
| 241 | + return this; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + public ImagePreView setMaxScale(float scale) { | ||
| 245 | + this.mMaxScale = scale; | ||
| 246 | + return this; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + public ImagePreView setMinScale(float scale) { | ||
| 250 | + this.mMinScale = scale; | ||
| 251 | + return this; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + public ImagePreView setOnItemClickListener(OnItemClickListener listener) { | ||
| 255 | + this.mItemClickListener = listener; | ||
| 256 | + return this; | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + public ImagePreView setOnItemLongPressListener(OnItemLongPressListener listener) { | ||
| 260 | + this.mItemLongPressListener = listener; | ||
| 261 | + return this; | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + public ImagePreView setOnItemChangedListener(OnItemChangedListener listener) { | ||
| 265 | + this.mItemChangedListener = listener; | ||
| 266 | + return this; | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + public ImagePreView setOnDragStatusListener(OnDragStatusListener listener) { | ||
| 270 | + this.mDragStatusListener = listener; | ||
| 271 | + return this; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + public ImagePreView setOnBrowseStatusListener(OnBrowseStatusListener listener) { | ||
| 275 | + this.mBrowseStatusListener = listener; | ||
| 276 | + return this; | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + /** | ||
| 280 | + * 开启浏览 | ||
| 281 | + * | ||
| 282 | + * @param startPosition 开始位置,即点击的 ImageView 的位置 | ||
| 283 | + */ | ||
| 284 | + public void watch(@IntRange(from = 0) int startPosition) { | ||
| 285 | + watch(startPosition, 0, 0, null); | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + /** | ||
| 289 | + * 开启浏览 | ||
| 290 | + * | ||
| 291 | + * @param startPosition 开始位置,即点击的 ImageView 的位置 | ||
| 292 | + * @param callback 进场动画执行回调 | ||
| 293 | + */ | ||
| 294 | + public void watch(@IntRange(from = 0) int startPosition, ImageTransfer.OnTransCallback callback) { | ||
| 295 | + watch(startPosition, 0, 0, callback); | ||
| 296 | + } | ||
| 297 | + | ||
| 298 | + /** | ||
| 299 | + * 开启浏览 | ||
| 300 | + * | ||
| 301 | + * @param startPosition 开始位置,即点击的 ImageView 的位置 | ||
| 302 | + * @param startImageWidth 被点击的 ImageView 加载的资源图片的实际宽度 | ||
| 303 | + * @param startImageHeight 被点击的 ImageView 加载的资源图片的实际高度 | ||
| 304 | + */ | ||
| 305 | + public void watch(@IntRange(from = 0) int startPosition, int startImageWidth, int startImageHeight) { | ||
| 306 | + watch(startPosition, startImageWidth, startImageHeight, null); | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + /** | ||
| 310 | + * 开启浏览 | ||
| 311 | + * | ||
| 312 | + * @param startPosition 开始位置,即点击的 ImageView 的位置 | ||
| 313 | + * @param startImageWidth 被点击的 ImageView 加载的资源图片的实际宽度 | ||
| 314 | + * @param startImageHeight 被点击的 ImageView 加载的资源图片的实际高度 | ||
| 315 | + * @param callback 进场动画执行回调 | ||
| 316 | + */ | ||
| 317 | + public void watch(@IntRange(from = 0) final int startPosition, int startImageWidth, int startImageHeight, final ImageTransfer.OnTransCallback callback) { | ||
| 318 | + if (mSourceList == null || startPosition >= mSourceList.size()) { | ||
| 319 | + Log.e(TAG, "SourceList is null or StartPosition greater than or equal to the length of Sourcelist."); | ||
| 320 | + return; | ||
| 321 | + } | ||
| 322 | + if (startImageWidth != 0 && startImageHeight != 0 | ||
| 323 | + && (mSourceList.get(startPosition).getImageWidth() == 0 || | ||
| 324 | + mSourceList.get(startPosition).getImageHeight() == 0)) { | ||
| 325 | + mSourceList.get(startPosition).setImageWidth(startImageWidth); | ||
| 326 | + mSourceList.get(startPosition).setImageHeight(startImageHeight); | ||
| 327 | + } | ||
| 328 | + viewPager.setScrollable(true); | ||
| 329 | + mAdapter = new ImagePagerAdapter(mSourceList.size()) { | ||
| 330 | + @NonNull | ||
| 331 | + @Override | ||
| 332 | + public Object instantiateItem(@NonNull ViewGroup container, int position) { | ||
| 333 | + return ImagePreView.this.instantiateItem(container, position, startPosition, callback); | ||
| 334 | + } | ||
| 335 | + }; | ||
| 336 | + viewPager.setAdapter(mAdapter); | ||
| 337 | + viewPager.setCurrentItem(startPosition); | ||
| 338 | + setVisibility(VISIBLE); | ||
| 339 | + if (!playEnterAnim) { | ||
| 340 | + noteBrowseStatus(ViewerStatus.STATUS_WATCHING); | ||
| 341 | + handleIndexUI(startPosition); | ||
| 342 | + } | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + /** | ||
| 346 | + * 取消浏览 | ||
| 347 | + */ | ||
| 348 | + public void cancel() { | ||
| 349 | + cancel(null); | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + /** | ||
| 353 | + * 取消浏览 | ||
| 354 | + * | ||
| 355 | + * @param callback 退场动画执行回调 | ||
| 356 | + */ | ||
| 357 | + public void cancel(final ImageTransfer.OnTransCallback callback) { | ||
| 358 | + if (indexUI != null) { | ||
| 359 | + indexUI.hide(); | ||
| 360 | + } | ||
| 361 | + if (playExitAnim) { | ||
| 362 | + int position = getCurrentPosition(); | ||
| 363 | + new ImageTransfer(getWidth(), getHeight()) | ||
| 364 | + .with(getCurrentItem().getImageView()) | ||
| 365 | + .background(getBackground()) | ||
| 366 | + .duration(mDuration) | ||
| 367 | + .loadExitData(mSourceList.get(position)) | ||
| 368 | + .callback(new ImageTransfer.OnTransCallback() { | ||
| 369 | + @Override | ||
| 370 | + public void onStart() { | ||
| 371 | + noteBrowseStatus(ViewerStatus.STATUS_BEGIN_CLOSE); | ||
| 372 | + if (callback != null) { | ||
| 373 | + callback.onStart(); | ||
| 374 | + } | ||
| 375 | + } | ||
| 376 | + | ||
| 377 | + @Override | ||
| 378 | + public void onRunning(float progress) { | ||
| 379 | + noteBrowseStatus(ViewerStatus.STATUS_CLOSING); | ||
| 380 | + if (callback != null) { | ||
| 381 | + callback.onRunning(progress); | ||
| 382 | + } | ||
| 383 | + } | ||
| 384 | + | ||
| 385 | + @Override | ||
| 386 | + public void onEnd() { | ||
| 387 | + noteBrowseStatus(ViewerStatus.STATUS_SILENCE); | ||
| 388 | + if (callback != null) { | ||
| 389 | + callback.onEnd(); | ||
| 390 | + } | ||
| 391 | + shutComplete(); | ||
| 392 | + } | ||
| 393 | + }) | ||
| 394 | + .play(); | ||
| 395 | + } else { | ||
| 396 | + noteBrowseStatus(ViewerStatus.STATUS_SILENCE); | ||
| 397 | + shutComplete(); | ||
| 398 | + } | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | + /** | ||
| 402 | + * 实例化 item | ||
| 403 | + */ | ||
| 404 | + private ImageDrawee instantiateItem(ViewGroup container, int position, final int startPosition, final ImageTransfer.OnTransCallback callback) { | ||
| 405 | + ImageDrawee drawee = null; | ||
| 406 | + if (mViewBox.size() > 0) { | ||
| 407 | + for (ImageDrawee item : mViewBox) { | ||
| 408 | + if (item.getParent() == null) { | ||
| 409 | + drawee = item; | ||
| 410 | + break; | ||
| 411 | + } | ||
| 412 | + } | ||
| 413 | + } | ||
| 414 | + if (drawee == null) { | ||
| 415 | + drawee = new ImageDrawee(container.getContext()); | ||
| 416 | + drawee.setProgressUI(progressUI); | ||
| 417 | + mViewBox.add(drawee); | ||
| 418 | + } | ||
| 419 | + container.addView(drawee); | ||
| 420 | + configureItem(position, drawee); | ||
| 421 | + if (playEnterAnim && !hasPlayEnterAnim && startPosition == position) { | ||
| 422 | + hasPlayEnterAnim = true; | ||
| 423 | + new ImageTransfer(getWidth(), getHeight()) | ||
| 424 | + .with(drawee.getImageView()) | ||
| 425 | + .loadEnterData(mSourceList.get(position)) | ||
| 426 | + .background(getBackground()) | ||
| 427 | + .duration(mDuration) | ||
| 428 | + .callback(new ImageTransfer.OnTransCallback() { | ||
| 429 | + @Override | ||
| 430 | + public void onStart() { | ||
| 431 | + noteBrowseStatus(ViewerStatus.STATUS_BEGIN_OPEN); | ||
| 432 | + if (callback != null) { | ||
| 433 | + callback.onStart(); | ||
| 434 | + } | ||
| 435 | + } | ||
| 436 | + | ||
| 437 | + @Override | ||
| 438 | + public void onRunning(float progress) { | ||
| 439 | + noteBrowseStatus(ViewerStatus.STATUS_OPENING); | ||
| 440 | + if (callback != null) { | ||
| 441 | + callback.onRunning(progress); | ||
| 442 | + } | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + @Override | ||
| 446 | + public void onEnd() { | ||
| 447 | + handleIndexUI(startPosition); | ||
| 448 | + noteBrowseStatus(ViewerStatus.STATUS_WATCHING); | ||
| 449 | + if (callback != null) { | ||
| 450 | + callback.onEnd(); | ||
| 451 | + } | ||
| 452 | + } | ||
| 453 | + }) | ||
| 454 | + .play(); | ||
| 455 | + } | ||
| 456 | + return drawee; | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + /** | ||
| 460 | + * 配置 item | ||
| 461 | + */ | ||
| 462 | + private void configureItem(final int position, final ImageDrawee drawee) { | ||
| 463 | + drawee.setTag(position); | ||
| 464 | + if (mMaxScale > 0) { | ||
| 465 | + drawee.setMaxScale(mMaxScale); | ||
| 466 | + } | ||
| 467 | + if (mMinScale > 0) { | ||
| 468 | + drawee.setMinScale(mMinScale); | ||
| 469 | + } | ||
| 470 | + mLoader.displayImage(mSourceList.get(position).getImageSrc(), drawee.getImageView(), new LoadImage.LoadCallback() { | ||
| 471 | + @Override | ||
| 472 | + public void onLoadStarted(Object placeholder) { | ||
| 473 | + drawee.setImage(placeholder); | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + @Override | ||
| 477 | + public void onLoading(float progress) { | ||
| 478 | + drawee.handleProgress(progress); | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + @Override | ||
| 482 | + public void onLoadSucceed(Object source) { | ||
| 483 | + drawee.hideProgressUI(); | ||
| 484 | + drawee.setImage(source); | ||
| 485 | + if (mSourceList.get(position).getImageWidth() == 0 || | ||
| 486 | + mSourceList.get(position).getImageHeight() == 0) { | ||
| 487 | + Drawable drawable = drawee.getImageView().getDrawable(); | ||
| 488 | + if (drawable != null) { | ||
| 489 | + mSourceList.get(position).setImageWidth(drawable.getIntrinsicWidth()); | ||
| 490 | + mSourceList.get(position).setImageHeight(drawable.getIntrinsicHeight()); | ||
| 491 | + } | ||
| 492 | + } | ||
| 493 | + } | ||
| 494 | + | ||
| 495 | + @Override | ||
| 496 | + public void onLoadFailed(Object error) { | ||
| 497 | + drawee.hideProgressUI(); | ||
| 498 | + drawee.setImage(error); | ||
| 499 | + } | ||
| 500 | + }); | ||
| 501 | + // 单击事件 | ||
| 502 | + drawee.getImageView().setOnClickListener(new View.OnClickListener() { | ||
| 503 | + @Override | ||
| 504 | + public void onClick(View v) { | ||
| 505 | + if (!hasAnimRunning && mItemClickListener != null) { | ||
| 506 | + final boolean result = mItemClickListener.onItemClick(position, drawee.getImageView()); | ||
| 507 | + // 判断是否消费了单击事件,如果消费了,则单击事件的后续方法不执行 | ||
| 508 | + if (result) { | ||
| 509 | + return; | ||
| 510 | + } | ||
| 511 | + } | ||
| 512 | + cancel(); | ||
| 513 | + } | ||
| 514 | + }); | ||
| 515 | + // 长按事件 | ||
| 516 | + drawee.getImageView().setOnLongClickListener(new View.OnLongClickListener() { | ||
| 517 | + @Override | ||
| 518 | + public boolean onLongClick(View v) { | ||
| 519 | + if (!hasAnimRunning && mItemLongPressListener != null) { | ||
| 520 | + return mItemLongPressListener.onItemLongPress(position, drawee.getImageView()); | ||
| 521 | + } | ||
| 522 | + return false; | ||
| 523 | + } | ||
| 524 | + }); | ||
| 525 | + } | ||
| 526 | + | ||
| 527 | + private void noteDragStatus(int status) { | ||
| 528 | + switch (status) { | ||
| 529 | + case DragStatus.STATUS_BEGIN_RESTORE: | ||
| 530 | + case DragStatus.STATUS_BEGIN_EXIT: | ||
| 531 | + hasAnimRunning = true; | ||
| 532 | + break; | ||
| 533 | + case DragStatus.STATUS_COMPLETE_RESTORE: | ||
| 534 | + case DragStatus.STATUS_COMPLETE_EXIT: | ||
| 535 | + hasAnimRunning = false; | ||
| 536 | + break; | ||
| 537 | + } | ||
| 538 | + if (mDragStatusListener != null) { | ||
| 539 | + mDragStatusListener.onDragStatusChanged(status); | ||
| 540 | + } | ||
| 541 | + } | ||
| 542 | + | ||
| 543 | + private void noteBrowseStatus(int status) { | ||
| 544 | + mViewStatus = status; | ||
| 545 | + switch (status) { | ||
| 546 | + case ViewerStatus.STATUS_BEGIN_OPEN: | ||
| 547 | + hasAnimRunning = true; | ||
| 548 | + break; | ||
| 549 | + case ViewerStatus.STATUS_BEGIN_CLOSE: | ||
| 550 | + viewPager.setScrollable(false); | ||
| 551 | + hasAnimRunning = true; | ||
| 552 | + break; | ||
| 553 | + case ViewerStatus.STATUS_WATCHING: | ||
| 554 | + hasAnimRunning = false; | ||
| 555 | + break; | ||
| 556 | + case ViewerStatus.STATUS_SILENCE: | ||
| 557 | + viewPager.setScrollable(true); | ||
| 558 | + hasAnimRunning = false; | ||
| 559 | + break; | ||
| 560 | + } | ||
| 561 | + if (mBrowseStatusListener != null) { | ||
| 562 | + mBrowseStatusListener.onBrowseStatus(mViewStatus); | ||
| 563 | + } | ||
| 564 | + } | ||
| 565 | + | ||
| 566 | + /** | ||
| 567 | + * 处理索引 UI | ||
| 568 | + */ | ||
| 569 | + private void handleIndexUI(int startPosition) { | ||
| 570 | + if (indexUI == null) { | ||
| 571 | + indexUI = new DefaultIndexUI(overlayStatusBar); | ||
| 572 | + } | ||
| 573 | + if (showIndex) { | ||
| 574 | + if (mSourceList.size() > 1) { | ||
| 575 | + indexUI.setup(this, startPosition, mSourceList.size()); | ||
| 576 | + } else { | ||
| 577 | + indexUI.hide(); | ||
| 578 | + } | ||
| 579 | + } else { | ||
| 580 | + indexUI.hide(); | ||
| 581 | + } | ||
| 582 | + } | ||
| 583 | + | ||
| 584 | + private void shutComplete() { | ||
| 585 | + setVisibility(GONE); | ||
| 586 | + reset(); | ||
| 587 | + } | ||
| 588 | + | ||
| 589 | + private void reset() { | ||
| 590 | + if (mViewBox.size() > 0) { | ||
| 591 | + mViewBox.clear(); | ||
| 592 | + } | ||
| 593 | + if (mDragHandler != null) { | ||
| 594 | + mDragHandler.clear(); | ||
| 595 | + mDragHandler = null; | ||
| 596 | + } | ||
| 597 | + mAdapter = null; | ||
| 598 | + hasAnimRunning = false; | ||
| 599 | + hasPlayEnterAnim = false; | ||
| 600 | + } | ||
| 601 | + | ||
| 602 | + public List<ViewData> getViewData() { | ||
| 603 | + return mSourceList; | ||
| 604 | + } | ||
| 605 | + | ||
| 606 | + public ImageDrawee getCurrentItem() { | ||
| 607 | + if (mViewBox != null) { | ||
| 608 | + for (ImageDrawee drawee : mViewBox) { | ||
| 609 | + if ((int) drawee.getTag() == getCurrentPosition()) { | ||
| 610 | + return drawee; | ||
| 611 | + } | ||
| 612 | + } | ||
| 613 | + } | ||
| 614 | + return (ImageDrawee) viewPager.findViewWithTag(getCurrentPosition()); | ||
| 615 | + } | ||
| 616 | + | ||
| 617 | + public int getCurrentPosition() { | ||
| 618 | + return viewPager != null ? viewPager.getCurrentItem() : 0; | ||
| 619 | + } | ||
| 620 | + | ||
| 621 | + public int getViewStatus() { | ||
| 622 | + return mViewStatus; | ||
| 623 | + } | ||
| 624 | + | ||
| 625 | + //////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 626 | + //// 拖拽相关 | ||
| 627 | + //////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 628 | + | ||
| 629 | + @Override | ||
| 630 | + public boolean onInterceptTouchEvent(MotionEvent ev) { | ||
| 631 | + boolean isIntercept = super.onInterceptTouchEvent(ev); | ||
| 632 | + if (!hasAnimRunning && draggable) { | ||
| 633 | + // 是否拦截触摸事件? | ||
| 634 | + // 若拦截,则 ImageViewer 自己处理触摸事件; | ||
| 635 | + // 若不拦截,则 ImageView 处理触摸事件 | ||
| 636 | + int action = ev.getAction() & ev.getActionMasked(); | ||
| 637 | + if (action == MotionEvent.ACTION_DOWN) { | ||
| 638 | + mLastX = ev.getX(); | ||
| 639 | + mLastY = ev.getY(); | ||
| 640 | + } else if (action == MotionEvent.ACTION_MOVE) { | ||
| 641 | + /** | ||
| 642 | + * 拖拽触发条件: | ||
| 643 | + * 1.允许拖拽 | ||
| 644 | + * 2.仅有一个触摸点 | ||
| 645 | + * 3.图片的缩放等级 = 1f | ||
| 646 | + * 4.拖拽处理类不为空 | ||
| 647 | + * 5.手势为上下滑动手势,左右滑动不触发 | ||
| 648 | + */ | ||
| 649 | + if (ev.getPointerCount() == 1 && getCurrentItem().getScale() <= 1f) { | ||
| 650 | + float disX = ev.getX() - mLastX; | ||
| 651 | + float disY = ev.getY() - mLastY; | ||
| 652 | + // 上下滑动手势 | ||
| 653 | + if (Math.abs(disX) < Math.abs(disY)) { | ||
| 654 | + if (mDragMode == DragMode.MODE_AGILE && disY < 0) { | ||
| 655 | + return isIntercept; | ||
| 656 | + } | ||
| 657 | + isDragging = true; | ||
| 658 | + if (mDragHandler == null) { | ||
| 659 | + mDragHandler = new DragHandler(getWidth(), getHeight()); | ||
| 660 | + } | ||
| 661 | + mDragHandler.onReay(mDragMode, getBackground()); | ||
| 662 | + noteDragStatus(DragStatus.STATUS_READY); | ||
| 663 | + isIntercept = true; | ||
| 664 | + } | ||
| 665 | + } | ||
| 666 | + } | ||
| 667 | + } | ||
| 668 | + return isIntercept; | ||
| 669 | + } | ||
| 670 | + | ||
| 671 | + @Override | ||
| 672 | + public boolean onTouchEvent(MotionEvent event) { | ||
| 673 | + int action = event.getAction() & event.getActionMasked(); | ||
| 674 | + if (action == MotionEvent.ACTION_MOVE) { | ||
| 675 | + if (draggable && isDragging && mDragHandler != null) { | ||
| 676 | + mDragHandler.onDrag(mLastX, mLastY, event, getCurrentItem().getImageView()); | ||
| 677 | + noteDragStatus(DragStatus.STATUS_DRAGGING); | ||
| 678 | + } | ||
| 679 | + mLastX = event.getX(); | ||
| 680 | + mLastY = event.getY(); | ||
| 681 | + } else if (action == MotionEvent.ACTION_UP) { | ||
| 682 | + if (draggable && isDragging && mDragHandler != null) { | ||
| 683 | + isDragging = false; | ||
| 684 | + // 释放图片 | ||
| 685 | + mDragHandler.onUp(getCurrentItem().getImageView(), | ||
| 686 | + mSourceList.get(getCurrentPosition()), new ImageTransfer.OnTransCallback() { | ||
| 687 | + @Override | ||
| 688 | + public void onStart() { | ||
| 689 | + handleDragResultStatus("start"); | ||
| 690 | + } | ||
| 691 | + | ||
| 692 | + @Override | ||
| 693 | + public void onRunning(float progress) { | ||
| 694 | + handleDragResultStatus("running"); | ||
| 695 | + } | ||
| 696 | + | ||
| 697 | + @Override | ||
| 698 | + public void onEnd() { | ||
| 699 | + handleDragResultStatus("end"); | ||
| 700 | + } | ||
| 701 | + }); | ||
| 702 | + } | ||
| 703 | + mLastX = 0; | ||
| 704 | + mLastY = 0; | ||
| 705 | + } | ||
| 706 | + return super.onTouchEvent(event); | ||
| 707 | + } | ||
| 708 | + | ||
| 709 | + private void handleDragResultStatus(String proceed) { | ||
| 710 | + if (mDragHandler.getAction() == ImageTransfer.ACTION_DRAG_RESTORE) { | ||
| 711 | + int status = proceed.equals("start") ? DragStatus.STATUS_BEGIN_RESTORE : | ||
| 712 | + (proceed.equals("running") ? DragStatus.STATUS_RESTORING : | ||
| 713 | + DragStatus.STATUS_COMPLETE_RESTORE); | ||
| 714 | + if (status == DragStatus.STATUS_BEGIN_RESTORE) { | ||
| 715 | + viewPager.setScrollable(false); | ||
| 716 | + hasAnimRunning = true; | ||
| 717 | + } else if (status == DragStatus.STATUS_COMPLETE_RESTORE) { | ||
| 718 | + viewPager.setScrollable(true); | ||
| 719 | + hasAnimRunning = false; | ||
| 720 | + } | ||
| 721 | + noteDragStatus(status); | ||
| 722 | + } else if (mDragHandler.getAction() == ImageTransfer.ACTION_DRAG_EXIT_AGILE | ||
| 723 | + || mDragHandler.getAction() == ImageTransfer.ACTION_DRAG_EXIT_SIMPLE) { | ||
| 724 | + int status = proceed.equals("start") ? DragStatus.STATUS_BEGIN_EXIT : | ||
| 725 | + (proceed.equals("running") ? DragStatus.STATUS_EXITTING : | ||
| 726 | + DragStatus.STATUS_COMPLETE_EXIT); | ||
| 727 | + if (status == DragStatus.STATUS_BEGIN_EXIT) { | ||
| 728 | + viewPager.setScrollable(false); | ||
| 729 | + hasAnimRunning = true; | ||
| 730 | + } else if (status == DragStatus.STATUS_COMPLETE_EXIT) { | ||
| 731 | + viewPager.setScrollable(true); | ||
| 732 | + hasAnimRunning = false; | ||
| 733 | + } | ||
| 734 | + noteDragStatus(status); | ||
| 735 | + if (proceed.equals("end")) { | ||
| 736 | + noteBrowseStatus(ViewerStatus.STATUS_SILENCE); | ||
| 737 | + shutComplete(); | ||
| 738 | + } | ||
| 739 | + } | ||
| 740 | + } | ||
| 741 | + | ||
| 742 | + /** | ||
| 743 | + * 如果本方法未执行,则是因为图片浏览器为获取到焦点,可在外部手动获取焦点 | ||
| 744 | + * 建议在外部手动调动本方法 | ||
| 745 | + * | ||
| 746 | + * @param keyCode | ||
| 747 | + * @param event | ||
| 748 | + * @return | ||
| 749 | + */ | ||
| 750 | + @Override | ||
| 751 | + public boolean onKeyDown(int keyCode, KeyEvent event) { | ||
| 752 | + if (keyCode == KeyEvent.KEYCODE_BACK) { | ||
| 753 | + if (!hasAnimRunning) { | ||
| 754 | + if (mViewStatus == ViewerStatus.STATUS_WATCHING) { | ||
| 755 | + cancel(); | ||
| 756 | + // 消费返回键点击事件,不传递出去 | ||
| 757 | + return true; | ||
| 758 | + } | ||
| 759 | + } | ||
| 760 | + } | ||
| 761 | + return super.onKeyDown(keyCode, event); | ||
| 762 | + } | ||
| 763 | + | ||
| 764 | + @Override | ||
| 765 | + protected void onDetachedFromWindow() { | ||
| 766 | + super.onDetachedFromWindow(); | ||
| 767 | + mSourceList = null; | ||
| 768 | + mLoader = null; | ||
| 769 | + reset(); | ||
| 770 | + } | ||
| 771 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/ImageTransfer.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +import android.animation.Animator; | ||
| 4 | +import android.animation.AnimatorListenerAdapter; | ||
| 5 | +import android.animation.ValueAnimator; | ||
| 6 | +import android.graphics.drawable.Drawable; | ||
| 7 | +import android.widget.FrameLayout; | ||
| 8 | +import android.widget.ImageView; | ||
| 9 | + | ||
| 10 | +import androidx.annotation.NonNull; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 图片进退场动画处理类 | ||
| 14 | + * created by hanyayun | ||
| 15 | + * on 2020/1/20 | ||
| 16 | + */ | ||
| 17 | +public class ImageTransfer { | ||
| 18 | + // 没有需要执行的动画 | ||
| 19 | + public static final int ACTION_IDEL = -1; | ||
| 20 | + // 执行进场动画 | ||
| 21 | + public static final int ACTION_ENTER = 0; | ||
| 22 | + // 执行退场动画 | ||
| 23 | + public static final int ACTION_EXIT = 1; | ||
| 24 | + // 拖拽后,执行复原动画 | ||
| 25 | + public static final int ACTION_DRAG_RESTORE = 2; | ||
| 26 | + // 在灵巧模式下,拖拽后,执行退场动画 | ||
| 27 | + public static final int ACTION_DRAG_EXIT_AGILE = 3; | ||
| 28 | + // 在简单模式下,拖拽后,执行退场动画 | ||
| 29 | + public static final int ACTION_DRAG_EXIT_SIMPLE = 4; | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + private int interfaceWidth, interfaceHeight; | ||
| 33 | + private int startWidth, startHeight; | ||
| 34 | + private int endWidth, endHeight; | ||
| 35 | + private float startX, startY; | ||
| 36 | + private float endX, endY; | ||
| 37 | + private long duration; | ||
| 38 | + private Drawable background; | ||
| 39 | + private int startAlpha, endAlpha; | ||
| 40 | + | ||
| 41 | + private int animAction; | ||
| 42 | + // 是否设置了图片的原始尺寸 | ||
| 43 | + private boolean hasSetImageOriginalSize; | ||
| 44 | + private ImageView imageView; | ||
| 45 | + private OnTransCallback mTransCallback; | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + public ImageTransfer(int interfaceWidth, int interfaceHeight) { | ||
| 49 | + this.interfaceWidth = interfaceWidth; | ||
| 50 | + this.interfaceHeight = interfaceHeight; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public ImageTransfer with(@NonNull ImageView target) { | ||
| 54 | + this.imageView = target; | ||
| 55 | + return this; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * 加载进场动画数据 | ||
| 60 | + */ | ||
| 61 | + public ImageTransfer loadEnterData(@NonNull ViewData viewData) { | ||
| 62 | + startX = viewData.getTargetX(); | ||
| 63 | + startY = viewData.getTargetY(); | ||
| 64 | + startWidth = viewData.getTargetWidth(); | ||
| 65 | + startHeight = viewData.getTargetHeight(); | ||
| 66 | + int imageWidth, imageHeight; | ||
| 67 | + if (viewData.getImageWidth() == 0 || viewData.getImageHeight() == 0) { | ||
| 68 | + imageWidth = interfaceWidth; | ||
| 69 | + imageHeight = interfaceHeight; | ||
| 70 | + hasSetImageOriginalSize = false; | ||
| 71 | + } else { | ||
| 72 | + imageWidth = viewData.getImageWidth(); | ||
| 73 | + imageHeight = viewData.getImageHeight(); | ||
| 74 | + hasSetImageOriginalSize = true; | ||
| 75 | + } | ||
| 76 | + float scale = Math.min(interfaceWidth * 1f / imageWidth, interfaceHeight * 1f / imageHeight); | ||
| 77 | + endWidth = (int) (imageWidth * scale); | ||
| 78 | + endHeight = (int) (imageHeight * scale); | ||
| 79 | + endX = (interfaceWidth - endWidth) * 1f / 2; | ||
| 80 | + endY = (interfaceHeight - endHeight) * 1f / 2; | ||
| 81 | + startAlpha = 0; | ||
| 82 | + endAlpha = 255; | ||
| 83 | + animAction = ACTION_ENTER; | ||
| 84 | + return this; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * 加载退场动画数据 | ||
| 89 | + */ | ||
| 90 | + public ImageTransfer loadExitData(@NonNull ViewData viewData) { | ||
| 91 | + endX = viewData.getTargetX(); | ||
| 92 | + endY = viewData.getTargetY(); | ||
| 93 | + endWidth = viewData.getTargetWidth(); | ||
| 94 | + endHeight = viewData.getTargetHeight(); | ||
| 95 | + int imageWidth, imageHeight; | ||
| 96 | + if (viewData.getImageWidth() == 0 || viewData.getImageHeight() == 0) { | ||
| 97 | + Drawable thumb = imageView.getDrawable(); | ||
| 98 | + if (thumb != null) { | ||
| 99 | + imageWidth = thumb.getIntrinsicWidth(); | ||
| 100 | + imageHeight = thumb.getIntrinsicHeight(); | ||
| 101 | + hasSetImageOriginalSize = true; | ||
| 102 | + } else { | ||
| 103 | + imageWidth = interfaceWidth; | ||
| 104 | + imageHeight = interfaceHeight; | ||
| 105 | + hasSetImageOriginalSize = false; | ||
| 106 | + } | ||
| 107 | + } else { | ||
| 108 | + imageWidth = viewData.getImageWidth(); | ||
| 109 | + imageHeight = viewData.getImageHeight(); | ||
| 110 | + hasSetImageOriginalSize = true; | ||
| 111 | + } | ||
| 112 | + float scale = Math.min(interfaceWidth * 1f / imageWidth, interfaceHeight * 1f / imageHeight); | ||
| 113 | + startWidth = (int) (imageWidth * scale); | ||
| 114 | + startHeight = (int) (imageHeight * scale); | ||
| 115 | + startX = (interfaceWidth - startWidth) * 1f / 2; | ||
| 116 | + startY = (interfaceHeight - startHeight) * 1f / 2; | ||
| 117 | + startAlpha = background.getAlpha(); | ||
| 118 | + endAlpha = 0; | ||
| 119 | + animAction = ACTION_EXIT; | ||
| 120 | + return this; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + /** | ||
| 124 | + * 加载拖拽复原动画数据 | ||
| 125 | + */ | ||
| 126 | + public ImageTransfer loadDragRestoreData() { | ||
| 127 | + startX = imageView.getTranslationX(); | ||
| 128 | + startY = imageView.getTranslationY(); | ||
| 129 | + startWidth = imageView.getWidth(); | ||
| 130 | + startHeight = imageView.getHeight(); | ||
| 131 | + endX = 0; | ||
| 132 | + endY = 0; | ||
| 133 | + endWidth = interfaceWidth; | ||
| 134 | + endHeight = interfaceHeight; | ||
| 135 | + startAlpha = background.getAlpha(); | ||
| 136 | + endAlpha = 255; | ||
| 137 | + animAction = ACTION_DRAG_RESTORE; | ||
| 138 | + return this; | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + | ||
| 142 | + /** | ||
| 143 | + * 灵巧拖拽模式下,加载拖拽退场动画数据 | ||
| 144 | + */ | ||
| 145 | + public ImageTransfer loadDragExitDataInAgile(@NonNull ViewData viewData) { | ||
| 146 | + int imageWidth, imageHeight; | ||
| 147 | + if (viewData.getImageWidth() == 0 || viewData.getImageHeight() == 0) { | ||
| 148 | + Drawable thumb = imageView.getDrawable(); | ||
| 149 | + if (thumb != null) { | ||
| 150 | + imageWidth = thumb.getIntrinsicWidth(); | ||
| 151 | + imageHeight = thumb.getIntrinsicHeight(); | ||
| 152 | + hasSetImageOriginalSize = true; | ||
| 153 | + } else { | ||
| 154 | + imageWidth = interfaceWidth; | ||
| 155 | + imageHeight = interfaceHeight; | ||
| 156 | + hasSetImageOriginalSize = false; | ||
| 157 | + } | ||
| 158 | + } else { | ||
| 159 | + imageWidth = viewData.getImageWidth(); | ||
| 160 | + imageHeight = viewData.getImageHeight(); | ||
| 161 | + hasSetImageOriginalSize = true; | ||
| 162 | + } | ||
| 163 | + float adjustScale = Math.min(interfaceWidth * 1f / imageWidth, interfaceHeight * 1f / imageHeight); | ||
| 164 | + float dragScale = imageView.getWidth() * 1f / interfaceWidth; | ||
| 165 | + startWidth = (int) (imageWidth * adjustScale * dragScale); | ||
| 166 | + startHeight = (int) (imageHeight * adjustScale * dragScale); | ||
| 167 | + startX = imageView.getTranslationX() + (imageView.getWidth() - startWidth) * 1f / 2; | ||
| 168 | + startY = imageView.getTranslationY() + (imageView.getHeight() - startHeight) * 1f / 2; | ||
| 169 | + // 图片是否已经滑出预览界面 | ||
| 170 | + if ( | ||
| 171 | + // imageView 已经从左边滑出预览界面 | ||
| 172 | + (startX + startWidth) <= 0 | ||
| 173 | + // imageView 已经从右边滑出预览界面 | ||
| 174 | + || startX >= interfaceWidth | ||
| 175 | + // imageView 已经从底部滑出图片预览界面 | ||
| 176 | + || startY >= interfaceHeight) { | ||
| 177 | + endX = startX; | ||
| 178 | + endY = startY; | ||
| 179 | + endWidth = startWidth; | ||
| 180 | + endHeight = startHeight; | ||
| 181 | + } else { | ||
| 182 | + endX = viewData.getTargetX(); | ||
| 183 | + endY = viewData.getTargetY(); | ||
| 184 | + endWidth = viewData.getTargetWidth(); | ||
| 185 | + endHeight = viewData.getTargetHeight(); | ||
| 186 | + } | ||
| 187 | + startAlpha = background.getAlpha(); | ||
| 188 | + endAlpha = 0; | ||
| 189 | + animAction = ACTION_DRAG_EXIT_AGILE; | ||
| 190 | + return this; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** | ||
| 194 | + * 简单拖拽模式下,加载拖拽退场动画数据 | ||
| 195 | + */ | ||
| 196 | + public ImageTransfer loadDragExitDataInSimple(@NonNull ViewData viewData) { | ||
| 197 | + startX = endX = 0; | ||
| 198 | + startY = imageView.getTranslationY(); | ||
| 199 | + startWidth = endWidth = imageView.getWidth(); | ||
| 200 | + startHeight = endHeight = imageView.getHeight(); | ||
| 201 | + | ||
| 202 | + // 计算 endY | ||
| 203 | + int imageWidth, imageHeight; | ||
| 204 | + if (viewData.getImageWidth() == 0 || viewData.getImageHeight() == 0) { | ||
| 205 | + Drawable thumb = imageView.getDrawable(); | ||
| 206 | + if (thumb != null) { | ||
| 207 | + imageWidth = thumb.getIntrinsicWidth(); | ||
| 208 | + imageHeight = thumb.getIntrinsicHeight(); | ||
| 209 | + hasSetImageOriginalSize = true; | ||
| 210 | + } else { | ||
| 211 | + imageWidth = interfaceWidth; | ||
| 212 | + imageHeight = interfaceHeight; | ||
| 213 | + hasSetImageOriginalSize = false; | ||
| 214 | + } | ||
| 215 | + } else { | ||
| 216 | + imageWidth = viewData.getImageWidth(); | ||
| 217 | + imageHeight = viewData.getImageHeight(); | ||
| 218 | + hasSetImageOriginalSize = true; | ||
| 219 | + } | ||
| 220 | + float scale = Math.min(interfaceWidth * 1f / imageWidth, interfaceHeight * 1f / imageHeight); | ||
| 221 | + // 图片的缩放等级为 1f 时,图片的高度 | ||
| 222 | + int adjustImageHeight = (int) (imageHeight * scale); | ||
| 223 | + // 图片的缩放等级为 1f 且居中时时,在预览界面中的距离容器顶部的距离 | ||
| 224 | + float disOnYFromTop = (interfaceHeight - adjustImageHeight) / 2; | ||
| 225 | + // 图片在预览界面中的当前 Y 轴坐标 | ||
| 226 | + float currentImageY = startY + disOnYFromTop; | ||
| 227 | + // 图片是否已经滑出浏览界面 | ||
| 228 | + if ( | ||
| 229 | + // 图片已经从顶部滑出预览界面 | ||
| 230 | + (currentImageY + adjustImageHeight) <= 0 | ||
| 231 | + // 图片已经从底部滑出预览界面 | ||
| 232 | + || currentImageY >= interfaceHeight) { | ||
| 233 | + endY = startY; | ||
| 234 | + } else { | ||
| 235 | + // 此处加 20 ,是为了减少误差,防止影响动画美观 | ||
| 236 | + endY = currentImageY > disOnYFromTop ? | ||
| 237 | + // 向下滑动 | ||
| 238 | + startY + (interfaceHeight - currentImageY) + 20 | ||
| 239 | + // 向上滑动 | ||
| 240 | + : startY - (currentImageY + adjustImageHeight) - 20; | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + startAlpha = background.getAlpha(); | ||
| 244 | + endAlpha = 0; | ||
| 245 | + animAction = ACTION_DRAG_EXIT_SIMPLE; | ||
| 246 | + return this; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + public ImageTransfer background(Drawable background) { | ||
| 250 | + this.background = background; | ||
| 251 | + return this; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + public ImageTransfer duration(long duration) { | ||
| 255 | + this.duration = duration; | ||
| 256 | + return this; | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + public ImageTransfer callback(OnTransCallback callback) { | ||
| 260 | + this.mTransCallback = callback; | ||
| 261 | + return this; | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + public void play() { | ||
| 265 | + ValueAnimator animator = ValueAnimator.ofFloat(0, 1f); | ||
| 266 | + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | ||
| 267 | + | ||
| 268 | + @Override | ||
| 269 | + public void onAnimationUpdate(ValueAnimator animation) { | ||
| 270 | + final float progress = (float) animation.getAnimatedValue(); | ||
| 271 | + if (startX != endX) { | ||
| 272 | + imageView.setTranslationX(calculateByProgress(progress, startX, endX)); | ||
| 273 | + } | ||
| 274 | + if (startY != endY) { | ||
| 275 | + imageView.setTranslationY(calculateByProgress(progress, startY, endY)); | ||
| 276 | + } | ||
| 277 | + if (startWidth != endWidth || startHeight != endHeight) { | ||
| 278 | + imageView.getLayoutParams().width = (int) calculateByProgress(progress, startWidth, endWidth); | ||
| 279 | + imageView.getLayoutParams().height = (int) calculateByProgress(progress, startHeight, endHeight); | ||
| 280 | + imageView.requestLayout(); | ||
| 281 | + } | ||
| 282 | + if (startAlpha != endAlpha) { | ||
| 283 | + background.setAlpha((int) calculateByProgress(progress, startAlpha, endAlpha)); | ||
| 284 | + } | ||
| 285 | + if (mTransCallback != null) { | ||
| 286 | + mTransCallback.onRunning(progress); | ||
| 287 | + } | ||
| 288 | + } | ||
| 289 | + }); | ||
| 290 | + animator.addListener(new AnimatorListenerAdapter() { | ||
| 291 | + @Override | ||
| 292 | + public void onAnimationStart(Animator animation) { | ||
| 293 | + super.onAnimationStart(animation); | ||
| 294 | + if (animAction == ACTION_ENTER | ||
| 295 | + || animAction == ACTION_EXIT | ||
| 296 | + || animAction == ACTION_DRAG_EXIT_AGILE) { | ||
| 297 | + if (hasSetImageOriginalSize) { | ||
| 298 | + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||
| 299 | + } | ||
| 300 | + } | ||
| 301 | + if (mTransCallback != null) { | ||
| 302 | + mTransCallback.onStart(); | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + @Override | ||
| 307 | + public void onAnimationEnd(Animator animation) { | ||
| 308 | + super.onAnimationEnd(animation); | ||
| 309 | + if (animAction == ACTION_ENTER && hasSetImageOriginalSize) { | ||
| 310 | + imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); | ||
| 311 | + imageView.setTranslationX(0); | ||
| 312 | + imageView.setTranslationY(0); | ||
| 313 | + imageView.getLayoutParams().width = FrameLayout.LayoutParams.MATCH_PARENT; | ||
| 314 | + imageView.getLayoutParams().height = FrameLayout.LayoutParams.MATCH_PARENT; | ||
| 315 | + imageView.requestLayout(); | ||
| 316 | + } | ||
| 317 | + imageView = null; | ||
| 318 | + background = null; | ||
| 319 | + animAction = ACTION_IDEL; | ||
| 320 | + if (mTransCallback != null) { | ||
| 321 | + mTransCallback.onEnd(); | ||
| 322 | + } | ||
| 323 | + } | ||
| 324 | + }); | ||
| 325 | + animator.setDuration(duration); | ||
| 326 | + animator.start(); | ||
| 327 | + } | ||
| 328 | + | ||
| 329 | + /** | ||
| 330 | + * 根据进度,计算过渡值 | ||
| 331 | + */ | ||
| 332 | + private float calculateByProgress(float progress, float startVal, float endVal) { | ||
| 333 | + return startVal + progress * (endVal - startVal); | ||
| 334 | + } | ||
| 335 | + | ||
| 336 | + public interface OnTransCallback { | ||
| 337 | + void onStart(); | ||
| 338 | + | ||
| 339 | + void onRunning(float progress); | ||
| 340 | + | ||
| 341 | + void onEnd(); | ||
| 342 | + } | ||
| 343 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/LoadImage.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +import android.widget.ImageView; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * created by hanyayun | ||
| 7 | + * on 2020/1/21 | ||
| 8 | + */ | ||
| 9 | +public abstract class LoadImage { | ||
| 10 | + /** | ||
| 11 | + * 加载图片 | ||
| 12 | + */ | ||
| 13 | + public abstract void displayImage(Object src, ImageView imageView, LoadCallback callback); | ||
| 14 | + | ||
| 15 | + public interface LoadCallback { | ||
| 16 | + void onLoadStarted(Object placeholder); | ||
| 17 | + | ||
| 18 | + void onLoading(float progress); | ||
| 19 | + | ||
| 20 | + void onLoadSucceed(Object source); | ||
| 21 | + | ||
| 22 | + void onLoadFailed(Object error); | ||
| 23 | + } | ||
| 24 | +} | ||
| 25 | + |
core/imageload/src/main/java/com/cnlive/core/imagepreview/PhotoLoader.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +import android.graphics.drawable.Drawable; | ||
| 4 | +import android.widget.ImageView; | ||
| 5 | + | ||
| 6 | +import com.bumptech.glide.request.target.CustomViewTarget; | ||
| 7 | +import com.bumptech.glide.request.transition.Transition; | ||
| 8 | +import com.cnlive.core.imageload.config.ScaleMode; | ||
| 9 | +import com.cnlive.core.imageload.loader.ImageLoader; | ||
| 10 | +import com.cnlive.core.libs.base.application.GlideApp; | ||
| 11 | + | ||
| 12 | +import androidx.annotation.NonNull; | ||
| 13 | +import androidx.annotation.Nullable; | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * created by hanyayun | ||
| 18 | + * on 2020/2/12 | ||
| 19 | + */ | ||
| 20 | +public class PhotoLoader extends LoadImage { | ||
| 21 | + @Override | ||
| 22 | + public void displayImage(Object src, ImageView imageView, LoadCallback callback) { | ||
| 23 | + GlideApp.with(imageView.getContext()) | ||
| 24 | + .load(src) | ||
| 25 | + .into(new CustomViewTarget<ImageView, Drawable>(imageView) { | ||
| 26 | + @Override | ||
| 27 | + public void onLoadFailed(@Nullable Drawable errorDrawable) { | ||
| 28 | + if(callback!=null) { | ||
| 29 | + callback.onLoadFailed(errorDrawable); | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||
| 35 | + if(callback!=null) { | ||
| 36 | + callback.onLoadSucceed(resource); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + @Override | ||
| 41 | + protected void onResourceLoading(@Nullable Drawable placeholder) { | ||
| 42 | + super.onResourceLoading(placeholder); | ||
| 43 | + if(callback!=null){ | ||
| 44 | + callback.onLoadStarted(placeholder); | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + protected void onResourceCleared(@Nullable Drawable placeholder) { | ||
| 50 | + | ||
| 51 | + } | ||
| 52 | + }); | ||
| 53 | + } | ||
| 54 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/Utils.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.os.Handler; | ||
| 5 | +import android.os.Message; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * created by hanyayun | ||
| 9 | + * on 2020/1/20 | ||
| 10 | + */ | ||
| 11 | +public class Utils { | ||
| 12 | + | ||
| 13 | + public static int dp2px(Context context, float dpVal) { | ||
| 14 | + final float scale = context.getResources().getDisplayMetrics().density; | ||
| 15 | + return (int) (dpVal * scale + 0.5f); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public static int getStatusBarHeight(Context context) { | ||
| 19 | + int result = 0; | ||
| 20 | + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); | ||
| 21 | + if (resourceId > 0) { | ||
| 22 | + result = context.getResources().getDimensionPixelSize(resourceId); | ||
| 23 | + } | ||
| 24 | + return result; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public static Handler sHandler = new Handler() { | ||
| 28 | + @Override | ||
| 29 | + public void handleMessage(Message msg) { | ||
| 30 | + super.handleMessage(msg); | ||
| 31 | + | ||
| 32 | + } | ||
| 33 | + }; | ||
| 34 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/ViewData.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * created by hanyayun | ||
| 5 | + * on 2020/1/20 | ||
| 6 | + */ | ||
| 7 | +public class ViewData { | ||
| 8 | + // 图片资源 | ||
| 9 | + private Object imageSrc; | ||
| 10 | + // 图片的原始宽度 | ||
| 11 | + private int imageWidth; | ||
| 12 | + // 图片的原始高度 | ||
| 13 | + private int imageHeight; | ||
| 14 | + // 目标 view 的 x 轴坐标 | ||
| 15 | + private float targetX; | ||
| 16 | + // 目标 view 的 y 轴坐标 | ||
| 17 | + private float targetY; | ||
| 18 | + // 目标 view 的宽度 | ||
| 19 | + private int targetWidth; | ||
| 20 | + // 目标 view 的高度 | ||
| 21 | + private int targetHeight; | ||
| 22 | + | ||
| 23 | + public ViewData() { | ||
| 24 | + | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public ViewData(Object imageSrc) { | ||
| 28 | + this.imageSrc = imageSrc; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public ViewData(float targetX, float targetY, int targetWidth, int targetHeight) { | ||
| 32 | + this.targetX = targetX; | ||
| 33 | + this.targetY = targetY; | ||
| 34 | + this.targetWidth = targetWidth; | ||
| 35 | + this.targetHeight = targetHeight; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public ViewData(Object imageSrc, float targetX, float targetY, int targetWidth, int targetHeight) { | ||
| 39 | + this.imageSrc = imageSrc; | ||
| 40 | + this.targetX = targetX; | ||
| 41 | + this.targetY = targetY; | ||
| 42 | + this.targetWidth = targetWidth; | ||
| 43 | + this.targetHeight = targetHeight; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public ViewData(Object imageSrc, int imageWidth, int imageHeight, float targetX, float targetY, int targetWidth, int targetHeight) { | ||
| 47 | + this.imageSrc = imageSrc; | ||
| 48 | + this.imageWidth = imageWidth; | ||
| 49 | + this.imageHeight = imageHeight; | ||
| 50 | + this.targetX = targetX; | ||
| 51 | + this.targetY = targetY; | ||
| 52 | + this.targetWidth = targetWidth; | ||
| 53 | + this.targetHeight = targetHeight; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public Object getImageSrc() { | ||
| 57 | + return imageSrc; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + public void setImageSrc(Object imageSrc) { | ||
| 61 | + this.imageSrc = imageSrc; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + public int getImageWidth() { | ||
| 65 | + return imageWidth; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public void setImageWidth(int imageWidth) { | ||
| 69 | + this.imageWidth = imageWidth; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + public int getImageHeight() { | ||
| 73 | + return imageHeight; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + public void setImageHeight(int imageHeight) { | ||
| 77 | + this.imageHeight = imageHeight; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + public float getTargetX() { | ||
| 81 | + return targetX; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + public void setTargetX(float targetX) { | ||
| 85 | + this.targetX = targetX; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + public float getTargetY() { | ||
| 89 | + return targetY; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + public void setTargetY(float targetY) { | ||
| 93 | + this.targetY = targetY; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + public int getTargetWidth() { | ||
| 97 | + return targetWidth; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + public void setTargetWidth(int targetWidth) { | ||
| 101 | + this.targetWidth = targetWidth; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + public int getTargetHeight() { | ||
| 105 | + return targetHeight; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + public void setTargetHeight(int targetHeight) { | ||
| 109 | + this.targetHeight = targetHeight; | ||
| 110 | + } | ||
| 111 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/ViewerStatus.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * created by hanyayun | ||
| 5 | + * on 2020/1/21 | ||
| 6 | + */ | ||
| 7 | +public final class ViewerStatus { | ||
| 8 | + /** | ||
| 9 | + * 图片浏览器处于未开启状态 | ||
| 10 | + */ | ||
| 11 | + public static final int STATUS_SILENCE = 0; | ||
| 12 | + /** | ||
| 13 | + * 图片浏览器开始执行进场动画 | ||
| 14 | + */ | ||
| 15 | + public static final int STATUS_BEGIN_OPEN = 1; | ||
| 16 | + /** | ||
| 17 | + * 图片浏览器正在执行进场动画 | ||
| 18 | + */ | ||
| 19 | + public static final int STATUS_OPENING = 2; | ||
| 20 | + /** | ||
| 21 | + * 图片正在被浏览中 | ||
| 22 | + */ | ||
| 23 | + public static final int STATUS_WATCHING = 3; | ||
| 24 | + /** | ||
| 25 | + * 图片浏览器开始执行退场动画 | ||
| 26 | + */ | ||
| 27 | + public static final int STATUS_BEGIN_CLOSE = 4; | ||
| 28 | + /** | ||
| 29 | + * 图片浏览器正在执行退场动画 | ||
| 30 | + */ | ||
| 31 | + public static final int STATUS_CLOSING = 5; | ||
| 32 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/dragger/DragHandler.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.dragger; | ||
| 2 | + | ||
| 3 | +import android.graphics.drawable.Drawable; | ||
| 4 | +import android.view.MotionEvent; | ||
| 5 | +import android.widget.ImageView; | ||
| 6 | + | ||
| 7 | +import com.cnlive.core.imagepreview.ImageTransfer; | ||
| 8 | +import com.cnlive.core.imagepreview.ViewData; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 拖拽工具类 | ||
| 12 | + * created by hanyayun | ||
| 13 | + * on 2020/1/20 | ||
| 14 | + */ | ||
| 15 | +public class DragHandler { | ||
| 16 | + // 完全不透明的透明度值 | ||
| 17 | + private final int FULL_ALPHA = 255; | ||
| 18 | + // 动画执行时间 | ||
| 19 | + private final int ANIM_DURATION = 300; | ||
| 20 | + // 最小缩放比例 | ||
| 21 | + private final float MIN_SCALE = 0.2f; | ||
| 22 | + // 在不退出浏览的情况下, 图片在 Y 轴上的最大可移动距离 | ||
| 23 | + private final float MAX_MOVABLE_DIS_ON_Y; | ||
| 24 | + // 背景透明度的变换基数 | ||
| 25 | + private final float ALPHA_BASE; | ||
| 26 | + | ||
| 27 | + // 拖拽模式 | ||
| 28 | + private int mMode; | ||
| 29 | + // 浏览界面的宽高 | ||
| 30 | + private int mIfWidth, mIfHeight; | ||
| 31 | + private Drawable mBackground; | ||
| 32 | + private ImageTransfer mTransfer; | ||
| 33 | + private int mAction; | ||
| 34 | + | ||
| 35 | + public DragHandler(int ifWidth, int ifHeight) { | ||
| 36 | + this.mIfWidth = ifWidth; | ||
| 37 | + this.mIfHeight = ifHeight; | ||
| 38 | + this.MAX_MOVABLE_DIS_ON_Y = ifHeight / 5f; | ||
| 39 | + this.ALPHA_BASE = MAX_MOVABLE_DIS_ON_Y * 2; | ||
| 40 | + this.mTransfer = new ImageTransfer(ifWidth, ifHeight); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * 准备拖拽 | ||
| 45 | + */ | ||
| 46 | + public void onReay(int mode, Drawable bg) { | ||
| 47 | + this.mMode = mode; | ||
| 48 | + this.mBackground = bg; | ||
| 49 | + mAction = ImageTransfer.ACTION_IDEL; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 拖拽中 | ||
| 54 | + * | ||
| 55 | + * @param lastX 上一次触摸点的 x 轴坐标 | ||
| 56 | + * @param lastY 上一次触摸点的 y 轴坐标 | ||
| 57 | + * @param event 本次触摸点的手势事件 | ||
| 58 | + * @param imageView | ||
| 59 | + */ | ||
| 60 | + public void onDrag(float lastX, float lastY, MotionEvent event, ImageView imageView) { | ||
| 61 | + if (mMode == DragMode.MODE_SIMPLE) { | ||
| 62 | + dragBySimple(lastY, event, imageView); | ||
| 63 | + } else if (mMode == DragMode.MODE_AGILE) { | ||
| 64 | + dragByAgile(lastX, lastY, event, imageView); | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * 手指抬起 | ||
| 70 | + */ | ||
| 71 | + public void onUp(ImageView imageView, ViewData viewData, ImageTransfer.OnTransCallback callback) { | ||
| 72 | + final float transY = imageView.getTranslationY(); | ||
| 73 | + mTransfer.with(imageView) | ||
| 74 | + .background(mBackground) | ||
| 75 | + .duration(ANIM_DURATION); | ||
| 76 | + // 执行复原动画 | ||
| 77 | + if (Math.abs(transY) <= MAX_MOVABLE_DIS_ON_Y) { | ||
| 78 | + mAction = ImageTransfer.ACTION_DRAG_RESTORE; | ||
| 79 | + mTransfer.loadDragRestoreData() | ||
| 80 | + .callback(callback); | ||
| 81 | + } | ||
| 82 | + // 执行退场动画 | ||
| 83 | + else { | ||
| 84 | + if (mMode == DragMode.MODE_AGILE) { | ||
| 85 | + if (transY < 0) { | ||
| 86 | + mAction = ImageTransfer.ACTION_DRAG_RESTORE; | ||
| 87 | + mTransfer.loadDragRestoreData() | ||
| 88 | + .callback(callback); | ||
| 89 | + } else { | ||
| 90 | + mAction = ImageTransfer.ACTION_DRAG_EXIT_AGILE; | ||
| 91 | + mTransfer.loadDragExitDataInAgile(viewData) | ||
| 92 | + .callback(callback); | ||
| 93 | + } | ||
| 94 | + } else { | ||
| 95 | + mAction = ImageTransfer.ACTION_DRAG_EXIT_SIMPLE; | ||
| 96 | + mTransfer.loadDragExitDataInSimple(viewData) | ||
| 97 | + .callback(callback); | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + mTransfer.play(); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public int getAction() { | ||
| 104 | + return mAction; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + public void clear() { | ||
| 108 | + if (mTransfer != null) { | ||
| 109 | + mTransfer = null; | ||
| 110 | + } | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * 简单模式拖拽(类似今日头条) | ||
| 115 | + */ | ||
| 116 | + private void dragBySimple(float lastY, MotionEvent event, ImageView imageView) { | ||
| 117 | + final float disY = event.getY() - lastY; | ||
| 118 | + final float nextY = imageView.getTranslationY() + disY; | ||
| 119 | + imageView.setTranslationY(nextY); | ||
| 120 | + // 计算背景透明度 | ||
| 121 | + final float value = Math.abs(nextY) / ALPHA_BASE; | ||
| 122 | + transformBgAlpha((int) ((value < 0.8f ? 1 - value : 0.2f) * FULL_ALPHA)); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * 灵巧模式拖拽(类似微信朋友圈) | ||
| 128 | + */ | ||
| 129 | + private void dragByAgile(float lastX, float lastY, MotionEvent event, ImageView imageView) { | ||
| 130 | + // 手指的移动距离 | ||
| 131 | + final float disX = event.getX() - lastX; | ||
| 132 | + final float disY = event.getY() - lastY; | ||
| 133 | + // imageView 被拖拽后的坐标 | ||
| 134 | + final float nextX = imageView.getTranslationX() + disX; | ||
| 135 | + final float nextY = imageView.getTranslationY() + disY; | ||
| 136 | + // 向上移动 | ||
| 137 | + if (nextY <= 0) { | ||
| 138 | + if (imageView.getLayoutParams().width != mIfWidth || | ||
| 139 | + imageView.getLayoutParams().height != mIfHeight) { | ||
| 140 | + imageView.getLayoutParams().width = mIfWidth; | ||
| 141 | + imageView.getLayoutParams().height = mIfHeight; | ||
| 142 | + imageView.requestLayout(); | ||
| 143 | + } | ||
| 144 | + transformBgAlpha(FULL_ALPHA); | ||
| 145 | + } | ||
| 146 | + // 向下移动 | ||
| 147 | + else { | ||
| 148 | + // 计算缩放比例 | ||
| 149 | + final float scale = Math.min(Math.max(1f - nextY / mIfHeight, MIN_SCALE), 1f); | ||
| 150 | + imageView.getLayoutParams().width = (int) (mIfWidth * scale); | ||
| 151 | + imageView.getLayoutParams().height = (int) (mIfHeight * scale); | ||
| 152 | + imageView.requestLayout(); | ||
| 153 | + // 变换背景透明度 | ||
| 154 | + transformBgAlpha((int) (scale * FULL_ALPHA)); | ||
| 155 | + } | ||
| 156 | + imageView.setTranslationX(nextX); | ||
| 157 | + imageView.setTranslationY(nextY); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + /** | ||
| 161 | + * 变换背景透明度 | ||
| 162 | + */ | ||
| 163 | + private void transformBgAlpha(int alpha) { | ||
| 164 | + if (mBackground != null && mBackground.getAlpha() != alpha) { | ||
| 165 | + mBackground.setAlpha(alpha); | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/dragger/DragMode.java
0 → 100644
core/imageload/src/main/java/com/cnlive/core/imagepreview/dragger/DragStatus.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.dragger; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * created by hanyayun | ||
| 5 | + * on 2020/1/20 | ||
| 6 | + */ | ||
| 7 | +public class DragStatus { | ||
| 8 | + /** | ||
| 9 | + * 准备开始拖拽 | ||
| 10 | + */ | ||
| 11 | + public static final int STATUS_READY = 1; | ||
| 12 | + /** | ||
| 13 | + * 正在拖拽中 | ||
| 14 | + */ | ||
| 15 | + public static final int STATUS_DRAGGING = 2; | ||
| 16 | + /** | ||
| 17 | + * 开始执行复原动画 | ||
| 18 | + */ | ||
| 19 | + public static final int STATUS_BEGIN_RESTORE = 3; | ||
| 20 | + /** | ||
| 21 | + * 复原动画执行中 | ||
| 22 | + */ | ||
| 23 | + public static final int STATUS_RESTORING = 4; | ||
| 24 | + /** | ||
| 25 | + * 复原动画执行完毕 | ||
| 26 | + */ | ||
| 27 | + public static final int STATUS_COMPLETE_RESTORE = 5; | ||
| 28 | + /** | ||
| 29 | + * 开始执行退出浏览动画 | ||
| 30 | + */ | ||
| 31 | + public static final int STATUS_BEGIN_EXIT = 6; | ||
| 32 | + /** | ||
| 33 | + * 退出浏览动画执行中 | ||
| 34 | + */ | ||
| 35 | + public static final int STATUS_EXITTING = 7; | ||
| 36 | + /** | ||
| 37 | + * 退出浏览动画执行完毕 | ||
| 38 | + */ | ||
| 39 | + public static final int STATUS_COMPLETE_EXIT = 8; | ||
| 40 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/indexui/DefaultIndexUI.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.indexui; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.graphics.Color; | ||
| 5 | +import android.util.TypedValue; | ||
| 6 | +import android.view.Gravity; | ||
| 7 | +import android.view.View; | ||
| 8 | +import android.widget.FrameLayout; | ||
| 9 | +import android.widget.TextView; | ||
| 10 | + | ||
| 11 | +import com.cnlive.core.imagepreview.Utils; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * 默认的索引视图 | ||
| 15 | + * created by hanyayun | ||
| 16 | + * on 2020/1/20 | ||
| 17 | + */ | ||
| 18 | +public class DefaultIndexUI extends IndexUI { | ||
| 19 | + private boolean overlayStatusBar; | ||
| 20 | + | ||
| 21 | + public DefaultIndexUI(boolean overlayStatusBar) { | ||
| 22 | + this.overlayStatusBar = overlayStatusBar; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + @Override | ||
| 26 | + public View createView(Context context) { | ||
| 27 | + TextView indexView = new TextView(context); | ||
| 28 | + FrameLayout.LayoutParams textParams = new FrameLayout.LayoutParams( | ||
| 29 | + FrameLayout.LayoutParams.WRAP_CONTENT, | ||
| 30 | + FrameLayout.LayoutParams.WRAP_CONTENT); | ||
| 31 | + textParams.setMargins(0, | ||
| 32 | + Utils.dp2px(context, overlayStatusBar ? Utils.getStatusBarHeight(context) + 5 : 5), | ||
| 33 | + 0, 0); | ||
| 34 | + textParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; | ||
| 35 | + indexView.setLayoutParams(textParams); | ||
| 36 | + indexView.setIncludeFontPadding(false); | ||
| 37 | + indexView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); | ||
| 38 | + indexView.setTextColor(Color.WHITE); | ||
| 39 | + return indexView; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public void init(int position, int length) { | ||
| 44 | + ((TextView) getIndexView()).setText((position + 1) + "/" + length); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + public void handleItemChanged(int position, int length) { | ||
| 49 | + ((TextView) getIndexView()).setText((position + 1) + "/" + length); | ||
| 50 | + } | ||
| 51 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/indexui/DefaultProgressUI.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.indexui; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.graphics.Color; | ||
| 5 | +import android.view.Gravity; | ||
| 6 | +import android.view.View; | ||
| 7 | +import android.widget.FrameLayout; | ||
| 8 | + | ||
| 9 | +import com.cnlive.core.imagepreview.Utils; | ||
| 10 | +import com.cnlive.core.imagepreview.uti.ProgressWheel; | ||
| 11 | + | ||
| 12 | +import java.text.DecimalFormat; | ||
| 13 | + | ||
| 14 | +import static android.view.View.VISIBLE; | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * 默认的加载进度视图 | ||
| 18 | + * created by hanyayun | ||
| 19 | + * on 2020/1/20 | ||
| 20 | + */ | ||
| 21 | +public class DefaultProgressUI extends ProgressUI{ | ||
| 22 | + private DecimalFormat mProgressFormat; | ||
| 23 | + | ||
| 24 | + public DefaultProgressUI() { | ||
| 25 | + mProgressFormat = new DecimalFormat("#%"); | ||
| 26 | + } | ||
| 27 | + @Override | ||
| 28 | + public View createView(Context context) { | ||
| 29 | + // 添加进度条 | ||
| 30 | + ProgressWheel progressView = new ProgressWheel(context); | ||
| 31 | + final int size = Utils.dp2px(context, 60); | ||
| 32 | + FrameLayout.LayoutParams barLp = new FrameLayout.LayoutParams(size, size); | ||
| 33 | + barLp.gravity = Gravity.CENTER; | ||
| 34 | + progressView.setLayoutParams(barLp); | ||
| 35 | + final int barWidth = Utils.dp2px(context, 3); | ||
| 36 | + progressView.setBarColor(Color.parseColor("#CCFFFFFF")); | ||
| 37 | + progressView.setBarWidth(barWidth); | ||
| 38 | + progressView.setBarLength(Utils.dp2px(context, 50)); | ||
| 39 | + progressView.setRimColor(Color.parseColor("#22FFFFFF")); | ||
| 40 | + progressView.setRimWidth(barWidth); | ||
| 41 | + progressView.setContourColor(Color.parseColor("#10000000")); | ||
| 42 | + progressView.setSpinSpeed(3.5f); | ||
| 43 | + progressView.setText(""); | ||
| 44 | + progressView.setTextColor(Color.parseColor("#CCFFFFFF")); | ||
| 45 | + progressView.setTextSize(Utils.dp2px(context, 14)); | ||
| 46 | + return progressView; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @Override | ||
| 50 | + public void handleProgress(float progress) { | ||
| 51 | + if (getProgressView().getVisibility() == VISIBLE) { | ||
| 52 | + ((ProgressWheel) getProgressView()).setText(mProgressFormat.format(progress)); | ||
| 53 | + ((ProgressWheel) getProgressView()).setProgress((int) (progress * 360)); | ||
| 54 | + if (progress == 1f) { | ||
| 55 | + stop(); | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public void start() { | ||
| 62 | + super.start(); | ||
| 63 | + ((ProgressWheel) getProgressView()).startSpinning(); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + @Override | ||
| 67 | + public void stop() { | ||
| 68 | + super.stop(); | ||
| 69 | + ((ProgressWheel) getProgressView()).stopSpinning(); | ||
| 70 | + } | ||
| 71 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/indexui/IndexUI.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.indexui; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.View; | ||
| 5 | +import android.view.ViewGroup; | ||
| 6 | + | ||
| 7 | +import androidx.annotation.NonNull; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 索引视图基类 | ||
| 11 | + * created by hanyayun | ||
| 12 | + * on 2020/1/20 | ||
| 13 | + */ | ||
| 14 | +public abstract class IndexUI { | ||
| 15 | + private View indexView; | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 创建索引视图 | ||
| 19 | + */ | ||
| 20 | + public abstract View createView(Context context); | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 初始设置 | ||
| 24 | + */ | ||
| 25 | + public abstract void init(int position, int length); | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 处理 item 切换事件 | ||
| 29 | + */ | ||
| 30 | + public abstract void handleItemChanged(int position, int length); | ||
| 31 | + | ||
| 32 | + public void setup(@NonNull ViewGroup parent, int startPosition, int length) { | ||
| 33 | + if (indexView == null) { | ||
| 34 | + indexView = createView(parent.getContext()); | ||
| 35 | + } | ||
| 36 | + if (indexView.getParent() == null) { | ||
| 37 | + parent.addView(indexView); | ||
| 38 | + } | ||
| 39 | + init(startPosition, length); | ||
| 40 | + show(); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * 显示索引 | ||
| 45 | + */ | ||
| 46 | + public void show() { | ||
| 47 | + if (indexView != null) { | ||
| 48 | + indexView.setVisibility(View.VISIBLE); | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 隐藏索引 | ||
| 54 | + */ | ||
| 55 | + public void hide() { | ||
| 56 | + if (indexView != null) { | ||
| 57 | + indexView.setVisibility(View.GONE); | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public View getIndexView() { | ||
| 62 | + return indexView; | ||
| 63 | + } | ||
| 64 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/indexui/ProgressUI.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.indexui; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.view.View; | ||
| 5 | +import android.view.ViewGroup; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * created by hanyayun | ||
| 9 | + * on 2020/1/20 | ||
| 10 | + */ | ||
| 11 | +public abstract class ProgressUI { | ||
| 12 | + private View progressView; | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 创建加载进度视图 | ||
| 16 | + */ | ||
| 17 | + public abstract View createView(Context context); | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 处理进度 | ||
| 21 | + * | ||
| 22 | + * @param progress 范围: 0-1 | ||
| 23 | + */ | ||
| 24 | + public abstract void handleProgress(float progress); | ||
| 25 | + | ||
| 26 | + public void init(ViewGroup parent) { | ||
| 27 | + if (progressView == null) { | ||
| 28 | + progressView = createView(parent.getContext()); | ||
| 29 | + } | ||
| 30 | + if (progressView.getParent() == null) { | ||
| 31 | + parent.addView(progressView); | ||
| 32 | + } | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public void start() { | ||
| 36 | + if (progressView != null) { | ||
| 37 | + progressView.setVisibility(View.VISIBLE); | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public void stop() { | ||
| 42 | + if (progressView != null) { | ||
| 43 | + progressView.setVisibility(View.GONE); | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public View getProgressView() { | ||
| 48 | + return progressView; | ||
| 49 | + } | ||
| 50 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/listener/OnBrowseStatusListener.java
0 → 100644
core/imageload/src/main/java/com/cnlive/core/imagepreview/listener/OnDragStatusListener.java
0 → 100644
core/imageload/src/main/java/com/cnlive/core/imagepreview/listener/OnItemChangedListener.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.listener; | ||
| 2 | + | ||
| 3 | +import com.cnlive.core.imagepreview.ImageDrawee; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 图片item 的切换事件 | ||
| 7 | + * created by hanyayun | ||
| 8 | + * on 2020/1/20 | ||
| 9 | + */ | ||
| 10 | +public interface OnItemChangedListener { | ||
| 11 | + | ||
| 12 | + void onItemChanged(int position, ImageDrawee drawee); | ||
| 13 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/listener/OnItemClickListener.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.listener; | ||
| 2 | + | ||
| 3 | +import android.widget.ImageView; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 图片单击事件 | ||
| 7 | + * created by hanyayun | ||
| 8 | + * on 2020/1/20 | ||
| 9 | + */ | ||
| 10 | +public interface OnItemClickListener { | ||
| 11 | + /** | ||
| 12 | + * @param position | ||
| 13 | + * @param imageView | ||
| 14 | + * @return {@code true}: 消费了点击事件,后续方法不再执行 {@code false}: 没有消费点击事件,后续方法继续执行 | ||
| 15 | + */ | ||
| 16 | + boolean onItemClick(int position, ImageView imageView); | ||
| 17 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/listener/OnItemLongPressListener.java
0 → 100644
core/imageload/src/main/java/com/cnlive/core/imagepreview/uti/ProgressWheel.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.uti; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.content.res.TypedArray; | ||
| 5 | +import android.graphics.Canvas; | ||
| 6 | +import android.graphics.Paint; | ||
| 7 | +import android.graphics.RectF; | ||
| 8 | +import android.graphics.Shader; | ||
| 9 | +import android.util.AttributeSet; | ||
| 10 | +import android.view.View; | ||
| 11 | + | ||
| 12 | +import com.cnlive.core.imageload.R; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * created by hanyayun | ||
| 16 | + * on 2020/1/20 | ||
| 17 | + */ | ||
| 18 | +public class ProgressWheel extends View { | ||
| 19 | + // Sizes (with defaults) | ||
| 20 | + private int layoutHeight = 0; | ||
| 21 | + private int layoutWidth = 0; | ||
| 22 | + private int fullRadius = 100; | ||
| 23 | + private int circleRadius = 80; | ||
| 24 | + private int barLength = 60; | ||
| 25 | + private int barWidth = 20; | ||
| 26 | + private int rimWidth = 20; | ||
| 27 | + private int textSize = 20; | ||
| 28 | + private float contourSize = 0; | ||
| 29 | + | ||
| 30 | + // Padding (with defaults) | ||
| 31 | + private int paddingTop = 5; | ||
| 32 | + private int paddingBottom = 5; | ||
| 33 | + private int paddingLeft = 5; | ||
| 34 | + private int paddingRight = 5; | ||
| 35 | + | ||
| 36 | + // Colors (with defaults) | ||
| 37 | + private int barColor = 0xAA000000; | ||
| 38 | + private int contourColor = 0xAA000000; | ||
| 39 | + private int circleColor = 0x00000000; | ||
| 40 | + private int rimColor = 0xAADDDDDD; | ||
| 41 | + private int textColor = 0xFF000000; | ||
| 42 | + | ||
| 43 | + // Paints | ||
| 44 | + private Paint barPaint = new Paint(); | ||
| 45 | + private Paint circlePaint = new Paint(); | ||
| 46 | + private Paint rimPaint = new Paint(); | ||
| 47 | + private Paint textPaint = new Paint(); | ||
| 48 | + private Paint contourPaint = new Paint(); | ||
| 49 | + | ||
| 50 | + // Rectangles | ||
| 51 | + private RectF innerCircleBounds = new RectF(); | ||
| 52 | + private RectF circleBounds = new RectF(); | ||
| 53 | + private RectF circleOuterContour = new RectF(); | ||
| 54 | + private RectF circleInnerContour = new RectF(); | ||
| 55 | + | ||
| 56 | + // Animation | ||
| 57 | + // The amount of pixels to move the bar by on each draw | ||
| 58 | + private float spinSpeed = 2f; | ||
| 59 | + // The number of milliseconds to wait in between each draw | ||
| 60 | + private int delayMillis = 10; | ||
| 61 | + private float progress = 0; | ||
| 62 | + boolean isSpinning = false; | ||
| 63 | + | ||
| 64 | + // Other | ||
| 65 | + private String text = ""; | ||
| 66 | + private String[] splitText = {}; | ||
| 67 | + | ||
| 68 | + public ProgressWheel(Context context){ | ||
| 69 | + super(context); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * The constructor for the ProgressWheel | ||
| 74 | + * | ||
| 75 | + * @param context | ||
| 76 | + * @param attrs | ||
| 77 | + */ | ||
| 78 | + public ProgressWheel(Context context, AttributeSet attrs) { | ||
| 79 | + super(context, attrs); | ||
| 80 | + parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.ivr_ProgressWheel)); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + /* | ||
| 84 | + * When this is called, make the view square. | ||
| 85 | + * From: http://www.jayway.com/2012/12/12/creating-custom-android-views-part-4-measuring-and-how-to-force-a-view-to-be-square/ | ||
| 86 | + * | ||
| 87 | + */ | ||
| 88 | + @Override | ||
| 89 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
| 90 | + // The first thing that happen is that we call the superclass | ||
| 91 | + // implementation of onMeasure. The reason for that is that measuring | ||
| 92 | + // can be quite a complex process and calling the super method is a | ||
| 93 | + // convenient way to get most of this complexity handled. | ||
| 94 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
| 95 | + | ||
| 96 | + // We can’t use getWidth() or getHight() here. During the measuring | ||
| 97 | + // pass the view has not gotten its final size yet (this happens first | ||
| 98 | + // at the watch of the layout pass) so we have to use getMeasuredWidth() | ||
| 99 | + // and getMeasuredHeight(). | ||
| 100 | + int size = 0; | ||
| 101 | + int width = getMeasuredWidth(); | ||
| 102 | + int height = getMeasuredHeight(); | ||
| 103 | + int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight(); | ||
| 104 | + int heightWithoutPadding = height - getPaddingTop() - getPaddingBottom(); | ||
| 105 | + | ||
| 106 | + // Finally we have some simple logic that calculates the size of the view | ||
| 107 | + // and calls setMeasuredDimension() to set that size. | ||
| 108 | + // Before we compare the width and height of the view, we remove the padding, | ||
| 109 | + // and when we set the dimension we add it back again. Now the actual content | ||
| 110 | + // of the view will be square, but, depending on the padding, the total dimensions | ||
| 111 | + // of the view might not be. | ||
| 112 | + int heightMode = MeasureSpec.getMode(heightMeasureSpec); | ||
| 113 | + int widthMode = MeasureSpec.getMode(widthMeasureSpec); | ||
| 114 | + if (heightMode != MeasureSpec.UNSPECIFIED && widthMode != MeasureSpec.UNSPECIFIED) { | ||
| 115 | + if (widthWithoutPadding > heightWithoutPadding) { | ||
| 116 | + size = heightWithoutPadding; | ||
| 117 | + } else { | ||
| 118 | + size = widthWithoutPadding; | ||
| 119 | + } | ||
| 120 | + } else { | ||
| 121 | + size = Math.max(heightWithoutPadding, widthWithoutPadding); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + | ||
| 125 | + // If you override onMeasure() you have to call setMeasuredDimension(). | ||
| 126 | + // This is how you report back the measured size. If you don’t call | ||
| 127 | + // setMeasuredDimension() the parent will throw an exception and your | ||
| 128 | + // application will crash. | ||
| 129 | + // We are calling the onMeasure() method of the superclass so we don’t | ||
| 130 | + // actually need to call setMeasuredDimension() since that takes care | ||
| 131 | + // of that. However, the purpose with overriding onMeasure() was to | ||
| 132 | + // change the default behaviour and to do that we need to call | ||
| 133 | + // setMeasuredDimension() with our own values. | ||
| 134 | + setMeasuredDimension( | ||
| 135 | + size + getPaddingLeft() + getPaddingRight(), | ||
| 136 | + size + getPaddingTop() + getPaddingBottom()); | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + /** | ||
| 140 | + * Use onSizeChanged instead of onAttachedToWindow to get the dimensions of the view, | ||
| 141 | + * because this method is called after measuring the dimensions of MATCH_PARENT & WRAP_CONTENT. | ||
| 142 | + * Use this dimensions to setup the bounds and paints. | ||
| 143 | + */ | ||
| 144 | + @Override | ||
| 145 | + protected void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight) { | ||
| 146 | + super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight); | ||
| 147 | + layoutWidth = newWidth; | ||
| 148 | + layoutHeight = newHeight; | ||
| 149 | + setupBounds(); | ||
| 150 | + setupPaints(); | ||
| 151 | + invalidate(); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + /** | ||
| 155 | + * Set the properties of the paints we're using to | ||
| 156 | + * draw the progress wheel | ||
| 157 | + */ | ||
| 158 | + private void setupPaints() { | ||
| 159 | + barPaint.setColor(barColor); | ||
| 160 | + barPaint.setAntiAlias(true); | ||
| 161 | + barPaint.setStyle(Paint.Style.STROKE); | ||
| 162 | + barPaint.setStrokeWidth(barWidth); | ||
| 163 | + | ||
| 164 | + rimPaint.setColor(rimColor); | ||
| 165 | + rimPaint.setAntiAlias(true); | ||
| 166 | + rimPaint.setStyle(Paint.Style.STROKE); | ||
| 167 | + rimPaint.setStrokeWidth(rimWidth); | ||
| 168 | + | ||
| 169 | + circlePaint.setColor(circleColor); | ||
| 170 | + circlePaint.setAntiAlias(true); | ||
| 171 | + circlePaint.setStyle(Paint.Style.FILL); | ||
| 172 | + | ||
| 173 | + textPaint.setColor(textColor); | ||
| 174 | + textPaint.setStyle(Paint.Style.FILL); | ||
| 175 | + textPaint.setAntiAlias(true); | ||
| 176 | + textPaint.setTextSize(textSize); | ||
| 177 | + | ||
| 178 | + contourPaint.setColor(contourColor); | ||
| 179 | + contourPaint.setAntiAlias(true); | ||
| 180 | + contourPaint.setStyle(Paint.Style.STROKE); | ||
| 181 | + contourPaint.setStrokeWidth(contourSize); | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + /** | ||
| 185 | + * Set the bounds of the component | ||
| 186 | + */ | ||
| 187 | + private void setupBounds() { | ||
| 188 | + // Width should equal to Height, find the min value to setup the circle | ||
| 189 | + int minValue = Math.min(layoutWidth, layoutHeight); | ||
| 190 | + | ||
| 191 | + // Calc the Offset if needed | ||
| 192 | + int xOffset = layoutWidth - minValue; | ||
| 193 | + int yOffset = layoutHeight - minValue; | ||
| 194 | + | ||
| 195 | + // Add the offset | ||
| 196 | + paddingTop = this.getPaddingTop() + (yOffset / 2); | ||
| 197 | + paddingBottom = this.getPaddingBottom() + (yOffset / 2); | ||
| 198 | + paddingLeft = this.getPaddingLeft() + (xOffset / 2); | ||
| 199 | + paddingRight = this.getPaddingRight() + (xOffset / 2); | ||
| 200 | + | ||
| 201 | + int width = getWidth(); | ||
| 202 | + int height = getHeight(); | ||
| 203 | + | ||
| 204 | + innerCircleBounds = new RectF( | ||
| 205 | + paddingLeft + (1.5f * barWidth), | ||
| 206 | + paddingTop + (1.5f * barWidth), | ||
| 207 | + width - paddingRight - (1.5f * barWidth), | ||
| 208 | + height - paddingBottom - (1.5f * barWidth)); | ||
| 209 | + circleBounds = new RectF( | ||
| 210 | + paddingLeft + barWidth, | ||
| 211 | + paddingTop + barWidth, | ||
| 212 | + width - paddingRight - barWidth, | ||
| 213 | + height - paddingBottom - barWidth); | ||
| 214 | + circleInnerContour = new RectF( | ||
| 215 | + circleBounds.left + (rimWidth / 2.0f) + (contourSize / 2.0f), | ||
| 216 | + circleBounds.top + (rimWidth / 2.0f) + (contourSize / 2.0f), | ||
| 217 | + circleBounds.right - (rimWidth / 2.0f) - (contourSize / 2.0f), | ||
| 218 | + circleBounds.bottom - (rimWidth / 2.0f) - (contourSize / 2.0f)); | ||
| 219 | + circleOuterContour = new RectF( | ||
| 220 | + circleBounds.left - (rimWidth / 2.0f) - (contourSize / 2.0f), | ||
| 221 | + circleBounds.top - (rimWidth / 2.0f) - (contourSize / 2.0f), | ||
| 222 | + circleBounds.right + (rimWidth / 2.0f) + (contourSize / 2.0f), | ||
| 223 | + circleBounds.bottom + (rimWidth / 2.0f) + (contourSize / 2.0f)); | ||
| 224 | + | ||
| 225 | + fullRadius = (width - paddingRight - barWidth) / 2; | ||
| 226 | + circleRadius = (fullRadius - barWidth) + 1; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + /** | ||
| 230 | + * Parse the attributes passed to the view from the XML | ||
| 231 | + * | ||
| 232 | + * @param a the attributes to parse | ||
| 233 | + */ | ||
| 234 | + private void parseAttributes(TypedArray a) { | ||
| 235 | + barColor = a.getColor(R.styleable.ivr_ProgressWheel_pwBarColor, barColor); | ||
| 236 | + barWidth = (int) a.getDimension(R.styleable.ivr_ProgressWheel_pwBarWidth, barWidth); | ||
| 237 | + barLength = (int) a.getDimension(R.styleable.ivr_ProgressWheel_pwBarLength, barLength); | ||
| 238 | + rimColor = a.getColor(R.styleable.ivr_ProgressWheel_pwRimColor, rimColor); | ||
| 239 | + rimWidth = (int) a.getDimension(R.styleable.ivr_ProgressWheel_pwRimWidth, rimWidth); | ||
| 240 | + contourColor = a.getColor(R.styleable.ivr_ProgressWheel_pwContourColor, contourColor); | ||
| 241 | + contourSize = a.getDimension(R.styleable.ivr_ProgressWheel_pwContourSize, contourSize); | ||
| 242 | + circleColor = a.getColor(R.styleable.ivr_ProgressWheel_pwCircleColor, circleColor); | ||
| 243 | + | ||
| 244 | + // Only set the text if it is explicitly defined | ||
| 245 | + if (a.hasValue(R.styleable.ivr_ProgressWheel_pwText)) { | ||
| 246 | + setText(a.getString(R.styleable.ivr_ProgressWheel_pwText)); | ||
| 247 | + } | ||
| 248 | + textColor = a.getColor(R.styleable.ivr_ProgressWheel_pwTextColor, textColor); | ||
| 249 | + textSize = (int) a.getDimension(R.styleable.ivr_ProgressWheel_pwTextSize, textSize); | ||
| 250 | + | ||
| 251 | + spinSpeed = a.getFloat(R.styleable.ivr_ProgressWheel_pwSpinSpeed, spinSpeed); | ||
| 252 | + delayMillis = a.getInteger(R.styleable.ivr_ProgressWheel_pwDelayMillis, delayMillis); | ||
| 253 | + if (delayMillis < 0) { | ||
| 254 | + delayMillis = 10; | ||
| 255 | + } | ||
| 256 | + a.recycle(); | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + //---------------------------------- | ||
| 260 | + //Animation stuff | ||
| 261 | + //---------------------------------- | ||
| 262 | + | ||
| 263 | + protected void onDraw(Canvas canvas) { | ||
| 264 | + super.onDraw(canvas); | ||
| 265 | + //Draw the inner circle | ||
| 266 | + canvas.drawArc(innerCircleBounds, 360, 360, false, circlePaint); | ||
| 267 | + //Draw the rim | ||
| 268 | + canvas.drawArc(circleBounds, 360, 360, false, rimPaint); | ||
| 269 | + canvas.drawArc(circleOuterContour, 360, 360, false, contourPaint); | ||
| 270 | + //canvas.drawArc(circleInnerContour, 360, 360, false, contourPaint); | ||
| 271 | + //Draw the bar | ||
| 272 | + if (isSpinning) { | ||
| 273 | + canvas.drawArc(circleBounds, progress - 90, barLength, false, barPaint); | ||
| 274 | + } else { | ||
| 275 | + canvas.drawArc(circleBounds, -90, progress, false, barPaint); | ||
| 276 | + } | ||
| 277 | + //Draw the text (attempts to center it horizontally and vertically) | ||
| 278 | + float textHeight = textPaint.descent() - textPaint.ascent(); | ||
| 279 | + float verticalTextOffset = (textHeight / 2) - textPaint.descent(); | ||
| 280 | + | ||
| 281 | + for (String line : splitText) { | ||
| 282 | + float horizontalTextOffset = textPaint.measureText(line) / 2; | ||
| 283 | + canvas.drawText( | ||
| 284 | + line, | ||
| 285 | + this.getWidth() / 2 - horizontalTextOffset, | ||
| 286 | + this.getHeight() / 2 + verticalTextOffset, | ||
| 287 | + textPaint); | ||
| 288 | + } | ||
| 289 | + if (isSpinning) { | ||
| 290 | + scheduleRedraw(); | ||
| 291 | + } | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + private void scheduleRedraw() { | ||
| 295 | + progress += spinSpeed; | ||
| 296 | + if (progress > 360) { | ||
| 297 | + progress = 0; | ||
| 298 | + } | ||
| 299 | + postInvalidateDelayed(delayMillis); | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + /** | ||
| 303 | + * Check if the wheel is currently spinning | ||
| 304 | + */ | ||
| 305 | + public boolean isSpinning() { | ||
| 306 | + return isSpinning; | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + /** | ||
| 310 | + * Reset the count (in increment mode) | ||
| 311 | + */ | ||
| 312 | + public void resetCount() { | ||
| 313 | + progress = 0; | ||
| 314 | + setText("0%"); | ||
| 315 | + invalidate(); | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + /** | ||
| 319 | + * Turn off startSpinning mode | ||
| 320 | + */ | ||
| 321 | + public void stopSpinning() { | ||
| 322 | + isSpinning = false; | ||
| 323 | + progress = 0; | ||
| 324 | + postInvalidate(); | ||
| 325 | + } | ||
| 326 | + | ||
| 327 | + | ||
| 328 | + /** | ||
| 329 | + * Puts the view on spin mode | ||
| 330 | + */ | ||
| 331 | + public void startSpinning() { | ||
| 332 | + isSpinning = true; | ||
| 333 | + postInvalidate(); | ||
| 334 | + } | ||
| 335 | + | ||
| 336 | + /** | ||
| 337 | + * Increment the progress by 1 (of 360) | ||
| 338 | + */ | ||
| 339 | + public void incrementProgress() { | ||
| 340 | + incrementProgress(1); | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + public void incrementProgress(int amount) { | ||
| 344 | + isSpinning = false; | ||
| 345 | + progress += amount; | ||
| 346 | + if (progress > 360) | ||
| 347 | + progress %= 360; | ||
| 348 | + postInvalidate(); | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + | ||
| 352 | + /** | ||
| 353 | + * Set the progress to a specific value | ||
| 354 | + */ | ||
| 355 | + public void setProgress(int i) { | ||
| 356 | + isSpinning = false; | ||
| 357 | + progress = i; | ||
| 358 | + postInvalidate(); | ||
| 359 | + } | ||
| 360 | + | ||
| 361 | + //---------------------------------- | ||
| 362 | + //Getters + setters | ||
| 363 | + //---------------------------------- | ||
| 364 | + | ||
| 365 | + /** | ||
| 366 | + * Set the text in the progress bar | ||
| 367 | + * Doesn't invalidate the view | ||
| 368 | + * | ||
| 369 | + * @param text the text to show ('\n' constitutes a new line) | ||
| 370 | + */ | ||
| 371 | + public void setText(String text) { | ||
| 372 | + this.text = text; | ||
| 373 | + splitText = this.text.split("\n"); | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + public int getCircleRadius() { | ||
| 377 | + return circleRadius; | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + public void setCircleRadius(int circleRadius) { | ||
| 381 | + this.circleRadius = circleRadius; | ||
| 382 | + } | ||
| 383 | + | ||
| 384 | + public int getBarLength() { | ||
| 385 | + return barLength; | ||
| 386 | + } | ||
| 387 | + | ||
| 388 | + public void setBarLength(int barLength) { | ||
| 389 | + this.barLength = barLength; | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + public int getBarWidth() { | ||
| 393 | + return barWidth; | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + public void setBarWidth(int barWidth) { | ||
| 397 | + this.barWidth = barWidth; | ||
| 398 | + | ||
| 399 | + if (this.barPaint != null) { | ||
| 400 | + this.barPaint.setStrokeWidth(this.barWidth); | ||
| 401 | + } | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + public int getTextSize() { | ||
| 405 | + return textSize; | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + public void setTextSize(int textSize) { | ||
| 409 | + this.textSize = textSize; | ||
| 410 | + | ||
| 411 | + if (this.textPaint != null) { | ||
| 412 | + this.textPaint.setTextSize(this.textSize); | ||
| 413 | + } | ||
| 414 | + } | ||
| 415 | + | ||
| 416 | + public int getPaddingTop() { | ||
| 417 | + return paddingTop; | ||
| 418 | + } | ||
| 419 | + | ||
| 420 | + public void setPaddingTop(int paddingTop) { | ||
| 421 | + this.paddingTop = paddingTop; | ||
| 422 | + } | ||
| 423 | + | ||
| 424 | + public int getPaddingBottom() { | ||
| 425 | + return paddingBottom; | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + public void setPaddingBottom(int paddingBottom) { | ||
| 429 | + this.paddingBottom = paddingBottom; | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + public int getPaddingLeft() { | ||
| 433 | + return paddingLeft; | ||
| 434 | + } | ||
| 435 | + | ||
| 436 | + public void setPaddingLeft(int paddingLeft) { | ||
| 437 | + this.paddingLeft = paddingLeft; | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + public int getPaddingRight() { | ||
| 441 | + return paddingRight; | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + public void setPaddingRight(int paddingRight) { | ||
| 445 | + this.paddingRight = paddingRight; | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + public int getBarColor() { | ||
| 449 | + return barColor; | ||
| 450 | + } | ||
| 451 | + | ||
| 452 | + public void setBarColor(int barColor) { | ||
| 453 | + this.barColor = barColor; | ||
| 454 | + | ||
| 455 | + if (this.barPaint != null) { | ||
| 456 | + this.barPaint.setColor(this.barColor); | ||
| 457 | + } | ||
| 458 | + } | ||
| 459 | + | ||
| 460 | + public int getCircleColor() { | ||
| 461 | + return circleColor; | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | + public void setCircleColor(int circleColor) { | ||
| 465 | + this.circleColor = circleColor; | ||
| 466 | + | ||
| 467 | + if (this.circlePaint != null) { | ||
| 468 | + this.circlePaint.setColor(this.circleColor); | ||
| 469 | + } | ||
| 470 | + } | ||
| 471 | + | ||
| 472 | + public int getRimColor() { | ||
| 473 | + return rimColor; | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + public void setRimColor(int rimColor) { | ||
| 477 | + this.rimColor = rimColor; | ||
| 478 | + | ||
| 479 | + if (this.rimPaint != null) { | ||
| 480 | + this.rimPaint.setColor(this.rimColor); | ||
| 481 | + } | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | + public Shader getRimShader() { | ||
| 485 | + return rimPaint.getShader(); | ||
| 486 | + } | ||
| 487 | + | ||
| 488 | + public void setRimShader(Shader shader) { | ||
| 489 | + this.rimPaint.setShader(shader); | ||
| 490 | + } | ||
| 491 | + | ||
| 492 | + public int getTextColor() { | ||
| 493 | + return textColor; | ||
| 494 | + } | ||
| 495 | + | ||
| 496 | + public void setTextColor(int textColor) { | ||
| 497 | + this.textColor = textColor; | ||
| 498 | + | ||
| 499 | + if (this.textPaint != null) { | ||
| 500 | + this.textPaint.setColor(this.textColor); | ||
| 501 | + } | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + public float getSpinSpeed() { | ||
| 505 | + return spinSpeed; | ||
| 506 | + } | ||
| 507 | + | ||
| 508 | + public void setSpinSpeed(float spinSpeed) { | ||
| 509 | + this.spinSpeed = spinSpeed; | ||
| 510 | + } | ||
| 511 | + | ||
| 512 | + public int getRimWidth() { | ||
| 513 | + return rimWidth; | ||
| 514 | + } | ||
| 515 | + | ||
| 516 | + public void setRimWidth(int rimWidth) { | ||
| 517 | + this.rimWidth = rimWidth; | ||
| 518 | + | ||
| 519 | + if (this.rimPaint != null) { | ||
| 520 | + this.rimPaint.setStrokeWidth(this.rimWidth); | ||
| 521 | + } | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + public int getDelayMillis() { | ||
| 525 | + return delayMillis; | ||
| 526 | + } | ||
| 527 | + | ||
| 528 | + public void setDelayMillis(int delayMillis) { | ||
| 529 | + this.delayMillis = delayMillis; | ||
| 530 | + } | ||
| 531 | + | ||
| 532 | + public int getContourColor() { | ||
| 533 | + return contourColor; | ||
| 534 | + } | ||
| 535 | + | ||
| 536 | + public void setContourColor(int contourColor) { | ||
| 537 | + this.contourColor = contourColor; | ||
| 538 | + | ||
| 539 | + if (contourPaint != null) { | ||
| 540 | + this.contourPaint.setColor(this.contourColor); | ||
| 541 | + } | ||
| 542 | + } | ||
| 543 | + | ||
| 544 | + public float getContourSize() { | ||
| 545 | + return this.contourSize; | ||
| 546 | + } | ||
| 547 | + | ||
| 548 | + public void setContourSize(float contourSize) { | ||
| 549 | + this.contourSize = contourSize; | ||
| 550 | + | ||
| 551 | + if (contourPaint != null) { | ||
| 552 | + this.contourPaint.setStrokeWidth(this.contourSize); | ||
| 553 | + } | ||
| 554 | + } | ||
| 555 | + | ||
| 556 | + public int getProgress() { | ||
| 557 | + return (int) progress; | ||
| 558 | + } | ||
| 559 | +} |
core/imageload/src/main/java/com/cnlive/core/imagepreview/viewpager/ImagePagerAdapter.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.viewpager; | ||
| 2 | + | ||
| 3 | +import android.view.View; | ||
| 4 | +import android.view.ViewGroup; | ||
| 5 | + | ||
| 6 | +import com.cnlive.core.imagepreview.ImageDrawee; | ||
| 7 | + | ||
| 8 | +import androidx.annotation.NonNull; | ||
| 9 | +import androidx.viewpager.widget.PagerAdapter; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * created by hanyayun | ||
| 13 | + * on 2020/1/20 | ||
| 14 | + */ | ||
| 15 | +public class ImagePagerAdapter extends PagerAdapter { | ||
| 16 | + private int mItemCount; | ||
| 17 | + | ||
| 18 | + public ImagePagerAdapter(int count) { | ||
| 19 | + this.mItemCount = count; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + @Override | ||
| 23 | + public int getCount() { | ||
| 24 | + return mItemCount; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + @NonNull | ||
| 28 | + @Override | ||
| 29 | + public Object instantiateItem(@NonNull ViewGroup container, int position) { | ||
| 30 | + return null; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { | ||
| 35 | + if (object != null) { | ||
| 36 | + ((ImageDrawee) object).recycle(); | ||
| 37 | + // 移除页面 | ||
| 38 | + container.removeView((View) object); | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { | ||
| 44 | + return view == object; | ||
| 45 | + } | ||
| 46 | +} | ||
| 47 | + |
core/imageload/src/main/java/com/cnlive/core/imagepreview/viewpager/ImageViewPager.java
0 → 100644
| 1 | +package com.cnlive.core.imagepreview.viewpager; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.util.AttributeSet; | ||
| 5 | +import android.view.MotionEvent; | ||
| 6 | + | ||
| 7 | +import androidx.viewpager.widget.ViewPager; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 预览器 ViewPager | ||
| 11 | + * created by hanyayun | ||
| 12 | + * on 2020/1/20 | ||
| 13 | + */ | ||
| 14 | +public class ImageViewPager extends ViewPager { | ||
| 15 | + // 是否可滑动 | ||
| 16 | + private boolean isScrollable = true; | ||
| 17 | + | ||
| 18 | + public ImageViewPager(Context context) { | ||
| 19 | + super(context); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public ImageViewPager(Context context, AttributeSet attrs) { | ||
| 23 | + super(context, attrs); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + @Override | ||
| 27 | + public void scrollTo(int x, int y) { | ||
| 28 | + if (isScrollable) { | ||
| 29 | + super.scrollTo(x, y); | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 设置是否可滑动 | ||
| 35 | + * | ||
| 36 | + * @param isScrollable | ||
| 37 | + */ | ||
| 38 | + public void setScrollable(boolean isScrollable) { | ||
| 39 | + this.isScrollable = isScrollable; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * 重写 onInterceptTouchEvent 和 onTouchEvent 方法是为了解决 | ||
| 44 | + * PhotoView + Viewpager 双指缩放的时候出现 pointerIndex out of range 问题 | ||
| 45 | + */ | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + public boolean onInterceptTouchEvent(MotionEvent ev) { | ||
| 49 | + try { | ||
| 50 | + return super.onInterceptTouchEvent(ev); | ||
| 51 | + } catch (IllegalArgumentException ex) { | ||
| 52 | + ex.printStackTrace(); | ||
| 53 | + } | ||
| 54 | + return false; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Override | ||
| 58 | + public boolean onTouchEvent(MotionEvent ev) { | ||
| 59 | + try { | ||
| 60 | + return super.onTouchEvent(ev); | ||
| 61 | + } catch (IllegalArgumentException ex) { | ||
| 62 | + ex.printStackTrace(); | ||
| 63 | + } | ||
| 64 | + return false; | ||
| 65 | + } | ||
| 66 | +} | ||
| 0 | \ No newline at end of file | 67 | \ No newline at end of file |
core/imageload/src/main/res/layout/auto_grid_item_simple_pic.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:layout_width="match_parent" | ||
| 4 | + android:layout_height="match_parent" | ||
| 5 | + android:orientation="vertical"> | ||
| 6 | + | ||
| 7 | + <ImageView | ||
| 8 | + android:id="@+id/iv_auto_grid_item_simple_pic" | ||
| 9 | + android:layout_width="match_parent" | ||
| 10 | + android:layout_height="match_parent" | ||
| 11 | + android:scaleType="centerCrop" /> | ||
| 12 | +</LinearLayout> | ||
| 0 | \ No newline at end of file | 13 | \ No newline at end of file |
core/imageload/src/main/res/layout/auto_grid_item_simple_pic_single.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:layout_width="match_parent" | ||
| 4 | + android:layout_height="match_parent" | ||
| 5 | + android:orientation="vertical"> | ||
| 6 | + | ||
| 7 | + <ImageView | ||
| 8 | + android:id="@+id/iv_auto_grid_item_simple_pic" | ||
| 9 | + android:layout_width="200dp" | ||
| 10 | + android:layout_height="wrap_content" | ||
| 11 | + android:adjustViewBounds="true" /> | ||
| 12 | +</LinearLayout> | ||
| 0 | \ No newline at end of file | 13 | \ No newline at end of file |
core/imageload/src/main/res/values/auto_grid_view_attrs.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<resources> | ||
| 3 | + <!--网格控件--> | ||
| 4 | + <declare-styleable name="AutoGridView"> | ||
| 5 | + <!--网格图的类型--> | ||
| 6 | + <attr name="agv_mode"> | ||
| 7 | + <!--类似QQ空间、微信朋友圈的九宫格类型网格图--> | ||
| 8 | + <enum name="nine" value="0" /> | ||
| 9 | + <!--依次显示网格的普通类型网格图--> | ||
| 10 | + <enum name="normal" value="1" /> | ||
| 11 | + </attr> | ||
| 12 | + <!--网格的行数--> | ||
| 13 | + <attr name="agv_row" format="integer" /> | ||
| 14 | + <!--网格的列数--> | ||
| 15 | + <attr name="agv_column" format="integer" /> | ||
| 16 | + <!--item 的高度--> | ||
| 17 | + <attr name="agv_item_height" format="dimension" /> | ||
| 18 | + <!--item 之间的横向间距--> | ||
| 19 | + <attr name="agv_horizontal_space" format="dimension" /> | ||
| 20 | + <!--item 之间的纵向间距--> | ||
| 21 | + <attr name="agv_vertical_space" format="dimension" /> | ||
| 22 | + <!--九宫格模式下,单个 item 时,item 的宽与 parent 的可用总宽的比--> | ||
| 23 | + <attr name="agv_nines_widthper" format="float" /> | ||
| 24 | + <!--九宫格模式下,单个 item 时,item 的高与 parent 的可用总宽的比--> | ||
| 25 | + <attr name="agv_nines_heightper" format="float" /> | ||
| 26 | + </declare-styleable> | ||
| 27 | +</resources> |
core/imageload/src/main/res/values/grid_attrs.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<resources> | ||
| 3 | + <declare-styleable name="ImagePreView"> | ||
| 4 | + <!--是否开启进场动画--> | ||
| 5 | + <attr name="ivr_playEnterAnim" format="boolean" /> | ||
| 6 | + <!--是否开启退场动画--> | ||
| 7 | + <attr name="ivr_playExitAnim" format="boolean" /> | ||
| 8 | + <!--进场与退场动画的执行时间--> | ||
| 9 | + <attr name="ivr_duration" format="integer" /> | ||
| 10 | + <!--是否显示图片位置--> | ||
| 11 | + <attr name="ivr_showIndex" format="boolean" /> | ||
| 12 | + <!--是否允许图片拖拽--> | ||
| 13 | + <attr name="ivr_draggable" format="boolean" /> | ||
| 14 | + <!--拖拽模式--> | ||
| 15 | + <attr name="ivr_dragMode"> | ||
| 16 | + <enum name="simple" value="1" /> | ||
| 17 | + <enum name="agile" value="2" /> | ||
| 18 | + </attr> | ||
| 19 | + </declare-styleable> | ||
| 20 | +</resources> | ||
| 0 | \ No newline at end of file | 21 | \ No newline at end of file |
core/imageload/src/main/res/values/ivr_progrv_attrs.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<resources> | ||
| 3 | + <declare-styleable name="ivr_ProgressWheel"> | ||
| 4 | + <attr name="pwText" format="string" /> | ||
| 5 | + <attr name="pwTextColor" format="color" /> | ||
| 6 | + <attr name="pwTextSize" format="dimension" /> | ||
| 7 | + <attr name="pwBarColor" format="color" /> | ||
| 8 | + <attr name="pwBarWidth" format="dimension" /> | ||
| 9 | + <attr name="pwBarLength" format="dimension" /> | ||
| 10 | + <attr name="pwRimColor" format="color" /> | ||
| 11 | + <attr name="pwRimWidth" format="dimension" /> | ||
| 12 | + <attr name="pwContourColor" format="color" /> | ||
| 13 | + <attr name="pwContourSize" format="dimension" /> | ||
| 14 | + <attr name="pwRadius" format="dimension" /> | ||
| 15 | + <attr name="pwCircleColor" format="color" /> | ||
| 16 | + <attr name="pwSpinSpeed" format="float" /> | ||
| 17 | + <attr name="pwDelayMillis" format="integer" /> | ||
| 18 | + </declare-styleable> | ||
| 19 | +</resources> | ||
| 0 | \ No newline at end of file | 20 | \ No newline at end of file |