diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index cc72de3..e0d5b93 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,45 +5,34 @@
-
+
-
-
-
-
- 1.8
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index b737894..82d0710 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 27
- buildToolsVersion '27.0.2'
+ compileSdkVersion 28
+ buildToolsVersion '28.0.3'
defaultConfig {
applicationId "ch.ielse.demo.p02"
- minSdkVersion 14
- targetSdkVersion 27
+ minSdkVersion 15
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
}
@@ -19,8 +19,8 @@ android {
}
dependencies {
- implementation 'com.android.support:appcompat-v7:27.0.2'
- implementation 'com.android.support:recyclerview-v7:27.0.2'
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
diff --git a/app/src/main/java/ch/ielse/demo/p02/CustomLoadingUIProvider2.java b/app/src/main/java/ch/ielse/demo/p02/CustomLoadingUIProvider2.java
new file mode 100644
index 0000000..7951b3f
--- /dev/null
+++ b/app/src/main/java/ch/ielse/demo/p02/CustomLoadingUIProvider2.java
@@ -0,0 +1,47 @@
+package ch.ielse.demo.p02;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.github.ielse.imagewatcher.ImageWatcher;
+
+
+public class CustomLoadingUIProvider2 implements ImageWatcher.LoadingUIProvider {
+ private final FrameLayout.LayoutParams lpCenterInParent = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ private final Handler mHandler = new Handler();
+
+ private Runnable runDelayDisplay;
+
+ @Override
+ public View initialView(Context context) {
+ ImageView load = new ImageView(context);
+ lpCenterInParent.gravity = Gravity.CENTER;
+ load.setLayoutParams(lpCenterInParent);
+ load.setImageResource(R.mipmap.loading);
+ return load;
+ }
+
+ @Override
+ public void start(final View loadView) {
+ if (runDelayDisplay != null) mHandler.removeCallbacks(runDelayDisplay);
+ runDelayDisplay = new Runnable() {
+ @Override
+ public void run() {
+ loadView.setVisibility(View.VISIBLE);
+ }
+ };
+ mHandler.postDelayed(runDelayDisplay, 500);
+ }
+
+ @Override
+ public void stop(View loadView) {
+ if (runDelayDisplay != null) mHandler.removeCallbacks(runDelayDisplay);
+ runDelayDisplay = null;
+ loadView.setVisibility(View.GONE);
+ }
+}
diff --git a/app/src/main/java/ch/ielse/demo/p02/DecorationLayout.java b/app/src/main/java/ch/ielse/demo/p02/DecorationLayout.java
new file mode 100644
index 0000000..abc2346
--- /dev/null
+++ b/app/src/main/java/ch/ielse/demo/p02/DecorationLayout.java
@@ -0,0 +1,93 @@
+package ch.ielse.demo.p02;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.github.ielse.imagewatcher.ImageWatcher;
+import com.github.ielse.imagewatcher.ImageWatcherHelper;
+
+public class DecorationLayout extends FrameLayout implements ViewPager.OnPageChangeListener, View.OnClickListener {
+
+ private ImageWatcherHelper mHolder;
+ private TextView vDisplayOrigin;
+ private View vDownload;
+ private int currentPosition;
+ private int mPagerPositionOffsetPixels;
+
+ public DecorationLayout(Context context) {
+ super(context);
+ final FrameLayout vContainer = (FrameLayout) LayoutInflater.from(context).inflate(R.layout.layout_watcher_decoration, this);
+ vDisplayOrigin = vContainer.findViewById(R.id.vDisplayOrigin);
+ vDisplayOrigin.setOnClickListener(this);
+ vDownload = vContainer.findViewById(R.id.vDownload);
+ vDownload.setOnClickListener(this);
+
+ }
+
+ public void attachImageWatcher(ImageWatcherHelper iwHelper) {
+ mHolder = iwHelper;
+ }
+
+
+ @Override
+ public void onClick(View v) {
+ if (mPagerPositionOffsetPixels != 0) return;
+
+ if (v.getId() == R.id.vDownload) {
+ final int clickPosition = currentPosition;
+ Toast.makeText(v.getContext().getApplicationContext(), "download [" + clickPosition + "] ", Toast.LENGTH_SHORT).show();
+ } else if (v.getId() == R.id.vDisplayOrigin) {
+ final int clickPosition = currentPosition;
+ Toast.makeText(v.getContext().getApplicationContext(), "display origin [" + clickPosition + "]", Toast.LENGTH_SHORT).show();
+ Uri newUri = Uri.parse("https://pub-static.haozhaopian.net/static/web/site/features/cn/crop/images/crop_20a7dc7fbd29d679b456fa0f77bd9525d.jpg");
+ notifyAdapterItemChanged(clickPosition, newUri);
+
+ }
+ }
+
+ @Override
+ public void onPageScrolled(int i, float v, int i1) {
+ mPagerPositionOffsetPixels = i1;
+ notifyAlphaChanged(v);
+ // setAlpha(1 - v);
+ }
+
+ @Override
+ public void onPageSelected(int i) {
+ currentPosition = i;
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int i) {
+
+ }
+
+ private void notifyAdapterItemChanged(int position, Uri newUri) {
+ if (mHolder != null) {
+ final ImageWatcher iw = mHolder.getImageWatcher();
+ if (iw != null) {
+ iw.notifyItemChanged(position, newUri);
+ }
+ }
+ }
+
+ private void notifyAlphaChanged(float p) {
+ if (0 < p && p <= 0.2f) {
+ float r = (0.2f - p) * 5;
+ setAlpha(r);
+ } else if (0.8f <= p && p < 1) {
+ float r = (p - 0.8f) * 5;
+ setAlpha(r);
+ } else if (p == 0) {
+ setAlpha(1f);
+ } else {
+ setAlpha(0f);
+ }
+ }
+}
diff --git a/app/src/main/java/ch/ielse/demo/p02/MainActivity.java b/app/src/main/java/ch/ielse/demo/p02/MainActivity.java
index b05e59b..987ef67 100644
--- a/app/src/main/java/ch/ielse/demo/p02/MainActivity.java
+++ b/app/src/main/java/ch/ielse/demo/p02/MainActivity.java
@@ -64,7 +64,7 @@ public void onClick(View v) {
// 长按图片的回调,你可以显示一个框继续提供一些复制,发送等功能
vImageWatcher.setOnPictureLongPressListener(this);
vImageWatcher.setLoader(new GlideSimpleLoader());
- vImageWatcher.setOnStateChangedListener(new ImageWatcher.OnStateChangedListener() {
+ vImageWatcher.addOnStateChangedListener(new ImageWatcher.OnStateChangedListener() {
@Override
public void onStateChangeUpdate(ImageWatcher imageWatcher, ImageView clicked, int position, Uri uri, float animatedValue, int actionTag) {
Log.e("IW", "onStateChangeUpdate [" + position + "][" + uri + "][" + animatedValue + "][" + actionTag + "]");
diff --git a/app/src/main/java/ch/ielse/demo/p02/MainActivity2.java b/app/src/main/java/ch/ielse/demo/p02/MainActivity2.java
index e08c5c9..0017284 100644
--- a/app/src/main/java/ch/ielse/demo/p02/MainActivity2.java
+++ b/app/src/main/java/ch/ielse/demo/p02/MainActivity2.java
@@ -26,6 +26,8 @@ public class MainActivity2 extends Activity implements MessagePicturesLayout.Cal
private RecyclerView vRecycler;
private MessageAdapter adapter;
+ private DecorationLayout layDecoration;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
boolean isTranslucentStatus = false;
@@ -40,6 +42,7 @@ protected void onCreate(Bundle savedInstanceState) {
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
+ layDecoration = new DecorationLayout(this);
vRecycler = (RecyclerView) findViewById(R.id.v_recycler);
vRecycler.setLayoutManager(new LinearLayoutManager(this));
@@ -74,7 +77,12 @@ public void onStateChanged(ImageWatcher imageWatcher, int position, Uri uri, int
}
}
})
- .setLoadingUIProvider(new CustomLoadingUIProvider()); // 自定义LoadingUI
+ .setOtherView(layDecoration)
+ .addOnPageChangeListener(layDecoration)
+ .setLoadingUIProvider(new CustomLoadingUIProvider2()); // 自定义LoadingUI
+
+
+ layDecoration.attachImageWatcher(iwHelper);
Utils.fitsSystemWindows(isTranslucentStatus, findViewById(R.id.v_fit));
diff --git a/app/src/main/java/ch/ielse/demo/p02/MainActivity4.java b/app/src/main/java/ch/ielse/demo/p02/MainActivity4.java
index 0efdc99..a45df49 100644
--- a/app/src/main/java/ch/ielse/demo/p02/MainActivity4.java
+++ b/app/src/main/java/ch/ielse/demo/p02/MainActivity4.java
@@ -66,7 +66,8 @@ public void onClick(View v) {
iwHelper = ImageWatcherHelper.with(this, new GlideSimpleLoader()) // 一般来讲, ImageWatcher 需要占据全屏的位置
- .setIndexProvider(new CustomDotIndexProvider()); // 自定义index
+ .setIndexProvider(new CustomDotIndexProvider()) // 自定义index
+ .setLoadingUIProvider(new CustomLoadingUIProvider()); // 骰子loading
}
diff --git a/app/src/main/res/drawable/b_white_ffffff_stroke_round_3_shape.xml b/app/src/main/res/drawable/b_white_ffffff_stroke_round_3_shape.xml
new file mode 100644
index 0000000..3b6a250
--- /dev/null
+++ b/app/src/main/res/drawable/b_white_ffffff_stroke_round_3_shape.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/layout_watcher_decoration.xml b/app/src/main/res/layout/layout_watcher_decoration.xml
new file mode 100644
index 0000000..33a56f5
--- /dev/null
+++ b/app/src/main/res/layout/layout_watcher_decoration.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-xxhdpi/download.png b/app/src/main/res/mipmap-xxhdpi/download.png
new file mode 100755
index 0000000..a1c8a89
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/download.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/loading.png b/app/src/main/res/mipmap-xxhdpi/loading.png
new file mode 100644
index 0000000..74a47f3
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/loading.png differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 922a100..9602a69 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,4 +1,5 @@
ImageWatcher
+
diff --git a/build.gradle b/build.gradle
index 4c2a261..a687f8c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ buildscript {
maven { url 'https://maven.google.com' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.0.1'
+ classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8098292..4a105d6 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
diff --git a/imagewatcher/build.gradle b/imagewatcher/build.gradle
index 2218847..b2664e4 100644
--- a/imagewatcher/build.gradle
+++ b/imagewatcher/build.gradle
@@ -4,15 +4,14 @@ apply plugin: 'com.jfrog.bintray'
android {
- compileSdkVersion 27
- buildToolsVersion "27.0.2"
+ compileSdkVersion 28
resourcePrefix "imagewatcher__"
defaultConfig {
- minSdkVersion 14
- targetSdkVersion 27
- versionCode 7
- versionName "1.1.4"
+ minSdkVersion 15
+ targetSdkVersion 28
+ versionCode 8
+ versionName "1.1.5"
}
buildTypes {
@@ -24,5 +23,5 @@ android {
}
dependencies {
- implementation 'com.android.support:appcompat-v7:27.0.2'
+ implementation 'com.android.support:appcompat-v7:28.0.0'
}
\ No newline at end of file
diff --git a/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcher.java b/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcher.java
index d4b5734..c3ce6da 100644
--- a/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcher.java
+++ b/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcher.java
@@ -9,7 +9,6 @@
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Animatable;
-import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
@@ -34,11 +33,13 @@
import android.widget.TextView;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.List;
public class ImageWatcher extends FrameLayout implements GestureDetector.OnGestureListener, ViewPager.OnPageChangeListener {
private static final int SINGLE_TAP_UP_CONFIRMED = 1;
private static final int DATA_INITIAL = 2;
+
public static final int STATE_ENTER_DISPLAYING = 3;
public static final int STATE_EXIT_HIDING = 4;
private final Handler mHandler;
@@ -90,10 +91,11 @@ public class ImageWatcher extends FrameLayout implements GestureDetector.OnGestu
private int currentPosition;
private int mPagerPositionOffsetPixels; // viewpager当前在屏幕上偏移量
private Loader loader; // 图片加载者
- private OnStateChangedListener stateChangedListener;
+ private final List onStateChangedListeners = new ArrayList<>();
private IndexProvider indexProvider; // 索引ui接口
private View idxView; // 索引ui
private LoadingUIProvider loadingUIProvider; // 加载ui
+ private final List onPageChangeListeners = new ArrayList<>();
private boolean detachAffirmative; // dismiss detach parent 退出查看大图模式后,立即释放内存
private boolean detachedParent;
@@ -110,7 +112,6 @@ public ImageWatcher(Context context, AttributeSet attrs) {
addView(vPager = new ViewPager(context));
vPager.addOnPageChangeListener(this);
setVisibility(View.INVISIBLE);
-
setIndexProvider(new DefaultIndexProvider());
setLoadingUIProvider(new DefaultLoadingUIProvider());
}
@@ -136,14 +137,22 @@ public void setLoadingUIProvider(LoadingUIProvider lp) {
loadingUIProvider = lp;
}
- public void setOnStateChangedListener(OnStateChangedListener changedListener) {
- stateChangedListener = changedListener;
+ public void addOnStateChangedListener(OnStateChangedListener listener) {
+ if (!onStateChangedListeners.contains(listener)) {
+ onStateChangedListeners.add(listener);
+ }
}
public void setOnPictureLongPressListener(OnPictureLongPressListener listener) {
pictureLongPressListener = listener;
}
+ public void addOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+ if (!onPageChangeListeners.contains(listener)) {
+ onPageChangeListeners.add(listener);
+ }
+ }
+
public interface Loader {
void load(Context context, Uri uri, LoadCallback lc);
}
@@ -201,6 +210,7 @@ public interface LoadingUIProvider {
public class DefaultLoadingUIProvider implements LoadingUIProvider {
final LayoutParams lpCenterInParent = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ private Runnable runDelayDisplay;
@Override
public View initialView(Context context) {
@@ -211,15 +221,30 @@ public View initialView(Context context) {
}
@Override
- public void start(View loadView) {
- loadView.setVisibility(View.VISIBLE);
- ((ProgressView) loadView).start();
+ public void start(final View loadView) {
+ if (runDelayDisplay != null) mHandler.removeCallbacks(runDelayDisplay);
+ runDelayDisplay = new Runnable() {
+ @Override
+ public void run() {
+ loadView.setVisibility(View.VISIBLE);
+ if (!((ProgressView) loadView).isRunning()) {
+ ((ProgressView) loadView).start();
+ }
+ }
+ };
+ mHandler.postDelayed(runDelayDisplay, 500);
}
@Override
public void stop(View loadView) {
- ((ProgressView) loadView).stop();
+ if (runDelayDisplay != null) mHandler.removeCallbacks(runDelayDisplay);
+ runDelayDisplay = null;
+
+ if (((ProgressView) loadView).isRunning()) {
+ ((ProgressView) loadView).stop();
+ }
loadView.setVisibility(View.GONE);
+
}
}
@@ -256,7 +281,7 @@ public void show(List urlList, int initPos) {
* @param imageGroupList 被点击的ImageView的所在列表,加载图片时会提前展示列表中已经下载完成的thumb图片
* @param urlList 被加载的图片url列表,数量必须大于等于 imageGroupList.size。 且顺序应当和imageGroupList保持一致
*/
- public void show(ImageView i, SparseArray imageGroupList, final List urlList) {
+ public boolean show(ImageView i, SparseArray imageGroupList, final List urlList) {
if (i == null || imageGroupList == null || urlList == null) {
throw new NullPointerException("i[" + i + "] imageGroupList[" + imageGroupList + "] urlList[" + urlList + "]");
}
@@ -270,7 +295,10 @@ public void show(ImageView i, SparseArray imageGroupList, final List<
if (initPosition < 0) {
throw new IllegalArgumentException("param ImageView i must be a member of the List imageGroupList!");
}
+
+ if (i.getDrawable() == null) return false;
showInternal(i, imageGroupList, urlList);
+ return true;
}
private void showInternal(ImageView i, SparseArray imageGroupList, final List urlList) {
@@ -278,8 +306,6 @@ private void showInternal(ImageView i, SparseArray imageGroupList, fi
throw new NullPointerException("please invoke `setLoader` first [loader == null]");
}
- if (i != null && i.getDrawable() == null) return;
-
if (!isInitLayout) {
initI = i;
initImageGroupList = imageGroupList;
@@ -307,7 +333,22 @@ public int getCurrentPosition() {
}
public Uri getDisplayingUri() {
- return mUrlList != null ? mUrlList.get(getCurrentPosition()) : null;
+ return getUri(getCurrentPosition());
+ }
+
+ public Uri getUri(int position) {
+ if (mUrlList == null || mUrlList.size() <= position || position < 0) {
+ return null;
+ }
+ return mUrlList.get(position);
+ }
+
+ public void notifyItemChanged(int position, Uri newUri) {
+ if (mUrlList == null || mUrlList.size() <= position || position < 0) {
+ return;
+ }
+ mUrlList.set(position, newUri);
+ adapter.notifyItemChanged(position);
}
@Override
@@ -839,6 +880,12 @@ private void handleExitTouchResult() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mPagerPositionOffsetPixels = positionOffsetPixels;
+
+ if (!onPageChangeListeners.isEmpty()) {
+ for (ViewPager.OnPageChangeListener onPageChangeListener : onPageChangeListeners) {
+ onPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
+ }
+ }
}
/**
@@ -860,11 +907,22 @@ public void onPageSelected(int position) {
if (ViewState.read(mNext, ViewState.STATE_DEFAULT) != null) {
ViewState.restoreByAnim(mNext, ViewState.STATE_DEFAULT).create().start();
}
+
+ if (!onPageChangeListeners.isEmpty()) {
+ for (ViewPager.OnPageChangeListener onPageChangeListener : onPageChangeListeners) {
+ onPageChangeListener.onPageSelected(position);
+ }
+ }
}
@Override
public void onPageScrollStateChanged(int state) {
+ if (!onPageChangeListeners.isEmpty()) {
+ for (ViewPager.OnPageChangeListener onPageChangeListener : onPageChangeListeners) {
+ onPageChangeListener.onPageScrollStateChanged(state);
+ }
+ }
}
class ImagePagerAdapter extends PagerAdapter {
@@ -917,6 +975,74 @@ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
+ void notifyItemChanged(final int position) {
+ final ImageView imageView = mImageSparseArray.get(position);
+ if (imageView != null) {
+ loader.load(imageView.getContext(), mUrlList.get(position), new LoadCallback() {
+ @Override
+ public void onResourceReady(Drawable resource) {
+ final int sourceDefaultWidth, sourceDefaultHeight, sourceDefaultTranslateX, sourceDefaultTranslateY;
+ int resourceImageWidth = resource.getIntrinsicWidth();
+ int resourceImageHeight = resource.getIntrinsicHeight();
+ if (resourceImageWidth * 1f / resourceImageHeight > mWidth * 1f / mHeight) {
+ sourceDefaultWidth = mWidth;
+ sourceDefaultHeight = (int) (sourceDefaultWidth * 1f / resourceImageWidth * resourceImageHeight);
+ sourceDefaultTranslateX = 0;
+ sourceDefaultTranslateY = (mHeight - sourceDefaultHeight) / 2;
+ imageView.setTag(R.id.image_orientation, "horizontal");
+ } else {
+ sourceDefaultWidth = mWidth;
+ sourceDefaultHeight = (int) (sourceDefaultWidth * 1f / resourceImageWidth * resourceImageHeight);
+ sourceDefaultTranslateX = 0;
+ sourceDefaultTranslateY = 0;
+ imageView.setTag(R.id.image_orientation, "vertical");
+ }
+ imageView.setImageDrawable(resource);
+ notifyItemChangedState(position, false, false);
+
+ ViewState vsDefault = ViewState.write(imageView, ViewState.STATE_DEFAULT).width(sourceDefaultWidth).height(sourceDefaultHeight)
+ .translationX(sourceDefaultTranslateX).translationY(sourceDefaultTranslateY);
+
+ ViewState.restore(imageView, vsDefault.mTag);
+ imageView.setAlpha(1f);
+ imageView.animate().alpha(1).start();
+
+ imageView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ Drawable displayingDrawable = imageView.getDrawable();
+ if (displayingDrawable instanceof Animatable) {
+ ((Animatable) displayingDrawable).stop();
+ }
+ }
+ });
+
+ Drawable displayingDrawable = imageView.getDrawable();
+ if (displayingDrawable instanceof Animatable) {
+ if (!((Animatable) displayingDrawable).isRunning()) {
+ ((Animatable) displayingDrawable).start();
+ }
+ }
+ }
+
+ @Override
+ public void onLoadStarted(Drawable placeholder) {
+ notifyItemChangedState(position, true, false);
+ }
+
+ @Override
+ public void onLoadFailed(Drawable errorDrawable) {
+ notifyItemChangedState(position, false, imageView.getDrawable() == null);
+ }
+ });
+ }
+
+ }
+
/**
* 更新ViewPager中每项的当前状态,比如是否加载,比如是否加载失败
*
@@ -1229,8 +1355,10 @@ public void onAnimationUpdate(ValueAnimator animation) {
float p = (float) animation.getAnimatedValue();
setBackgroundColor(mColorEvaluator.evaluate(p, mCurrentBackgroundColor, colorResult));
- if (stateChangedListener != null) {
- stateChangedListener.onStateChangeUpdate(ImageWatcher.this, iSource, getCurrentPosition(), getDisplayingUri(), p, tag);
+ if (!onStateChangedListeners.isEmpty()) {
+ for (OnStateChangedListener stateChangedListener : onStateChangedListeners) {
+ stateChangedListener.onStateChangeUpdate(ImageWatcher.this, iSource, getCurrentPosition(), getDisplayingUri(), p, tag);
+ }
}
}
});
@@ -1238,18 +1366,22 @@ public void onAnimationUpdate(ValueAnimator animation) {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
- if (stateChangedListener != null) {
+ if (!onStateChangedListeners.isEmpty()) {
if (tag == STATE_ENTER_DISPLAYING) {
- stateChangedListener.onStateChanged(ImageWatcher.this, getCurrentPosition(), getDisplayingUri(), tag);
+ for (OnStateChangedListener stateChangedListener : onStateChangedListeners) {
+ stateChangedListener.onStateChanged(ImageWatcher.this, getCurrentPosition(), getDisplayingUri(), tag);
+ }
}
}
}
@Override
public void onAnimationEnd(Animator animation) {
- if (stateChangedListener != null) {
+ if (!onStateChangedListeners.isEmpty()) {
if (tag == STATE_EXIT_HIDING) {
- stateChangedListener.onStateChanged(ImageWatcher.this, getCurrentPosition(), getDisplayingUri(), tag);
+ for (OnStateChangedListener stateChangedListener : onStateChangedListeners) {
+ stateChangedListener.onStateChanged(ImageWatcher.this, getCurrentPosition(), getDisplayingUri(), tag);
+ }
}
}
diff --git a/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcherHelper.java b/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcherHelper.java
index fc083e9..e7e1549 100644
--- a/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcherHelper.java
+++ b/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ImageWatcherHelper.java
@@ -2,15 +2,19 @@
import android.app.Activity;
import android.net.Uri;
+import android.support.v4.view.ViewPager;
+import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
+import java.util.ArrayList;
import java.util.List;
public class ImageWatcherHelper {
+ private static final int VIEW_DECORATION_ID = R.id.view_decoration;
private static final int VIEW_IMAGE_WATCHER_ID = R.id.view_image_watcher;
private final Activity holder;
private final ViewGroup activityDecorView;
@@ -21,7 +25,10 @@ public class ImageWatcherHelper {
private ImageWatcher.OnPictureLongPressListener listener;
private ImageWatcher.IndexProvider indexProvider;
private ImageWatcher.LoadingUIProvider loadingUIProvider;
- private ImageWatcher.OnStateChangedListener onStateChangedListener;
+ private final List onPageChangeListeners = new ArrayList<>();
+ private final List onStateChangedListeners = new ArrayList<>();
+ private View otherView;
+
private ImageWatcherHelper(Activity activity) {
holder = activity;
@@ -51,6 +58,19 @@ public ImageWatcherHelper setOnPictureLongPressListener(ImageWatcher.OnPictureLo
return this;
}
+
+ public ImageWatcherHelper addOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+ if (!onPageChangeListeners.contains(listener)) {
+ onPageChangeListeners.add(listener);
+ }
+ return this;
+ }
+
+ public ImageWatcherHelper setOtherView(View other) {
+ otherView = other;
+ return this;
+ }
+
public ImageWatcherHelper setIndexProvider(ImageWatcher.IndexProvider ip) {
indexProvider = ip;
return this;
@@ -62,18 +82,24 @@ public ImageWatcherHelper setLoadingUIProvider(ImageWatcher.LoadingUIProvider lp
}
public ImageWatcherHelper setOnStateChangedListener(ImageWatcher.OnStateChangedListener listener) {
- onStateChangedListener = listener;
+ if (!onStateChangedListeners.contains(listener)) {
+ onStateChangedListeners.add(listener);
+ }
return this;
}
public void show(ImageView i, SparseArray imageGroupList, List urlList) {
init();
- mImageWatcher.show(i, imageGroupList, urlList);
+ final boolean displaySuccess = mImageWatcher.show(i, imageGroupList, urlList);
+ if (displaySuccess) {
+ appendOtherView();
+ }
}
public void show(List urlList, int initPos) {
init();
mImageWatcher.show(urlList, initPos);
+ appendOtherView();
}
private void init() {
@@ -86,29 +112,72 @@ private void init() {
if (listener != null) mImageWatcher.setOnPictureLongPressListener(listener);
if (indexProvider != null) mImageWatcher.setIndexProvider(indexProvider);
if (loadingUIProvider != null) mImageWatcher.setLoadingUIProvider(loadingUIProvider);
- if (onStateChangedListener != null)
- mImageWatcher.setOnStateChangedListener(onStateChangedListener);
+ if (!onStateChangedListeners.isEmpty()) {
+ for (ImageWatcher.OnStateChangedListener onStateChangedListener : onStateChangedListeners) {
+ mImageWatcher.addOnStateChangedListener(onStateChangedListener);
+ }
+ }
+ if (!onPageChangeListeners.isEmpty()) {
+ for (ViewPager.OnPageChangeListener onPageChangeListener : onPageChangeListeners) {
+ mImageWatcher.addOnPageChangeListener(onPageChangeListener);
+ }
+ }
+
- removeExistingOverlayInView(activityDecorView); // 理论上是无意义的操作。在ImageWatcher 'dismiss' 时会移除自身。但检查一下不错
+ removeExistingOverlayInView(activityDecorView, mImageWatcher.getId()); // 理论上是无意义的操作。在ImageWatcher 'dismiss' 时会移除自身。但检查一下不错
activityDecorView.addView(mImageWatcher);
+
+ }
+
+ public ImageWatcher getImageWatcher() {
+ if (mImageWatcher == null) {
+ Log.i("ImageWatcherHelper", "please invoke 'show' first");
+ }
+ return mImageWatcher;
}
public boolean handleBackPressed() {
return mImageWatcher != null && mImageWatcher.handleBackPressed();
}
- private void removeExistingOverlayInView(ViewGroup parent) {
+ private void removeExistingOverlayInView(ViewGroup parent, int viewId) {
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
- if (child.getId() == VIEW_IMAGE_WATCHER_ID) {
+ if (child.getId() == viewId) {
parent.removeView(child);
}
+
if (child instanceof ViewGroup) {
- removeExistingOverlayInView((ViewGroup) child);
+ removeExistingOverlayInView((ViewGroup) child, viewId);
}
}
}
+ private void appendOtherView() {
+ if (otherView != null) {
+ if (otherView.getId() == View.NO_ID) otherView.setId(VIEW_DECORATION_ID);
+ removeExistingOverlayInView(activityDecorView, otherView.getId());
+ activityDecorView.addView(otherView);
+ mImageWatcher.addOnStateChangedListener(new ImageWatcher.OnStateChangedListener() {
+ @Override
+ public void onStateChangeUpdate(ImageWatcher imageWatcher, ImageView clicked, int position, Uri uri, float animatedValue, int actionTag) {
+ }
+
+ @Override
+ public void onStateChanged(ImageWatcher imageWatcher, int position, Uri uri, int actionTag) {
+ if (actionTag == ImageWatcher.STATE_EXIT_HIDING) {
+ if (otherView != null) {
+ if (otherView.getParent() != null) {
+ ((ViewGroup) otherView.getParent()).removeView(otherView);
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+
+
public interface Provider {
ImageWatcherHelper iwHelper();
}
diff --git a/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ProgressView.java b/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ProgressView.java
index 80fc13c..6b1ecf6 100644
--- a/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ProgressView.java
+++ b/imagewatcher/src/main/java/com/github/ielse/imagewatcher/ProgressView.java
@@ -60,6 +60,10 @@ public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long
}
+ public boolean isRunning() {
+ return mDrawable.isRunning();
+ }
+
public void start() {
mDrawable.start();
}
diff --git a/imagewatcher/src/main/res/values/ids.xml b/imagewatcher/src/main/res/values/ids.xml
index d18bc82..4008cdc 100644
--- a/imagewatcher/src/main/res/values/ids.xml
+++ b/imagewatcher/src/main/res/values/ids.xml
@@ -9,4 +9,5 @@
+
\ No newline at end of file