私のアダプタで問題が発生しています。私は、次のようにグリッドに表示画像の選択を持っている:私はアイテムの単一画面分を持っており、彼らはすべての罰金を表示するときこれがうまく機能RecyclerView - 最初のレイアウトパスをスキップするオフスクリーンアイテム
。下にスクロールする項目がさらにある場合に問題が発生します。私は、さらに項目が空白で表示され、下にスクロールするとき最初に、GridLayout
コンテナがあると、画像を表示するためのコードが実行されますが、ここで示したように、彼らが画面に表示されません。
私はスクロールするとバックアップ、そして再び下方向にスクロールし、画像が本来あるべき場所を正確に表示されます。
私はレイアウトを更新したり、何かが変更されたレンダラを伝える必要がありますように思えるが、私がしようと、何も思いません何をするにも。私はrequestLayout
とinvalidate
を呼び出そうとしましたが、問題を解決していないようです。私はGlobalOnLayoutListenerも登録しましたが、これ以上はうまくいきませんでした。ここで
は、関連するコードです:
これは私のonBindViewHolder
方法
final GridLayout grid = ((KKAlbumViewHolder) holder).mGridLayout;
grid.removeAllViews();
int width = grid.getWidth();
if(width > 0) {
albumHolder.setPreviewImages(posts);
}else {
albumHolder.itemView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
albumHolder.itemView.removeOnLayoutChangeListener(this);
albumHolder.setPreviewImages(posts);
albumHolder.mGridLayout.invalidate();
}
});
}
これは私が画像をレイアウトするために使用する方法であるからです。基本的には、不規則なグリッド内に画像を配置するので、長い画像や大きい画像がある場合、その画像は空き領域に応じて完全な行または完全な列を占めようとします。私はのparam幅と高さを設定した理由は、そうピカソが.fit()
方法文句ないんです
public void setPreviewImages(ArrayList<KKPost> posts) {
Picasso picasso = Picasso.with(itemView.getContext());
int space = 0;
int tl = 1 << 0;
int tr = 1 << 1;
int bl = 1 << 2;
int br = 1 << 3;
int lCol = tl | bl;
int rCol = tr | br;
int tRow = tl | tr;
int bRow = bl | br;
int full = lCol | rCol;
boolean hasLongImage = false;
for(KKPost post : posts) {
if(space == full){
break;
}
int margin = 2;
ImageView view = new ImageView(itemView.getContext());
GridLayout.LayoutParams param = new GridLayout.LayoutParams();
view.setBackgroundColor(Color.LTGRAY);
if(posts.size() < 4){
param.columnSpec = GridLayout.spec(0, 2);
param.rowSpec = GridLayout.spec(0, 2);
param.width = mGridLayout.getWidth();
param.height = mGridLayout.getHeight();
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
break;
}
if (post.aspectRatio >= 1.2 && !hasLongImage) {
//landscape
if((space & tRow) == 0){
param.rowSpec = GridLayout.spec(0, 1);
param.columnSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight()/2;
param.width = mGridLayout.getWidth();
param.bottomMargin = margin;
space |= tRow;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
if((space & bRow) == 0){
param.rowSpec = GridLayout.spec(1, 1);
param.columnSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight()/2;
param.width = mGridLayout.getWidth();
param.topMargin = margin;
space |= bRow;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
} else if (post.aspectRatio <= 0.8 && post.aspectRatio > 0 && !hasLongImage) {
//portrait
if((space & lCol) == 0){
param.columnSpec = GridLayout.spec(0, 1);
param.rowSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight();
param.width = mGridLayout.getWidth()/2;
param.rightMargin = margin;
space |= lCol;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
if((space & rCol) == 0){
param.columnSpec = GridLayout.spec(1, 1);
param.rowSpec = GridLayout.spec(0, 2);
param.height = mGridLayout.getHeight();
param.width = mGridLayout.getWidth()/2;
param.leftMargin = margin;
space |= rCol;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
hasLongImage = true;
continue;
}
}
//square or no space or unknown
if((space & tl) == 0){
param.columnSpec = GridLayout.spec(0,1);
param.rowSpec = GridLayout.spec(0,1);
space |= tl;
param.bottomMargin = margin;
param.rightMargin = margin;
}else
if((space & tr) == 0) {
param.columnSpec = GridLayout.spec(1,1);
param.rowSpec = GridLayout.spec(0,1);
space |= tr;
param.bottomMargin = margin;
param.leftMargin = margin;
}else
if((space & bl) == 0){
param.columnSpec = GridLayout.spec(0,1);
param.rowSpec = GridLayout.spec(1,1);
space |= bl;
param.rightMargin = margin;
param.topMargin = margin;
}else
if((space & br) == 0){
param.columnSpec = GridLayout.spec(1,1);
param.rowSpec = GridLayout.spec(1,1);
space |= br;
param.leftMargin = margin;
param.topMargin = margin;
}
param.height = mGridLayout.getHeight()/2;
param.width = mGridLayout.getWidth()/2;
mGridLayout.addView(view, param);
picasso.load(post.url).fit().centerCrop().into(view);
}
}
}
なぜこれが最初に表示項目のための第1のレンダリングパスでないうちスキップするように見えるのでしょうか?
EDIT:リファクタリングを少しして、新しいものを削除/作成するのではなく、イメージビューを再利用して、それらのアイテムに追加されたビューがonLayoutChangeコールバックを取得しないことを知りました。他のすべてのアイテムはonLayoutChangeコールバックを取得し、前と同じように、最初にコールを取得しないアイテムは、スクロールしてスクロールした後に取得します。参照:
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
view.removeOnLayoutChangeListener(this);
picasso.load(post.url).into(view);
}
});
編集:ここでは11月15日
がviewholderレイアウトのXMLあなたが指定するgetItemId(int position)
をオーバーライドする必要があることを行う場合は、setHasStableIds(true)
を持っているかどうかを
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android:id="@+id/album_card_view"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
card_view:cardCornerRadius="@dimen/feed_card_corner_radius"
card_view:cardElevation="@dimen/cardview_default_elevation"
card_view:cardMaxElevation="@dimen/cardview_default_elevation"
card_view:cardUseCompatPadding="true"
xmlns:autofit="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/percent_layout">
<GridLayout
android:background="@color/white"
android:id="@+id/preview_grid_layout"
android:columnCount="2"
android:rowCount="2"
android:alignmentMode="alignBounds"
android:layout_height="0dp"
android:layout_width="0dp"
app:layout_widthPercent="100%"
app:layout_aspectRatio="100%">
</GridLayout>
</android.support.percent.PercentRelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/card_padding_4dp"
android:orientation="vertical">
<TextView
android:id="@+id/album_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Family Photos"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
誰かがこの質問のより良いタイトルを考えることができるなら、それを自由に編集してください –
'onBindViewHolder'が呼び出されるたびに、' GridView'からすべてのイメージが置き換えられますか?どうして? – rubenlop
1つのアイテムのレイアウトには1〜4の画像がありますので、アイテムがリサイクルされたときにオーバーハングが発生します。私はImageViewsのリストを保持して、リサイクルされたときに見えなくなるように設定することができたと思うが、スクロールのパフォーマンスはまあまあだったので、レンダリングの問題よりもそれほど気にならなかった。 –