Improve GalleryActivity
This commit is contained in:
1 parent
7ad8a3afd1
commit
6f37491471
22 files changed
+620
-273
No files matched your search
@@ -18,7 +18,9 @@ package com.hippo.ehviewer;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.Debug;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.hippo.beerbelly.LruCacheEx;
|
||||
@@ -33,7 +35,9 @@ import com.hippo.okhttp.CookieDB;
|
||||
import com.hippo.scene.SceneApplication;
|
||||
import com.hippo.text.Html;
|
||||
import com.hippo.util.ReadableTime;
|
||||
import com.hippo.yorozuya.FileUtils;
|
||||
import com.hippo.yorozuya.IntIdGenerator;
|
||||
import com.hippo.yorozuya.SimpleHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Comparator;
|
||||
@@ -43,7 +47,10 @@ import okhttp3.OkHttpClient;
|
||||
|
||||
public class EhApplication extends SceneApplication {
|
||||
|
||||
private static final String TAG = EhApplication.class.getSimpleName();
|
||||
|
||||
private static final boolean DEBUG_CONACO = false;
|
||||
private static final boolean DEBUG_NATIVE_MEMORY = false;
|
||||
|
||||
private IntIdGenerator mIdGenerator = new IntIdGenerator();
|
||||
private SparseArray<Object> mGlobalStuffMap = new SparseArray<>();
|
||||
@@ -60,11 +67,27 @@ public class EhApplication extends SceneApplication {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
GetText.initialize(this);
|
||||
CookieDB.initialize(this);
|
||||
StatusCodeException.initialize(this);
|
||||
Settings.initialize(this);
|
||||
ReadableTime.initialize(this);
|
||||
Html.initialize(this);
|
||||
|
||||
if (DEBUG_NATIVE_MEMORY) {
|
||||
debugNativeMemory();
|
||||
}
|
||||
}
|
||||
|
||||
private void debugNativeMemory() {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "Native memory: " + FileUtils.humanReadableByteCount(
|
||||
Debug.getNativeHeapAllocatedSize(), false));
|
||||
SimpleHandler.getInstance().postDelayed(this, 3000);
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
|
||||
public int putGlobalStuff(@NonNull Object o) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
public class GetText {
|
||||
|
||||
private static Resources sResources;
|
||||
|
||||
public static void initialize(Context context) {
|
||||
sResources = context.getApplicationContext().getResources();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getString(@StringRes int id) {
|
||||
return sResources.getString(id);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getString(@StringRes int id, Object... formatArgs) {
|
||||
return sResources.getString(id, formatArgs);
|
||||
}
|
||||
}
|
||||
@@ -17,50 +17,68 @@
|
||||
package com.hippo.ehviewer.gallery;
|
||||
|
||||
import android.os.Process;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hippo.ehviewer.GetText;
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.image.Image;
|
||||
import com.hippo.yorozuya.PriorityThread;
|
||||
import com.hippo.yorozuya.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class DirGalleryProvider extends GalleryProvider {
|
||||
public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
|
||||
private static final String TAG = DirGalleryProvider.class.getSimpleName();
|
||||
private static final AtomicInteger sIdGenerator = new AtomicInteger();
|
||||
|
||||
private File mDir;
|
||||
private String[] mFiles;
|
||||
|
||||
private final File mDir;
|
||||
private final Stack<Integer> mRequests = new Stack<>();
|
||||
|
||||
private boolean mRun = true;
|
||||
@Nullable
|
||||
private Thread mBgThread;
|
||||
private volatile int mSize = STATE_WAIT;
|
||||
private String mError;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public DirGalleryProvider(File dir) {
|
||||
mDir = dir;
|
||||
mFiles = mDir.list(new ImageFilter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
mRun = true;
|
||||
new Decoder().start();
|
||||
}
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Can't start it twice");
|
||||
}
|
||||
mStarted = true;
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
mRun = false;
|
||||
synchronized (mRequests) {
|
||||
mRequests.notify();
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
mBgThread = new PriorityThread(this, TAG + '-' + sIdGenerator.incrementAndGet(),
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mBgThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBgThread.interrupt();
|
||||
mBgThread = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return mFiles != null ? mFiles.length : 0;
|
||||
return mSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,69 +95,74 @@ public class DirGalleryProvider extends GalleryProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] ENDS = {
|
||||
".jpg", // Joint Photographic Experts Group
|
||||
".jpeg",
|
||||
".png", // Portable Network Graphics
|
||||
".gif", // Graphics Interchange Format
|
||||
};
|
||||
@Override
|
||||
public String getError() {
|
||||
return mError;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// It may take a long time, so run it in new thread
|
||||
String[] files = mDir.list(new ImageFilter());
|
||||
|
||||
if (files == null) {
|
||||
mSize = STATE_ERROR;
|
||||
mError = GetText.getString(R.string.error_not_folder_path);
|
||||
mBgThread = null;
|
||||
|
||||
// Notify to to show error
|
||||
notifyDataChanged();
|
||||
|
||||
Log.i(TAG, "ImageDecoder end with error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort it
|
||||
Arrays.sort(files);
|
||||
|
||||
// Set state normal and notify
|
||||
mSize = files.length;
|
||||
notifyDataChanged();
|
||||
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
int index;
|
||||
synchronized (mRequests) {
|
||||
if (mRequests.isEmpty()) {
|
||||
try {
|
||||
mRequests.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Interrupted
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
index = mRequests.pop();
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream is = new FileInputStream(new File(mDir, files[index]));
|
||||
Image image = Image.decode(is, false);
|
||||
if (image != null) {
|
||||
notifyPageSucceed(index, image);
|
||||
} else {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_decoding_failed));
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_not_found));
|
||||
}
|
||||
}
|
||||
|
||||
// Clear
|
||||
mBgThread = null;
|
||||
|
||||
Log.i(TAG, "ImageDecoder end");
|
||||
}
|
||||
|
||||
private static class ImageFilter implements FilenameFilter {
|
||||
|
||||
private static boolean endsWith(String str, String[] ends) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0, n = ends.length; i < n; i++) {
|
||||
if (str.endsWith(ends[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File dir, String filename) {
|
||||
return endsWith(filename.toLowerCase(), ENDS);
|
||||
}
|
||||
}
|
||||
|
||||
private class Decoder extends Thread {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
|
||||
while (mRun) {
|
||||
int index;
|
||||
synchronized (mRequests) {
|
||||
if (mRequests.isEmpty()) {
|
||||
try {
|
||||
mRequests.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
continue;
|
||||
}
|
||||
index = mRequests.pop();
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream is = new FileInputStream(new File(mDir, mFiles[index]));
|
||||
Image image = Image.decode(is, false);
|
||||
if (image != null) {
|
||||
notifyPageSucceed(index, image);
|
||||
} else {
|
||||
notifyPageFailed(index, new Exception("Decode error"));
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
notifyPageFailed(index, e);
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "ImageDecoder end");
|
||||
return StringUtils.endsWith(filename.toLowerCase(), SUPPORT_IMAGE_EXTENSIONS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer.gallery;
|
||||
|
||||
public class EhGalleryProvider extends GalleryProvider {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int request(int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getError() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -30,15 +30,22 @@ import java.util.List;
|
||||
|
||||
public abstract class GalleryProvider {
|
||||
|
||||
@IntDef({RESULT_FAILED, RESULT_WAIT, RESULT_ERROR})
|
||||
@IntDef({RESULT_WAIT, RESULT_ERROR})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Result {}
|
||||
|
||||
public static final int RESULT_FAILED = 0;
|
||||
public static final int RESULT_WAIT = 1;
|
||||
public static final int RESULT_ERROR = 2;
|
||||
public static final int RESULT_WAIT = 0;
|
||||
public static final int RESULT_ERROR = 1;
|
||||
|
||||
public static final int SIZE_WAIT = -1;
|
||||
public static final int STATE_WAIT = -1;
|
||||
public static final int STATE_ERROR = -2;
|
||||
|
||||
public static final String[] SUPPORT_IMAGE_EXTENSIONS = {
|
||||
".jpg", // Joint Photographic Experts Group
|
||||
".jpeg",
|
||||
".png", // Portable Network Graphics
|
||||
".gif", // Graphics Interchange Format
|
||||
};
|
||||
|
||||
private List<GalleryProviderListener> mGalleryProviderListeners = new ArrayList<>(2);
|
||||
private Pool<NotifyTask> mNotifyTaskPool = new Pool<>(5);
|
||||
@@ -49,13 +56,15 @@ public abstract class GalleryProvider {
|
||||
public abstract void stop();
|
||||
|
||||
/**
|
||||
* @return {@link #SIZE_WAIT} for wait, 0 for empty
|
||||
* @return {@link #STATE_WAIT} for wait, 0 for empty
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
@Result
|
||||
public abstract int request(int index);
|
||||
|
||||
public abstract String getError();
|
||||
|
||||
public void addGalleryProviderListener(GalleryProviderListener listener) {
|
||||
mGalleryProviderListeners.add(listener);
|
||||
}
|
||||
@@ -64,36 +73,41 @@ public abstract class GalleryProvider {
|
||||
mGalleryProviderListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
notify(NotifyTask.TYPE_DATA_CHANGED, 0, 0.0f, null, null);
|
||||
}
|
||||
|
||||
public void notifyPagePercent(int index, float percent) {
|
||||
notifyPage(NotifyTask.TYPE_PERCENT, index, percent, null, null);
|
||||
notify(NotifyTask.TYPE_PERCENT, index, percent, null, null);
|
||||
}
|
||||
|
||||
public void notifyPageSucceed(int index, Image image) {
|
||||
notifyPage(NotifyTask.TYPE_SUCCEED, index, 0.0f, image, null);
|
||||
notify(NotifyTask.TYPE_SUCCEED, index, 0.0f, image, null);
|
||||
}
|
||||
|
||||
public void notifyPageFailed(int index, Exception e) {
|
||||
notifyPage(NotifyTask.TYPE_FAILED, index, 0.0f, null, e);
|
||||
public void notifyPageFailed(int index, String error) {
|
||||
notify(NotifyTask.TYPE_FAILED, index, 0.0f, null, error);
|
||||
}
|
||||
|
||||
private void notifyPage(@NotifyTask.Type int type, int index, float percent, Image image, Exception exception) {
|
||||
private void notify(@NotifyTask.Type int type, int index, float percent, Image image, String error) {
|
||||
NotifyTask task = mNotifyTaskPool.pop();
|
||||
if (task == null) {
|
||||
task = new NotifyTask(mGalleryProviderListeners, mNotifyTaskPool);
|
||||
}
|
||||
task.setData(type, index, percent, image, exception);
|
||||
task.setData(type, index, percent, image, error);
|
||||
mHandler.post(task);
|
||||
}
|
||||
|
||||
private static class NotifyTask implements Runnable {
|
||||
|
||||
@IntDef({TYPE_PERCENT, TYPE_SUCCEED, TYPE_FAILED})
|
||||
@IntDef({TYPE_DATA_CHANGED, TYPE_PERCENT, TYPE_SUCCEED, TYPE_FAILED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Type {}
|
||||
|
||||
public static final int TYPE_PERCENT = 0;
|
||||
public static final int TYPE_SUCCEED = 1;
|
||||
public static final int TYPE_FAILED = 2;
|
||||
public static final int TYPE_DATA_CHANGED = 0;
|
||||
public static final int TYPE_PERCENT = 1;
|
||||
public static final int TYPE_SUCCEED = 2;
|
||||
public static final int TYPE_FAILED = 3;
|
||||
|
||||
private List<GalleryProviderListener> mGalleryProviderListeners;
|
||||
private Pool<NotifyTask> mPool;
|
||||
@@ -103,24 +117,29 @@ public abstract class GalleryProvider {
|
||||
private int mIndex;
|
||||
private float mPercent;
|
||||
private Image mImage;
|
||||
private Exception mException;
|
||||
private String mError;
|
||||
|
||||
public NotifyTask(List<GalleryProviderListener> galleryProviderListeners, Pool<NotifyTask> pool) {
|
||||
mGalleryProviderListeners = galleryProviderListeners;
|
||||
mPool = pool;
|
||||
}
|
||||
|
||||
public void setData(@Type int type, int index, float percent, Image image, Exception exception) {
|
||||
public void setData(@Type int type, int index, float percent, Image image, String error) {
|
||||
mType = type;
|
||||
mIndex = index;
|
||||
mPercent = percent;
|
||||
mImage = image;
|
||||
mException = exception;
|
||||
mError = error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
switch (mType) {
|
||||
case TYPE_DATA_CHANGED:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onDataChanged();
|
||||
}
|
||||
break;
|
||||
case TYPE_PERCENT:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onPagePercent(mIndex, mPercent);
|
||||
@@ -133,14 +152,14 @@ public abstract class GalleryProvider {
|
||||
break;
|
||||
case TYPE_FAILED:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onPageFailed(mIndex, mException);
|
||||
mGalleryProviderListeners.get(i).onPageFailed(mIndex, mError);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Clean data
|
||||
mImage = null;
|
||||
mException = null;
|
||||
mError = null;
|
||||
// Push back
|
||||
mPool.push(this);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@ import com.hippo.image.Image;
|
||||
|
||||
public interface GalleryProviderListener {
|
||||
|
||||
void onDataChanged();
|
||||
|
||||
void onPagePercent(int index, float percent);
|
||||
|
||||
void onPageSucceed(int index, Image image);
|
||||
|
||||
void onPageFailed(int index, Exception e);
|
||||
void onPageFailed(int index, String error);
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer.gallery;
|
||||
|
||||
import android.os.Process;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hippo.ehviewer.GetText;
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.image.Image;
|
||||
import com.hippo.yorozuya.PriorityThread;
|
||||
import com.hippo.yorozuya.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
|
||||
private static final String TAG = ZipGalleryProvider.class.getSimpleName();
|
||||
private static final AtomicInteger sIdGenerator = new AtomicInteger();
|
||||
|
||||
private final File mFile;
|
||||
private final Stack<Integer> mRequests = new Stack<>();
|
||||
@Nullable
|
||||
private Thread mBgThread;
|
||||
private volatile int mSize = STATE_WAIT;
|
||||
private String mError;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public ZipGalleryProvider(File file) {
|
||||
mFile = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Can't start it twice");
|
||||
}
|
||||
mStarted = true;
|
||||
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
mBgThread = new PriorityThread(this, TAG + '-' + sIdGenerator.incrementAndGet(),
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mBgThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBgThread.interrupt();
|
||||
mBgThread = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int request(int index) {
|
||||
if (index < 0 || index >= mSize) {
|
||||
return RESULT_ERROR;
|
||||
} else {
|
||||
synchronized (mRequests) {
|
||||
mRequests.add(index);
|
||||
mRequests.notify();
|
||||
}
|
||||
return RESULT_WAIT;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getError() {
|
||||
return mError;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ZipFile zipFile = null;
|
||||
try {
|
||||
zipFile = new ZipFile(mFile);
|
||||
} catch (ZipException e) {
|
||||
mError = GetText.getString(R.string.error_invalid_zip_file);
|
||||
} catch (FileNotFoundException e) {
|
||||
mError = GetText.getString(R.string.error_not_found);
|
||||
} catch (IOException e) {
|
||||
mError = GetText.getString(R.string.error_reading_failed);
|
||||
}
|
||||
|
||||
// Check zip file null
|
||||
if (zipFile == null) {
|
||||
mSize = STATE_ERROR;
|
||||
if (mError == null) {
|
||||
mError = GetText.getString(R.string.error_unknown);
|
||||
}
|
||||
mBgThread = null;
|
||||
|
||||
// Notify to to show error
|
||||
notifyDataChanged();
|
||||
|
||||
Log.i(TAG, "ImageDecoder end with error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all image name
|
||||
List<String> filenames = new ArrayList<>(zipFile.size());
|
||||
Enumeration<? extends ZipEntry> enumeration = zipFile.entries();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
ZipEntry zipEntry = enumeration.nextElement();
|
||||
String filename = zipEntry.getName();
|
||||
if (!zipEntry.isDirectory() && StringUtils.endsWith(filename, SUPPORT_IMAGE_EXTENSIONS)) {
|
||||
filenames.add(filename);
|
||||
}
|
||||
}
|
||||
Collections.sort(filenames);
|
||||
|
||||
// Update size and notify changed
|
||||
mSize = filenames.size();
|
||||
notifyDataChanged();
|
||||
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
int index;
|
||||
synchronized (mRequests) {
|
||||
if (mRequests.isEmpty()) {
|
||||
try {
|
||||
mRequests.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Interrupted
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
index = mRequests.pop();
|
||||
}
|
||||
|
||||
try {
|
||||
ZipEntry zipEntry = zipFile.getEntry(filenames.get(index));
|
||||
if (zipEntry != null) {
|
||||
InputStream is = zipFile.getInputStream(zipEntry);
|
||||
Image image = Image.decode(is, false);
|
||||
if (image != null) {
|
||||
notifyPageSucceed(index, image);
|
||||
} else {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_decoding_failed));
|
||||
}
|
||||
} else {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_reading_failed));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_reading_failed));
|
||||
}
|
||||
}
|
||||
|
||||
// Clear
|
||||
try {
|
||||
zipFile.close();
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
mBgThread = null;
|
||||
|
||||
Log.i(TAG, "ImageDecoder end");
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.hippo.ehviewer.gallery.gl;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.hippo.gl.glrenderer.BasicTexture;
|
||||
import com.hippo.gl.glrenderer.ImageTexture;
|
||||
import com.hippo.gl.glrenderer.MovableTextTexture;
|
||||
@@ -27,9 +29,11 @@ import com.hippo.gl.widget.GLMovableTextView;
|
||||
import com.hippo.gl.widget.GLProgressView;
|
||||
import com.hippo.gl.widget.GLTextureView;
|
||||
import com.hippo.image.Image;
|
||||
import com.hippo.yorozuya.LayoutUtils;
|
||||
|
||||
public class GalleryPageView extends GLFrameLayout {
|
||||
|
||||
private static final int INFO_INTERVAL = 24;
|
||||
public static final float PROGRESS_GONE = -1.0f;
|
||||
public static final float PROGRESS_INDETERMINATE = -2.0f;
|
||||
|
||||
@@ -39,7 +43,7 @@ public class GalleryPageView extends GLFrameLayout {
|
||||
private GLTextureView mError;
|
||||
private GLProgressView mProgress;
|
||||
|
||||
public GalleryPageView(MovableTextTexture pageTextTexture,
|
||||
public GalleryPageView(Context context, MovableTextTexture pageTextTexture,
|
||||
int progressColor, int progressSize) {
|
||||
// Add image
|
||||
mImage = new ImageView();
|
||||
@@ -50,6 +54,7 @@ public class GalleryPageView extends GLFrameLayout {
|
||||
// Add other panel
|
||||
mInfo = new GLLinearLayout();
|
||||
mInfo.setOrientation(GLLinearLayout.VERTICAL);
|
||||
mInfo.setInterval(LayoutUtils.dp2pix(context, INFO_INTERVAL));
|
||||
glp = new GravityLayoutParams(LayoutParams.WRAP_CONTENT,
|
||||
LayoutParams.WRAP_CONTENT);
|
||||
glp.gravity = Gravity.CENTER;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.hippo.ehviewer.gallery.gl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
@@ -144,8 +143,8 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
mLayoutMode = layoutMode;
|
||||
mProgressColor = ResourcesUtils.getAttrColor(context, R.attr.colorPrimary);
|
||||
mProgressSize = LayoutUtils.dp2pix(context, PROGRESS_SIZE_IN_DP);
|
||||
mErrorSize = context.getResources().getDimension(R.dimen.text_medium);
|
||||
mErrorColor = Color.RED;
|
||||
mErrorSize = context.getResources().getDimension(R.dimen.text_large);
|
||||
mErrorColor = context.getResources().getColor(R.color.red_500);
|
||||
mPageMinHeight = LayoutUtils.dp2pix(context, PAGE_MIN_HEIGHT_IN_DP);
|
||||
mInterval = LayoutUtils.dp2pix(context, INTERVAL_IN_DP);
|
||||
|
||||
@@ -154,7 +153,7 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
|
||||
private void ensurePagerLayoutManager() {
|
||||
if (mPagerLayoutManager == null) {
|
||||
mPagerLayoutManager = new PagerLayoutManager(mContext, this, mInterval);
|
||||
mPagerLayoutManager = new PagerLayoutManager(mContext, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +435,7 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
public GalleryPageView obtainPage() {
|
||||
GalleryPageView page = mRecycler.obtain();
|
||||
if (page == null) {
|
||||
page = new GalleryPageView(mPageTextTexture, mProgressColor, mProgressSize);
|
||||
page = new GalleryPageView(mContext, mPageTextTexture, mProgressColor, mProgressSize);
|
||||
page.setMinimumHeight(mPageMinHeight);
|
||||
}
|
||||
return page;
|
||||
@@ -523,12 +522,16 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
|
||||
public abstract void reset();
|
||||
|
||||
public abstract boolean isBusy();
|
||||
/**
|
||||
* @return True for waiting now, layout manager
|
||||
* should show a progress bar or something like it
|
||||
*/
|
||||
public abstract boolean isWaiting();
|
||||
|
||||
/**
|
||||
* Null for no error
|
||||
* @return Null for no error
|
||||
*/
|
||||
public abstract String isError();
|
||||
public abstract String getError();
|
||||
|
||||
public abstract boolean hasNext();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.hippo.gl.widget.GLEdgeView;
|
||||
import com.hippo.gl.widget.GLProgressView;
|
||||
import com.hippo.gl.widget.GLTextureView;
|
||||
import com.hippo.yorozuya.AssertUtils;
|
||||
import com.hippo.yorozuya.LayoutUtils;
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -43,6 +44,8 @@ public class PagerLayoutManager extends GalleryView.LayoutManager {
|
||||
public static final int MODE_LEFT_TO_RIGHT = 0;
|
||||
public static final int MODE_RIGHT_TO_LEFT = 1;
|
||||
|
||||
private static final int INTERVAL = 48;
|
||||
|
||||
private static final Interpolator SMOOTH_SCROLLER_INTERPOLATOR = new Interpolator() {
|
||||
@Override
|
||||
public float getInterpolation(float t) {
|
||||
@@ -76,10 +79,9 @@ public class PagerLayoutManager extends GalleryView.LayoutManager {
|
||||
private SmoothScroller mSmoothScroller;
|
||||
private SmoothScaler mSmoothScaler;
|
||||
|
||||
public PagerLayoutManager(Context context, @NonNull GalleryView galleryView,
|
||||
int interval) {
|
||||
public PagerLayoutManager(Context context, @NonNull GalleryView galleryView) {
|
||||
super(galleryView);
|
||||
mInterval = interval;
|
||||
mInterval = LayoutUtils.dp2pix(context, INTERVAL);
|
||||
|
||||
mPageFling = new PageFling(context);
|
||||
mSmoothScroller = new SmoothScroller();
|
||||
@@ -239,7 +241,7 @@ public class PagerLayoutManager extends GalleryView.LayoutManager {
|
||||
|
||||
int width = galleryView.getWidth();
|
||||
int height = galleryView.getHeight();
|
||||
String errorStr = iterator.isError();
|
||||
String errorStr = iterator.getError();
|
||||
|
||||
if (errorStr != null) {
|
||||
// Remove progress and all pages
|
||||
@@ -260,7 +262,7 @@ public class PagerLayoutManager extends GalleryView.LayoutManager {
|
||||
|
||||
// Place error view center
|
||||
placeCenter(mErrorView);
|
||||
} else if (iterator.isBusy()) {
|
||||
} else if (iterator.isWaiting()) {
|
||||
// Remove error view and all pages
|
||||
removeErrorView();
|
||||
removeAllPages();
|
||||
|
||||
@@ -138,7 +138,7 @@ public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
|
||||
int width = galleryView.getWidth();
|
||||
int height = galleryView.getHeight();
|
||||
String errorStr = iterator.isError();
|
||||
String errorStr = iterator.getError();
|
||||
|
||||
if (errorStr != null) {
|
||||
// Remove progress and all pages
|
||||
@@ -159,7 +159,7 @@ public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
|
||||
// Place error view center
|
||||
placeCenter(mErrorView);
|
||||
} else if (iterator.isBusy()) {
|
||||
} else if (iterator.isWaiting()) {
|
||||
// Remove error view and all pages
|
||||
removeErrorView();
|
||||
removeAllPages();
|
||||
@@ -177,6 +177,12 @@ public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
removeProgress();
|
||||
removeErrorView();
|
||||
|
||||
|
||||
// TODO ensure first shown
|
||||
|
||||
|
||||
|
||||
|
||||
int minY = (int) (-height * RESERVATIONS);
|
||||
|
||||
// Remove useless top view
|
||||
@@ -281,6 +287,10 @@ public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
}
|
||||
iterator.reset();
|
||||
|
||||
|
||||
// TODO Avoid page not fill bottom, but has previous
|
||||
|
||||
|
||||
// Remove useless page
|
||||
while (mPages.size() > pageSize) {
|
||||
GalleryPageView page = mPages.removeLast();
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
package com.hippo.ehviewer.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -28,6 +29,7 @@ import com.hippo.ehviewer.R;
|
||||
import com.hippo.ehviewer.gallery.DirGalleryProvider;
|
||||
import com.hippo.ehviewer.gallery.GalleryProvider;
|
||||
import com.hippo.ehviewer.gallery.GalleryProviderListener;
|
||||
import com.hippo.ehviewer.gallery.ZipGalleryProvider;
|
||||
import com.hippo.ehviewer.gallery.gl.GalleryPageView;
|
||||
import com.hippo.ehviewer.gallery.gl.GalleryView;
|
||||
import com.hippo.gl.glrenderer.ImageTexture;
|
||||
@@ -41,6 +43,20 @@ import java.io.File;
|
||||
|
||||
public class GalleryActivity extends AppCompatActivity implements GalleryProviderListener {
|
||||
|
||||
public static final String ACTION_DIR = "dir";
|
||||
public static final String ACTION_ZIP = "zip";
|
||||
public static final String ACTION_EH = "eh";
|
||||
|
||||
public static final String KEY_ACTION = "action";
|
||||
public static final String KEY_FILENAME = "filename";
|
||||
public static final String KEY_GID = "gid";
|
||||
public static final String KEY_TOKEN = "token";
|
||||
|
||||
private String mAction;
|
||||
private String mFilename;
|
||||
private int mGid;
|
||||
private String mToken;
|
||||
|
||||
@Nullable
|
||||
private GalleryView mGalleryView;
|
||||
|
||||
@@ -53,26 +69,82 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
@Nullable
|
||||
private SparseIntArray mIndexIdMap;
|
||||
|
||||
private void buildProvider() {
|
||||
if (mGalleryProvider != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ACTION_DIR.equals(mAction)) {
|
||||
if (mFilename != null) {
|
||||
mGalleryProvider = new DirGalleryProvider(new File(mFilename));
|
||||
}
|
||||
} else if (ACTION_ZIP.equals(mAction)) {
|
||||
if (mFilename != null) {
|
||||
mGalleryProvider = new ZipGalleryProvider(new File(mFilename));
|
||||
}
|
||||
} else if (ACTION_EH.equals(mAction)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void onInit() {
|
||||
Intent intent = getIntent();
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAction = intent.getAction();
|
||||
mFilename = intent.getStringExtra(KEY_FILENAME);
|
||||
mGid = intent.getIntExtra(KEY_GID, -1);
|
||||
mToken = intent.getStringExtra(KEY_TOKEN);
|
||||
buildProvider();
|
||||
}
|
||||
|
||||
private void onRestore(@NonNull Bundle savedInstanceState) {
|
||||
mAction = savedInstanceState.getString(KEY_ACTION);
|
||||
mFilename = savedInstanceState.getString(KEY_FILENAME);
|
||||
mGid = savedInstanceState.getInt(KEY_GID, -1);
|
||||
mToken = savedInstanceState.getString(KEY_TOKEN);
|
||||
buildProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(KEY_ACTION, mAction);
|
||||
outState.putString(KEY_FILENAME, mFilename);
|
||||
outState.putInt(KEY_GID, mGid);
|
||||
outState.putString(KEY_TOKEN, mToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_gallery);
|
||||
GLRootView glRootView = (GLRootView) findViewById(R.id.gl_root_view);
|
||||
if (savedInstanceState == null) {
|
||||
onInit();
|
||||
} else {
|
||||
onRestore(savedInstanceState);
|
||||
}
|
||||
|
||||
mUploader = new ImageTexture.Uploader(glRootView);
|
||||
mIndexIdMap = new SparseIntArray();
|
||||
mGalleryProvider = new DirGalleryProvider(new File(Environment.getExternalStorageDirectory(), "nmb/image"));
|
||||
if (mGalleryProvider == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
mGalleryProvider.addGalleryProviderListener(this);
|
||||
mGalleryProvider.start();
|
||||
|
||||
setContentView(R.layout.activity_gallery);
|
||||
GLRootView glRootView = (GLRootView) findViewById(R.id.gl_root_view);
|
||||
mUploader = new ImageTexture.Uploader(glRootView);
|
||||
mIndexIdMap = new SparseIntArray();
|
||||
mPageTextTexture = MovableTextTexture.create(Typeface.DEFAULT,
|
||||
getResources().getDimensionPixelSize(R.dimen.gallery_page_text),
|
||||
getResources().getColor(R.color.secondary_text_dark),
|
||||
new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'});
|
||||
|
||||
mGalleryView = new GalleryView(this, new GalleryPageIterator(),
|
||||
mPageTextTexture, null, GalleryView.LAYOUT_MODE_LEFT_TO_RIGHT);
|
||||
mPageTextTexture, null, GalleryView.LAYOUT_MODE_RIGHT_TO_LEFT);
|
||||
glRootView.setContentPane(mGalleryView);
|
||||
}
|
||||
|
||||
@@ -182,6 +254,13 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
return mGalleryView.findPageById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataChanged() {
|
||||
if (mGalleryView != null) {
|
||||
mGalleryView.onDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPagePercent(int index, float percent) {
|
||||
GalleryPageView page = findPageByIndex(index);
|
||||
@@ -203,18 +282,20 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
page.setPage(index + 1);
|
||||
page.setProgress(GalleryPageView.PROGRESS_GONE);
|
||||
page.setError(null, null);
|
||||
} else {
|
||||
image.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFailed(int index, Exception e) {
|
||||
public void onPageFailed(int index, String error) {
|
||||
GalleryPageView page = findPageByIndex(index);
|
||||
if (page != null && mGalleryView != null) {
|
||||
page.showInfo();
|
||||
page.setImage(null);
|
||||
page.setPage(index + 1);
|
||||
page.setProgress(GalleryPageView.PROGRESS_GONE);
|
||||
page.setError("Error", mGalleryView);
|
||||
page.setError(error, mGalleryView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,20 +316,23 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
return mGalleryProvider == null ||
|
||||
mGalleryProvider.size() == GalleryProvider.SIZE_WAIT;
|
||||
public boolean isWaiting() {
|
||||
return mGalleryProvider != null && mGalleryProvider.size() == GalleryProvider.STATE_WAIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String isError() {
|
||||
if (mGalleryProvider != null) {
|
||||
int size = mGalleryProvider.size();
|
||||
if (size == 0) {
|
||||
return "Empty Gallery"; // TODO hardcode
|
||||
} else if (size < 0 && size != GalleryProvider.SIZE_WAIT) {
|
||||
return "Weird"; // TODO hardcode
|
||||
public String getError() {
|
||||
if (mGalleryProvider == null) {
|
||||
return getString(R.string.error_no_provider);
|
||||
} else if (mGalleryProvider.size() == GalleryProvider.STATE_ERROR) {
|
||||
String error = mGalleryProvider.getError();
|
||||
if (error != null) {
|
||||
return error;
|
||||
} else {
|
||||
return getString(R.string.error_unknown);
|
||||
}
|
||||
} else if (mGalleryProvider.size() == 0) {
|
||||
return getString(R.string.error_empty);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -282,29 +366,12 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
@Override
|
||||
public int onBind(GalleryPageView view) {
|
||||
if (mGalleryProvider != null && mGalleryView != null) {
|
||||
switch (mGalleryProvider.request(mIndex)) {
|
||||
case GalleryProvider.RESULT_WAIT:
|
||||
view.showInfo();
|
||||
view.setImage(null);
|
||||
view.setPage(mIndex + 1);
|
||||
view.setProgress(GalleryPageView.PROGRESS_INDETERMINATE);
|
||||
view.setError(null, null);
|
||||
break;
|
||||
case GalleryProvider.RESULT_FAILED:
|
||||
view.showInfo();
|
||||
view.setImage(null);
|
||||
view.setPage(mIndex + 1);
|
||||
view.setProgress(GalleryPageView.PROGRESS_GONE);
|
||||
view.setError("Failed", mGalleryView);
|
||||
break;
|
||||
case GalleryProvider.RESULT_ERROR:
|
||||
view.showInfo();
|
||||
view.setImage(null);
|
||||
view.setPage(mIndex + 1);
|
||||
view.setProgress(GalleryPageView.PROGRESS_GONE);
|
||||
view.setError("Error", mGalleryView);
|
||||
break;
|
||||
}
|
||||
mGalleryProvider.request(mIndex);
|
||||
view.showInfo();
|
||||
view.setImage(null);
|
||||
view.setPage(mIndex + 1);
|
||||
view.setProgress(GalleryPageView.PROGRESS_INDETERMINATE);
|
||||
view.setError(null, null);
|
||||
}
|
||||
|
||||
int id = mIdGenerator.nextId();
|
||||
|
||||
@@ -128,6 +128,8 @@ public final class MainActivity extends StageActivity
|
||||
private void onRestore(Bundle savedInstanceState) {
|
||||
Log.d("TAG", "onRestore");
|
||||
|
||||
Log.d("TAG", "action = " + getIntent().getAction());
|
||||
|
||||
mNavCheckedItem = savedInstanceState.getInt(KEY_NAV_CHECKED_ITEM);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,9 @@ public class GalleryPreviewsScene extends ToolbarScene {
|
||||
public final static String KEY_HAS_FIRST_REFRESH = "has_first_refresh";
|
||||
|
||||
private EhClient mClient;
|
||||
@Nullable
|
||||
private GalleryPreviewAdapter mAdapter;
|
||||
@Nullable
|
||||
private GalleryPreviewHelper mHelper;
|
||||
private int mGid = -1;
|
||||
private String mToken = null;
|
||||
@@ -169,6 +171,9 @@ public class GalleryPreviewsScene extends ToolbarScene {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_go_to:
|
||||
if (mHelper == null) {
|
||||
return true;
|
||||
}
|
||||
int pages = mHelper.getPages();
|
||||
if (pages > 0 && mHelper.canGoTo()) {
|
||||
GoToDialogHelper helper = new GoToDialogHelper(pages, mHelper.getPageForTop());
|
||||
@@ -211,14 +216,16 @@ public class GalleryPreviewsScene extends ToolbarScene {
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(GalleryPreviewHolder holder, int position) {
|
||||
GalleryPreview preview = mHelper.getDataAt(position);
|
||||
holder.image.load(EhCacheKeyFactory.getLargePreviewKey(mGid, preview.index), preview.imageUrl);
|
||||
holder.text.setText(String.format(Locale.US, "%d", preview.index + 1));
|
||||
if (mHelper != null) {
|
||||
GalleryPreview preview = mHelper.getDataAt(position);
|
||||
holder.image.load(EhCacheKeyFactory.getLargePreviewKey(mGid, preview.index), preview.imageUrl);
|
||||
holder.text.setText(String.format(Locale.US, "%d", preview.index + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mHelper.size();
|
||||
return mHelper != null ? mHelper.size() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,17 +267,23 @@ public class GalleryPreviewsScene extends ToolbarScene {
|
||||
|
||||
@Override
|
||||
protected void notifyDataSetChanged() {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
if (mAdapter != null) {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyItemRangeRemoved(int positionStart, int itemCount) {
|
||||
mAdapter.notifyItemRangeRemoved(positionStart, itemCount);
|
||||
if (mAdapter != null) {
|
||||
mAdapter.notifyItemRangeRemoved(positionStart, itemCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyItemRangeInserted(int positionStart, int itemCount) {
|
||||
mAdapter.notifyItemRangeInserted(positionStart, itemCount);
|
||||
if (mAdapter != null) {
|
||||
mAdapter.notifyItemRangeInserted(positionStart, itemCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +389,7 @@ public class GalleryPreviewsScene extends ToolbarScene {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int page = mSlider.getProgress() - 1;
|
||||
if (page >= 0 && page < mPages) {
|
||||
if (page >= 0 && page < mPages && mHelper != null) {
|
||||
mHelper.goTo(page);
|
||||
if (mDialog != null) {
|
||||
mDialog.dismiss();
|
||||
|
||||
@@ -52,7 +52,7 @@ import java.util.ArrayList;
|
||||
public class GLView implements TouchOwner {
|
||||
private static final String TAG = "GLView";
|
||||
|
||||
private static final boolean DEBUG_DRAW_BOUNDS = true;
|
||||
private static final boolean DEBUG_DRAW_BOUNDS = false;
|
||||
|
||||
@IntDef({VISIBLE, INVISIBLE, GONE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
|
||||
Reference in new issue
Block a user