StaggeredGridLayoutManager错位(二)
StaggeredGridLayoutManager dislocation (2)
同样的问题,不知道这算不算重复。
我对 Android 的 StaggeredGridLayoutManager
有疑问。问题的描述和StaggeredGridLayoutManager dislocation.
差不多
这是屏幕截图(对审查感到抱歉,这些是 CardViews
):
适配器:
public class ProductItemStaggeredAdapter extends RecyclerView.Adapter<ViewHolderRVProductItem> {
public ProductItemStaggeredAdapter(RealmResults<ProductItem> items, int theme) {
mItems = items;
this.theme = theme;
setHasStableIds(true);
}
@Override
public ViewHolderRVProductItem onCreateViewHolder(final ViewGroup parent, final int viewType) {
Context context = parent.getContext();
int blackGrey1 = ContextCompat.getColor(context, R.color.black_grey1);
int white = ContextCompat.getColor(context, R.color.white);
LayoutInflater inflater = LayoutInflater.from(context);
View view;
ViewHolderRVProductItem vh = null;
switch (viewType) {
case 100:
/** Error **/
view = inflater.inflate(R.layout.item_retry, parent, false);
StaggeredGridLayoutManager.LayoutParams lp3 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp3.setFullSpan(true);
view.setLayoutParams(lp3);
view.setOnClickListener(retryClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case 101:
/** Loading **/
view = inflater.inflate(R.layout.item_loading, parent, false);
StaggeredGridLayoutManager.LayoutParams lp4 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp4.setFullSpan(true);
view.setLayoutParams(lp4);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.ONE:
/**
* This banner occupies 1 column of the screen
* The height is set programmatically based on screen width
*
* Product image ratio is 32 x 15
*/
view = inflater.inflate(R.layout.item_banner_big, parent, false);
view.setOnClickListener(productClickListener);
StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp.setFullSpan(true);
view.setLayoutParams(lp);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.TWO:
/**
* This banner occupies 1 column of the screen
* The height is smaller than BANNER_ONE
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_big, parent, false);
view.setOnClickListener(productClickListener);
StaggeredGridLayoutManager.LayoutParams lp2 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp2.setFullSpan(true);
view.setLayoutParams(lp2);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.THREE:
/**
* This banner occupies 3 column of the screen
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_long_rect, parent, false);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.FOUR:
/**
* This banner occupies 3 column of the screen
* The height is smaller than BANNER_THREE
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_long_rect, parent, false);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
default: /** ProductItem.BANNER_FIVE **/
/**
* This banner occupies 2 column of the screen
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_recommended, parent, false);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
}
/** Set image ratio **/
if (vh.productImage != null) {
final ViewHolderRVProductItem finalVh = vh;
vh.itemView.post(new Runnable() {
@Override
public void run() {
setImageRatio(finalVh.productImage, viewType, finalVh.productImage.getWidth());
}
});
}
return vh;
}
@Override
public void onBindViewHolder(final ViewHolderRVProductItem holder, final int position) {
if (holder == null) return;
final Context context = holder.itemView.getContext();
final ProductItem item = mItems.get(position);
holder.itemView.setTag(item);
final int bannerType = holder.getItemViewType();
final Banner banner = bannerType == Banner.ONE ? item.getBanner1() : (bannerType == Banner.FIVE ? item.getBanner5() : (bannerType == Banner.TWO ? item.getBanner2() : (bannerType == Banner.THREE ? item.getBanner3() : item.getBanner4())));
if (banner != null && holder.productImage != null) {
holder.productImage.post(new Runnable() {
@Override
public void run() {
float width = holder.productImage.getWidth();
float height = holder.productImage.getHeight();
Picasso.with(context)
.load(banner.getImageURL6())
.resize((int) width, (int) height)
.into(holder.productImage);
}
});
}
}
private void setImageRatio(ImageView imgview, int bannerType, int width) {
Context context = imgview.getContext();
switch (bannerType) {
case Banner.ONE:
/** Product image ratio is 32 x 15 **/
float height = (15f / 32f) * width;
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imgview.getLayoutParams();
params.width = width;
params.height = (int) height;
imgview.setLayoutParams(params);
break;
case Banner.TWO:
/** Product image ratio is 11 x 3 **/
float height1 = (3f / 11f) * width;
LinearLayout.LayoutParams params1 = (LinearLayout.LayoutParams) imgview.getLayoutParams();
params1.width = width;
params1.height = (int) height1;
imgview.setLayoutParams(params1);
break;
case Banner.THREE:
/** Product image ratio: 27 x 40 **/
float height2 = (40f / 27f) * width;
RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) imgview.getLayoutParams();
params2.width = (int) width;
params2.height = (int) height2;
imgview.setLayoutParams(params2);
break;
case Banner.FOUR:
int dip8 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8f, context.getResources().getDisplayMetrics());
/** Product image ratio: 1 x 1 **/
int size = (int) width - dip8;
RelativeLayout.LayoutParams params3 = (RelativeLayout.LayoutParams) imgview.getLayoutParams();
params3.width = size;
params3.height = size;
params3.leftMargin = dip8;
params3.topMargin = dip8;
params3.rightMargin = dip8;
imgview.setLayoutParams(params3);
break;
case Banner.FIVE:
/** Product image ratio: 162 x 71 **/
float height3 = (71f / 162f) * width;
RelativeLayout.LayoutParams params4 = (RelativeLayout.LayoutParams) imgview.getLayoutParams();
params4.width = (int) width;
params4.height = (int) height3;
imgview.setLayoutParams(params4);
break;
}
}
}
previous problem 和这个问题所做的事情是以编程方式更改 ImageView
宽度和高度。为什么更改 View
的布局会对 RecyclerView
产生影响?
我找到了最终解决方案。我没有使用 previous solution,而是找到了罪魁祸首:
final ViewHolderRVProductItem finalVh = vh;
vh.itemView.post(new Runnable() {
@Override
public void run() {
setImageRatio(finalVh.productImage, viewType, finalVh.productImage.getWidth());
}
});
我认为不建议在适配器中使用 post
修改 ImageView
的大小。我现在正在使用 AspectRatioImageView
并且运行顺利。
同样的问题,不知道这算不算重复。
我对 Android 的 StaggeredGridLayoutManager
有疑问。问题的描述和StaggeredGridLayoutManager dislocation.
这是屏幕截图(对审查感到抱歉,这些是 CardViews
):
适配器:
public class ProductItemStaggeredAdapter extends RecyclerView.Adapter<ViewHolderRVProductItem> {
public ProductItemStaggeredAdapter(RealmResults<ProductItem> items, int theme) {
mItems = items;
this.theme = theme;
setHasStableIds(true);
}
@Override
public ViewHolderRVProductItem onCreateViewHolder(final ViewGroup parent, final int viewType) {
Context context = parent.getContext();
int blackGrey1 = ContextCompat.getColor(context, R.color.black_grey1);
int white = ContextCompat.getColor(context, R.color.white);
LayoutInflater inflater = LayoutInflater.from(context);
View view;
ViewHolderRVProductItem vh = null;
switch (viewType) {
case 100:
/** Error **/
view = inflater.inflate(R.layout.item_retry, parent, false);
StaggeredGridLayoutManager.LayoutParams lp3 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp3.setFullSpan(true);
view.setLayoutParams(lp3);
view.setOnClickListener(retryClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case 101:
/** Loading **/
view = inflater.inflate(R.layout.item_loading, parent, false);
StaggeredGridLayoutManager.LayoutParams lp4 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp4.setFullSpan(true);
view.setLayoutParams(lp4);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.ONE:
/**
* This banner occupies 1 column of the screen
* The height is set programmatically based on screen width
*
* Product image ratio is 32 x 15
*/
view = inflater.inflate(R.layout.item_banner_big, parent, false);
view.setOnClickListener(productClickListener);
StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp.setFullSpan(true);
view.setLayoutParams(lp);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.TWO:
/**
* This banner occupies 1 column of the screen
* The height is smaller than BANNER_ONE
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_big, parent, false);
view.setOnClickListener(productClickListener);
StaggeredGridLayoutManager.LayoutParams lp2 = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
lp2.setFullSpan(true);
view.setLayoutParams(lp2);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.THREE:
/**
* This banner occupies 3 column of the screen
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_long_rect, parent, false);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
case Banner.FOUR:
/**
* This banner occupies 3 column of the screen
* The height is smaller than BANNER_THREE
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_long_rect, parent, false);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
default: /** ProductItem.BANNER_FIVE **/
/**
* This banner occupies 2 column of the screen
* The height is set programmatically based on screen width
*/
view = inflater.inflate(R.layout.item_banner_recommended, parent, false);
view.setOnClickListener(productClickListener);
vh = new ViewHolderRVProductItem(view);
break;
}
/** Set image ratio **/
if (vh.productImage != null) {
final ViewHolderRVProductItem finalVh = vh;
vh.itemView.post(new Runnable() {
@Override
public void run() {
setImageRatio(finalVh.productImage, viewType, finalVh.productImage.getWidth());
}
});
}
return vh;
}
@Override
public void onBindViewHolder(final ViewHolderRVProductItem holder, final int position) {
if (holder == null) return;
final Context context = holder.itemView.getContext();
final ProductItem item = mItems.get(position);
holder.itemView.setTag(item);
final int bannerType = holder.getItemViewType();
final Banner banner = bannerType == Banner.ONE ? item.getBanner1() : (bannerType == Banner.FIVE ? item.getBanner5() : (bannerType == Banner.TWO ? item.getBanner2() : (bannerType == Banner.THREE ? item.getBanner3() : item.getBanner4())));
if (banner != null && holder.productImage != null) {
holder.productImage.post(new Runnable() {
@Override
public void run() {
float width = holder.productImage.getWidth();
float height = holder.productImage.getHeight();
Picasso.with(context)
.load(banner.getImageURL6())
.resize((int) width, (int) height)
.into(holder.productImage);
}
});
}
}
private void setImageRatio(ImageView imgview, int bannerType, int width) {
Context context = imgview.getContext();
switch (bannerType) {
case Banner.ONE:
/** Product image ratio is 32 x 15 **/
float height = (15f / 32f) * width;
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imgview.getLayoutParams();
params.width = width;
params.height = (int) height;
imgview.setLayoutParams(params);
break;
case Banner.TWO:
/** Product image ratio is 11 x 3 **/
float height1 = (3f / 11f) * width;
LinearLayout.LayoutParams params1 = (LinearLayout.LayoutParams) imgview.getLayoutParams();
params1.width = width;
params1.height = (int) height1;
imgview.setLayoutParams(params1);
break;
case Banner.THREE:
/** Product image ratio: 27 x 40 **/
float height2 = (40f / 27f) * width;
RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) imgview.getLayoutParams();
params2.width = (int) width;
params2.height = (int) height2;
imgview.setLayoutParams(params2);
break;
case Banner.FOUR:
int dip8 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8f, context.getResources().getDisplayMetrics());
/** Product image ratio: 1 x 1 **/
int size = (int) width - dip8;
RelativeLayout.LayoutParams params3 = (RelativeLayout.LayoutParams) imgview.getLayoutParams();
params3.width = size;
params3.height = size;
params3.leftMargin = dip8;
params3.topMargin = dip8;
params3.rightMargin = dip8;
imgview.setLayoutParams(params3);
break;
case Banner.FIVE:
/** Product image ratio: 162 x 71 **/
float height3 = (71f / 162f) * width;
RelativeLayout.LayoutParams params4 = (RelativeLayout.LayoutParams) imgview.getLayoutParams();
params4.width = (int) width;
params4.height = (int) height3;
imgview.setLayoutParams(params4);
break;
}
}
}
previous problem 和这个问题所做的事情是以编程方式更改 ImageView
宽度和高度。为什么更改 View
的布局会对 RecyclerView
产生影响?
我找到了最终解决方案。我没有使用 previous solution,而是找到了罪魁祸首:
final ViewHolderRVProductItem finalVh = vh;
vh.itemView.post(new Runnable() {
@Override
public void run() {
setImageRatio(finalVh.productImage, viewType, finalVh.productImage.getWidth());
}
});
我认为不建议在适配器中使用 post
修改 ImageView
的大小。我现在正在使用 AspectRatioImageView
并且运行顺利。