Ensure first shown loaded page top is the same in ScrollLayoutManager
This commit is contained in:
1 parent
383fc3b227
commit
77f7840cf6
3 files changed
+176
-147
No files matched your search
@@ -154,4 +154,8 @@ public class GalleryPageView extends GLFrameLayout {
|
||||
public ImageView getImageView() {
|
||||
return mImage;
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return mImage.getVisibility() == VISIBLE;
|
||||
}
|
||||
}
|
||||
@@ -201,6 +201,36 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
mLayoutManager = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
// Do not need requestLayout, because the size will not change
|
||||
requestFill();
|
||||
}
|
||||
|
||||
public void requestFill() {
|
||||
if (mEnableRequestFill) {
|
||||
mRequestFill = true;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean dispatchTouchEvent(MotionEvent event) {
|
||||
// Do not pass event to component, so handle event here
|
||||
mGestureRecognizer.onTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
GLEdgeView getEdgeView() {
|
||||
return mEdgeView;
|
||||
}
|
||||
|
||||
public boolean isFirstScroll() {
|
||||
boolean firstScroll = mFirstScroll;
|
||||
mFirstScroll = false;
|
||||
return firstScroll;
|
||||
}
|
||||
|
||||
public void setLayoutMode(@LayoutMode int layoutMode) {
|
||||
if (mLayoutMode == layoutMode) {
|
||||
return;
|
||||
@@ -242,26 +272,6 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
// Do not need requestLayout, because the size will not change
|
||||
requestFill();
|
||||
}
|
||||
|
||||
public void requestFill() {
|
||||
if (mEnableRequestFill) {
|
||||
mRequestFill = true;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean dispatchTouchEvent(MotionEvent event) {
|
||||
// Do not pass event to component, so handle event here
|
||||
mGestureRecognizer.onTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(float x, float y) {
|
||||
return true;
|
||||
@@ -289,16 +299,6 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
return true;
|
||||
}
|
||||
|
||||
GLEdgeView getEdgeView() {
|
||||
return mEdgeView;
|
||||
}
|
||||
|
||||
public boolean isFirstScroll() {
|
||||
boolean firstScroll = mFirstScroll;
|
||||
mFirstScroll = false;
|
||||
return firstScroll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(float dx, float dy, float totalX, float totalY, float x, float y) {
|
||||
if (mScale) {
|
||||
@@ -377,7 +377,6 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changeSize, int left, int top, int right, int bottom) {
|
||||
|
||||
mEdgeView.layout(left, top, right, bottom);
|
||||
|
||||
fill();
|
||||
@@ -504,7 +503,10 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
mErrorViewCache = errorView;
|
||||
}
|
||||
|
||||
@RenderThread
|
||||
public void onDataChanged() {
|
||||
GalleryUtils.assertInRenderThread();
|
||||
|
||||
if (mLayoutManager != null){
|
||||
mLayoutManager.onDataChanged();
|
||||
}
|
||||
@@ -553,10 +555,6 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
public abstract int onBind(GalleryPageView view);
|
||||
|
||||
public abstract void onUnbind(GalleryPageView view);
|
||||
|
||||
public void notifyDataChanged() {
|
||||
mGalleryView.onDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class LayoutManager {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.hippo.ehviewer.gallery.gl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
@@ -131,13 +132,129 @@ public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
return iterator;
|
||||
}
|
||||
|
||||
private void fillPages() {
|
||||
GalleryView.PageIterator iterator = mIterator;
|
||||
GalleryView galleryView = mGalleryView;
|
||||
int width = galleryView.getWidth();
|
||||
int height = galleryView.getHeight();
|
||||
|
||||
int minY = (int) (-height * RESERVATIONS);
|
||||
|
||||
// Remove useless top view
|
||||
Iterator<GalleryPageView> pages = mPages.iterator();
|
||||
int nextTop = mOffset;
|
||||
while (pages.hasNext()) {
|
||||
GalleryPageView page = pages.next();
|
||||
nextTop += page.getHeight() + mInterval;
|
||||
if (nextTop < minY) {
|
||||
removePage(page);
|
||||
pages.remove();
|
||||
// Update offset
|
||||
mOffset = nextTop;
|
||||
if (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
} else {
|
||||
Log.e(TAG, "iterator should has next");
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill missing top
|
||||
int oldOffset = mOffset;
|
||||
int y = oldOffset;
|
||||
int widthSpec = GLView.MeasureSpec.makeMeasureSpec(width, GLView.MeasureSpec.EXACTLY);
|
||||
int heightSpec = GLView.MeasureSpec.makeMeasureSpec(height, GLView.MeasureSpec.UNSPECIFIED);
|
||||
int pageSize = 0;
|
||||
while (y >= minY && iterator.hasPrevious()) {
|
||||
iterator.previous();
|
||||
|
||||
GalleryPageView page = galleryView.obtainPage();
|
||||
iterator.bind(page);
|
||||
galleryView.addComponent(page);
|
||||
mPages.add(0, page);
|
||||
|
||||
// Add interval
|
||||
y -= mInterval;
|
||||
|
||||
// Measure and layout
|
||||
page.measure(widthSpec, heightSpec);
|
||||
page.layout(0, y - page.getMeasuredHeight(), width, y);
|
||||
|
||||
// Update y
|
||||
y -= page.getMeasuredHeight();
|
||||
|
||||
// size increase
|
||||
pageSize++;
|
||||
}
|
||||
mOffset = y;
|
||||
|
||||
// Fill from oldOffset
|
||||
iterator.mark();
|
||||
// Go to oldOffset
|
||||
int maxY = (int) (height * (1 + RESERVATIONS));
|
||||
y = oldOffset;
|
||||
pages = mPages.iterator();
|
||||
for (int i = 0; i < pageSize; i++) {
|
||||
if (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
} else {
|
||||
Log.e(TAG, "iterator should has next");
|
||||
}
|
||||
pages.next();
|
||||
}
|
||||
// Do fill
|
||||
while (true) {
|
||||
GalleryPageView page;
|
||||
if (pages == null || !pages.hasNext()) {
|
||||
pages = null;
|
||||
// New page
|
||||
page = galleryView.obtainPage();
|
||||
iterator.bind(page);
|
||||
galleryView.addComponent(page);
|
||||
mPages.add(page);
|
||||
} else {
|
||||
page = pages.next();
|
||||
}
|
||||
|
||||
// Measure and layout
|
||||
page.measure(widthSpec, heightSpec);
|
||||
page.layout(0, y, width, y + page.getMeasuredHeight());
|
||||
|
||||
// size increase
|
||||
pageSize++;
|
||||
|
||||
// Update y and check out of range
|
||||
y += page.getMeasuredHeight();
|
||||
if (y > maxY) {
|
||||
break;
|
||||
}
|
||||
|
||||
y += mInterval;
|
||||
|
||||
// Check has next
|
||||
if (!iterator.hasNext()) {
|
||||
break;
|
||||
}
|
||||
|
||||
iterator.next();
|
||||
}
|
||||
iterator.reset();
|
||||
|
||||
// Remove useless page
|
||||
while (mPages.size() > pageSize) {
|
||||
GalleryPageView page = mPages.removeLast();
|
||||
removePage(page);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onFill() {
|
||||
GalleryView.PageIterator iterator = mIterator;
|
||||
GalleryView galleryView = mGalleryView;
|
||||
AssertUtils.assertNotEquals("The PagerLayoutManager is not attached", iterator, null);
|
||||
|
||||
int width = galleryView.getWidth();
|
||||
int height = galleryView.getHeight();
|
||||
String errorStr = iterator.getError();
|
||||
|
||||
@@ -178,124 +295,34 @@ public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
removeProgress();
|
||||
removeErrorView();
|
||||
|
||||
|
||||
// TODO ensure first shown
|
||||
|
||||
|
||||
|
||||
|
||||
int minY = (int) (-height * RESERVATIONS);
|
||||
|
||||
// Remove useless top view
|
||||
Iterator<GalleryPageView> pages = mPages.iterator();
|
||||
int nextTop = mOffset;
|
||||
while (pages.hasNext()) {
|
||||
GalleryPageView page = pages.next();
|
||||
nextTop += page.getHeight() + mInterval;
|
||||
if (nextTop < minY) {
|
||||
removePage(page);
|
||||
pages.remove();
|
||||
// Update offset
|
||||
mOffset = nextTop;
|
||||
if (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
} else {
|
||||
Log.e(TAG, "iterator should has next");
|
||||
// Find first shown loaded page
|
||||
GalleryPageView firstShownLoadedPage = null;
|
||||
int firstShownLoadedPageTop = mOffset;
|
||||
for (GalleryPageView page : mPages) {
|
||||
// Check first shown loaded page
|
||||
if (page.isLoaded()) {
|
||||
Rect bound = page.bounds();
|
||||
int pageTop = bound.top;
|
||||
int pageBottom = bound.bottom;
|
||||
if ((pageTop > 0 && pageTop < height) || (pageBottom > 0 && pageBottom < height)) {
|
||||
firstShownLoadedPage = page;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
firstShownLoadedPageTop += page.getHeight() + mInterval;
|
||||
}
|
||||
|
||||
// Fill missing top
|
||||
int oldOffset = mOffset;
|
||||
int y = oldOffset;
|
||||
int widthSpec = GLView.MeasureSpec.makeMeasureSpec(width, GLView.MeasureSpec.EXACTLY);
|
||||
int heightSpec = GLView.MeasureSpec.makeMeasureSpec(height, GLView.MeasureSpec.UNSPECIFIED);
|
||||
int pageSize = 0;
|
||||
while (y >= minY && iterator.hasPrevious()) {
|
||||
iterator.previous();
|
||||
|
||||
GalleryPageView page = galleryView.obtainPage();
|
||||
iterator.bind(page);
|
||||
galleryView.addComponent(page);
|
||||
mPages.add(0, page);
|
||||
|
||||
// Add interval
|
||||
y -= mInterval;
|
||||
|
||||
// Measure and layout
|
||||
page.measure(widthSpec, heightSpec);
|
||||
page.layout(0, y - page.getMeasuredHeight(), width, y);
|
||||
|
||||
// Update y
|
||||
y -= page.getMeasuredHeight();
|
||||
|
||||
// size increase
|
||||
pageSize++;
|
||||
}
|
||||
mOffset = y;
|
||||
|
||||
// Fill from oldOffset
|
||||
iterator.mark();
|
||||
// Go to oldOffset
|
||||
int maxY = (int) (height * (1 + RESERVATIONS));
|
||||
y = oldOffset;
|
||||
pages = mPages.iterator();
|
||||
for (int i = 0; i < pageSize; i++) {
|
||||
if (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
} else {
|
||||
Log.e(TAG, "iterator should has next");
|
||||
}
|
||||
pages.next();
|
||||
}
|
||||
// Do fill
|
||||
while (true) {
|
||||
GalleryPageView page;
|
||||
if (pages == null || !pages.hasNext()) {
|
||||
pages = null;
|
||||
// New page
|
||||
page = galleryView.obtainPage();
|
||||
iterator.bind(page);
|
||||
galleryView.addComponent(page);
|
||||
mPages.add(page);
|
||||
} else {
|
||||
page = pages.next();
|
||||
}
|
||||
|
||||
// Measure and layout
|
||||
page.measure(widthSpec, heightSpec);
|
||||
page.layout(0, y, width, y + page.getMeasuredHeight());
|
||||
|
||||
// size increase
|
||||
pageSize++;
|
||||
|
||||
// Update y and check out of range
|
||||
y += page.getMeasuredHeight();
|
||||
if (y > maxY) {
|
||||
break;
|
||||
}
|
||||
|
||||
y += mInterval;
|
||||
|
||||
// Check has next
|
||||
if (!iterator.hasNext()) {
|
||||
break;
|
||||
}
|
||||
|
||||
iterator.next();
|
||||
}
|
||||
iterator.reset();
|
||||
|
||||
fillPages();
|
||||
|
||||
// TODO Avoid page not fill bottom, but has previous
|
||||
|
||||
|
||||
// Remove useless page
|
||||
while (mPages.size() > pageSize) {
|
||||
GalleryPageView page = mPages.removeLast();
|
||||
removePage(page);
|
||||
// Ensure first shown loaded page top is the same
|
||||
if (firstShownLoadedPage != null && firstShownLoadedPage.isAttachedToRoot()) {
|
||||
int newTop = firstShownLoadedPage.bounds().top;
|
||||
if (firstShownLoadedPageTop != newTop) {
|
||||
mOffset += firstShownLoadedPageTop - newTop;
|
||||
fillPages();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user