J'utilise un RecyclerView qui contient CardViews avec un TextView et un ImageView (chaque carte représente une ville). J'ai également un onClickListener sur chaque carte qui m'amène à une liste de musées de la ville. (Le RecyclerView est rempli par une ArrayList). La liste est un RecyclerView composé du même Cardview qui défile verticalement.
Lorsqu'une ville n'a qu'un seul musée, comment puis-je afficher l'unique CardView au centre de l'écran?
Voici l'activité xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.bebbo203.mymuseum.MuseumActivity">
<Android.support.v7.widget.RecyclerView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:id="@+id/recyclerViewMuseum"
Android:scrollbars="vertical"
Android:scrollIndicators="none"
Android:gravity="center_horizontal"
/>
</RelativeLayout>
Et voici le xml RecyclerView:
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:baselineAligned="false"
xmlns:card_view="http://schemas.Android.com/apk/res-auto">
<Android.support.v7.widget.CardView
xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="150dp"
Android:id="@+id/cardView"
card_view:cardCornerRadius="2dp"
card_view:cardUseCompatPadding="true"
Android:gravity="center_horizontal"
Android:animateLayoutChanges="true"
>
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<ImageView
Android:layout_width="match_parent"
Android:layout_height="150dp"
Android:id="@+id/imageViewList"
Android:layout_gravity="center_horizontal|top"
Android:adjustViewBounds="true"
Android:scaleType="centerCrop"/>
<TextView
Android:id="@+id/textViewList"
Android:layout_width="match_parent"
Android:layout_height="150dp"
Android:textSize="40sp"
Android:textIsSelectable="false"
Android:textAlignment="center"
Android:gravity="fill"
Android:textStyle="bold"
Android:layout_weight="1"
Android:layout_gravity="center_horizontal|top"/>
</FrameLayout>
</Android.support.v7.widget.CardView>
</RelativeLayout>`
Merci pour ton aide.
Voici donc la MainActivity. Une liste de villes. Tout va bien ici.
Lorsque je clique sur Parigi qui n'a qu'un seul musée, je voulais montrer la vue unique de la carte au centre de l'écran
(Et si c'est possible, je voudrais faire la vue de la carte à partir du centre de l'écran, pas du haut. Comme si la vue centrale de la carte est toujours au centre lorsque j'ouvre l'activité. Par exemple, traduire NationalGallery au centre en gardant le ordre de l'autre)
J'ai implémenté une application HelloWorld simple, qui affiche la liste des villes et en fonction du nombre de musées qu'elle possède - montre la carte de la ville en taille réelle ou sa version centrée et enveloppée.
(Oui, je ne suis pas vraiment bon en arts :-))
Voici comment je l'ai fait.
La partie cruciale est ItemDecoration
: définissez les éléments corrects et vous obtiendrez ce dont vous avez besoin; Voici comment je l'ai fait:
RecyclerView recyclerViewMuseum = (RecyclerView)findViewById(R.id.recyclerViewMuseum);
recyclerViewMuseum.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerViewMuseum.setAdapter(adapter);
recyclerViewMuseum.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (view instanceof CityWithOneMuseumCardView) {
int totalWidth = parent.getWidth();
int cardWidth = getResources().getDimensionPixelOffset(R.dimen.small_card_width);
int sidePadding = (totalWidth - cardWidth) / 2;
sidePadding = Math.max(0, sidePadding);
outRect.set(sidePadding, 0, sidePadding, 0);
}
}
});
Voici mon modèle - City
et Museum
classes:
public class Museum {
public String title;
public Museum(String title) {
this.title = title;
}
}
public class City {
public String title;
public int imageRes;
public List<Museum> museums = new ArrayList<>();
public City(String title, int imageRes) {
this.title = title;
this.imageRes = imageRes;
}
}
Puis Vues: CityWithManyMuseumsCardView
et CityWithOneMuseumCardView
. Les deux utilisent l'interface d'assistance IItemDisplayer
.
public class CityWithOneMuseumCardView extends CardView implements IItemDisplayer<City> {
public CityWithOneMuseumCardView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.one_museum_layout, this);
}
@Override
public void displayItem(City city) {
TextView cityTitleTextView = (TextView)findViewById(R.id.cityTitleTextView);
cityTitleTextView.setText(city.title);
}
}
public class CityWithManyMuseumsCardView extends CardView implements IItemDisplayer<City> {
public CityWithManyMuseumsCardView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.many_museums_layout, this);
}
@Override
public void displayItem(City city) {
ImageView cityBackgroundImageView = (ImageView)findViewById(R.id.cityBackgroundImageView);
cityBackgroundImageView.setImageResource(city.imageRes);
TextView cityTitleTextView = (TextView)findViewById(R.id.cityTitleTextView);
cityTitleTextView.setText(city.title);
TextView cityNumberOrMuseumsTextView = (TextView)findViewById(R.id.cityNumberOrMuseumsTextView);
cityNumberOrMuseumsTextView.setText(String.valueOf(city.museums.size()));
}
}
public interface IItemDisplayer<TItem> {
public void displayItem(TItem item);
}
Et leurs dispositions:
<!-- One Museum card -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:background="#BB2050AB"
Android:layout_width="@dimen/small_card_width"
Android:layout_height="200dp">
<TextView
Android:background="#AA000000"
Android:textColor="#FFFFFF"
Android:text="Only one museum available"
Android:textSize="16sp"
Android:padding="4dp"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
<TextView
Android:id="@+id/cityTitleTextView"
Android:layout_gravity="bottom"
Android:background="#AAFFFFFF"
Android:textColor="#000000"
Android:textSize="24sp"
Android:paddingStart="16dp"
Android:paddingEnd="16dp"
Android:gravity="center"
Android:layout_width="match_parent"
Android:layout_height="48dp" />
</FrameLayout>
<!-- Many museums card -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="240dp">
<ImageView
Android:id="@+id/cityBackgroundImageView"
Android:scaleType="fitXY"
Android:layout_width="500dp"
Android:layout_height="match_parent" />
<TextView
Android:id="@+id/cityNumberOrMuseumsTextView"
Android:layout_gravity="top|end"
Android:background="#AA000000"
Android:textColor="#FFFFFF"
Android:textSize="16sp"
Android:padding="4dp"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
<TextView
Android:id="@+id/cityTitleTextView"
Android:layout_gravity="bottom"
Android:background="#AA000000"
Android:textColor="#FFFFFF"
Android:textSize="24sp"
Android:paddingStart="16dp"
Android:paddingEnd="16dp"
Android:gravity="center_vertical"
Android:layout_width="match_parent"
Android:layout_height="48dp" />
</FrameLayout>
Ensuite, nous devons créer un adaptateur pour notre RecyclerView
CityAdapter.Java
public class CityAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final static int ITEM_TYPE_MANY_MUSEUMS = 0;
final static int ITEM_TYPE_ONE_MUSEUM = 1;
private List<City> items;
public CityAdapter(List<City> items) {
this.items = items;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType) {
case ITEM_TYPE_MANY_MUSEUMS:
return new ViewHolder(new CityWithManyMuseumsCardView(viewGroup.getContext()));
case ITEM_TYPE_ONE_MUSEUM:
return new ViewHolder(new CityWithOneMuseumCardView(viewGroup.getContext()));
default:
throw new IllegalArgumentException(String.format("Unexpected viewType: %d", viewType));
}
}
@Override
public int getItemViewType(int position) {
if (items == null || items.size() < position) {
throw new IllegalArgumentException("Wrong position!");
}
if (items.get(position).museums.size() > 1) {
return ITEM_TYPE_MANY_MUSEUMS;
} else if (items.get(position).museums.size() == 1){
return ITEM_TYPE_ONE_MUSEUM;
}
throw new IllegalArgumentException("Wrong number of museums!");
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((IItemDisplayer<City>) holder.itemView).displayItem(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}
J'ai téléchargé ce projet dans ma boîte de dépôt - n'hésitez pas à vérifiez-le ! J'espère que cela aide.
Pouvez-vous essayer ceci:
import Android.content.Context;
import Android.graphics.Rect;
import Android.support.v4.view.ViewCompat;
import Android.support.v7.widget.RecyclerView;
import Android.util.Log;
import Android.view.View;
import Java.lang.reflect.Field;
/**
* {@link Android.support.v7.widget.LinearLayoutManager} which wraps its content. Note that this class will always
* wrap the content regardless of {@link Android.support.v7.widget.RecyclerView} layout parameters.
* <p/>
* Now it's impossible to run add/remove animations with child views which have arbitrary dimensions (height for
* VERTICAL orientation and width for HORIZONTAL). However if child views have fixed dimensions
* {@link #setChildSize(int)} method might be used to let the layout manager know how big they are going to be.
* If animations are not used at all then a normal measuring procedure will run and child views will be measured during
* the measure pass.
*/
public class WrapContentLinearLayoutManager extends Android.support.v7.widget.LinearLayoutManager {
private static boolean canMakeInsetsDirty = true;
private static Field insetsDirtyField = null;
private static final int CHILD_WIDTH = 0;
private static final int CHILD_HEIGHT = 1;
private static final int DEFAULT_CHILD_SIZE = 100;
private final int[] childDimensions = new int[2];
private final RecyclerView view;
private int childSize = DEFAULT_CHILD_SIZE;
private boolean hasChildSize;
private int overScrollMode = ViewCompat.OVER_SCROLL_ALWAYS;
private final Rect tmpRect = new Rect();
@SuppressWarnings("UnusedDeclaration")
public WrapContentLinearLayoutManager(Context context) {
super(context);
this.view = null;
}
@SuppressWarnings("UnusedDeclaration")
public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
this.view = null;
}
@SuppressWarnings("UnusedDeclaration")
public WrapContentLinearLayoutManager(RecyclerView view) {
super(view.getContext());
this.view = view;
this.overScrollMode = ViewCompat.getOverScrollMode(view);
}
@SuppressWarnings("UnusedDeclaration")
public WrapContentLinearLayoutManager(RecyclerView view, int orientation, boolean reverseLayout) {
super(view.getContext(), orientation, reverseLayout);
this.view = view;
this.overScrollMode = ViewCompat.getOverScrollMode(view);
}
public void setOverScrollMode(int overScrollMode) {
if (overScrollMode < ViewCompat.OVER_SCROLL_ALWAYS || overScrollMode > ViewCompat.OVER_SCROLL_NEVER)
throw new IllegalArgumentException("Unknown overscroll mode: " + overScrollMode);
if (this.view == null) throw new IllegalStateException("view == null");
this.overScrollMode = overScrollMode;
ViewCompat.setOverScrollMode(view, overScrollMode);
}
public static int makeUnspecifiedSpec() {
return View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
}
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
final boolean hasWidthSize = widthMode != View.MeasureSpec.UNSPECIFIED;
final boolean hasHeightSize = heightMode != View.MeasureSpec.UNSPECIFIED;
final boolean exactWidth = widthMode == View.MeasureSpec.EXACTLY;
final boolean exactHeight = heightMode == View.MeasureSpec.EXACTLY;
final int unspecified = makeUnspecifiedSpec();
if (exactWidth && exactHeight) {
// in case of exact calculations for both dimensions let's use default "onMeasure" implementation
super.onMeasure(recycler, state, widthSpec, heightSpec);
return;
}
final boolean vertical = getOrientation() == VERTICAL;
initChildDimensions(widthSize, heightSize, vertical);
int width = 0;
int height = 0;
// it's possible to get scrap views in recycler which are bound to old (invalid) adapter entities. This
// happens because their invalidation happens after "onMeasure" method. As a workaround let's clear the
// recycler now (it should not cause any performance issues while scrolling as "onMeasure" is never
// called whiles scrolling)
recycler.clear();
final int stateItemCount = state.getItemCount();
final int adapterItemCount = getItemCount();
// adapter always contains actual data while state might contain old data (f.e. data before the animation is
// done). As we want to measure the view with actual data we must use data from the adapter and not from the
// state
for (int i = 0; i < adapterItemCount; i++) {
if (vertical) {
if (!hasChildSize) {
if (i < stateItemCount) {
// we should not exceed state count, otherwise we'll get IndexOutOfBoundsException. For such items
// we will use previously calculated dimensions
measureChild(recycler, i, widthSize, unspecified, childDimensions);
} else {
logMeasureWarning(i);
}
}
height += childDimensions[CHILD_HEIGHT];
if (i == 0) {
width = childDimensions[CHILD_WIDTH];
}
if (hasHeightSize && height >= heightSize) {
break;
}
} else {
if (!hasChildSize) {
if (i < stateItemCount) {
// we should not exceed state count, otherwise we'll get IndexOutOfBoundsException. For such items
// we will use previously calculated dimensions
measureChild(recycler, i, unspecified, heightSize, childDimensions);
} else {
logMeasureWarning(i);
}
}
width += childDimensions[CHILD_WIDTH];
if (i == 0) {
height = childDimensions[CHILD_HEIGHT];
}
if (hasWidthSize && width >= widthSize) {
break;
}
}
}
if (exactWidth) {
width = widthSize;
} else {
width += getPaddingLeft() + getPaddingRight();
if (hasWidthSize) {
width = Math.min(width, widthSize);
}
}
if (exactHeight) {
height = heightSize;
} else {
height += getPaddingTop() + getPaddingBottom();
if (hasHeightSize) {
height = Math.min(height, heightSize);
}
}
setMeasuredDimension(width, height);
if (view != null && overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS) {
final boolean fit = (vertical && (!hasHeightSize || height < heightSize))
|| (!vertical && (!hasWidthSize || width < widthSize));
ViewCompat.setOverScrollMode(view, fit ? ViewCompat.OVER_SCROLL_NEVER : ViewCompat.OVER_SCROLL_ALWAYS);
}
}
private void logMeasureWarning(int child) {
if (BuildConfig.DEBUG) {
Log.w("LinearLayoutManager", "Can't measure child #" + child + ", previously used dimensions will be reused." +
"To remove this message either use #setChildSize() method or don't run RecyclerView animations");
}
}
private void initChildDimensions(int width, int height, boolean vertical) {
if (childDimensions[CHILD_WIDTH] != 0 || childDimensions[CHILD_HEIGHT] != 0) {
// already initialized, skipping
return;
}
if (vertical) {
childDimensions[CHILD_WIDTH] = width;
childDimensions[CHILD_HEIGHT] = childSize;
} else {
childDimensions[CHILD_WIDTH] = childSize;
childDimensions[CHILD_HEIGHT] = height;
}
}
@Override
public void setOrientation(int orientation) {
// might be called before the constructor of this class is called
//noinspection ConstantConditions
if (childDimensions != null) {
if (getOrientation() != orientation) {
childDimensions[CHILD_WIDTH] = 0;
childDimensions[CHILD_HEIGHT] = 0;
}
}
super.setOrientation(orientation);
}
public void clearChildSize() {
hasChildSize = false;
setChildSize(DEFAULT_CHILD_SIZE);
}
public void setChildSize(int childSize) {
hasChildSize = true;
if (this.childSize != childSize) {
this.childSize = childSize;
requestLayout();
}
}
private void measureChild(RecyclerView.Recycler recycler, int position, int widthSize, int heightSize, int[] dimensions) {
final View child;
try {
child = recycler.getViewForPosition(position);
} catch (IndexOutOfBoundsException e) {
if (BuildConfig.DEBUG) {
Log.w("LinearLayoutManager", "LinearLayoutManager doesn't work well with animations. Consider switching them off", e);
}
return;
}
final RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) child.getLayoutParams();
final int hPadding = getPaddingLeft() + getPaddingRight();
final int vPadding = getPaddingTop() + getPaddingBottom();
final int hMargin = p.leftMargin + p.rightMargin;
final int vMargin = p.topMargin + p.bottomMargin;
// we must make insets dirty in order calculateItemDecorationsForChild to work
makeInsetsDirty(p);
// this method should be called before any getXxxDecorationXxx() methods
calculateItemDecorationsForChild(child, tmpRect);
final int hDecoration = getRightDecorationWidth(child) + getLeftDecorationWidth(child);
final int vDecoration = getTopDecorationHeight(child) + getBottomDecorationHeight(child);
final int childWidthSpec = getChildMeasureSpec(widthSize, hPadding + hMargin + hDecoration, p.width, canScrollHorizontally());
final int childHeightSpec = getChildMeasureSpec(heightSize, vPadding + vMargin + vDecoration, p.height, canScrollVertically());
child.measure(childWidthSpec, childHeightSpec);
dimensions[CHILD_WIDTH] = getDecoratedMeasuredWidth(child) + p.leftMargin + p.rightMargin;
dimensions[CHILD_HEIGHT] = getDecoratedMeasuredHeight(child) + p.bottomMargin + p.topMargin;
// as view is recycled let's not keep old measured values
makeInsetsDirty(p);
recycler.recycleView(child);
}
private static void makeInsetsDirty(RecyclerView.LayoutParams p) {
if (!canMakeInsetsDirty) {
return;
}
try {
if (insetsDirtyField == null) {
insetsDirtyField = RecyclerView.LayoutParams.class.getDeclaredField("mInsetsDirty");
insetsDirtyField.setAccessible(true);
}
insetsDirtyField.set(p, true);
} catch (NoSuchFieldException e) {
onMakeInsertDirtyFailed();
} catch (IllegalAccessException e) {
onMakeInsertDirtyFailed();
}
}
private static void onMakeInsertDirtyFailed() {
canMakeInsetsDirty = false;
if (BuildConfig.DEBUG) {
Log.w("LinearLayoutManager", "Can't make LayoutParams insets dirty, decorations measurements might be incorrect");
}
}
}
Mettez ce WrapContentLinearLayoutManager dans votre vue de recyclage
mRecyclerView.setLayoutManager(new WrapContentLinearLayoutManager(activity));
Et cela dans le xml (avec le parent dans le parent)
<Android.support.v7.widget.RecyclerView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_centerInParent="true"
Android:id="@+id/recyclerViewMuseum"
Android:scrollbars="vertical"
Android:scrollIndicators="none"/>
Cela devrait fonctionner :)
Essayez de définir la hauteur de RecyclerView
lorsque vous n'avez qu'un ou plusieurs éléments. Reportez-vous à ce sujet pour le faire. Lorsque vous n'avez qu'un seul élément, définissez RecyclerView
sur WRAP_CONTENT
. Et lorsque vous avez plusieurs éléments, définissez RecyclerView
sur MATCH_CONTENT
. Bonne chance!
1.Essayez de définir LayoutParams CENTER_IN_PARENT lorsque recyclerview a 1 enfant
2. Ou utilisez un FrameLayout
comme parent de recyclerView
et définissez layout_gravity
3.Ou calculez simplement l'espace au-dessus de cardview
et définissez marginTop
sur recyclerView
ou setTranslationY
sur recyclerView 4.Ou ajoutez un itemDecaration
avec space'height à Recylerview
.
RelativeLayout.LayoutParams rLp = (RelativeLayout.LayoutParams) recyclerView.getLayoutParams();
if(data != null || data.size()>1){
rLp.removeRule(RelativeLayout.CENTER_IN_PARENT);
}else{
rLp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
}
recyclerView.setLayoutParams(rLp);
Lorsque recyclerView n'a qu'un seul enfant, utilisez ce LayoutManager:
import Android.content.Context;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.util.Log;
import Android.view.View;
import Android.view.ViewGroup;
public class FullyLinearLayoutManager extends LinearLayoutManager {
private static final String TAG = FullyLinearLayoutManager.class.getSimpleName();
private MeasureEndListener mMeasureEndListener;
public FullyLinearLayoutManager(Context context) {
super(context);
}
private float divHeight =0;
public FullyLinearLayoutManager(Context context,float height) {
super(context);
divHeight = height;
}
public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
private int[] mMeasuredDimension = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode
+ " \nheightMode " + heightSpec
+ " \nwidthSize " + widthSize
+ " \nheightSize " + heightSize
+ " \ngetItemCount() " + getItemCount());
int width = 0;
int height = 0;
for (int i = 0; i < getItemCount(); i++) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
if (getOrientation() == HORIZONTAL) {
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
// LogUtils.e(mMeasuredDimension[1]);
height = height + mMeasuredDimension[1];
if(i!= getItemCount()-1){
height += divHeight;
// LogUtils.e(divHeight + "xxx add"+DensityUtils.dp2px(divHeight));
}else{
height += 2*divHeight;
// LogUtils.e(divHeight+ "xxx no add"+ DensityUtils.dp2px(divHeight));
}
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
if(mMeasureEndListener!=null){
mMeasureEndListener.onMeasureEnd(width,height);
// new Thread().interrupt();
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public interface MeasureEndListener{
void onMeasureEnd(int width,int height);
}
public void setMeasureEndListener(MeasureEndListener mMeasureEndListener){
this.mMeasureEndListener = mMeasureEndListener;
}
}
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recyclerview"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_marginTop="@dimen/margin_twenty"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
Android:layout_marginBottom="@dimen/margin_twenty">
</Android.support.v7.widget.RecyclerView>