提交 42dff21f 编写于 作者: T Takeshi Hagikura 提交者: Takeshi Hagikura

Extract the common logic to calculate the initial flex lines (#128)

Extract the common logic to calculate the initial flex lines from the
FlexboxLayout to FlexboxHelper to re-use it from the FlexboxLayout and the
FlexboxLayoutManager.
上级 8b999bd3
......@@ -74,8 +74,8 @@ public class FlexboxLayoutFragment extends Fragment {
mFlexContainer.addView(textView);
}
} else {
for (int i = 0; i < mFlexContainer.getChildCount(); i++) {
mFlexContainer.getChildAt(i).setOnClickListener(
for (int i = 0; i < mFlexContainer.getFlexItemCount(); i++) {
mFlexContainer.getFlexItemAt(i).setOnClickListener(
new FlexItemClickListener(activity,
new FlexItemChangedListenerImpl(mFlexContainer), i));
}
......@@ -86,7 +86,7 @@ public class FlexboxLayoutFragment extends Fragment {
addFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int viewIndex = mFlexContainer.getChildCount();
int viewIndex = mFlexContainer.getFlexItemCount();
// index starts from 0. New View's index is N if N views ([0, 1, 2, ... N-1])
// exist.
TextView textView = createBaseFlexItemTextView(activity, viewIndex);
......@@ -107,10 +107,10 @@ public class FlexboxLayoutFragment extends Fragment {
removeFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mFlexContainer.getChildCount() == 0) {
if (mFlexContainer.getFlexItemCount() == 0) {
return;
}
mFlexContainer.removeViewAt(mFlexContainer.getChildCount() - 1);
mFlexContainer.removeViewAt(mFlexContainer.getFlexItemCount() - 1);
}
});
}
......@@ -120,8 +120,8 @@ public class FlexboxLayoutFragment extends Fragment {
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
ArrayList<FlexItem> flexItems = new ArrayList<>();
for (int i = 0; i < mFlexContainer.getChildCount(); i++) {
View child = mFlexContainer.getChildAt(i);
for (int i = 0; i < mFlexContainer.getFlexItemCount(); i++) {
View child = mFlexContainer.getFlexItemAt(i);
flexItems.add((FlexItem) child.getLayoutParams());
}
outState.putParcelableArrayList(FLEX_ITEMS_KEY, flexItems);
......
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.apps.flexbox;
import com.google.android.apps.flexbox.recyclerview.FlexItemAdapter;
......@@ -64,10 +80,13 @@ public class RecyclerViewFragment extends Fragment {
removeFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (flexboxLayoutManager.getChildCount() == 0) {
if (adapter.getItemCount() == 0) {
return;
}
flexboxLayoutManager.removeViewAt(flexboxLayoutManager.getChildCount() - 1);
adapter.removeFlexItem(adapter.getItemCount() - 1);
// TODO: Specify index?
adapter.notifyDataSetChanged();
}
});
}
......
......@@ -35,7 +35,7 @@ public class FlexItemChangedListenerImpl implements FlexItemChangedListener {
@Override
public void onFlexItemChanged(FlexItem flexItem, int viewIndex) {
View view = mFlexContainer.getChildAt(viewIndex);
View view = mFlexContainer.getFlexItemAt(viewIndex);
view.setLayoutParams((FlexboxLayout.LayoutParams) flexItem);
}
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.apps.flexbox.recyclerview;
import com.google.android.apps.flexbox.R;
......@@ -39,6 +55,7 @@ public class FlexItemAdapter extends RecyclerView.Adapter<FlexItemViewHolder> {
holder.mTextView.setText(String.valueOf(position + 1));
holder.mTextView.setBackgroundResource(R.drawable.flex_item_background);
holder.mTextView.setGravity(Gravity.CENTER);
holder.mItemView.setLayoutParams((RecyclerView.LayoutParams) mFlexItems.get(position));
}
public void addFlexItem(FlexItem flexItem) {
......
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.apps.flexbox.recyclerview;
import com.google.android.apps.flexbox.R;
......@@ -12,10 +28,12 @@ import android.widget.TextView;
public class FlexItemViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
View mItemView;
public FlexItemViewHolder(View itemView) {
super(itemView);
mItemView = itemView;
mTextView = (TextView) itemView.findViewById(R.id.textview);
}
}
......@@ -13,8 +13,7 @@ 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.
-->
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Fake implementation of {@link FlexContainer}.
*/
class FakeFlexContainer implements FlexContainer {
private List<View> mViews = new ArrayList<>();
private List<FlexLine> mFlexLines = new ArrayList<>();
@FlexDirection
private int mFlexDirection = FlexDirection.ROW;
@FlexWrap
private int mFlexWrap = FlexWrap.WRAP;
@JustifyContent
private int mJustifyContent = JustifyContent.FLEX_START;
@AlignItems
private int mAlignItems = AlignItems.STRETCH;
@AlignContent
private int mAlignContent = AlignContent.STRETCH;
@Override
public int getFlexItemCount() {
return mViews.size();
}
@Override
public View getFlexItemAt(int index) {
return mViews.get(index);
}
@Override
public View getReorderedFlexItemAt(int index) {
return mViews.get(index);
}
@Override
public void addView(View view) {
mViews.add(view);
}
@Override
public void addView(View view, int index) {
mViews.add(index, view);
}
@Override
public void removeAllViews() {
mViews.clear();
}
@Override
public void removeViewAt(int index) {
mViews.remove(index);
}
@Override
public int getFlexDirection() {
return mFlexDirection;
}
@Override
public void setFlexDirection(@FlexDirection int flexDirection) {
mFlexDirection = flexDirection;
}
@Override
public int getFlexWrap() {
return mFlexWrap;
}
@Override
public void setFlexWrap(@FlexWrap int flexWrap) {
mFlexWrap = flexWrap;
}
@Override
public int getJustifyContent() {
return mJustifyContent;
}
@Override
public void setJustifyContent(@JustifyContent int justifyContent) {
mJustifyContent = justifyContent;
}
@Override
public int getAlignContent() {
return mAlignContent;
}
@Override
public void setAlignContent(@AlignContent int alignContent) {
mAlignContent = alignContent;
}
@Override
public int getAlignItems() {
return mAlignItems;
}
@Override
public void setAlignItems(@AlignItems int alignItems) {
mAlignItems = alignItems;
}
@Override
public List<FlexLine> getFlexLines() {
return mFlexLines;
}
@Override
public int getDecorationLength(int childAbsoluteIndex, int childRelativeIndexInFlexLine,
FlexItem flexItem) {
return 0;
}
@Override
public int getPaddingTop() {
return 0;
}
@Override
public int getPaddingLeft() {
return 0;
}
@Override
public int getPaddingRight() {
return 0;
}
@Override
public int getPaddingBottom() {
return 0;
}
@Override
public int getPaddingStart() {
return 0;
}
@Override
public int getPaddingEnd() {
return 0;
}
@Override
public int getChildWidthMeasureSpec(int widthSpec, int padding, int childDimension) {
return ViewGroup.getChildMeasureSpec(widthSpec, padding, childDimension);
}
@Override
public int getChildHeightMeasureSpec(int heightSpec, int padding, int childDimension) {
return ViewGroup.getChildMeasureSpec(heightSpec, padding, childDimension);
}
@Override
public void onNewFlexItemAdded(int childAbsoluteIndex, int childRelativeIndexInFlexLine,
FlexLine flexLine) {
// No op
}
@Override
public void onNewFlexLineAdded(FlexLine flexLine) {
// No op
}
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox;
import com.google.android.flexbox.test.FlexboxTestActivity;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import android.app.Activity;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.view.View;
import static junit.framework.Assert.assertEquals;
/**
* Unit tests for {@link FlexboxHelper}.
*/
@RunWith(AndroidJUnit4.class)
public class FlexboxHelperTest {
@Rule
public ActivityTestRule<FlexboxTestActivity> mActivityRule =
new ActivityTestRule<>(FlexboxTestActivity.class);
private FlexboxHelper mFlexboxHelper;
private FlexContainer mFlexContainer;
@Before
public void setUp() {
mFlexContainer = new FakeFlexContainer();
mFlexboxHelper = new FlexboxHelper(mFlexContainer);
}
@Test
public void testCalculateHorizontalFlexLines() throws Throwable {
Activity activity = mActivityRule.getActivity();
FlexboxLayout.LayoutParams lp1 = new FlexboxLayout.LayoutParams(100, 100);
View view1 = new View(activity);
view1.setLayoutParams(lp1);
FlexboxLayout.LayoutParams lp2 = new FlexboxLayout.LayoutParams(200, 100);
View view2 = new View(activity);
view2.setLayoutParams(lp2);
FlexboxLayout.LayoutParams lp3 = new FlexboxLayout.LayoutParams(300, 100);
View view3 = new View(activity);
view3.setLayoutParams(lp3);
FlexboxLayout.LayoutParams lp4 = new FlexboxLayout.LayoutParams(400, 100);
View view4 = new View(activity);
view4.setLayoutParams(lp4);
mFlexContainer.addView(view1);
mFlexContainer.addView(view2);
mFlexContainer.addView(view3);
mFlexContainer.addView(view4);
mFlexContainer.setFlexWrap(FlexWrap.WRAP);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec
.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED);
FlexboxHelper.FlexLinesResult result = mFlexboxHelper
.calculateHorizontalFlexLines(widthMeasureSpec, heightMeasureSpec);
assertEquals(3, result.mFlexLines.size());
assertEquals(300, result.mFlexLines.get(0).getMainSize());
assertEquals(300, result.mFlexLines.get(1).getMainSize());
assertEquals(400, result.mFlexLines.get(2).getMainSize());
assertEquals(100, result.mFlexLines.get(0).getCrossSize());
assertEquals(100, result.mFlexLines.get(1).getCrossSize());
assertEquals(100, result.mFlexLines.get(2).getCrossSize());
}
@Test
public void testCalculateVerticalFlexLines() throws Throwable {
Activity activity = mActivityRule.getActivity();
FlexboxLayout.LayoutParams lp1 = new FlexboxLayout.LayoutParams(100, 100);
View view1 = new View(activity);
view1.setLayoutParams(lp1);
FlexboxLayout.LayoutParams lp2 = new FlexboxLayout.LayoutParams(100, 200);
View view2 = new View(activity);
view2.setLayoutParams(lp2);
FlexboxLayout.LayoutParams lp3 = new FlexboxLayout.LayoutParams(100, 300);
View view3 = new View(activity);
view3.setLayoutParams(lp3);
FlexboxLayout.LayoutParams lp4 = new FlexboxLayout.LayoutParams(100, 400);
View view4 = new View(activity);
view4.setLayoutParams(lp4);
mFlexContainer.addView(view1);
mFlexContainer.addView(view2);
mFlexContainer.addView(view3);
mFlexContainer.addView(view4);
mFlexContainer.setFlexWrap(FlexWrap.WRAP);
mFlexContainer.setFlexDirection(FlexDirection.COLUMN);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY);
FlexboxHelper.FlexLinesResult result = mFlexboxHelper
.calculateVerticalFlexLines(widthMeasureSpec, heightMeasureSpec);
assertEquals(3, result.mFlexLines.size());
assertEquals(300, result.mFlexLines.get(0).getMainSize());
assertEquals(300, result.mFlexLines.get(1).getMainSize());
assertEquals(400, result.mFlexLines.get(2).getMainSize());
assertEquals(100, result.mFlexLines.get(0).getCrossSize());
assertEquals(100, result.mFlexLines.get(1).getCrossSize());
assertEquals(100, result.mFlexLines.get(2).getCrossSize());
}
}
......@@ -27,21 +27,21 @@ import java.util.List;
public interface FlexContainer {
/**
* @return the number of child count contained in the flex container.
* @return the number of flex items contained in the flex container.
*/
int getChildCount();
int getFlexItemCount();
/**
* Returns the view at the given index.
* Returns a flex item as a View at the given index.
*
* @param index the index
* @return the view at the index
*/
View getChildAt(int index);
View getFlexItemAt(int index);
/**
* Returns a View, which is reordered by taking the order attribute into account.
* Returns a flex item as a View, which is reordered by taking the order attribute into
* account.
*
* @param index the index of the view
* @return the reordered view, which order attribute is taken into account.
......@@ -49,7 +49,7 @@ public interface FlexContainer {
* returns {@code null}.
* @see FlexItem#getOrder()
*/
View getReorderedChildAt(int index);
View getReorderedFlexItemAt(int index);
/**
* Adds the view to the flex container as a flex item.
......@@ -159,4 +159,82 @@ public interface FlexContainer {
* returned list are not reflected to the original list.
*/
List<FlexLine> getFlexLines();
/**
* Returns the length of decoration (such as deviders) of the flex item
*
* @param childAbsoluteIndex the absolute index of the flex item within the flex
* container
* @param childRelativeIndexInFlexLine the relative index of the flex item within the flex line
* @param flexItem the flex item from which the lenght of the decoration is
* calculated
* @return the length of the decoration. Note that the length of the flex item itself is not
* included in the result.
*/
int getDecorationLength(int childAbsoluteIndex,
int childRelativeIndexInFlexLine, FlexItem flexItem);
/**
* @return the top padding of the flex container.
*/
int getPaddingTop();
/**
* @return the left padding of the flex container.
*/
int getPaddingLeft();
/**
* @return the right padding of the flex container.
*/
int getPaddingRight();
/**
* @return the bottom padding of the flex container.
*/
int getPaddingBottom();
/**
* @return the start padding of this view depending on its resolved layout direction.
*/
int getPaddingStart();
/**
* @return the end padding of this view depending on its resolved layout direction.
*/
int getPaddingEnd();
/**
* Returns the child measure spec for its width.
*
* @param widthSpec the measure spec for the width imposed by the parent
* @param padding the padding along the width for the parent
* @param childDimension the value of the child dimension
*/
int getChildWidthMeasureSpec(int widthSpec, int padding, int childDimension);
/**
* Returns the child measure spec for its height.
*
* @param heightSpec the measure spec for the height imposed by the parent
* @param padding the padding along the height for the parent
* @param childDimension the value of the child dimension
*/
int getChildHeightMeasureSpec(int heightSpec, int padding, int childDimension);
/**
* Callback when a new flex item is added to the current container
*
* @param index the absolute index of the flex item added
* @param indexInFlexLine the relative index of the flex item added within the flex line
* @param flexLine the flex line where the new flex item is added
*/
void onNewFlexItemAdded(int index, int indexInFlexLine, FlexLine flexLine);
/**
* Callback when a new flex line is added to the current container
*
* @param flexLine the new added flex line
*/
void onNewFlexLineAdded(FlexLine flexLine);
}
......@@ -238,4 +238,34 @@ public interface FlexItem extends Parcelable {
* @param flexBasisPercent the order attribute
*/
void setFlexBasisPercent(float flexBasisPercent);
/**
* @return the left margin of the flex item.
*/
int getMarginLeft();
/**
* @return the top margin of the flex item.
*/
int getMarginTop();
/**
* @return the right margin of the flex item.
*/
int getMarginRight();
/**
* @return the bottom margin of the flex item.
*/
int getMarginBottom();
/**
* @return the start margin of the flex item depending on its resolved layout direction.
*/
int getMarginStart();
/**
* @return the end margin of the flex item depending on its resolved layout direction.
*/
int getMarginEnd();
}
......@@ -22,6 +22,7 @@ import android.os.Parcelable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
......@@ -35,6 +36,10 @@ import java.util.List;
*/
public class FlexboxLayoutManager extends RecyclerView.LayoutManager implements FlexContainer {
private static final String TAG = "FlexboxLayoutManager";
private static final boolean DEBUG = false;
/**
* The current value of the {@link FlexDirection}, the default value is {@link
* FlexDirection#ROW}.
......@@ -68,6 +73,22 @@ public class FlexboxLayoutManager extends RecyclerView.LayoutManager implements
private final FlexboxHelper mFlexboxHelper = new FlexboxHelper(this);
/**
* A snapshot of the {@link RecyclerView.Recycler} instance at a given moment.
* It's not guaranteed that this instance has a reference to the latest Recycler.
* When you want to use the latest Recycler, use the one passed as an method argument
* (such as the one in {@link #onLayoutChildren(RecyclerView.Recycler, RecyclerView.State)})
*/
private RecyclerView.Recycler mRecycler;
/**
* A snapshot of the {@link RecyclerView.State} instance at a given moment.
* It's not guaranteed that this instance has a reference to the latest State.
* When you want to use the latest State, use the one passed as an method argument
* (such as the one in {@link #onLayoutChildren(RecyclerView.Recycler, RecyclerView.State)})
*/
private RecyclerView.State mState;
/**
* Creates a default FlexboxLayoutManager.
*/
......@@ -142,6 +163,7 @@ public class FlexboxLayoutManager extends RecyclerView.LayoutManager implements
setAutoMeasureEnabled(true);
}
// From here, methods from FlexContainer
@FlexDirection
@Override
public int getFlexDirection() {
......@@ -225,33 +247,49 @@ public class FlexboxLayoutManager extends RecyclerView.LayoutManager implements
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
public int getDecorationLength(int childAbsoluteIndex, int childRelativeIndexInFlexLine,
FlexItem flexItem) {
// TODO: Implement the method
return 0;
}
@Override
public RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
return new LayoutParams(c, attrs);
public void onNewFlexItemAdded(int childAbsoluteIndex, int childRelativeIndexInFlexLine,
FlexLine flexLine) {
// TODO: Implement the method
}
/**
* @return the number of flex items contained in the flex container.
* This method doesn't always reflect the latest state of the adapter.
* If you want to access the latest state of the adapter, use the {@link RecyclerView.State}
* instance passed as an argument for some methods (such as
* {@link #onLayoutChildren(RecyclerView.Recycler, RecyclerView.State)})
*
* This method is used to avoid the implementation of the similar method.
* i.e. {@link FlexboxLayoutManager#getChildCount()} returns the child count, but it doesn't
* include the children that are detached or scrapped.
*/
@Override
public boolean checkLayoutParams(RecyclerView.LayoutParams lp) {
return lp instanceof LayoutParams;
public int getFlexItemCount() {
return mState.getItemCount();
}
/**
* @return the flex item as a view specified as the index.
* This method doesn't always return the latest state of the view in the adapter.
* If you want to access the latest state, use the {@link RecyclerView.Recycler}
* instance passed as an argument for some methods (such as
* {@link #onLayoutChildren(RecyclerView.Recycler, RecyclerView.State)})
*
* This method is used to avoid the implementation of the similar method.
* i.e. {@link FlexboxLayoutManager#getChildAt(int)} returns a view for the given index,
* but the index is based on the layout position, not based on the adapter position, which
* isn't desired given the usage of this method.
*/
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() == 0) {
detachAndScrapAttachedViews(recycler);
return;
}
int childCount = getChildCount();
if (childCount == 0 && state.isPreLayout()) {
return;
}
mFlexboxHelper.createReorderedIndices();
//TODO: Implement the rest of the method
public View getFlexItemAt(int index) {
return mRecycler.getViewForPosition(index);
}
/**
......@@ -267,7 +305,130 @@ public class FlexboxLayoutManager extends RecyclerView.LayoutManager implements
if (index < 0 || index >= mFlexboxHelper.mReorderedIndices.length) {
return null;
}
return getChildAt(mFlexboxHelper.mReorderedIndices[index]);
return mRecycler.getViewForPosition(mFlexboxHelper.mReorderedIndices[index]);
}
@Override
public View getReorderedFlexItemAt(int index) {
return getReorderedChildAt(index);
}
@Override
public void onNewFlexLineAdded(FlexLine flexLine) {
// No op
}
@Override
public int getChildWidthMeasureSpec(int widthSpec, int padding, int childDimension) {
return getChildMeasureSpec(getWidth(), getWidthMode(), padding, childDimension,
canScrollHorizontally());
}
@Override
public int getChildHeightMeasureSpec(int heightSpec, int padding, int childDimension) {
return getChildMeasureSpec(getHeight(), getHeightMode(), padding, childDimension,
canScrollVertically());
}
// The end of methods from FlexContainer
private int getLargestMainSize() {
int largest = 0;
for (int i = 0, size = mFlexLines.size(); i < size; i++) {
FlexLine flexLine = mFlexLines.get(i);
largest = Math.max(largest, flexLine.getMainSize());
}
return largest;
}
private int getSumOfCrossSize() {
int sum = 0;
for (int i = 0, size = mFlexLines.size(); i < size; i++) {
FlexLine flexLine = mFlexLines.get(i);
sum += flexLine.mCrossSize;
}
return sum;
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@Override
public RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
return new LayoutParams(c, attrs);
}
@Override
public boolean checkLayoutParams(RecyclerView.LayoutParams lp) {
return lp instanceof LayoutParams;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (DEBUG) {
Log.i(TAG,
String.format("onLayoutChildren. recycler.getScrapList.size(): %s, state: %s",
recycler.getScrapList().size(), state));
Log.i(TAG, String.format("getChildCount: %d", getChildCount()));
}
// Assign the Recycler and the State as the member variables so that
// the method from FlexContainer (such as getFlexItemCount()) returns the number of
// flex items from the adapter not the child count in the LayoutManager because
// LayoutManager#getChildCount doesn't include the views that are detached or scrapped.
mRecycler = recycler;
mState = state;
if (state.getItemCount() == 0) {
return;
}
int childCount = state.getItemCount();
if (childCount == 0 && state.isPreLayout()) {
return;
}
// TODO: If we support the order attribute, we need to inflate the all ViewHolders in the
// adapter instead of inflating only the visible ViewHolders, which is inefficient given
// that this is part of RecyclerView
if (mFlexboxHelper.isOrderChangedFromLastMeasurement()) {
mFlexboxHelper.mReorderedIndices = mFlexboxHelper.createReorderedIndices();
}
//noinspection ResourceType
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(getWidth(), getWidthMode());
//noinspection ResourceType
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(getHeight(), getHeightMode());
FlexboxHelper.FlexLinesResult flexLinesResult;
mFlexLines.clear();
// TODO: Change the code to calculate only the visible area
if (isMainAxisDirectionHorizontal()) {
flexLinesResult = mFlexboxHelper
.calculateHorizontalFlexLines(widthMeasureSpec, heightMeasureSpec);
} else {
flexLinesResult = mFlexboxHelper
.calculateVerticalFlexLines(widthMeasureSpec, heightMeasureSpec);
}
mFlexLines = flexLinesResult.mFlexLines;
if (DEBUG) {
for (int i = 0, size = mFlexLines.size(); i < size; i++) {
FlexLine flexLine = mFlexLines.get(i);
Log.i(TAG, String.format("%d flex line. MainSize: %d, CrossSize: %d, itemCount: %d",
i, flexLine.getMainSize(), flexLine.getCrossSize(),
flexLine.getItemCount()));
}
}
// TODO: Layout the visible ViewHolders
}
@Override
public void onAdapterChanged(RecyclerView.Adapter oldAdapter, RecyclerView.Adapter newAdapter) {
removeAllViews();
}
private boolean isMainAxisDirectionHorizontal() {
return mFlexDirection == FlexDirection.ROW || mFlexDirection == FlexDirection.ROW_REVERSE;
}
/**
......@@ -441,6 +602,26 @@ public class FlexboxLayoutManager extends RecyclerView.LayoutManager implements
this.mFlexBasisPercent = flexBasisPercent;
}
@Override
public int getMarginLeft() {
return leftMargin;
}
@Override
public int getMarginTop() {
return topMargin;
}
@Override
public int getMarginRight() {
return rightMargin;
}
@Override
public int getMarginBottom() {
return bottomMargin;
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册