Skip to content
This repository was archived by the owner on Dec 1, 2017. It is now read-only.

Fixes for screen orientation changes #214

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/src/main/java/org/lucasr/twowayview/TwoWayLayoutManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public static enum Direction {
END
}

private int mScreenOrientation;

private RecyclerView mRecyclerView;

private boolean mIsVertical = true;
Expand All @@ -63,9 +65,13 @@ public static enum Direction {

public TwoWayLayoutManager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
this.mScreenOrientation = context.getResources().getConfiguration().orientation;
}

public TwoWayLayoutManager(Context context, AttributeSet attrs, int defStyle) {

this.mScreenOrientation = context.getResources().getConfiguration().orientation;

final TypedArray a =
context.obtainStyledAttributes(attrs, R.styleable.twowayview_TwoWayLayoutManager, defStyle, 0);

Expand All @@ -88,6 +94,14 @@ public TwoWayLayoutManager(Orientation orientation) {
mIsVertical = (orientation == Orientation.VERTICAL);
}

public void setScreenOrientation(int orientation) {
this.mScreenOrientation = orientation;
}

public int getScreenOrientation() {
return mScreenOrientation;
}

private int getTotalSpace() {
if (mIsVertical) {
return getHeight() - getPaddingBottom() - getPaddingTop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.LayoutParams;
import android.support.v7.widget.RecyclerView.Recycler;
import android.support.v7.widget.RecyclerView.State;
Expand All @@ -36,6 +35,7 @@
import static org.lucasr.twowayview.widget.Lanes.calculateLaneSize;

public abstract class BaseLayoutManager extends TwoWayLayoutManager {

private static final String LOGTAG = "BaseLayoutManager";

protected static class ItemEntry implements Parcelable {
Expand Down Expand Up @@ -195,6 +195,11 @@ void getDecoratedChildFrame(View child, Rect childFrame) {
childFrame.bottom = getDecoratedBottom(child);
}

@Override
public void setScreenOrientation(int orientation) {
super.setScreenOrientation(orientation);
}

boolean isVertical() {
return (getOrientation() == Orientation.VERTICAL);
}
Expand All @@ -217,6 +222,8 @@ void clearItemEntries() {
if (mItemEntries != null) {
mItemEntries.clear();
}
invalidateItemLanesAfter(0);
ensureLayoutState();
}

void invalidateItemLanesAfter(int position) {
Expand Down Expand Up @@ -334,8 +341,11 @@ public void offsetChildrenVertical(int offset) {

@Override
public void onLayoutChildren(Recycler recycler, State state) {

final boolean restoringLanes = (mLanesToRestore != null);

if (restoringLanes) {

mLanes = mLanesToRestore;
mItemEntries = mItemEntriesToRestore;

Expand All @@ -353,10 +363,6 @@ public void onLayoutChildren(Recycler recycler, State state) {

final int itemCount = state.getItemCount();

if (mItemEntries != null) {
mItemEntries.setAdapterSize(itemCount);
}

final int anchorItemPosition = getAnchorItemPosition(state);

// Only move layout if we're not restoring a layout state.
Expand Down Expand Up @@ -419,6 +425,7 @@ public Parcelable onSaveInstanceState() {
state.lanes[i] = laneRect;
}

state.screenOrientation = getScreenOrientation();
state.orientation = getOrientation();
state.laneSize = (mLanes != null ? mLanes.getLaneSize() : 0);
state.itemEntries = mItemEntries;
Expand All @@ -430,9 +437,14 @@ public Parcelable onSaveInstanceState() {
public void onRestoreInstanceState(Parcelable state) {
final LanedSavedState ss = (LanedSavedState) state;

if (ss.lanes != null && ss.laneSize > 0) {
if (ss.lanes != null && ss.laneSize > 0 && ss.screenOrientation == getScreenOrientation()) {
mLanesToRestore = new Lanes(this, ss.orientation, ss.lanes, ss.laneSize);
mItemEntriesToRestore = ss.itemEntries;
} else {
if(mItemEntries!=null) {
mItemEntries.clear();
}
invalidateItemLanesAfter(0);
}

super.onRestoreInstanceState(ss.getSuperState());
Expand Down Expand Up @@ -567,6 +579,7 @@ public LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
abstract void moveLayoutToPosition(int position, int offset, Recycler recycler, State state);

protected static class LanedSavedState extends SavedState {
private int screenOrientation;
private Orientation orientation;
private Rect[] lanes;
private int laneSize;
Expand All @@ -579,6 +592,7 @@ protected LanedSavedState(Parcelable superState) {
private LanedSavedState(Parcel in) {
super(in);

screenOrientation = in.readInt();
orientation = Orientation.values()[in.readInt()];
laneSize = in.readInt();

Expand Down Expand Up @@ -606,6 +620,7 @@ private LanedSavedState(Parcel in) {
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);

out.writeInt(screenOrientation);
out.writeInt(orientation.ordinal());
out.writeInt(laneSize);

Expand Down Expand Up @@ -637,4 +652,6 @@ public LanedSavedState[] newArray(int size) {
}
};
}


}
107 changes: 39 additions & 68 deletions layouts/src/main/java/org/lucasr/twowayview/widget/ItemEntries.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,112 +22,83 @@
package org.lucasr.twowayview.widget;

import android.util.Log;
import android.util.SparseArray;

import java.util.Arrays;

import org.lucasr.twowayview.widget.BaseLayoutManager.ItemEntry;

class ItemEntries {
private static final int MIN_SIZE = 10;

private ItemEntry[] mItemEntries;
private int mAdapterSize;
private boolean mRestoringItem;

private int sizeForPosition(int position) {
int len = mItemEntries.length;
while (len <= position) {
len *= 2;
}

// We don't apply any constraints while restoring
// item entries.
if (!mRestoringItem && len > mAdapterSize) {
len = mAdapterSize;
}

return len;
}

private void ensureSize(int position) {
if (mItemEntries == null) {
mItemEntries = new ItemEntry[Math.max(position, MIN_SIZE) + 1];
Arrays.fill(mItemEntries, null);
} else if (position >= mItemEntries.length) {
ItemEntry[] oldItemEntries = mItemEntries;
mItemEntries = new ItemEntry[sizeForPosition(position)];
System.arraycopy(oldItemEntries, 0, mItemEntries, 0, oldItemEntries.length);
Arrays.fill(mItemEntries, oldItemEntries.length, mItemEntries.length, null);
}
}
private SparseArray<ItemEntry> mItemEntries = new SparseArray<ItemEntry>();

public ItemEntry getItemEntry(int position) {
if (mItemEntries == null || position >= mItemEntries.length) {
return null;
}

return mItemEntries[position];
return mItemEntries.get(position);
}

public void putItemEntry(int position, ItemEntry entry) {
ensureSize(position);
mItemEntries[position] = entry;
mItemEntries.put(position,entry);
}

public void restoreItemEntry(int position, ItemEntry entry) {
mRestoringItem = true;
putItemEntry(position, entry);
mRestoringItem = false;
}

public int size() {
return (mItemEntries != null ? mItemEntries.length : 0);
}

public void setAdapterSize(int adapterSize) {
mAdapterSize = adapterSize;
/**
* From android.util.SparseArray:
*
* The keys corresponding to indices in ascending order are guaranteed to be in ascending
* order, e.g., keyAt(0) will return the smallest key and keyAt(size()-1) will return the
* largest key.
*/

public int size() {
return (mItemEntries.size()==0 ? 0 : mItemEntries.keyAt(mItemEntries.size()-1));
}

public void invalidateItemLanesAfter(int position) {
if (mItemEntries == null || position >= mItemEntries.length) {
if (mItemEntries.size()==0 || position > mItemEntries.keyAt(mItemEntries.size()-1)) {
return;
}

for (int i = position; i < mItemEntries.length; i++) {
final ItemEntry entry = mItemEntries[i];
if (entry != null) {
entry.invalidateLane();
}
for (int i = position; i < mItemEntries.size(); i++) {
final ItemEntry entry = mItemEntries.valueAt(i);
entry.invalidateLane();
}
}

public void clear() {
if (mItemEntries != null) {
Arrays.fill(mItemEntries, null);
}
mItemEntries.clear();
}

void offsetForRemoval(int positionStart, int itemCount) {
if (mItemEntries == null || positionStart >= mItemEntries.length) {
return;
}

ensureSize(positionStart + itemCount);
for(int n = 0; n < (mItemEntries.size() - positionStart - itemCount); n++) {

int actualPosition = positionStart+itemCount+n;
int movedPosition = positionStart+n;

ItemEntry temp = mItemEntries.get(actualPosition);
mItemEntries.remove(actualPosition);
mItemEntries.put(movedPosition, temp);

}

System.arraycopy(mItemEntries, positionStart + itemCount, mItemEntries, positionStart,
mItemEntries.length - positionStart - itemCount);
Arrays.fill(mItemEntries, mItemEntries.length - itemCount, mItemEntries.length, null);
}

void offsetForAddition(int positionStart, int itemCount) {
if (mItemEntries == null || positionStart >= mItemEntries.length) {
return;
}

ensureSize(positionStart + itemCount);
for(int n = 0; n < itemCount; n++) {

int actualPosition = positionStart+n;
int movedPosition = positionStart+itemCount+n;

ItemEntry temp = mItemEntries.get(actualPosition);
mItemEntries.remove(actualPosition);
mItemEntries.put(movedPosition, temp);

}

System.arraycopy(mItemEntries, positionStart, mItemEntries, positionStart + itemCount,
mItemEntries.length - positionStart - itemCount);
Arrays.fill(mItemEntries, positionStart, positionStart + itemCount, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ private boolean isSecondLane(BaseLayoutManager lm, int itemPosition, int lane) {
previousPosition--;
}

final int previousLaneSpan = lm.getLaneSpanForPosition(previousPosition);
if (previousLane == 0) {
return (lane == previousLane + previousLaneSpan);
if(previousPosition>=0) {
final int previousLaneSpan = lm.getLaneSpanForPosition(previousPosition);
if (previousLane == 0) {
return (lane == previousLane + previousLaneSpan);
}
}

return false;
Expand Down